Merge branch 'for-4.20/apple' into for-linus
authorJiri Kosina <jkosina@suse.cz>
Tue, 23 Oct 2018 11:16:33 +0000 (13:16 +0200)
committerJiri Kosina <jkosina@suse.cz>
Tue, 23 Oct 2018 11:16:33 +0000 (13:16 +0200)
Support for Apple Magic Trackpad 2

2691 files changed:
.mailmap
Documentation/ABI/stable/sysfs-bus-xen-backend
Documentation/ABI/stable/sysfs-driver-mlxreg-io [new file with mode: 0644]
Documentation/ABI/testing/sysfs-driver-xen-blkback
Documentation/ABI/testing/sysfs-fs-f2fs
Documentation/admin-guide/cgroup-v2.rst
Documentation/admin-guide/kernel-parameters.txt
Documentation/arm64/sve.txt
Documentation/core-api/index.rst
Documentation/core-api/kernel-api.rst
Documentation/core-api/mm-api.rst [new file with mode: 0644]
Documentation/devicetree/bindings/arm/adapteva.txt [deleted file]
Documentation/devicetree/bindings/arm/amlogic.txt
Documentation/devicetree/bindings/arm/atmel-pmc.txt [deleted file]
Documentation/devicetree/bindings/arm/bcm/brcm,brcmstb.txt
Documentation/devicetree/bindings/arm/cpu-capacity.txt
Documentation/devicetree/bindings/arm/cpus.txt
Documentation/devicetree/bindings/arm/freescale/m4if.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/freescale/tigerp.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/fsl.txt
Documentation/devicetree/bindings/arm/idle-states.txt
Documentation/devicetree/bindings/arm/insignal-boards.txt [deleted file]
Documentation/devicetree/bindings/arm/mediatek.txt
Documentation/devicetree/bindings/arm/omap/l4.txt
Documentation/devicetree/bindings/arm/rockchip.txt
Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt
Documentation/devicetree/bindings/arm/shmobile.txt
Documentation/devicetree/bindings/arm/ti/k3.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/xilinx.txt
Documentation/devicetree/bindings/ata/ahci-platform.txt
Documentation/devicetree/bindings/ata/sata_rcar.txt
Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt [new file with mode: 0644]
Documentation/devicetree/bindings/bus/ti-sysc.txt
Documentation/devicetree/bindings/clock/at91-clock.txt
Documentation/devicetree/bindings/clock/exynos5440-clock.txt [deleted file]
Documentation/devicetree/bindings/cpufreq/cpufreq-exynos5440.txt [deleted file]
Documentation/devicetree/bindings/display/marvell,pxa2xx-lcdc.txt
Documentation/devicetree/bindings/display/marvell,pxa300-gcu.txt [new file with mode: 0644]
Documentation/devicetree/bindings/eeprom/at24.txt
Documentation/devicetree/bindings/i2c/i2c-fsi.txt [new file with mode: 0644]
Documentation/devicetree/bindings/i2c/i2c-imx-lpi2c.txt
Documentation/devicetree/bindings/i2c/i2c-owl.txt [new file with mode: 0644]
Documentation/devicetree/bindings/i2c/i2c-rcar.txt
Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt
Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt
Documentation/devicetree/bindings/interrupt-controller/riscv,cpu-intc.txt
Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
Documentation/devicetree/bindings/mmc/sunxi-mmc.txt
Documentation/devicetree/bindings/net/cpsw.txt
Documentation/devicetree/bindings/net/dwmac-sun8i.txt
Documentation/devicetree/bindings/net/nfc/pn544.txt
Documentation/devicetree/bindings/net/sh_eth.txt
Documentation/devicetree/bindings/power/reset/qcom,pon.txt [new file with mode: 0644]
Documentation/devicetree/bindings/power/supply/maxim,ds2760.txt [new file with mode: 0644]
Documentation/devicetree/bindings/power/supply/sbs_sbs-battery.txt
Documentation/devicetree/bindings/pwm/pwm-fsl-ftm.txt
Documentation/devicetree/bindings/pwm/pwm-mediatek.txt
Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.txt
Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
Documentation/devicetree/bindings/reset/amlogic,meson-axg-audio-arb.txt [new file with mode: 0644]
Documentation/devicetree/bindings/reset/qcom,aoss-reset.txt [new file with mode: 0644]
Documentation/devicetree/bindings/reset/uniphier-reset.txt
Documentation/devicetree/bindings/rtc/isil,isl1219.txt [new file with mode: 0644]
Documentation/devicetree/bindings/rtc/rtc-ds1307.txt
Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
Documentation/devicetree/bindings/sound/mrvl,pxa-ssp.txt
Documentation/devicetree/bindings/sram/sunxi-sram.txt
Documentation/devicetree/bindings/thermal/thermal.txt
Documentation/devicetree/bindings/timer/ti,davinci-timer.txt [new file with mode: 0644]
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/devicetree/bindings/w1/w1-gpio.txt
Documentation/devicetree/bindings/w1/w1.txt [new file with mode: 0644]
Documentation/devicetree/bindings/watchdog/renesas-wdt.txt
Documentation/driver-api/libata.rst
Documentation/early-userspace/README
Documentation/fb/fbcon.txt
Documentation/filesystems/Locking
Documentation/filesystems/f2fs.txt
Documentation/filesystems/overlayfs.txt
Documentation/filesystems/proc.txt
Documentation/filesystems/ramfs-rootfs-initramfs.txt
Documentation/filesystems/vfs.txt
Documentation/hwmon/ina2xx
Documentation/hwmon/raspberrypi-hwmon [new file with mode: 0644]
Documentation/i2c/DMA-considerations
Documentation/i2c/busses/i2c-i801
Documentation/i2c/busses/i2c-ocores
Documentation/i2c/gpio-fault-injection
Documentation/kbuild/kconfig-language.txt
Documentation/kbuild/makefiles.txt
Documentation/networking/dpaa2/dpio-driver.rst [new file with mode: 0644]
Documentation/networking/dpaa2/index.rst
Documentation/process/changes.rst
Documentation/scsi/scsi-parameters.txt
Documentation/sysctl/fs.txt
Documentation/sysctl/kernel.txt
Documentation/sysctl/vm.txt
Documentation/virtual/kvm/api.txt
Documentation/virtual/kvm/devices/arm-vgic-v3.txt
Documentation/virtual/kvm/devices/arm-vgic.txt
MAINTAINERS
Makefile
arch/Kconfig
arch/alpha/kernel/osf_sys.c
arch/arc/Kconfig
arch/arc/Makefile
arch/arc/boot/dts/axc003.dtsi
arch/arc/boot/dts/axc003_idu.dtsi
arch/arc/boot/dts/axs10x_mb.dtsi
arch/arc/boot/dts/hsdk.dts
arch/arc/configs/axs101_defconfig
arch/arc/configs/axs103_defconfig
arch/arc/configs/axs103_smp_defconfig
arch/arc/configs/haps_hs_defconfig
arch/arc/configs/haps_hs_smp_defconfig
arch/arc/configs/hsdk_defconfig
arch/arc/configs/nps_defconfig
arch/arc/configs/nsim_700_defconfig
arch/arc/configs/nsim_hs_defconfig
arch/arc/configs/nsim_hs_smp_defconfig
arch/arc/configs/nsimosci_defconfig
arch/arc/configs/nsimosci_hs_defconfig
arch/arc/configs/nsimosci_hs_smp_defconfig
arch/arc/configs/tb10x_defconfig
arch/arc/configs/vdk_hs38_defconfig
arch/arc/configs/vdk_hs38_smp_defconfig
arch/arc/include/asm/atomic.h
arch/arc/include/asm/dma-mapping.h [new file with mode: 0644]
arch/arc/kernel/troubleshoot.c
arch/arc/mm/cache.c
arch/arc/mm/dma.c
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/Makefile
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/am335x-baltos.dtsi
arch/arm/boot/dts/am335x-evm.dts
arch/arm/boot/dts/am335x-evmsk.dts
arch/arm/boot/dts/am335x-osd3358-sm-red.dts [new file with mode: 0644]
arch/arm/boot/dts/am335x-sancloud-bbe.dts [new file with mode: 0644]
arch/arm/boot/dts/am335x-sl50.dts
arch/arm/boot/dts/am33xx.dtsi
arch/arm/boot/dts/am3517-evm.dts
arch/arm/boot/dts/am3517-som.dtsi
arch/arm/boot/dts/am4372.dtsi
arch/arm/boot/dts/am437x-gp-evm.dts
arch/arm/boot/dts/am571x-idk.dts
arch/arm/boot/dts/am572x-idk-common.dtsi
arch/arm/boot/dts/am57xx-idk-common.dtsi
arch/arm/boot/dts/armada-388-clearfog-base.dts
arch/arm/boot/dts/armada-388-clearfog-pro.dts
arch/arm/boot/dts/armada-388-clearfog.dts
arch/arm/boot/dts/armada-388-clearfog.dtsi
arch/arm/boot/dts/armada-388-helios4.dts [new file with mode: 0644]
arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi
arch/arm/boot/dts/aspeed-ast2500-evb.dts
arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts
arch/arm/boot/dts/aspeed-g4.dtsi
arch/arm/boot/dts/aspeed-g5.dtsi
arch/arm/boot/dts/at91-dvk_som60.dts [new file with mode: 0644]
arch/arm/boot/dts/at91-dvk_su60_somc.dtsi [new file with mode: 0644]
arch/arm/boot/dts/at91-dvk_su60_somc_lcm.dtsi [new file with mode: 0644]
arch/arm/boot/dts/at91-gatwick.dts [new file with mode: 0644]
arch/arm/boot/dts/at91-som60.dtsi [new file with mode: 0644]
arch/arm/boot/dts/at91-wb45n.dts [new file with mode: 0644]
arch/arm/boot/dts/at91-wb45n.dtsi [new file with mode: 0644]
arch/arm/boot/dts/at91-wb50n.dts [new file with mode: 0644]
arch/arm/boot/dts/at91-wb50n.dtsi [new file with mode: 0644]
arch/arm/boot/dts/at91sam9261.dtsi
arch/arm/boot/dts/at91sam9263.dtsi
arch/arm/boot/dts/at91sam9rl.dtsi
arch/arm/boot/dts/at91sam9x5.dtsi
arch/arm/boot/dts/bcm-cygnus.dtsi
arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts [new file with mode: 0644]
arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi [new file with mode: 0644]
arch/arm/boot/dts/bcm2837.dtsi
arch/arm/boot/dts/bcm283x.dtsi
arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
arch/arm/boot/dts/bcm4708-linksys-ea6300-v1.dts
arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
arch/arm/boot/dts/bcm4708-netgear-r6250.dts
arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
arch/arm/boot/dts/bcm4709-netgear-r7000.dts
arch/arm/boot/dts/bcm4709-netgear-r8000.dts
arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
arch/arm/boot/dts/bcm47094-linksys-panamera.dts
arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
arch/arm/boot/dts/bcm47094-netgear-r8500.dts
arch/arm/boot/dts/bcm47094.dtsi
arch/arm/boot/dts/bcm5301x.dtsi
arch/arm/boot/dts/bcm53573.dtsi
arch/arm/boot/dts/bcm94708.dts
arch/arm/boot/dts/bcm94709.dts
arch/arm/boot/dts/bcm953012er.dts
arch/arm/boot/dts/bcm953012hr.dts
arch/arm/boot/dts/bcm953012k.dts
arch/arm/boot/dts/berlin2.dtsi
arch/arm/boot/dts/berlin2q.dtsi
arch/arm/boot/dts/da850-enbw-cmc.dts
arch/arm/boot/dts/da850-evm.dts
arch/arm/boot/dts/da850-lcdk.dts
arch/arm/boot/dts/da850-lego-ev3.dts
arch/arm/boot/dts/da850.dtsi
arch/arm/boot/dts/dra7-evm-common.dtsi
arch/arm/boot/dts/dra7-evm.dts
arch/arm/boot/dts/dra7.dtsi
arch/arm/boot/dts/dra71-evm.dts
arch/arm/boot/dts/dra72-evm-common.dtsi
arch/arm/boot/dts/dra74x.dtsi
arch/arm/boot/dts/dra76-evm.dts
arch/arm/boot/dts/dra76x.dtsi
arch/arm/boot/dts/emev2-kzm9d.dts
arch/arm/boot/dts/emev2.dtsi
arch/arm/boot/dts/exynos3250.dtsi
arch/arm/boot/dts/exynos4.dtsi
arch/arm/boot/dts/exynos4210.dtsi
arch/arm/boot/dts/exynos4412-midas.dtsi
arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi [deleted file]
arch/arm/boot/dts/exynos4412.dtsi
arch/arm/boot/dts/exynos5.dtsi
arch/arm/boot/dts/exynos5250.dtsi
arch/arm/boot/dts/exynos5410.dtsi
arch/arm/boot/dts/exynos5420-cpus.dtsi
arch/arm/boot/dts/exynos5420-tmu-sensor-conf.dtsi [deleted file]
arch/arm/boot/dts/exynos5420.dtsi
arch/arm/boot/dts/exynos5422-cpus.dtsi
arch/arm/boot/dts/gemini-sl93512r.dts [new file with mode: 0644]
arch/arm/boot/dts/gemini-sq201.dts
arch/arm/boot/dts/gr-peach-audiocamerashield.dtsi [new file with mode: 0644]
arch/arm/boot/dts/highbank.dts
arch/arm/boot/dts/imx23-evk.dts
arch/arm/boot/dts/imx28-evk.dts
arch/arm/boot/dts/imx31-lite.dts [new file with mode: 0644]
arch/arm/boot/dts/imx31.dtsi
arch/arm/boot/dts/imx50-evk.dts
arch/arm/boot/dts/imx50-pinfunc.h
arch/arm/boot/dts/imx50.dtsi
arch/arm/boot/dts/imx51-babbage.dts
arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts
arch/arm/boot/dts/imx51-zii-rdu1.dts
arch/arm/boot/dts/imx51-zii-scu2-mezz.dts [new file with mode: 0644]
arch/arm/boot/dts/imx51-zii-scu3-esb.dts [new file with mode: 0644]
arch/arm/boot/dts/imx51.dtsi
arch/arm/boot/dts/imx53-kp-ddc.dts [new file with mode: 0644]
arch/arm/boot/dts/imx53-kp-hsc.dts [new file with mode: 0644]
arch/arm/boot/dts/imx53-kp.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx53-ppd.dts
arch/arm/boot/dts/imx53-qsb-common.dtsi
arch/arm/boot/dts/imx53.dtsi
arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
arch/arm/boot/dts/imx6dl-icore-mipi.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl-mamoj.dts
arch/arm/boot/dts/imx6dl-nit6xlite.dts
arch/arm/boot/dts/imx6dl-nitrogen6x.dts
arch/arm/boot/dts/imx6dl-riotboard.dts
arch/arm/boot/dts/imx6dl.dtsi
arch/arm/boot/dts/imx6q-apalis-eval.dts
arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts
arch/arm/boot/dts/imx6q-apalis-ixora.dts
arch/arm/boot/dts/imx6q-cm-fx6.dts
arch/arm/boot/dts/imx6q-icore-mipi.dts
arch/arm/boot/dts/imx6q-nitrogen6_max.dts
arch/arm/boot/dts/imx6q-nitrogen6_som2.dts
arch/arm/boot/dts/imx6q-nitrogen6x.dts
arch/arm/boot/dts/imx6q-var-dt6customboard.dts
arch/arm/boot/dts/imx6q.dtsi
arch/arm/boot/dts/imx6qdl-apalis.dtsi
arch/arm/boot/dts/imx6qdl-colibri.dtsi
arch/arm/boot/dts/imx6qdl-icore.dtsi
arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi
arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi
arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
arch/arm/boot/dts/imx6qdl-sabresd.dtsi
arch/arm/boot/dts/imx6qdl-wandboard.dtsi
arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi
arch/arm/boot/dts/imx6qdl.dtsi
arch/arm/boot/dts/imx6qp-nitrogen6_max.dts
arch/arm/boot/dts/imx6qp-nitrogen6_som2.dts
arch/arm/boot/dts/imx6sl-evk.dts
arch/arm/boot/dts/imx6sl.dtsi
arch/arm/boot/dts/imx6sll-evk.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6sll-pinfunc.h [new file with mode: 0644]
arch/arm/boot/dts/imx6sll.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6sx-nitrogen6sx.dts
arch/arm/boot/dts/imx6sx-sdb-reva.dts
arch/arm/boot/dts/imx6sx.dtsi
arch/arm/boot/dts/imx6ul-ccimx6ulsbcexpress.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6ul-ccimx6ulsom.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6ul-pico-hobbit.dts
arch/arm/boot/dts/imx6ul.dtsi
arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi
arch/arm/boot/dts/imx6ull.dtsi
arch/arm/boot/dts/imx7d-nitrogen7.dts
arch/arm/boot/dts/imx7d-sdb.dts
arch/arm/boot/dts/imx7d.dtsi
arch/arm/boot/dts/imx7s.dtsi
arch/arm/boot/dts/iwg20d-q7-common.dtsi
arch/arm/boot/dts/iwg20d-q7-dbcm-ca.dtsi
arch/arm/boot/dts/keystone-k2e-netcp.dtsi
arch/arm/boot/dts/keystone-k2g-evm.dts
arch/arm/boot/dts/keystone-k2g-ice.dts
arch/arm/boot/dts/keystone-k2g-netcp.dtsi [new file with mode: 0644]
arch/arm/boot/dts/keystone-k2g.dtsi
arch/arm/boot/dts/keystone-k2hk-netcp.dtsi
arch/arm/boot/dts/keystone-k2l-netcp.dtsi
arch/arm/boot/dts/logicpd-som-lv.dtsi
arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
arch/arm/boot/dts/ls1021a.dtsi
arch/arm/boot/dts/mt7623.dtsi
arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
arch/arm/boot/dts/mt7623n-rfb-nand.dts [deleted file]
arch/arm/boot/dts/mt7623n-rfb.dtsi [deleted file]
arch/arm/boot/dts/omap3-cm-t3517.dts
arch/arm/boot/dts/omap3-cm-t3730.dts
arch/arm/boot/dts/omap3-evm-common.dtsi
arch/arm/boot/dts/omap3-igep0020-rev-f.dts
arch/arm/boot/dts/omap3-igep0030-rev-g.dts
arch/arm/boot/dts/omap3-zoom3.dts
arch/arm/boot/dts/omap4-droid4-xt894.dts
arch/arm/boot/dts/omap4-duovero-parlor.dts
arch/arm/boot/dts/omap4-duovero.dtsi
arch/arm/boot/dts/omap4-l4.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap4-panda-common.dtsi
arch/arm/boot/dts/omap4-panda-es.dts
arch/arm/boot/dts/omap4-sdp.dts
arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi
arch/arm/boot/dts/omap4.dtsi
arch/arm/boot/dts/omap4460.dtsi
arch/arm/boot/dts/omap5-board-common.dtsi
arch/arm/boot/dts/omap5.dtsi
arch/arm/boot/dts/pxa2xx.dtsi
arch/arm/boot/dts/pxa3xx.dtsi
arch/arm/boot/dts/qcom-ipq4019.dtsi
arch/arm/boot/dts/qcom-ipq8064.dtsi
arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
arch/arm/boot/dts/r7s72100-genmai.dts
arch/arm/boot/dts/r7s72100-gr-peach.dts
arch/arm/boot/dts/r7s72100-rskrza1.dts
arch/arm/boot/dts/r7s72100.dtsi
arch/arm/boot/dts/r8a73a4-ape6evm.dts
arch/arm/boot/dts/r8a73a4.dtsi
arch/arm/boot/dts/r8a7740-armadillo800eva.dts
arch/arm/boot/dts/r8a7740.dtsi
arch/arm/boot/dts/r8a7743-iwg20d-q7-dbcm-ca.dts
arch/arm/boot/dts/r8a7743-iwg20d-q7.dts
arch/arm/boot/dts/r8a7743-iwg20m.dtsi
arch/arm/boot/dts/r8a7743-sk-rzg1m.dts
arch/arm/boot/dts/r8a7743.dtsi
arch/arm/boot/dts/r8a7745-iwg22d-sodimm-dbhd-ca.dts
arch/arm/boot/dts/r8a7745-iwg22d-sodimm.dts
arch/arm/boot/dts/r8a7745-iwg22m.dtsi
arch/arm/boot/dts/r8a7745-sk-rzg1e.dts
arch/arm/boot/dts/r8a7745.dtsi
arch/arm/boot/dts/r8a77470.dtsi
arch/arm/boot/dts/r8a7778-bockw.dts
arch/arm/boot/dts/r8a7778.dtsi
arch/arm/boot/dts/r8a7779-marzen.dts
arch/arm/boot/dts/r8a7779.dtsi
arch/arm/boot/dts/r8a7790-lager.dts
arch/arm/boot/dts/r8a7790.dtsi
arch/arm/boot/dts/r8a7791-koelsch.dts
arch/arm/boot/dts/r8a7791-porter.dts
arch/arm/boot/dts/r8a7791.dtsi
arch/arm/boot/dts/r8a7792-blanche.dts
arch/arm/boot/dts/r8a7792-wheat.dts
arch/arm/boot/dts/r8a7792.dtsi
arch/arm/boot/dts/r8a7793-gose.dts
arch/arm/boot/dts/r8a7793.dtsi
arch/arm/boot/dts/r8a7794-alt.dts
arch/arm/boot/dts/r8a7794-silk.dts
arch/arm/boot/dts/r8a7794.dtsi
arch/arm/boot/dts/r8a77xx-aa104xd12-panel.dtsi
arch/arm/boot/dts/r8a77xx-aa121td01-panel.dtsi
arch/arm/boot/dts/r9a06g032-rzn1d400-db.dts [new file with mode: 0644]
arch/arm/boot/dts/r9a06g032.dtsi [new file with mode: 0644]
arch/arm/boot/dts/rk3036-evb.dts
arch/arm/boot/dts/rk3036-kylin.dts
arch/arm/boot/dts/rk3036.dtsi
arch/arm/boot/dts/rk3066a-bqcurie2.dts
arch/arm/boot/dts/rk3066a-marsboard.dts
arch/arm/boot/dts/rk3066a-mk808.dts
arch/arm/boot/dts/rk3066a-rayeager.dts
arch/arm/boot/dts/rk3066a.dtsi
arch/arm/boot/dts/rk3188-px3-evb.dts
arch/arm/boot/dts/rk3188-radxarock.dts
arch/arm/boot/dts/rk3188.dtsi
arch/arm/boot/dts/rk3228-evb.dts
arch/arm/boot/dts/rk3229-evb.dts
arch/arm/boot/dts/rk3229.dtsi
arch/arm/boot/dts/rk322x.dtsi
arch/arm/boot/dts/rk3288-evb-act8846.dts
arch/arm/boot/dts/rk3288-evb-rk808.dts
arch/arm/boot/dts/rk3288-evb.dtsi
arch/arm/boot/dts/rk3288-fennec.dts
arch/arm/boot/dts/rk3288-firefly-beta.dts
arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi
arch/arm/boot/dts/rk3288-firefly-reload.dts
arch/arm/boot/dts/rk3288-firefly.dts
arch/arm/boot/dts/rk3288-firefly.dtsi
arch/arm/boot/dts/rk3288-miqi.dts
arch/arm/boot/dts/rk3288-phycore-rdk.dts
arch/arm/boot/dts/rk3288-phycore-som.dtsi
arch/arm/boot/dts/rk3288-popmetal.dts
arch/arm/boot/dts/rk3288-r89.dts
arch/arm/boot/dts/rk3288-rock2-som.dtsi
arch/arm/boot/dts/rk3288-rock2-square.dts
arch/arm/boot/dts/rk3288-tinker.dts
arch/arm/boot/dts/rk3288-veyron-analog-audio.dtsi
arch/arm/boot/dts/rk3288-veyron-brain.dts
arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi
arch/arm/boot/dts/rk3288-veyron-jaq.dts
arch/arm/boot/dts/rk3288-veyron-jerry.dts
arch/arm/boot/dts/rk3288-veyron-mickey.dts
arch/arm/boot/dts/rk3288-veyron-minnie.dts
arch/arm/boot/dts/rk3288-veyron-pinky.dts
arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi
arch/arm/boot/dts/rk3288-veyron-speedy.dts
arch/arm/boot/dts/rk3288-veyron.dtsi
arch/arm/boot/dts/rk3288-vyasa.dts
arch/arm/boot/dts/rk3288.dtsi
arch/arm/boot/dts/rk3xxx.dtsi
arch/arm/boot/dts/rv1108-evb.dts
arch/arm/boot/dts/rv1108.dtsi
arch/arm/boot/dts/s5pv210-aries.dtsi [new file with mode: 0644]
arch/arm/boot/dts/s5pv210-fascinate4g.dts [new file with mode: 0644]
arch/arm/boot/dts/s5pv210-galaxys.dts [new file with mode: 0644]
arch/arm/boot/dts/s5pv210-pinctrl.dtsi
arch/arm/boot/dts/sama5d2-pinfunc.h
arch/arm/boot/dts/sama5d3.dtsi
arch/arm/boot/dts/sama5d4.dtsi
arch/arm/boot/dts/sh73a0-kzm9g.dts
arch/arm/boot/dts/sh73a0.dtsi
arch/arm/boot/dts/socfpga_arria10.dtsi
arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
arch/arm/boot/dts/stm32f429.dtsi
arch/arm/boot/dts/stm32f746.dtsi
arch/arm/boot/dts/stm32mp157-pinctrl.dtsi
arch/arm/boot/dts/stm32mp157c-ed1.dts
arch/arm/boot/dts/stm32mp157c-ev1.dts
arch/arm/boot/dts/stm32mp157c.dtsi
arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
arch/arm/boot/dts/sun4i-a10.dtsi
arch/arm/boot/dts/sun5i.dtsi
arch/arm/boot/dts/sun6i-a31.dtsi
arch/arm/boot/dts/sun7i-a20.dtsi
arch/arm/boot/dts/sun8i-a23-a33.dtsi
arch/arm/boot/dts/sun8i-a33.dtsi
arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts
arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts
arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts
arch/arm/boot/dts/sun8i-a83t.dtsi
arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts
arch/arm/boot/dts/sun8i-h3-beelink-x2.dts
arch/arm/boot/dts/sun8i-h3.dtsi
arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
arch/arm/boot/dts/sun8i-r40.dtsi
arch/arm/boot/dts/sunxi-h3-h5.dtsi
arch/arm/boot/dts/sunxi-libretech-all-h3-cc.dtsi
arch/arm/boot/dts/tegra114-dalmore.dts
arch/arm/boot/dts/tegra114-roth.dts
arch/arm/boot/dts/tegra114-tn7.dts
arch/arm/boot/dts/tegra114.dtsi
arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
arch/arm/boot/dts/tegra124-apalis.dtsi
arch/arm/boot/dts/tegra124-jetson-tk1.dts
arch/arm/boot/dts/tegra124-nyan.dtsi
arch/arm/boot/dts/tegra124-venice2.dts
arch/arm/boot/dts/tegra124.dtsi
arch/arm/boot/dts/tegra20-colibri-512.dtsi [deleted file]
arch/arm/boot/dts/tegra20-colibri-iris.dts [new file with mode: 0644]
arch/arm/boot/dts/tegra20-colibri.dtsi [new file with mode: 0644]
arch/arm/boot/dts/tegra20-harmony.dts
arch/arm/boot/dts/tegra20-iris-512.dts [deleted file]
arch/arm/boot/dts/tegra20-paz00.dts
arch/arm/boot/dts/tegra20-seaboard.dts
arch/arm/boot/dts/tegra20-tamonten.dtsi
arch/arm/boot/dts/tegra20-trimslice.dts
arch/arm/boot/dts/tegra20-ventana.dts
arch/arm/boot/dts/tegra20.dtsi
arch/arm/boot/dts/tegra30-apalis.dtsi
arch/arm/boot/dts/tegra30-beaver.dts
arch/arm/boot/dts/tegra30-cardhu.dtsi
arch/arm/boot/dts/tegra30-colibri.dtsi
arch/arm/boot/dts/tegra30.dtsi
arch/arm/boot/dts/uniphier-pxs2.dtsi
arch/arm/boot/dts/vf610-zii-cfu1.dts [new file with mode: 0644]
arch/arm/boot/dts/vf610-zii-ssmb-spu3.dts [new file with mode: 0644]
arch/arm/boot/dts/zynq-cc108.dts
arch/arm/boot/dts/zynq-microzed.dts
arch/arm/boot/dts/zynq-parallella.dts
arch/arm/boot/dts/zynq-zc702.dts
arch/arm/boot/dts/zynq-zc706.dts
arch/arm/boot/dts/zynq-zc770-xm010.dts
arch/arm/boot/dts/zynq-zc770-xm011.dts
arch/arm/boot/dts/zynq-zc770-xm012.dts
arch/arm/boot/dts/zynq-zc770-xm013.dts
arch/arm/boot/dts/zynq-zed.dts
arch/arm/boot/dts/zynq-zturn.dts [new file with mode: 0644]
arch/arm/boot/dts/zynq-zybo-z7.dts
arch/arm/boot/dts/zynq-zybo.dts
arch/arm/configs/aspeed_g4_defconfig
arch/arm/configs/aspeed_g5_defconfig
arch/arm/configs/bcm2835_defconfig
arch/arm/configs/davinci_all_defconfig
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/configs/keystone_defconfig
arch/arm/configs/multi_v5_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/mvebu_v7_defconfig
arch/arm/configs/mxs_defconfig
arch/arm/configs/qcom_defconfig
arch/arm/configs/s5pv210_defconfig
arch/arm/configs/shmobile_defconfig
arch/arm/configs/versatile_defconfig
arch/arm/crypto/sha256_glue.c
arch/arm/crypto/sha256_neon_glue.c
arch/arm/firmware/trusted_foundations.c
arch/arm/include/asm/kvm_emulate.h
arch/arm/include/asm/kvm_host.h
arch/arm/include/asm/kvm_mmu.h
arch/arm/include/debug/renesas-scif.S
arch/arm/include/uapi/asm/kvm.h
arch/arm/kernel/asm-offsets.c
arch/arm/kernel/process.c
arch/arm/kvm/coproc.c
arch/arm/kvm/guest.c
arch/arm/mach-at91/pm.c
arch/arm/mach-at91/pm.h
arch/arm/mach-at91/pm_suspend.S
arch/arm/mach-davinci/Kconfig
arch/arm/mach-davinci/Makefile
arch/arm/mach-davinci/aemif.c [deleted file]
arch/arm/mach-davinci/board-da830-evm.c
arch/arm/mach-davinci/board-da850-evm.c
arch/arm/mach-davinci/board-dm355-evm.c
arch/arm/mach-davinci/board-dm355-leopard.c
arch/arm/mach-davinci/board-dm365-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-neuros-osd2.c
arch/arm/mach-davinci/board-omapl138-hawk.c
arch/arm/mach-davinci/board-sffsdr.c
arch/arm/mach-davinci/clock.c [deleted file]
arch/arm/mach-davinci/clock.h
arch/arm/mach-davinci/common.c
arch/arm/mach-davinci/da830.c
arch/arm/mach-davinci/da850.c
arch/arm/mach-davinci/da8xx-dt.c
arch/arm/mach-davinci/davinci.h
arch/arm/mach-davinci/devices-da8xx.c
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/clock.h
arch/arm/mach-davinci/include/mach/common.h
arch/arm/mach-davinci/include/mach/da8xx.h
arch/arm/mach-davinci/pm_domain.c
arch/arm/mach-davinci/psc.c [deleted file]
arch/arm/mach-davinci/psc.h
arch/arm/mach-davinci/time.c
arch/arm/mach-davinci/usb-da8xx.c
arch/arm/mach-exynos/exynos.c
arch/arm/mach-exynos/suspend.c
arch/arm/mach-hisi/hotplug.c
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/Makefile
arch/arm/mach-imx/common.h
arch/arm/mach-imx/cpu-imx5.c
arch/arm/mach-imx/cpu.c
arch/arm/mach-imx/cpuidle-imx6sl.c
arch/arm/mach-imx/cpuidle-imx6sx.c
arch/arm/mach-imx/gpc.c
arch/arm/mach-imx/imx31-dt.c
arch/arm/mach-imx/mach-imx51.c
arch/arm/mach-imx/mach-imx53.c
arch/arm/mach-imx/mach-imx6sl.c
arch/arm/mach-imx/mach-imx7d-cm4.c [new file with mode: 0644]
arch/arm/mach-imx/pm-imx6.c
arch/arm/mach-mvebu/platsmp.c
arch/arm/mach-mvebu/pmsu.c
arch/arm/mach-omap1/ams-delta-fiq-handler.S
arch/arm/mach-omap1/ams-delta-fiq.c
arch/arm/mach-omap1/ams-delta-fiq.h [new file with mode: 0644]
arch/arm/mach-omap1/board-ams-delta.c
arch/arm/mach-omap1/board-h2.c
arch/arm/mach-omap1/board-h3.c
arch/arm/mach-omap1/board-htcherald.c
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap1/include/mach/ams-delta-fiq.h [deleted file]
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod_reset.c
arch/arm/mach-omap2/pm-asm-offsets.c
arch/arm/mach-omap2/pm-debug.c
arch/arm/mach-omap2/pm33xx-core.c
arch/arm/mach-omap2/sleep33xx.S
arch/arm/mach-omap2/sleep43xx.S
arch/arm/mach-pxa/devices.c
arch/arm/mach-pxa/hx4700.c
arch/arm/mach-pxa/mioa701.c
arch/arm/mach-pxa/zylonite.c
arch/arm/mach-rockchip/Kconfig
arch/arm/mach-s3c24xx/include/mach/s3c2412.h
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-shmobile/Makefile
arch/arm/mach-shmobile/common.h
arch/arm/mach-shmobile/headsmp-apmu.S
arch/arm/mach-shmobile/platsmp-apmu.c
arch/arm/mach-shmobile/platsmp-apmu.h [deleted file]
arch/arm/mach-shmobile/platsmp.c
arch/arm/mach-shmobile/pm-r8a7779.c [deleted file]
arch/arm/mach-shmobile/pm-rcar-gen2.c
arch/arm/mach-shmobile/r8a7779.h
arch/arm/mach-shmobile/r8a7790.h [deleted file]
arch/arm/mach-shmobile/r8a7791.h [deleted file]
arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
arch/arm/mach-shmobile/setup-emev2.c
arch/arm/mach-shmobile/setup-r7s72100.c
arch/arm/mach-shmobile/setup-r8a73a4.c
arch/arm/mach-shmobile/setup-r8a7740.c
arch/arm/mach-shmobile/setup-r8a7778.c
arch/arm/mach-shmobile/setup-r8a7779.c
arch/arm/mach-shmobile/setup-r8a7790.c [deleted file]
arch/arm/mach-shmobile/setup-r8a7791.c [deleted file]
arch/arm/mach-shmobile/setup-rcar-gen2.c
arch/arm/mach-shmobile/setup-sh73a0.c
arch/arm/mach-shmobile/smp-emev2.c
arch/arm/mach-shmobile/smp-r8a7779.c
arch/arm/mach-shmobile/smp-r8a7790.c [deleted file]
arch/arm/mach-shmobile/smp-r8a7791.c [deleted file]
arch/arm/mach-shmobile/timer.c
arch/arm/mach-uniphier/Kconfig
arch/arm/mach-uniphier/Makefile [deleted file]
arch/arm/probes/uprobes/core.c
arch/arm64/Kconfig
arch/arm64/Kconfig.platforms
arch/arm64/Makefile
arch/arm64/boot/dts/Makefile
arch/arm64/boot/dts/allwinner/Makefile
arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts [new file with mode: 0644]
arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts [new file with mode: 0644]
arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts
arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
arch/arm64/boot/dts/amlogic/Makefile
arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
arch/arm64/boot/dts/amlogic/meson-axg.dtsi
arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p231.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s905w-p281.dts [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts
arch/arm64/boot/dts/amlogic/meson-gxm-q201.dts
arch/arm64/boot/dts/arm/juno-r1.dts
arch/arm64/boot/dts/arm/juno-r2.dts
arch/arm64/boot/dts/arm/juno.dts
arch/arm64/boot/dts/broadcom/stingray/Makefile
arch/arm64/boot/dts/broadcom/stingray/bcm958742-base.dtsi
arch/arm64/boot/dts/broadcom/stingray/bcm958802a802x.dts [new file with mode: 0644]
arch/arm64/boot/dts/broadcom/stingray/stingray-board-base.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/broadcom/stingray/stingray-clock.dtsi
arch/arm64/boot/dts/broadcom/stingray/stingray-pcie.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
arch/arm64/boot/dts/exynos/exynos5433-tmu-g3d-sensor-conf.dtsi [deleted file]
arch/arm64/boot/dts/exynos/exynos5433-tmu-sensor-conf.dtsi [deleted file]
arch/arm64/boot/dts/exynos/exynos5433.dtsi
arch/arm64/boot/dts/exynos/exynos7-tmu-sensor-conf.dtsi [deleted file]
arch/arm64/boot/dts/exynos/exynos7.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts
arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts
arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts
arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1043-post.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts
arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts
arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1046-post.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts
arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts
arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts
arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts
arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts
arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts
arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts
arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts
arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi
arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi
arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
arch/arm64/boot/dts/freescale/qoriq-bman-portals.dtsi
arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi
arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi
arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-0.dtsi
arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-1.dtsi
arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-2.dtsi
arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-3.dtsi
arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-4.dtsi
arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-5.dtsi
arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi
arch/arm64/boot/dts/freescale/qoriq-qman-portals.dtsi
arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts
arch/arm64/boot/dts/hisilicon/hi3660.dtsi
arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
arch/arm64/boot/dts/hisilicon/hi6220.dtsi
arch/arm64/boot/dts/marvell/armada-37xx.dtsi
arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts
arch/arm64/boot/dts/marvell/armada-cp110.dtsi
arch/arm64/boot/dts/mediatek/Makefile
arch/arm64/boot/dts/mediatek/mt2712e.dtsi
arch/arm64/boot/dts/mediatek/mt6797-x20-dev.dts [new file with mode: 0644]
arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
arch/arm64/boot/dts/mediatek/mt7622.dtsi
arch/arm64/boot/dts/mediatek/mt8173.dtsi
arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
arch/arm64/boot/dts/nvidia/tegra194.dtsi
arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
arch/arm64/boot/dts/qcom/msm8916.dtsi
arch/arm64/boot/dts/qcom/msm8996.dtsi
arch/arm64/boot/dts/qcom/pm8005.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/qcom/pm8998.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/qcom/sdm845-mtp.dts
arch/arm64/boot/dts/qcom/sdm845.dtsi
arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts
arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
arch/arm64/boot/dts/renesas/r8a7795-salvator-xs.dts
arch/arm64/boot/dts/renesas/r8a7795.dtsi
arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts
arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts
arch/arm64/boot/dts/renesas/r8a7796-salvator-xs.dts
arch/arm64/boot/dts/renesas/r8a7796.dtsi
arch/arm64/boot/dts/renesas/r8a77965.dtsi
arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
arch/arm64/boot/dts/renesas/r8a77970.dtsi
arch/arm64/boot/dts/renesas/r8a77980-condor.dts
arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
arch/arm64/boot/dts/renesas/r8a77980.dtsi
arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
arch/arm64/boot/dts/renesas/r8a77990.dtsi
arch/arm64/boot/dts/renesas/r8a77995-draak.dts
arch/arm64/boot/dts/renesas/r8a77995.dtsi
arch/arm64/boot/dts/renesas/salvator-common.dtsi
arch/arm64/boot/dts/renesas/salvator-x.dtsi
arch/arm64/boot/dts/renesas/salvator-xs.dtsi
arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
arch/arm64/boot/dts/renesas/ulcb.dtsi
arch/arm64/boot/dts/rockchip/Makefile
arch/arm64/boot/dts/rockchip/rk3328-evb.dts
arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
arch/arm64/boot/dts/rockchip/rk3328.dtsi
arch/arm64/boot/dts/rockchip/rk3368-evb-act8846.dts
arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi
arch/arm64/boot/dts/rockchip/rk3368-geekbox.dts
arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts
arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts
arch/arm64/boot/dts/rockchip/rk3368-r88.dts
arch/arm64/boot/dts/rockchip/rk3368.dtsi
arch/arm64/boot/dts/rockchip/rk3399-evb.dts
arch/arm64/boot/dts/rockchip/rk3399-ficus.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts
arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi
arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi
arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts
arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi
arch/arm64/boot/dts/rockchip/rk3399.dtsi
arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts
arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts
arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
arch/arm64/boot/dts/sprd/sc2731.dtsi
arch/arm64/boot/dts/sprd/sc9860.dtsi
arch/arm64/boot/dts/sprd/whale2.dtsi
arch/arm64/boot/dts/ti/Makefile [new file with mode: 0644]
arch/arm64/boot/dts/ti/k3-am65-main.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/ti/k3-am65.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/ti/k3-am654-base-board.dts [new file with mode: 0644]
arch/arm64/boot/dts/ti/k3-am654.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/xilinx/Makefile
arch/arm64/boot/dts/xilinx/avnet-ultra96-rev1.dts [new file with mode: 0644]
arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi [deleted file]
arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts [deleted file]
arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
arch/arm64/boot/dts/xilinx/zynqmp.dtsi
arch/arm64/configs/defconfig
arch/arm64/crypto/ghash-ce-glue.c
arch/arm64/crypto/sm4-ce-glue.c
arch/arm64/include/asm/cpucaps.h
arch/arm64/include/asm/kvm_arm.h
arch/arm64/include/asm/kvm_emulate.h
arch/arm64/include/asm/kvm_host.h
arch/arm64/include/asm/kvm_mmu.h
arch/arm64/include/asm/memory.h
arch/arm64/include/asm/pgtable-prot.h
arch/arm64/include/asm/sysreg.h
arch/arm64/include/asm/tlb.h
arch/arm64/include/uapi/asm/kvm.h
arch/arm64/kernel/cpufeature.c
arch/arm64/kvm/guest.c
arch/arm64/kvm/hyp-init.S
arch/arm64/kvm/hyp/switch.c
arch/arm64/kvm/hyp/sysreg-sr.c
arch/arm64/kvm/inject_fault.c
arch/arm64/kvm/reset.c
arch/arm64/kvm/sys_regs.c
arch/arm64/mm/mmu.c
arch/c6x/Makefile
arch/h8300/Kconfig
arch/h8300/Makefile
arch/h8300/boot/dts/h8300h_sim.dts
arch/h8300/include/asm/bitops.h
arch/h8300/include/asm/ptrace.h
arch/h8300/kernel/kgdb.c
arch/h8300/kernel/setup.c
arch/h8300/kernel/sim-console.c
arch/hexagon/Makefile
arch/ia64/Kconfig
arch/ia64/hp/common/sba_iommu.c
arch/ia64/kernel/asm-offsets.c
arch/ia64/kernel/fsys.S
arch/ia64/kernel/setup.c
arch/ia64/mm/contig.c
arch/ia64/mm/discontig.c
arch/m68k/Makefile
arch/m68k/mac/misc.c
arch/m68k/mm/mcfmmu.c
arch/microblaze/Kconfig
arch/microblaze/Makefile
arch/microblaze/include/asm/Kbuild
arch/microblaze/include/asm/dma-mapping.h [deleted file]
arch/microblaze/include/asm/pgtable.h
arch/microblaze/kernel/dma.c
arch/microblaze/kernel/head.S
arch/microblaze/mm/consistent.c
arch/microblaze/pci/pci-common.c
arch/microblaze/pci/xilinx_pci.c
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/boot/compressed/Makefile
arch/mips/include/asm/asm-prototypes.h
arch/mips/include/asm/atomic.h
arch/mips/include/asm/compiler.h
arch/mips/include/asm/kvm_host.h
arch/mips/include/asm/mmu_context.h
arch/mips/include/asm/tlbex.h
arch/mips/kernel/traps.c
arch/mips/kernel/uprobes.c
arch/mips/kernel/vdso.c
arch/mips/kvm/mmu.c
arch/mips/lasat/image/Makefile
arch/mips/lib/multi3.c
arch/mips/mm/tlb-funcs.S
arch/mips/mm/tlbex.c
arch/nds32/Kconfig
arch/nds32/Makefile
arch/nds32/include/asm/elf.h
arch/nds32/include/asm/ftrace.h [new file with mode: 0644]
arch/nds32/include/asm/nds32.h
arch/nds32/include/asm/uaccess.h
arch/nds32/kernel/Makefile
arch/nds32/kernel/atl2c.c
arch/nds32/kernel/ex-entry.S
arch/nds32/kernel/ex-exit.S
arch/nds32/kernel/ftrace.c [new file with mode: 0644]
arch/nds32/kernel/module.c
arch/nds32/kernel/stacktrace.c
arch/nds32/kernel/traps.c
arch/nds32/kernel/vmlinux.lds.S
arch/nios2/Kconfig.debug
arch/openrisc/Kconfig
arch/openrisc/include/asm/Kbuild
arch/openrisc/include/asm/dma-mapping.h [deleted file]
arch/openrisc/kernel/dma.c
arch/parisc/include/asm/elf.h
arch/parisc/include/asm/linkage.h
arch/parisc/include/asm/processor.h
arch/parisc/include/asm/traps.h
arch/parisc/include/asm/unwind.h
arch/parisc/kernel/entry.S
arch/parisc/kernel/processor.c
arch/parisc/kernel/stacktrace.c
arch/parisc/kernel/sys_parisc.c
arch/parisc/kernel/syscall.S
arch/parisc/kernel/traps.c
arch/parisc/kernel/unwind.c
arch/powerpc/Makefile
arch/powerpc/include/asm/book3s/64/pgtable.h
arch/powerpc/include/asm/nohash/pgtable.h
arch/powerpc/include/asm/opal.h
arch/powerpc/include/asm/topology.h
arch/powerpc/kernel/fadump.c
arch/powerpc/kernel/idle_power4.S
arch/powerpc/kernel/smp.c
arch/powerpc/kernel/traps.c
arch/powerpc/kvm/book3s_64_mmu_hv.c
arch/powerpc/kvm/book3s_64_mmu_radix.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_pr.c
arch/powerpc/kvm/book3s_xive.c
arch/powerpc/mm/mmu_context_book3s64.c
arch/powerpc/mm/mmu_context_iommu.c
arch/powerpc/mm/numa.c
arch/powerpc/mm/pgtable-radix.c
arch/powerpc/mm/slb.c
arch/powerpc/platforms/powermac/low_i2c.c
arch/powerpc/platforms/powernv/opal.c
arch/powerpc/platforms/powernv/pci-ioda.c
arch/powerpc/platforms/powernv/vas-window.c
arch/powerpc/sysdev/xive/common.c
arch/riscv/Makefile
arch/riscv/include/asm/Kbuild
arch/riscv/include/asm/compat.h [deleted file]
arch/riscv/include/asm/tlb.h
arch/riscv/include/asm/unistd.h
arch/riscv/include/asm/vdso.h
arch/riscv/include/uapi/asm/syscalls.h
arch/riscv/kernel/sys_riscv.c
arch/s390/Kconfig
arch/s390/Makefile
arch/s390/include/asm/ap.h
arch/s390/include/asm/ftrace.h
arch/s390/include/asm/mmu.h
arch/s390/include/uapi/asm/zcrypt.h
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/crash_dump.c
arch/s390/kernel/ebcdic.c
arch/s390/kernel/ftrace.c
arch/s390/kernel/mcount.S
arch/s390/kernel/perf_cpum_sf.c
arch/s390/kvm/kvm-s390.c
arch/s390/kvm/priv.c
arch/s390/kvm/vsie.c
arch/s390/pci/pci.c
arch/s390/pci/pci_debug.c
arch/sh/Makefile
arch/sparc/Kconfig
arch/sparc/Makefile
arch/sparc/include/asm/dma-mapping.h
arch/sparc/kernel/ioport.c
arch/sparc/kernel/of_device_32.c
arch/sparc/kernel/of_device_64.c
arch/sparc/kernel/sys_sparc_32.c
arch/sparc/kernel/sys_sparc_64.c
arch/sparc/mm/init_32.c
arch/um/Makefile
arch/x86/Kconfig
arch/x86/Makefile
arch/x86/Makefile.um
arch/x86/boot/compressed/Makefile
arch/x86/boot/compressed/kaslr.c
arch/x86/crypto/aesni-intel_asm.S
arch/x86/entry/vdso/Makefile
arch/x86/events/core.c
arch/x86/hyperv/mmu.c
arch/x86/include/asm/Kbuild
arch/x86/include/asm/atomic.h
arch/x86/include/asm/atomic64_32.h
arch/x86/include/asm/atomic64_64.h
arch/x86/include/asm/export.h [deleted file]
arch/x86/include/asm/irq_remapping.h
arch/x86/include/asm/irqflags.h
arch/x86/include/asm/kdebug.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/mce.h
arch/x86/include/asm/paravirt.h
arch/x86/include/asm/paravirt_types.h
arch/x86/include/asm/pgtable-3level.h
arch/x86/include/asm/pgtable.h
arch/x86/include/asm/pgtable_64.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/set_memory.h
arch/x86/include/asm/signal.h
arch/x86/include/asm/stacktrace.h
arch/x86/include/asm/tlbflush.h
arch/x86/include/asm/vgtod.h
arch/x86/include/asm/vmx.h
arch/x86/include/asm/xen/hypercall.h
arch/x86/kernel/acpi/cstate.c
arch/x86/kernel/alternative.c
arch/x86/kernel/apic/vector.c
arch/x86/kernel/cpu/bugs.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/mcheck/mce-internal.h
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/cpu/microcode/amd.c
arch/x86/kernel/cpu/microcode/intel.c
arch/x86/kernel/dumpstack.c
arch/x86/kernel/kvm.c
arch/x86/kernel/paravirt.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/tsc.c
arch/x86/kvm/lapic.c
arch/x86/kvm/mmu.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/kvm/x86.h
arch/x86/lib/usercopy.c
arch/x86/mm/cpu_entry_area.c
arch/x86/mm/fault.c
arch/x86/mm/init.c
arch/x86/mm/mmap.c
arch/x86/mm/pageattr.c
arch/x86/mm/pat.c
arch/x86/mm/pgtable.c
arch/x86/mm/pti.c
arch/x86/mm/tlb.c
arch/x86/platform/efi/efi_32.c
arch/x86/xen/enlighten_pv.c
arch/x86/xen/mmu_pv.c
arch/x86/xen/setup.c
arch/x86/xen/xen-ops.h
arch/xtensa/Kconfig
arch/xtensa/Makefile
arch/xtensa/boot/boot-elf/Makefile
arch/xtensa/boot/boot-elf/bootstrap.S
arch/xtensa/configs/nommu_kc705_defconfig
arch/xtensa/include/asm/Kbuild
arch/xtensa/include/asm/cacheasm.h
arch/xtensa/include/asm/dma-mapping.h [deleted file]
arch/xtensa/include/asm/initialize_mmu.h
arch/xtensa/include/asm/irq.h
arch/xtensa/include/asm/kmem_layout.h
arch/xtensa/include/asm/page.h
arch/xtensa/include/asm/pgtable.h
arch/xtensa/include/asm/platform.h
arch/xtensa/include/asm/processor.h
arch/xtensa/include/asm/vectors.h
arch/xtensa/kernel/head.S
arch/xtensa/kernel/irq.c
arch/xtensa/kernel/pci-dma.c
arch/xtensa/kernel/setup.c
arch/xtensa/kernel/vmlinux.lds.S
arch/xtensa/platforms/iss/include/platform/hardware.h [deleted file]
arch/xtensa/platforms/xt2000/include/platform/hardware.h
arch/xtensa/platforms/xtfpga/include/platform/hardware.h
arch/xtensa/variants/test_kc705_be/include/variant/core.h [new file with mode: 0644]
arch/xtensa/variants/test_kc705_be/include/variant/tie-asm.h [new file with mode: 0644]
arch/xtensa/variants/test_kc705_be/include/variant/tie.h [new file with mode: 0644]
block/bfq-cgroup.c
block/bfq-iosched.c
block/bfq-wf2q.c
block/bio.c
block/blk-cgroup.c
block/blk-core.c
block/blk-mq-sched.c
block/blk-mq-sched.h
block/blk-mq-tag.c
block/blk-mq.c
block/blk-sysfs.c
block/blk-throttle.c
block/blk-wbt.c
block/blk.h
block/bsg.c
block/elevator.c
certs/system_certificates.S
drivers/acpi/Kconfig
drivers/acpi/acpi_lpss.c
drivers/acpi/acpica/aclocal.h
drivers/acpi/acpica/acnamesp.h
drivers/acpi/acpica/acutils.h
drivers/acpi/acpica/dbinput.c
drivers/acpi/acpica/dbmethod.c
drivers/acpi/acpica/dbxface.c
drivers/acpi/acpica/dsfield.c
drivers/acpi/acpica/hwregs.c
drivers/acpi/acpica/hwsleep.c
drivers/acpi/acpica/nsaccess.c
drivers/acpi/acpica/psloop.c
drivers/acpi/acpica/tbdata.c
drivers/acpi/acpica/utdelete.c
drivers/acpi/acpica/utstrsuppt.c
drivers/acpi/acpica/utstrtoul64.c
drivers/acpi/bus.c
drivers/acpi/nfit/core.c
drivers/acpi/nfit/nfit.h
drivers/acpi/pmic/intel_pmic_crc.c
drivers/acpi/processor_core.c
drivers/ata/ahci.c
drivers/ata/ahci.h
drivers/ata/ahci_brcm.c
drivers/ata/ahci_ceva.c
drivers/ata/ahci_da850.c
drivers/ata/ahci_dm816.c
drivers/ata/ahci_imx.c
drivers/ata/ahci_mtk.c
drivers/ata/ahci_mvebu.c
drivers/ata/ahci_platform.c
drivers/ata/ahci_qoriq.c
drivers/ata/ahci_seattle.c
drivers/ata/ahci_st.c
drivers/ata/ahci_sunxi.c
drivers/ata/ahci_tegra.c
drivers/ata/ahci_xgene.c
drivers/ata/libahci.c
drivers/ata/libahci_platform.c
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/pata_cmd640.c
drivers/ata/pata_ftide010.c
drivers/ata/pata_icside.c
drivers/ata/pata_imx.c
drivers/ata/pata_legacy.c
drivers/ata/pata_palmld.c
drivers/ata/pata_pcmcia.c
drivers/ata/pata_platform.c
drivers/ata/pata_via.c
drivers/ata/sata_rcar.c
drivers/base/memory.c
drivers/base/power/clock_ops.c
drivers/block/DAC960.c
drivers/block/mtip32xx/mtip32xx.c
drivers/block/nbd.c
drivers/block/pktcdvd.c
drivers/block/rbd.c
drivers/block/rsxx/core.c
drivers/block/xen-blkback/blkback.c
drivers/block/xen-blkback/common.h
drivers/block/xen-blkfront.c
drivers/block/zram/zram_drv.c
drivers/bluetooth/Kconfig
drivers/bluetooth/btmtkuart.c
drivers/bus/Kconfig
drivers/bus/Makefile
drivers/bus/sun50i-de2.c [new file with mode: 0644]
drivers/bus/ti-sysc.c
drivers/cdrom/cdrom.c
drivers/char/Kconfig
drivers/char/random.c
drivers/char/rtc.c
drivers/clk/clk-npcm7xx.c
drivers/clk/davinci/psc-da830.c
drivers/clk/davinci/psc-da850.c
drivers/clk/davinci/psc-dm365.c
drivers/clk/davinci/psc-dm644x.c
drivers/clk/davinci/psc-dm646x.c
drivers/clk/samsung/Makefile
drivers/clk/samsung/clk-exynos5440.c [deleted file]
drivers/clk/ti/clk-7xx.c
drivers/clk/x86/clk-st.c
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/Makefile
drivers/cpufreq/cpufreq_governor.c
drivers/cpufreq/exynos5440-cpufreq.c [deleted file]
drivers/cpuidle/governors/menu.c
drivers/crypto/caam/caamalg_qi.c
drivers/crypto/caam/caampkc.c
drivers/crypto/caam/jr.c
drivers/crypto/caam/sg_sw_qm2.h
drivers/crypto/caam/sg_sw_sec4.h
drivers/crypto/cavium/nitrox/nitrox_dev.h
drivers/crypto/cavium/nitrox/nitrox_lib.c
drivers/crypto/cavium/nitrox/nitrox_reqmgr.c
drivers/crypto/chelsio/chtls/chtls.h
drivers/crypto/chelsio/chtls/chtls_main.c
drivers/crypto/vmx/aes_cbc.c
drivers/crypto/vmx/aes_xts.c
drivers/crypto/vmx/ghashp8-ppc.pl
drivers/dax/device.c
drivers/dax/pmem.c
drivers/dax/super.c
drivers/dma/dmaengine.c
drivers/firmware/arm_scmi/perf.c
drivers/firmware/efi/efi-bgrt.c
drivers/firmware/efi/libstub/Makefile
drivers/firmware/psci_checker.c
drivers/firmware/raspberrypi.c
drivers/gpio/gpio-adp5588.c
drivers/gpio/gpio-dwapb.c
drivers/gpio/gpiolib-acpi.c
drivers/gpio/gpiolib-of.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
drivers/gpu/drm/amd/amdgpu/kv_dpm.c
drivers/gpu/drm/amd/amdgpu/si_dpm.c
drivers/gpu/drm/amd/amdgpu/vega20_reg_init.c
drivers/gpu/drm/amd/amdgpu/vi.c
drivers/gpu/drm/amd/display/Kconfig
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
drivers/gpu/drm/amd/display/dc/Makefile
drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c
drivers/gpu/drm/amd/display/dc/calcs/Makefile
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_debug.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.h
drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c
drivers/gpu/drm/amd/display/dc/dce/dce_clocks.h
drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/gpio/Makefile
drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c
drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c
drivers/gpu/drm/amd/display/dc/i2caux/Makefile
drivers/gpu/drm/amd/display/dc/i2caux/i2caux.c
drivers/gpu/drm/amd/display/dc/inc/core_types.h
drivers/gpu/drm/amd/display/dc/irq/Makefile
drivers/gpu/drm/amd/display/dc/irq/irq_service.c
drivers/gpu/drm/amd/display/dc/os_types.h
drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/gma500/framebuffer.c
drivers/gpu/drm/gma500/gem.c
drivers/gpu/drm/gma500/psb_drv.h
drivers/gpu/drm/i915/gvt/dmabuf.c
drivers/gpu/drm/i915/gvt/fb_decoder.c
drivers/gpu/drm/i915/gvt/fb_decoder.h
drivers/gpu/drm/i915/gvt/handlers.c
drivers/gpu/drm/i915/gvt/mmio_context.c
drivers/gpu/drm/i915/gvt/sched_policy.c
drivers/gpu/drm/i915/i915_gem_userptr.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/i915_utils.h
drivers/gpu/drm/i915/i915_vma.c
drivers/gpu/drm/i915/intel_audio.c
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_dp_mst.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_lspcon.c
drivers/gpu/drm/mediatek/mtk_disp_ovl.c
drivers/gpu/drm/mediatek/mtk_disp_rdma.c
drivers/gpu/drm/mediatek/mtk_drm_crtc.c
drivers/gpu/drm/mediatek/mtk_drm_crtc.h
drivers/gpu/drm/mediatek/mtk_drm_ddp.c
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
drivers/gpu/drm/mediatek/mtk_drm_drv.c
drivers/gpu/drm/panel/panel-simple.c
drivers/gpu/drm/radeon/radeon_mn.c
drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
drivers/hid/hid-ids.h
drivers/hid/hid-magicmouse.c
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/hwmon/adt7475.c
drivers/hwmon/ina2xx.c
drivers/hwmon/nct6775.c
drivers/hwmon/raspberrypi-hwmon.c [new file with mode: 0644]
drivers/hwtracing/intel_th/msu.c
drivers/i2c/Makefile
drivers/i2c/algos/i2c-algo-bit.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-amd8111.c
drivers/i2c/busses/i2c-aspeed.c
drivers/i2c/busses/i2c-brcmstb.c
drivers/i2c/busses/i2c-davinci.c
drivers/i2c/busses/i2c-designware-baytrail.c
drivers/i2c/busses/i2c-designware-common.c
drivers/i2c/busses/i2c-designware-core.h
drivers/i2c/busses/i2c-designware-master.c
drivers/i2c/busses/i2c-designware-pcidrv.c
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/i2c/busses/i2c-designware-slave.c
drivers/i2c/busses/i2c-emev2.c
drivers/i2c/busses/i2c-exynos5.c
drivers/i2c/busses/i2c-fsi.c [new file with mode: 0644]
drivers/i2c/busses/i2c-gpio.c
drivers/i2c/busses/i2c-highlander.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-imx-lpi2c.c
drivers/i2c/busses/i2c-imx.c
drivers/i2c/busses/i2c-mxs.c
drivers/i2c/busses/i2c-ocores.c
drivers/i2c/busses/i2c-owl.c [new file with mode: 0644]
drivers/i2c/busses/i2c-pasemi.c
drivers/i2c/busses/i2c-pmcmsp.c
drivers/i2c/busses/i2c-qcom-geni.c [new file with mode: 0644]
drivers/i2c/busses/i2c-rcar.c
drivers/i2c/busses/i2c-riic.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/busses/i2c-sh_mobile.c
drivers/i2c/busses/i2c-sprd.c
drivers/i2c/busses/i2c-stu300.c
drivers/i2c/busses/i2c-tegra.c
drivers/i2c/busses/i2c-uniphier-f.c
drivers/i2c/busses/i2c-uniphier.c
drivers/i2c/busses/i2c-xiic.c
drivers/i2c/busses/i2c-xlr.c
drivers/i2c/i2c-core-acpi.c
drivers/i2c/i2c-core-base.c
drivers/i2c/i2c-core-slave.c
drivers/i2c/i2c-mux.c
drivers/i2c/muxes/i2c-mux-mlxcpld.c
drivers/i2c/muxes/i2c-mux-pca9541.c
drivers/i2c/muxes/i2c-mux-pca954x.c
drivers/ide/hpt366.c
drivers/ide/ide-floppy.c
drivers/ide/ide-io.c
drivers/ide/ide-probe.c
drivers/ide/ide-tape.c
drivers/ide/ide-taskfile.c
drivers/ide/sis5513.c
drivers/iio/dac/ltc2632.c
drivers/iio/temperature/mlx90614.c
drivers/infiniband/Kconfig
drivers/infiniband/core/cma.c
drivers/infiniband/core/rdma_core.c
drivers/infiniband/core/ucma.c
drivers/infiniband/core/umem_odp.c
drivers/infiniband/core/uverbs_main.c
drivers/infiniband/hw/bnxt_re/ib_verbs.c
drivers/infiniband/hw/bnxt_re/qplib_fp.c
drivers/infiniband/hw/cxgb4/qp.c
drivers/infiniband/hw/hfi1/affinity.c
drivers/infiniband/hw/hfi1/mmu_rb.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx5/odp.c
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/input/serio/ams_delta_serio.c
drivers/input/touchscreen/rohm_bu21023.c
drivers/iommu/Kconfig
drivers/iommu/Makefile
drivers/iommu/amd_iommu.c
drivers/iommu/amd_iommu_debugfs.c [new file with mode: 0644]
drivers/iommu/amd_iommu_init.c
drivers/iommu/amd_iommu_proto.h
drivers/iommu/amd_iommu_types.h
drivers/iommu/arm-smmu-v3.c
drivers/iommu/arm-smmu.c
drivers/iommu/dmar.c
drivers/iommu/exynos-iommu.c
drivers/iommu/intel-iommu.c
drivers/iommu/intel-pasid.c [new file with mode: 0644]
drivers/iommu/intel-pasid.h [new file with mode: 0644]
drivers/iommu/intel-svm.c
drivers/iommu/io-pgtable-arm-v7s.c
drivers/iommu/io-pgtable-arm.c
drivers/iommu/iommu-debugfs.c [new file with mode: 0644]
drivers/iommu/iommu.c
drivers/iommu/ipmmu-vmsa.c
drivers/iommu/msm_iommu.c
drivers/iommu/mtk_iommu.c
drivers/iommu/mtk_iommu_v1.c
drivers/iommu/omap-iommu.c
drivers/iommu/qcom_iommu.c
drivers/iommu/rockchip-iommu.c
drivers/iommu/tegra-gart.c
drivers/iommu/tegra-smmu.c
drivers/irqchip/irq-bcm7038-l1.c
drivers/irqchip/irq-gic-v3-its.c
drivers/irqchip/irq-gic-v3.c
drivers/irqchip/irq-renesas-h8s.c
drivers/irqchip/irq-s3c24xx.c
drivers/irqchip/irq-stm32-exti.c
drivers/irqchip/irq-tango.c
drivers/irqchip/irq-xtensa-mx.c
drivers/irqchip/irq-xtensa-pic.c
drivers/macintosh/therm_windtunnel.c
drivers/md/bcache/Kconfig
drivers/md/bcache/alloc.c
drivers/md/bcache/bcache.h
drivers/md/bcache/bset.c
drivers/md/bcache/bset.h
drivers/md/bcache/btree.c
drivers/md/bcache/btree.h
drivers/md/bcache/closure.c
drivers/md/bcache/closure.h
drivers/md/bcache/debug.c
drivers/md/bcache/debug.h
drivers/md/bcache/extents.c
drivers/md/bcache/extents.h
drivers/md/bcache/io.c
drivers/md/bcache/journal.c
drivers/md/bcache/journal.h
drivers/md/bcache/movinggc.c
drivers/md/bcache/request.c
drivers/md/bcache/request.h
drivers/md/bcache/stats.c
drivers/md/bcache/stats.h
drivers/md/bcache/super.c
drivers/md/bcache/sysfs.c
drivers/md/bcache/sysfs.h
drivers/md/bcache/util.c
drivers/md/bcache/util.h
drivers/md/bcache/writeback.c
drivers/md/bcache/writeback.h
drivers/md/dm-writecache.c
drivers/md/md-cluster.c
drivers/md/raid10.c
drivers/md/raid5-log.h
drivers/md/raid5.c
drivers/media/dvb-frontends/af9013.c
drivers/media/dvb-frontends/drxk_hard.c
drivers/media/dvb-frontends/rtl2830.c
drivers/media/dvb-frontends/tda1004x.c
drivers/media/media-device.c
drivers/media/tuners/tda18271-common.c
drivers/memory/tegra/mc.c
drivers/memory/ti-aemif.c
drivers/memory/ti-emif-pm.c
drivers/mfd/88pm860x-i2c.c
drivers/misc/cb710/core.c
drivers/misc/eeprom/at24.c
drivers/misc/mic/scif/scif_dma.c
drivers/misc/sgi-gru/grutlbpurge.c
drivers/mmc/core/queue.c
drivers/mmc/core/queue.h
drivers/mmc/host/android-goldfish.c
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/renesas_sdhi_internal_dmac.c
drivers/mtd/nand/raw/denali.c
drivers/mtd/nand/raw/docg4.c
drivers/mtd/ubi/cdev.c
drivers/mtd/ubi/kapi.c
drivers/mtd/ubi/ubi-media.h
drivers/mtd/ubi/ubi.h
drivers/mtd/ubi/vmt.c
drivers/mtd/ubi/vtbl.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.h
drivers/net/ethernet/broadcom/genet/bcmgenet.h
drivers/net/ethernet/broadcom/genet/bcmmii.c
drivers/net/ethernet/cadence/macb_main.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c
drivers/net/ethernet/hisilicon/hns/hnae.h
drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h
drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h
drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
drivers/net/ethernet/hisilicon/hns/hns_enet.c
drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
drivers/net/ethernet/ibm/emac/core.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/intel/e1000/e1000_ethtool.c
drivers/net/ethernet/intel/i40e/i40e_ethtool.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/ice/ice.h
drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
drivers/net/ethernet/intel/ice/ice_common.c
drivers/net/ethernet/intel/ice/ice_controlq.c
drivers/net/ethernet/intel/ice/ice_ethtool.c
drivers/net/ethernet/intel/ice/ice_hw_autogen.h
drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/ice/ice_nvm.c
drivers/net/ethernet/intel/ice/ice_sched.c
drivers/net/ethernet/intel/ice/ice_switch.c
drivers/net/ethernet/intel/ice/ice_switch.h
drivers/net/ethernet/intel/ice/ice_txrx.h
drivers/net/ethernet/intel/ice/ice_type.h
drivers/net/ethernet/intel/igb/igb_ethtool.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/ixgb/ixgb_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlx5/core/wq.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
drivers/net/ethernet/netronome/nfp/flower/action.c
drivers/net/ethernet/netronome/nfp/nfp_net_common.c
drivers/net/ethernet/qlogic/qed/qed_init_ops.c
drivers/net/ethernet/qlogic/qed/qed_mcp.c
drivers/net/ethernet/qlogic/qed/qed_mcp.h
drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
drivers/net/ethernet/qlogic/qede/qede_filter.c
drivers/net/ethernet/qlogic/qlge/qlge_main.c
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/renesas/ravb.h
drivers/net/ethernet/renesas/ravb_main.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/renesas/sh_eth.h
drivers/net/ethernet/smsc/smc911x.c
drivers/net/ethernet/smsc/smc91x.c
drivers/net/ethernet/smsc/smc91x.h
drivers/net/ethernet/stmicro/stmmac/Kconfig
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
drivers/net/ethernet/ti/cpsw-phy-sel.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/phy/sfp.c
drivers/net/tun.c
drivers/net/usb/r8152.c
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
drivers/net/wireless/mac80211_hwsim.c
drivers/nvdimm/bus.c
drivers/nvdimm/dimm.c
drivers/nvdimm/dimm_devs.c
drivers/nvdimm/namespace_devs.c
drivers/nvdimm/nd-core.h
drivers/nvdimm/nd.h
drivers/nvdimm/pmem.c
drivers/nvdimm/pmem.h
drivers/nvdimm/region_devs.c
drivers/nvme/host/pci.c
drivers/nvme/target/core.c
drivers/nvme/target/fcloop.c
drivers/of/base.c
drivers/of/platform.c
drivers/pci/pci-acpi.c
drivers/pci/quirks.c
drivers/platform/chrome/chromeos_tbmc.c
drivers/platform/mellanox/Kconfig
drivers/platform/mellanox/Makefile
drivers/platform/mellanox/mlxreg-hotplug.c
drivers/platform/mellanox/mlxreg-io.c [new file with mode: 0644]
drivers/platform/x86/Kconfig
drivers/platform/x86/Makefile
drivers/platform/x86/acer-wmi.c
drivers/platform/x86/asus-nb-wmi.c
drivers/platform/x86/asus-wireless.c
drivers/platform/x86/asus-wmi.c
drivers/platform/x86/dell-smbios-base.c
drivers/platform/x86/dell-smbios-smm.c
drivers/platform/x86/dell-smbios-wmi.c
drivers/platform/x86/ideapad-laptop.c
drivers/platform/x86/intel-hid.c
drivers/platform/x86/intel-vbtn.c
drivers/platform/x86/intel_ips.c
drivers/platform/x86/intel_pmc_core.c
drivers/platform/x86/intel_pmc_core.h
drivers/platform/x86/intel_punit_ipc.c
drivers/platform/x86/mlx-platform.c
drivers/platform/x86/silead_dmi.c [deleted file]
drivers/platform/x86/thinkpad_acpi.c
drivers/platform/x86/toshiba_acpi.c
drivers/platform/x86/touchscreen_dmi.c [new file with mode: 0644]
drivers/platform/x86/wmi.c
drivers/power/reset/Kconfig
drivers/power/reset/Makefile
drivers/power/reset/gemini-poweroff.c
drivers/power/reset/ltc2952-poweroff.c
drivers/power/reset/qcom-pon.c [new file with mode: 0644]
drivers/power/reset/vexpress-poweroff.c
drivers/power/reset/zx-reboot.c
drivers/power/supply/Kconfig
drivers/power/supply/Makefile
drivers/power/supply/ab8500_fg.c
drivers/power/supply/adp5061.c [new file with mode: 0644]
drivers/power/supply/axp20x_usb_power.c
drivers/power/supply/axp288_charger.c
drivers/power/supply/bq27xxx_battery.c
drivers/power/supply/cros_usbpd-charger.c [new file with mode: 0644]
drivers/power/supply/ds2760_battery.c
drivers/power/supply/generic-adc-battery.c
drivers/power/supply/lego_ev3_battery.c
drivers/power/supply/max1721x_battery.c
drivers/power/supply/max77693_charger.c
drivers/power/supply/power_supply_core.c
drivers/power/supply/sbs-battery.c
drivers/power/supply/tps65217_charger.c
drivers/power/supply/wm8350_power.c
drivers/pwm/Kconfig
drivers/pwm/pwm-berlin.c
drivers/pwm/pwm-cros-ec.c
drivers/pwm/pwm-fsl-ftm.c
drivers/pwm/pwm-imx.c
drivers/pwm/pwm-mediatek.c
drivers/pwm/pwm-meson.c
drivers/pwm/pwm-mxs.c
drivers/pwm/pwm-omap-dmtimer.c
drivers/pwm/pwm-stm32-lp.c
drivers/pwm/pwm-tiehrpwm.c
drivers/rapidio/devices/rio_mport_cdev.c
drivers/reset/Kconfig
drivers/reset/Makefile
drivers/reset/reset-imx7.c
drivers/reset/reset-meson-audio-arb.c [new file with mode: 0644]
drivers/reset/reset-qcom-aoss.c [new file with mode: 0644]
drivers/reset/reset-simple.c
drivers/reset/reset-uniphier-usb3.c [new file with mode: 0644]
drivers/reset/reset-uniphier.c
drivers/rtc/Kconfig
drivers/rtc/class.c
drivers/rtc/interface.c
drivers/rtc/rtc-armada38x.c
drivers/rtc/rtc-bq4802.c
drivers/rtc/rtc-core.h
drivers/rtc/rtc-dev.c
drivers/rtc/rtc-ds1307.c
drivers/rtc/rtc-ds1685.c
drivers/rtc/rtc-isl1208.c
drivers/rtc/rtc-m48t59.c
drivers/rtc/rtc-max77686.c
drivers/rtc/rtc-max8997.c
drivers/rtc/rtc-max8998.c
drivers/rtc/rtc-omap.c
drivers/rtc/rtc-pcf2127.c
drivers/rtc/rtc-pcf85063.c
drivers/rtc/rtc-s5m.c
drivers/rtc/rtc-sa1100.c
drivers/rtc/rtc-sh.c
drivers/rtc/rtc-snvs.c
drivers/rtc/rtc-stmp3xxx.c
drivers/rtc/rtc-sysfs.c
drivers/rtc/rtc-test.c
drivers/s390/block/dcssblk.c
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/ap_bus.h
drivers/s390/crypto/ap_card.c
drivers/s390/crypto/ap_queue.c
drivers/s390/crypto/pkey_api.c
drivers/s390/crypto/zcrypt_api.c
drivers/s390/crypto/zcrypt_api.h
drivers/s390/crypto/zcrypt_card.c
drivers/s390/crypto/zcrypt_cca_key.h
drivers/s390/crypto/zcrypt_cex2a.c
drivers/s390/crypto/zcrypt_cex2a.h
drivers/s390/crypto/zcrypt_cex4.c
drivers/s390/crypto/zcrypt_error.h
drivers/s390/crypto/zcrypt_msgtype50.c
drivers/s390/crypto/zcrypt_msgtype50.h
drivers/s390/crypto/zcrypt_msgtype6.c
drivers/s390/crypto/zcrypt_msgtype6.h
drivers/s390/crypto/zcrypt_pcixcc.c
drivers/s390/crypto/zcrypt_pcixcc.h
drivers/s390/crypto/zcrypt_queue.c
drivers/scsi/Kconfig
drivers/scsi/aacraid/aacraid.h
drivers/scsi/csiostor/csio_hw.c
drivers/scsi/csiostor/csio_hw.h
drivers/scsi/csiostor/csio_mb.c
drivers/scsi/hosts.c
drivers/scsi/hpsa.c
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/osd/osd_uld.c
drivers/scsi/scsi_lib.c
drivers/scsi/sd.c
drivers/soc/bcm/brcmstb/pm/pm-arm.c
drivers/soc/fsl/Kconfig
drivers/soc/fsl/Makefile
drivers/soc/fsl/dpio/Makefile [new file with mode: 0644]
drivers/soc/fsl/dpio/dpio-cmd.h [new file with mode: 0644]
drivers/soc/fsl/dpio/dpio-driver.c [new file with mode: 0644]
drivers/soc/fsl/dpio/dpio-service.c [new file with mode: 0644]
drivers/soc/fsl/dpio/dpio.c [new file with mode: 0644]
drivers/soc/fsl/dpio/dpio.h [new file with mode: 0644]
drivers/soc/fsl/dpio/qbman-portal.c [new file with mode: 0644]
drivers/soc/fsl/dpio/qbman-portal.h [new file with mode: 0644]
drivers/soc/fsl/qbman/Kconfig
drivers/soc/fsl/qe/Kconfig
drivers/soc/fsl/qe/gpio.c
drivers/soc/imx/gpc.c
drivers/soc/mediatek/mtk-pmic-wrap.c
drivers/soc/renesas/Makefile
drivers/soc/renesas/r9a06g032-smp.c [new file with mode: 0644]
drivers/soc/renesas/rcar-sysc.c
drivers/soc/sunxi/sunxi_sram.c
drivers/soc/ti/Kconfig
drivers/soc/ti/pm33xx.c
drivers/soc/ti/wkup_m3_ipc.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h
drivers/staging/fsl-mc/Kconfig [deleted file]
drivers/staging/fsl-mc/Makefile [deleted file]
drivers/staging/fsl-mc/bus/Kconfig [deleted file]
drivers/staging/fsl-mc/bus/Makefile [deleted file]
drivers/staging/fsl-mc/bus/dpio/Makefile [deleted file]
drivers/staging/fsl-mc/bus/dpio/dpio-cmd.h [deleted file]
drivers/staging/fsl-mc/bus/dpio/dpio-driver.c [deleted file]
drivers/staging/fsl-mc/bus/dpio/dpio-driver.txt [deleted file]
drivers/staging/fsl-mc/bus/dpio/dpio-service.c [deleted file]
drivers/staging/fsl-mc/bus/dpio/dpio.c [deleted file]
drivers/staging/fsl-mc/bus/dpio/dpio.h [deleted file]
drivers/staging/fsl-mc/bus/dpio/qbman-portal.c [deleted file]
drivers/staging/fsl-mc/bus/dpio/qbman-portal.h [deleted file]
drivers/staging/fsl-mc/include/dpaa2-fd.h [deleted file]
drivers/staging/fsl-mc/include/dpaa2-global.h [deleted file]
drivers/staging/fsl-mc/include/dpaa2-io.h [deleted file]
drivers/target/iscsi/cxgbit/cxgbit_ddp.c
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target.h
drivers/target/iscsi/iscsi_target_login.c
drivers/tee/optee/Kconfig
drivers/tee/optee/core.c
drivers/tee/optee/rpc.c
drivers/thermal/Kconfig
drivers/thermal/intel_powerclamp.c
drivers/thermal/intel_soc_dts_thermal.c
drivers/thermal/of-thermal.c
drivers/thermal/qoriq_thermal.c
drivers/thermal/rcar_gen3_thermal.c
drivers/thermal/rcar_thermal.c
drivers/tty/hvc/hvc_opal.c
drivers/tty/sysrq.c
drivers/tty/tty_io.c
drivers/usb/host/ehci-exynos.c
drivers/usb/host/ohci-exynos.c
drivers/vhost/Kconfig
drivers/vhost/scsi.c
drivers/vhost/vhost.c
drivers/video/console/Kconfig
drivers/video/console/dummycon.c
drivers/video/console/vgacon.c
drivers/video/fbdev/amifb.c
drivers/video/fbdev/core/fbcon.c
drivers/video/fbdev/core/fbmem.c
drivers/video/fbdev/core/modedb.c
drivers/video/fbdev/efifb.c
drivers/video/fbdev/fsl-diu-fb.c
drivers/video/fbdev/goldfishfb.c
drivers/video/fbdev/i740fb.c
drivers/video/fbdev/metronomefb.c
drivers/video/fbdev/omap/omapfb_main.c
drivers/video/fbdev/omap2/omapfb/Makefile
drivers/video/fbdev/omap2/omapfb/displays/encoder-tpd12s015.c
drivers/video/fbdev/omap2/omapfb/dss/dispc.c
drivers/video/fbdev/omap2/omapfb/omapfb-main.c
drivers/video/fbdev/pm2fb.c
drivers/video/fbdev/pxa3xx-gcu.c
drivers/video/fbdev/pxafb.c
drivers/video/fbdev/pxafb.h
drivers/video/fbdev/simplefb.c
drivers/video/fbdev/tdfxfb.c
drivers/video/fbdev/tridentfb.c
drivers/video/fbdev/udlfb.c
drivers/video/fbdev/via/lcd.c
drivers/video/fbdev/via/viafbdev.c
drivers/virtio/virtio_balloon.c
drivers/virtio/virtio_mmio.c
drivers/virtio/virtio_pci_legacy.c
drivers/w1/slaves/Kconfig
drivers/w1/slaves/Makefile
drivers/w1/slaves/w1_ds2760.c [deleted file]
drivers/w1/slaves/w1_ds2760.h [deleted file]
drivers/w1/w1.c
drivers/watchdog/kempld_wdt.c
drivers/xen/gntdev.c
drivers/xen/mcelog.c
drivers/xen/xen-acpi-processor.c
drivers/xen/xenbus/xenbus_probe.c
fs/adfs/inode.c
fs/afs/internal.h
fs/afs/proc.c
fs/afs/write.c
fs/autofs/autofs_i.h
fs/autofs/expire.c
fs/autofs/inode.c
fs/autofs/root.c
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/qgroup.c
fs/btrfs/tree-log.c
fs/btrfs/tree-log.h
fs/btrfs/volumes.c
fs/buffer.c
fs/ceph/acl.c
fs/ceph/addr.c
fs/ceph/cache.c
fs/ceph/caps.c
fs/ceph/dir.c
fs/ceph/file.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/mds_client.h
fs/ceph/quota.c
fs/ceph/snap.c
fs/ceph/super.c
fs/ceph/super.h
fs/ceph/xattr.c
fs/cifs/cifs_unicode.c
fs/cifs/cifsfs.h
fs/cifs/connect.c
fs/cifs/inode.c
fs/cifs/sess.c
fs/cifs/smb2misc.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2pdu.h
fs/dax.c
fs/devpts/inode.c
fs/eventpoll.c
fs/exec.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/sysfs.c
fs/f2fs/xattr.c
fs/fat/cache.c
fs/fat/dir.c
fs/fat/fat.h
fs/fat/fatent.c
fs/fat/file.c
fs/fat/inode.c
fs/fat/misc.c
fs/fat/namei_msdos.c
fs/fat/namei_vfat.c
fs/fcntl.c
fs/file_table.c
fs/fuse/dev.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/inode.c
fs/hfs/brec.c
fs/hfsplus/Kconfig
fs/hfsplus/Makefile
fs/hfsplus/acl.h [deleted file]
fs/hfsplus/brec.c
fs/hfsplus/dir.c
fs/hfsplus/extents.c
fs/hfsplus/hfsplus_fs.h
fs/hfsplus/inode.c
fs/hfsplus/posix_acl.c [deleted file]
fs/hfsplus/super.c
fs/hfsplus/unicode.c
fs/hfsplus/xattr.c
fs/hfsplus/xattr.h
fs/hfsplus/xattr_security.c
fs/hpfs/namei.c
fs/hugetlbfs/inode.c
fs/inode.c
fs/internal.h
fs/ioctl.c
fs/iomap.c
fs/isofs/inode.c
fs/lockd/clntlock.c
fs/lockd/clntproc.c
fs/lockd/svclock.c
fs/lockd/svcsubs.c
fs/locks.c
fs/namei.c
fs/namespace.c
fs/nfs/blocklayout/blocklayout.c
fs/nfs/blocklayout/dev.c
fs/nfs/callback.h
fs/nfs/callback_proc.c
fs/nfs/callback_xdr.c
fs/nfs/client.c
fs/nfs/dir.c
fs/nfs/direct.c
fs/nfs/file.c
fs/nfs/flexfilelayout/flexfilelayout.c
fs/nfs/nfs3acl.c
fs/nfs/nfs42proc.c
fs/nfs/nfs42xdr.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4client.c
fs/nfs/nfs4file.c
fs/nfs/nfs4idmap.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c
fs/nfs/nfs4xdr.c
fs/nfs/pagelist.c
fs/nfs/pnfs.c
fs/nfs/pnfs.h
fs/nfs/pnfs_nfs.c
fs/nfs/super.c
fs/nfs/write.c
fs/nfsd/netns.h
fs/nfsd/nfs3proc.c
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4layouts.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfsctl.c
fs/nfsd/nfsd.h
fs/nfsd/nfsfh.c
fs/nfsd/nfsproc.c
fs/nfsd/state.h
fs/nilfs2/alloc.c
fs/nilfs2/alloc.h
fs/nilfs2/bmap.c
fs/nilfs2/bmap.h
fs/nilfs2/btnode.c
fs/nilfs2/btnode.h
fs/nilfs2/btree.c
fs/nilfs2/btree.h
fs/nilfs2/cpfile.c
fs/nilfs2/cpfile.h
fs/nilfs2/dat.c
fs/nilfs2/dat.h
fs/nilfs2/dir.c
fs/nilfs2/direct.c
fs/nilfs2/direct.h
fs/nilfs2/file.c
fs/nilfs2/gcinode.c
fs/nilfs2/ifile.c
fs/nilfs2/ifile.h
fs/nilfs2/inode.c
fs/nilfs2/ioctl.c
fs/nilfs2/mdt.c
fs/nilfs2/mdt.h
fs/nilfs2/namei.c
fs/nilfs2/nilfs.h
fs/nilfs2/page.c
fs/nilfs2/page.h
fs/nilfs2/recovery.c
fs/nilfs2/segbuf.c
fs/nilfs2/segbuf.h
fs/nilfs2/segment.c
fs/nilfs2/segment.h
fs/nilfs2/sufile.c
fs/nilfs2/sufile.h
fs/nilfs2/super.c
fs/nilfs2/sysfs.c
fs/nilfs2/sysfs.h
fs/nilfs2/the_nilfs.c
fs/nilfs2/the_nilfs.h
fs/notify/dnotify/dnotify.c
fs/notify/fanotify/fanotify.c
fs/notify/fsnotify.c
fs/notify/mark.c
fs/ocfs2/file.c
fs/open.c
fs/overlayfs/Kconfig
fs/overlayfs/Makefile
fs/overlayfs/copy_up.c
fs/overlayfs/dir.c
fs/overlayfs/export.c
fs/overlayfs/file.c [new file with mode: 0644]
fs/overlayfs/inode.c
fs/overlayfs/namei.c
fs/overlayfs/overlayfs.h
fs/overlayfs/ovl_entry.h
fs/overlayfs/readdir.c
fs/overlayfs/super.c
fs/overlayfs/util.c
fs/proc/Kconfig
fs/proc/base.c
fs/proc/generic.c
fs/proc/inode.c
fs/proc/internal.h
fs/proc/kcore.c
fs/proc/meminfo.c
fs/proc/stat.c
fs/proc/task_mmu.c
fs/proc/task_nommu.c
fs/proc/uptime.c
fs/proc/vmcore.c
fs/quota/quota.c
fs/read_write.c
fs/reiserfs/item_ops.c
fs/reiserfs/journal.c
fs/reiserfs/procfs.c
fs/reiserfs/reiserfs.h
fs/reiserfs/xattr.c
fs/super.c
fs/sysv/inode.c
fs/tracefs/inode.c
fs/ubifs/Kconfig
fs/ubifs/Makefile
fs/ubifs/budget.c
fs/ubifs/commit.c
fs/ubifs/crypto.c
fs/ubifs/debug.c
fs/ubifs/debug.h
fs/ubifs/dir.c
fs/ubifs/file.c
fs/ubifs/find.c
fs/ubifs/gc.c
fs/ubifs/io.c
fs/ubifs/journal.c
fs/ubifs/key.h
fs/ubifs/log.c
fs/ubifs/lprops.c
fs/ubifs/lpt.c
fs/ubifs/lpt_commit.c
fs/ubifs/master.c
fs/ubifs/misc.c
fs/ubifs/misc.h
fs/ubifs/orphan.c
fs/ubifs/recovery.c
fs/ubifs/replay.c
fs/ubifs/sb.c
fs/ubifs/scan.c
fs/ubifs/shrinker.c
fs/ubifs/super.c
fs/ubifs/tnc.c
fs/ubifs/tnc_commit.c
fs/ubifs/tnc_misc.c
fs/ubifs/ubifs.h
fs/ubifs/xattr.c
fs/udf/super.c
fs/userfaultfd.c
fs/xattr.c
fs/xfs/scrub/repair.c
fs/xfs/xfs_file.c
fs/xfs/xfs_mount.c
include/acpi/acconfig.h
include/acpi/acexcep.h
include/acpi/acpixf.h
include/asm-generic/bug.h
include/asm-generic/export.h
include/asm-generic/tlb.h
include/asm-generic/vmlinux.lds.h
include/dt-bindings/bus/ti-sysc.h
include/dt-bindings/clock/dra7.h
include/dt-bindings/clock/exynos5440.h [deleted file]
include/dt-bindings/memory/mt2712-larb-port.h [new file with mode: 0644]
include/dt-bindings/reset/amlogic,meson-axg-audio-arb.h [new file with mode: 0644]
include/dt-bindings/reset/qcom,sdm845-aoss.h [new file with mode: 0644]
include/kvm/arm_vgic.h
include/linux/ahci_platform.h
include/linux/arm-smccc.h
include/linux/backing-dev-defs.h
include/linux/backing-dev.h
include/linux/bitops.h
include/linux/blk-cgroup.h
include/linux/ceph/auth.h
include/linux/ceph/ceph_features.h
include/linux/ceph/decode.h
include/linux/ceph/messenger.h
include/linux/ceph/msgr.h
include/linux/ceph/osd_client.h
include/linux/ceph/pagelist.h
include/linux/clk/at91_pmc.h
include/linux/compiler-clang.h
include/linux/compiler-gcc.h
include/linux/compiler-intel.h
include/linux/compiler.h
include/linux/compiler_types.h
include/linux/console.h
include/linux/cpuhotplug.h
include/linux/crash_core.h
include/linux/crc64.h [new file with mode: 0644]
include/linux/dax.h
include/linux/dcache.h
include/linux/dmar.h
include/linux/export.h
include/linux/f2fs_fs.h
include/linux/fb.h
include/linux/fs.h
include/linux/fsnotify.h
include/linux/ftrace.h
include/linux/gfp.h
include/linux/huge_mm.h
include/linux/hugetlb.h
include/linux/i2c.h
include/linux/idr.h
include/linux/init.h
include/linux/init_task.h
include/linux/intel-iommu.h
include/linux/iommu.h
include/linux/ipc_namespace.h
include/linux/irqchip/arm-gic-v3.h
include/linux/irqchip/arm-gic.h
include/linux/irqflags.h
include/linux/kcore.h
include/linux/kernel.h
include/linux/kvm_host.h
include/linux/libata.h
include/linux/lockd/lockd.h
include/linux/lockdep.h
include/linux/memcontrol.h
include/linux/memory_hotplug.h
include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
include/linux/mm.h
include/linux/mmu_notifier.h
include/linux/mmzone.h
include/linux/net_dim.h
include/linux/nfs4.h
include/linux/nfs_fs.h
include/linux/nfs_fs_sb.h
include/linux/nfs_xdr.h
include/linux/nodemask.h
include/linux/of.h
include/linux/oom.h
include/linux/page-flags.h
include/linux/pci.h
include/linux/pci_ids.h
include/linux/percpu.h
include/linux/pid.h
include/linux/platform_data/ams-delta-fiq.h [new file with mode: 0644]
include/linux/platform_data/i2c-ocores.h
include/linux/platform_data/ina2xx.h
include/linux/platform_data/mtd-davinci-aemif.h
include/linux/platform_data/pm33xx.h
include/linux/platform_data/sh_ipmmu.h [deleted file]
include/linux/platform_data/ti-sysc.h
include/linux/power_supply.h
include/linux/preempt.h
include/linux/proc_fs.h
include/linux/ptrace.h
include/linux/quota.h
include/linux/ring_buffer.h
include/linux/rtc.h
include/linux/sched.h
include/linux/sched/signal.h
include/linux/sched/sysctl.h
include/linux/sched/user.h
include/linux/set_memory.h
include/linux/shrinker.h
include/linux/signal.h
include/linux/soc/renesas/rcar-sysc.h
include/linux/srcu.h
include/linux/sunrpc/auth.h
include/linux/sunrpc/clnt.h
include/linux/sunrpc/metrics.h
include/linux/sunrpc/svc.h
include/linux/sunrpc/svcauth.h
include/linux/swap.h
include/linux/swapops.h
include/linux/time32.h
include/linux/timekeeping.h
include/linux/tracepoint.h
include/linux/uprobes.h
include/linux/userfaultfd_k.h
include/linux/w1.h
include/linux/wkup_m3_ipc.h
include/net/act_api.h
include/net/cfg80211.h
include/net/pkt_cls.h
include/net/regulatory.h
include/net/scm.h
include/rdma/ib_cache.h
include/rdma/ib_umem_odp.h
include/soc/bcm2835/raspberrypi-firmware.h
include/soc/fsl/dpaa2-fd.h [new file with mode: 0644]
include/soc/fsl/dpaa2-global.h [new file with mode: 0644]
include/soc/fsl/dpaa2-io.h [new file with mode: 0644]
include/trace/events/cgroup.h
include/trace/events/preemptirq.h
include/uapi/linux/auto_fs.h
include/uapi/linux/bcache.h
include/uapi/linux/keyctl.h
include/uapi/linux/kvm.h
include/uapi/linux/rds.h
include/uapi/linux/vhost.h
include/uapi/mtd/ubi-user.h
include/video/udlfb.h
init/Kconfig
init/do_mounts.c
init/do_mounts_initrd.c
init/do_mounts_md.c
init/do_mounts_rd.c
init/init_task.c
init/initramfs.c
init/main.c
ipc/msg.c
ipc/namespace.c
ipc/sem.c
ipc/shm.c
ipc/util.c
ipc/util.h
kernel/bpf/hashtab.c
kernel/bpf/sockmap.c
kernel/cgroup/cgroup-internal.h
kernel/cgroup/cgroup-v1.c
kernel/cgroup/cgroup.c
kernel/cpu.c
kernel/crash_core.c
kernel/dma/direct.c
kernel/events/callchain.c
kernel/events/core.c
kernel/events/uprobes.c
kernel/exit.c
kernel/fork.c
kernel/futex.c
kernel/hung_task.c
kernel/kallsyms.c
kernel/livepatch/core.c
kernel/livepatch/transition.c
kernel/locking/lockdep.c
kernel/memremap.c
kernel/module.c
kernel/pid.c
kernel/power/Kconfig
kernel/printk/printk.c
kernel/printk/printk_safe.c
kernel/sched/core.c
kernel/sched/idle.c
kernel/sched/wait.c
kernel/signal.c
kernel/sys.c
kernel/sysctl.c
kernel/time/clocksource.c
kernel/time/itimer.c
kernel/time/posix-cpu-timers.c
kernel/time/posix-timers.c
kernel/trace/Kconfig
kernel/trace/Makefile
kernel/trace/blktrace.c
kernel/trace/bpf_trace.c
kernel/trace/ftrace.c
kernel/trace/preemptirq_delay_test.c [new file with mode: 0644]
kernel/trace/ring_buffer.c
kernel/trace/ring_buffer_benchmark.c
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_benchmark.h
kernel/trace/trace_clock.c
kernel/trace/trace_entries.h
kernel/trace/trace_event_perf.c
kernel/trace/trace_events.c
kernel/trace/trace_events_filter.c
kernel/trace/trace_events_filter_test.h
kernel/trace/trace_events_hist.c
kernel/trace/trace_events_trigger.c
kernel/trace/trace_hwlat.c
kernel/trace/trace_irqsoff.c
kernel/trace/trace_kprobe.c
kernel/trace/trace_kprobe_selftest.c [new file with mode: 0644]
kernel/trace/trace_kprobe_selftest.h [new file with mode: 0644]
kernel/trace/trace_output.c
kernel/trace/trace_output.h
kernel/trace/trace_preemptirq.c [new file with mode: 0644]
kernel/trace/trace_printk.c
kernel/trace/trace_probe.c
kernel/trace/trace_probe.h
kernel/trace/trace_seq.c
kernel/trace/trace_stat.h
kernel/trace/trace_uprobe.c
kernel/trace/tracing_map.c
kernel/trace/tracing_map.h
kernel/tracepoint.c
kernel/user.c
kernel/user_namespace.c
kernel/utsname_sysctl.c
kernel/watchdog.c
kernel/watchdog_hld.c
kernel/workqueue.c
lib/.gitignore
lib/Kconfig
lib/Kconfig.debug
lib/Makefile
lib/bitmap.c
lib/crc64.c [new file with mode: 0644]
lib/fonts/font_7x14.c
lib/fonts/font_8x16.c
lib/fonts/font_8x8.c
lib/fonts/font_pearl_8x8.c
lib/gen_crc64table.c [new file with mode: 0644]
lib/idr.c
lib/percpu_counter.c
lib/radix-tree.c
lib/rhashtable.c
lib/test_debug_virtual.c
lib/test_hexdump.c
lib/test_ida.c [new file with mode: 0644]
mm/Kconfig.debug
mm/backing-dev.c
mm/gup.c
mm/hmm.c
mm/huge_memory.c
mm/hugetlb.c
mm/internal.h
mm/khugepaged.c
mm/kmemleak.c
mm/ksm.c
mm/madvise.c
mm/memcontrol.c
mm/memory-failure.c
mm/memory.c
mm/memory_hotplug.c
mm/mempolicy.c
mm/mempool.c
mm/migrate.c
mm/mm_init.c
mm/mmap.c
mm/mmu_notifier.c
mm/oom_kill.c
mm/page-writeback.c
mm/page_alloc.c
mm/percpu.c
mm/shmem.c
mm/slub.c
mm/swap_slots.c
mm/swapfile.c
mm/util.c
mm/vmscan.c
net/ceph/Kconfig
net/ceph/Makefile
net/ceph/auth.c
net/ceph/auth_none.c
net/ceph/auth_none.h
net/ceph/auth_x.c
net/ceph/auth_x.h
net/ceph/auth_x_protocol.h
net/ceph/ceph_common.c
net/ceph/cls_lock_client.c
net/ceph/crush/mapper.c
net/ceph/messenger.c
net/ceph/mon_client.c
net/ceph/osd_client.c
net/ceph/pagevec.c
net/core/dev.c
net/core/filter.c
net/core/net_namespace.c
net/core/rtnetlink.c
net/dsa/dsa.c
net/dsa/slave.c
net/ipv4/igmp.c
net/ipv4/ip_gre.c
net/ipv4/tcp_bbr.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/ipv6/addrconf.c
net/ipv6/af_inet6.c
net/ipv6/ip6_fib.c
net/ipv6/ip6_gre.c
net/ipv6/ip6_tunnel.c
net/ipv6/ip6_vti.c
net/ipv6/route.c
net/mac80211/ibss.c
net/mac80211/main.c
net/mac80211/mesh_hwmp.c
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/tx.c
net/mac80211/util.c
net/ncsi/ncsi-netlink.c
net/netfilter/ipvs/Kconfig
net/netfilter/ipvs/ip_vs_mh.c
net/packet/af_packet.c
net/packet/internal.h
net/rds/Kconfig
net/rds/ib.c
net/rds/tcp.c
net/rfkill/rfkill-gpio.c
net/sched/act_api.c
net/sched/act_bpf.c
net/sched/act_connmark.c
net/sched/act_csum.c
net/sched/act_gact.c
net/sched/act_ife.c
net/sched/act_ipt.c
net/sched/act_mirred.c
net/sched/act_nat.c
net/sched/act_pedit.c
net/sched/act_police.c
net/sched/act_sample.c
net/sched/act_simple.c
net/sched/act_skbedit.c
net/sched/act_skbmod.c
net/sched/act_tunnel_key.c
net/sched/act_vlan.c
net/sched/cls_api.c
net/sched/cls_u32.c
net/sched/sch_cake.c
net/sctp/proc.c
net/sctp/socket.c
net/smc/smc_ib.c
net/sunrpc/auth.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/auth_gss/gss_generic_token.c
net/sunrpc/auth_gss/gss_krb5_crypto.c
net/sunrpc/auth_gss/gss_krb5_keys.c
net/sunrpc/auth_gss/gss_krb5_seal.c
net/sunrpc/auth_gss/gss_krb5_unseal.c
net/sunrpc/auth_gss/gss_krb5_wrap.c
net/sunrpc/auth_gss/gss_rpc_upcall.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/auth_null.c
net/sunrpc/auth_unix.c
net/sunrpc/backchannel_rqst.c
net/sunrpc/clnt.c
net/sunrpc/rpcb_clnt.c
net/sunrpc/stats.c
net/sunrpc/sunrpc.h
net/sunrpc/svc.c
net/sunrpc/xprt.c
net/sunrpc/xprtrdma/svc_rdma.c
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
net/sunrpc/xprtrdma/svc_rdma_rw.c
net/sunrpc/xprtrdma/svc_rdma_sendto.c
net/sunrpc/xprtrdma/svc_rdma_transport.c
net/sunrpc/xprtrdma/verbs.c
net/sunrpc/xprtsock.c
net/tipc/bcast.c
net/tipc/diag.c
net/tipc/name_table.c
net/tipc/name_table.h
net/tipc/netlink.c
net/tipc/socket.c
net/tipc/socket.h
net/tipc/topsrv.c
net/tls/tls_main.c
net/wireless/nl80211.c
net/wireless/reg.c
net/wireless/util.c
net/xdp/xdp_umem.c
scripts/Kbuild.include
scripts/Makefile.build
scripts/Makefile.lib
scripts/Makefile.modpost
scripts/checkpatch.pl
scripts/clang-version.sh
scripts/coccinelle/api/alloc/zalloc-simple.cocci
scripts/depmod.sh
scripts/dtc/Makefile
scripts/gcc-plugins/Kconfig
scripts/gen_initramfs_list.sh [deleted file]
scripts/get_maintainer.pl
scripts/kconfig/Makefile
scripts/kconfig/check-pkgconfig.sh [deleted file]
scripts/kconfig/conf.c
scripts/kconfig/gconf-cfg.sh
scripts/kconfig/mconf-cfg.sh
scripts/kconfig/mconf.c
scripts/kconfig/nconf-cfg.sh
scripts/kconfig/qconf-cfg.sh
scripts/kconfig/symbol.c
scripts/kconfig/tests/err_recursive_dep/Kconfig [new file with mode: 0644]
scripts/kconfig/tests/err_recursive_dep/__init__.py [new file with mode: 0644]
scripts/kconfig/tests/err_recursive_dep/expected_stderr [new file with mode: 0644]
scripts/kconfig/tests/warn_recursive_dep/Kconfig [deleted file]
scripts/kconfig/tests/warn_recursive_dep/__init__.py [deleted file]
scripts/kconfig/tests/warn_recursive_dep/expected_stderr [deleted file]
scripts/link-vmlinux.sh
scripts/mod/modpost.c
scripts/recordmcount.pl
scripts/setlocalversion
scripts/spelling.txt
security/apparmor/apparmorfs.c
security/apparmor/domain.c
security/apparmor/file.c
security/apparmor/include/perms.h
security/apparmor/lib.c
security/apparmor/policy_ns.c
security/apparmor/policy_unpack.c
security/apparmor/secid.c
security/commoncap.c
security/keys/dh.c
security/security.c
sound/ac97/bus.c
sound/ac97/snd_ac97_compat.c
sound/core/rawmidi.c
sound/core/seq/seq_virmidi.c
sound/hda/ext/hdac_ext_stream.c
sound/pci/hda/hda_codec.c
sound/pci/hda/patch_realtek.c
sound/soc/intel/common/sst-dsp-priv.h
tools/arch/x86/include/asm/cpufeatures.h
tools/arch/x86/lib/memcpy_64.S
tools/bpf/bpftool/map.c
tools/bpf/bpftool/map_perf_ring.c
tools/include/linux/bitmap.h
tools/kvm/kvm_stat/kvm_stat
tools/lib/lockdep/Makefile
tools/lib/traceevent/Makefile
tools/lib/traceevent/event-parse.c
tools/lib/traceevent/event-parse.h
tools/lib/traceevent/event-plugin.c
tools/lib/traceevent/event-utils.h
tools/lib/traceevent/kbuffer-parse.c
tools/lib/traceevent/parse-filter.c
tools/lib/traceevent/parse-utils.c
tools/lib/traceevent/plugin_cfg80211.c
tools/lib/traceevent/plugin_function.c
tools/lib/traceevent/plugin_hrtimer.c
tools/lib/traceevent/plugin_jbd2.c
tools/lib/traceevent/plugin_kmem.c
tools/lib/traceevent/plugin_kvm.c
tools/lib/traceevent/plugin_mac80211.c
tools/lib/traceevent/plugin_sched_switch.c
tools/lib/traceevent/plugin_scsi.c
tools/lib/traceevent/plugin_xen.c
tools/lib/traceevent/trace-seq.c
tools/perf/Documentation/perf-annotate.txt
tools/perf/Documentation/perf-report.txt
tools/perf/Makefile
tools/perf/arch/arm64/util/arm-spe.c
tools/perf/arch/powerpc/util/sym-handling.c
tools/perf/arch/s390/util/auxtrace.c
tools/perf/arch/x86/Makefile
tools/perf/builtin-annotate.c
tools/perf/builtin-kmem.c
tools/perf/builtin-report.c
tools/perf/builtin-script.c
tools/perf/builtin-trace.c
tools/perf/check-headers.sh
tools/perf/examples/bpf/augmented_syscalls.c [new file with mode: 0644]
tools/perf/examples/bpf/hello.c [new file with mode: 0644]
tools/perf/examples/bpf/sys_enter_openat.c [new file with mode: 0644]
tools/perf/include/bpf/bpf.h
tools/perf/include/bpf/stdio.h [new file with mode: 0644]
tools/perf/pmu-events/arch/arm64/ampere/emag/core-imp-def.json [new file with mode: 0644]
tools/perf/pmu-events/arch/arm64/mapfile.csv
tools/perf/tests/bitmap.c
tools/perf/tests/code-reading.c
tools/perf/tests/kmod-path.c
tools/perf/tests/mem2node.c
tools/perf/ui/browsers/annotate.c
tools/perf/util/Build
tools/perf/util/annotate.c
tools/perf/util/annotate.h
tools/perf/util/auxtrace.c
tools/perf/util/auxtrace.h
tools/perf/util/bpf-loader.c
tools/perf/util/bpf-loader.h
tools/perf/util/compress.h
tools/perf/util/data-convert-bt.c
tools/perf/util/dso.c
tools/perf/util/dso.h
tools/perf/util/event.c
tools/perf/util/evlist.c
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/header.c
tools/perf/util/llvm-utils.c
tools/perf/util/llvm-utils.h
tools/perf/util/lzma.c
tools/perf/util/machine.c
tools/perf/util/machine.h
tools/perf/util/map.c
tools/perf/util/map.h
tools/perf/util/mmap.c
tools/perf/util/mmap.h
tools/perf/util/namespaces.c
tools/perf/util/parse-events.c
tools/perf/util/python.c
tools/perf/util/s390-cpumsf-kernel.h [new file with mode: 0644]
tools/perf/util/s390-cpumsf.c [new file with mode: 0644]
tools/perf/util/s390-cpumsf.h [new file with mode: 0644]
tools/perf/util/scripting-engines/trace-event-perl.c
tools/perf/util/scripting-engines/trace-event-python.c
tools/perf/util/setup.py
tools/perf/util/sort.c
tools/perf/util/sort.h
tools/perf/util/trace-event-parse.c
tools/perf/util/trace-event-read.c
tools/perf/util/trace-event-scripting.c
tools/perf/util/trace-event.c
tools/perf/util/trace-event.h
tools/perf/util/zlib.c
tools/power/cpupower/po/de.po
tools/power/cpupower/po/fr.po
tools/testing/nvdimm/pmem-dax.c
tools/testing/nvdimm/test/nfit.c
tools/testing/radix-tree/Makefile
tools/testing/radix-tree/idr-test.c
tools/testing/radix-tree/linux/xarray.h [new file with mode: 0644]
tools/testing/radix-tree/main.c
tools/testing/radix-tree/test.h
tools/testing/selftests/android/ion/ionapp_export.c
tools/testing/selftests/cgroup/.gitignore [new file with mode: 0644]
tools/testing/selftests/cgroup/Makefile
tools/testing/selftests/cgroup/cgroup_util.c
tools/testing/selftests/cgroup/cgroup_util.h
tools/testing/selftests/cgroup/test_core.c [new file with mode: 0644]
tools/testing/selftests/ftrace/config
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc
tools/testing/selftests/ftrace/test.d/kprobe/probepoint.tc
tools/testing/selftests/ftrace/test.d/preemptirq/irqsoff_tracer.tc [new file with mode: 0644]
tools/testing/selftests/kvm/Makefile
tools/testing/selftests/kvm/cr4_cpuid_sync_test.c
tools/testing/selftests/kvm/dirty_log_test.c [new file with mode: 0644]
tools/testing/selftests/kvm/include/kvm_util.h
tools/testing/selftests/kvm/include/test_util.h
tools/testing/selftests/kvm/lib/kvm_util.c
tools/testing/selftests/kvm/lib/x86.c
tools/testing/selftests/kvm/set_sregs_test.c
tools/testing/selftests/kvm/state_test.c
tools/testing/selftests/kvm/sync_regs_test.c
tools/testing/selftests/kvm/vmx_tsc_adjust_test.c
tools/testing/selftests/mount/config
tools/testing/selftests/net/pmtu.sh
tools/testing/selftests/proc/.gitignore
tools/testing/selftests/proc/Makefile
tools/testing/selftests/proc/proc.h
tools/testing/selftests/proc/self.c [new file with mode: 0644]
tools/testing/selftests/proc/thread-self.c [new file with mode: 0644]
tools/testing/selftests/tc-testing/tc-tests/actions/police.json
tools/testing/selftests/vDSO/Makefile
tools/testing/selftests/vDSO/vdso_test.c
tools/testing/selftests/vm/.gitignore
tools/testing/selftests/vm/Makefile
tools/testing/selftests/vm/map_populate.c [new file with mode: 0644]
tools/testing/selftests/vm/run_vmtests
tools/vm/page-types.c
tools/vm/slabinfo.c
usr/Makefile
usr/gen_initramfs_list.sh [new file with mode: 0755]
usr/initramfs_data.S
virt/kvm/arm/arch_timer.c
virt/kvm/arm/arm.c
virt/kvm/arm/mmu.c
virt/kvm/arm/trace.h
virt/kvm/arm/vgic/vgic-debug.c
virt/kvm/arm/vgic/vgic-init.c
virt/kvm/arm/vgic/vgic-its.c
virt/kvm/arm/vgic/vgic-mmio-v2.c
virt/kvm/arm/vgic/vgic-mmio-v3.c
virt/kvm/arm/vgic/vgic-mmio.c
virt/kvm/arm/vgic/vgic-mmio.h
virt/kvm/arm/vgic/vgic-v2.c
virt/kvm/arm/vgic/vgic-v3.c
virt/kvm/arm/vgic/vgic.c
virt/kvm/arm/vgic/vgic.h
virt/kvm/kvm_main.c

index 2a6f685bf70633757017a3bd1ff72c9d080cd7fd..285e09645b31485d7bc314fb1fa7d055ec50fb46 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -159,6 +159,7 @@ Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
 Randy Dunlap <rdunlap@infradead.org> <rdunlap@xenotime.net>
 Rémi Denis-Courmont <rdenis@simphalempin.com>
 Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
+Ross Zwisler <zwisler@kernel.org> <ross.zwisler@linux.intel.com>
 Rudolf Marek <R.Marek@sh.cvut.cz>
 Rui Saraiva <rmps@joel.ist.utl.pt>
 Sachin P Sant <ssant@in.ibm.com>
index 3d5951c8bf5fe8b27f47b016289c910f90af97e6..e8b60bd766f7649a430a877628e73d8936d66cbb 100644 (file)
@@ -73,3 +73,12 @@ KernelVersion:       3.0
 Contact:       Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
 Description:
                 Number of sectors written by the frontend.
+
+What:          /sys/bus/xen-backend/devices/*/state
+Date:          August 2018
+KernelVersion: 4.19
+Contact:       Joe Jin <joe.jin@oracle.com>
+Description:
+                The state of the device. One of: 'Unknown',
+                'Initialising', 'Initialised', 'Connected', 'Closing',
+                'Closed', 'Reconfiguring', 'Reconfigured'.
diff --git a/Documentation/ABI/stable/sysfs-driver-mlxreg-io b/Documentation/ABI/stable/sysfs-driver-mlxreg-io
new file mode 100644 (file)
index 0000000..d9d117d
--- /dev/null
@@ -0,0 +1,78 @@
+What:          /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/
+                                                       asic_health
+
+Date:          June 2018
+KernelVersion: 4.19
+Contact:       Vadim Pasternak <vadimpmellanox.com>
+Description:   This file shows ASIC health status. The possible values are:
+               0 - health failed, 2 - health OK, 3 - ASIC in booting state.
+
+               The files are read only.
+
+What:          /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/
+                                                       cpld1_version
+                                                       cpld2_version
+
+Date:          June 2018
+KernelVersion: 4.19
+Contact:       Vadim Pasternak <vadimpmellanox.com>
+Description:   These files show with which CPLD versions have been burned
+               on carrier and switch boards.
+
+               The files are read only.
+
+What:          /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/select_iio
+Date:          June 2018
+KernelVersion: 4.19
+Contact:       Vadim Pasternak <vadimpmellanox.com>
+Description:   This file allows iio devices selection.
+
+               Attribute select_iio can be written with 0 or with 1. It
+               selects which one of iio devices can be accessed.
+
+               The file is read/write.
+
+What:          /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/psu1_on
+               /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/psu2_on
+               /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/pwr_cycle
+               /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/pwr_down
+Date:          June 2018
+KernelVersion: 4.19
+Contact:       Vadim Pasternak <vadimpmellanox.com>
+Description:   These files allow asserting system power cycling, switching
+               power supply units on and off and system's main power domain
+               shutdown.
+               Expected behavior:
+               When pwr_cycle is written 1: auxiliary power domain will go
+               down and after short period (about 1 second) up.
+               When  psu1_on or psu2_on is written 1, related unit will be
+               disconnected from the power source, when written 0 - connected.
+               If both are written 1 - power supplies main power domain will
+               go down.
+               When pwr_down is written 1, system's main power domain will go
+               down.
+
+               The files are write only.
+
+What:          /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/
+                                                       reset_aux_pwr_or_ref
+                                                       reset_asic_thermal
+                                                       reset_hotswap_or_halt
+                                                       reset_hotswap_or_wd
+                                                       reset_fw_reset
+                                                       reset_long_pb
+                                                       reset_main_pwr_fail
+                                                       reset_short_pb
+                                                       reset_sw_reset
+Date:          June 2018
+KernelVersion: 4.19
+Contact:       Vadim Pasternak <vadimpmellanox.com>
+Description:   These files show the system reset cause, as following: power
+               auxiliary outage or power refresh, ASIC thermal shutdown, halt,
+               hotswap, watchdog, firmware reset, long press power button,
+               short press power button, software reset. Value 1 in file means
+               this is reset cause, 0 - otherwise. Only one of the above
+               causes could be 1 at the same time, representing only last
+               reset cause.
+
+               The files are read only.
index 8bb43b66eb55a1f8c0cbac1917301b2e96a55bbc..4e7babb3ba1fecc673018253d4adbb860e0cb8a4 100644 (file)
@@ -15,3 +15,13 @@ Description:
                 blkback. If the frontend tries to use more than
                 max_persistent_grants, the LRU kicks in and starts
                 removing 5% of max_persistent_grants every 100ms.
+
+What:           /sys/module/xen_blkback/parameters/persistent_grant_unused_seconds
+Date:           August 2018
+KernelVersion:  4.19
+Contact:        Roger Pau Monné <roger.pau@citrix.com>
+Description:
+                How long a persistent grant is allowed to remain
+                allocated without being in use. The time is in
+                seconds, 0 means indefinitely long.
+                The default is 60 seconds.
index 9b0123388f182dfe5829205a73bdf5a63bd32e10..94a24aedcdb237cfe07fb9f4fe0c33e953a49bd5 100644 (file)
@@ -51,6 +51,14 @@ Description:
                 Controls the dirty page count condition for the in-place-update
                 policies.
 
+What:          /sys/fs/f2fs/<disk>/min_seq_blocks
+Date:          August 2018
+Contact:       "Jaegeuk Kim" <jaegeuk@kernel.org>
+Description:
+                Controls the dirty page count condition for batched sequential
+                writes in ->writepages.
+
+
 What:          /sys/fs/f2fs/<disk>/min_hot_blocks
 Date:          March 2017
 Contact:       "Jaegeuk Kim" <jaegeuk@kernel.org>
index 1746131bc9cb315dca4d4b03b23678cece518727..184193bcb262ac908f1f5a7a7c2c662dec0ea4b8 100644 (file)
@@ -1072,6 +1072,24 @@ PAGE_SIZE multiple when read back.
        high limit is used and monitored properly, this limit's
        utility is limited to providing the final safety net.
 
+  memory.oom.group
+       A read-write single value file which exists on non-root
+       cgroups.  The default value is "0".
+
+       Determines whether the cgroup should be treated as
+       an indivisible workload by the OOM killer. If set,
+       all tasks belonging to the cgroup or to its descendants
+       (if the memory cgroup is not a leaf cgroup) are killed
+       together or not at all. This can be used to avoid
+       partial kills to guarantee workload integrity.
+
+       Tasks with the OOM protection (oom_score_adj set to -1000)
+       are treated as an exception and are never killed.
+
+       If the OOM killer is invoked in a cgroup, it's not going
+       to kill any tasks outside of this cgroup, regardless
+       memory.oom.group values of ancestor cgroups.
+
   memory.events
        A read-only flat-keyed file which exists on non-root cgroups.
        The following entries are defined.  Unless specified
index bffb0caa369305e221108ae7557605acf7809b89..64a3bf54b97492e3b2b25508a7785d1f1e9e4186 100644 (file)
                merge
                nomerge
                soft
-               pt              [x86, IA-64]
+               pt              [x86]
+               nopt            [x86]
                nobypass        [PPC/POWERNV]
                        Disable IOMMU bypass, using IOMMU for PCI devices.
 
                        on: enable the feature
 
        page_poison=    [KNL] Boot-time parameter changing the state of
-                       poisoning on the buddy allocator.
-                       off: turn off poisoning
+                       poisoning on the buddy allocator, available with
+                       CONFIG_PAGE_POISONING=y.
+                       off: turn off poisoning (default)
                        on: turn on poisoning
 
        panic=          [KNL] Kernel behaviour on panic: delay <timeout>
        ramdisk_size=   [RAM] Sizes of RAM disks in kilobytes
                        See Documentation/blockdev/ramdisk.txt.
 
+       random.trust_cpu={on,off}
+                       [KNL] Enable or disable trusting the use of the
+                       CPU's random number generator (if available) to
+                       fully seed the kernel's CRNG. Default is controlled
+                       by CONFIG_RANDOM_TRUST_CPU.
+
        ras=option[,option,...] [KNL] RAS-specific options
 
                cec_disable     [X86]
index f128f736b4a5025f6c1964253b05472d6c76dc8b..7169a0ec41d86911ad4a9c7fc34488841dc7c1e6 100644 (file)
@@ -200,7 +200,7 @@ prctl(PR_SVE_SET_VL, unsigned long arg)
       thread.
 
     * Changing the vector length causes all of P0..P15, FFR and all bits of
-      Z0..V31 except for Z0 bits [127:0] .. Z31 bits [127:0] to become
+      Z0..Z31 except for Z0 bits [127:0] .. Z31 bits [127:0] to become
       unspecified.  Calling PR_SVE_SET_VL with vl equal to the thread's current
       vector length, or calling PR_SVE_SET_VL with the PR_SVE_SET_VL_ONEXEC
       flag, does not constitute a change to the vector length for this purpose.
@@ -500,7 +500,7 @@ References
 [2] arch/arm64/include/uapi/asm/ptrace.h
     AArch64 Linux ptrace ABI definitions
 
-[3] linux/Documentation/arm64/cpu-feature-registers.txt
+[3] Documentation/arm64/cpu-feature-registers.txt
 
 [4] ARM IHI0055C
     http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055c/IHI0055C_beta_aapcs64.pdf
index b5379fb740a58d1024b35c7d21b7d06f5cb8b98e..26b735cefb932fe5ec4bb861f48bf9339c59cd08 100644 (file)
@@ -27,6 +27,7 @@ Core utilities
    errseq
    printk-formats
    circular-buffers
+   mm-api
    gfp_mask-from-fs-io
    timekeeping
    boot-time-mm
index 76fe2d0f5e7d7db307bfa4ead890ead2d8840bdd..3431337ee4e62909fa03722de7d346c4d2a79c9f 100644 (file)
@@ -39,6 +39,10 @@ String Manipulation
 .. kernel-doc:: lib/string.c
    :export:
 
+.. kernel-doc:: mm/util.c
+   :functions: kstrdup kstrdup_const kstrndup kmemdup kmemdup_nul memdup_user
+               vmemdup_user strndup_user memdup_user_nul
+
 Basic Kernel Library Functions
 ==============================
 
@@ -155,60 +159,6 @@ UUID/GUID
 .. kernel-doc:: lib/uuid.c
    :export:
 
-Memory Management in Linux
-==========================
-
-The Slab Cache
---------------
-
-.. kernel-doc:: include/linux/slab.h
-   :internal:
-
-.. kernel-doc:: mm/slab.c
-   :export:
-
-.. kernel-doc:: mm/util.c
-   :export:
-
-User Space Memory Access
-------------------------
-
-.. kernel-doc:: arch/x86/include/asm/uaccess.h
-   :internal:
-
-.. kernel-doc:: arch/x86/lib/usercopy_32.c
-   :export:
-
-More Memory Management Functions
---------------------------------
-
-.. kernel-doc:: mm/readahead.c
-   :export:
-
-.. kernel-doc:: mm/filemap.c
-   :export:
-
-.. kernel-doc:: mm/memory.c
-   :export:
-
-.. kernel-doc:: mm/vmalloc.c
-   :export:
-
-.. kernel-doc:: mm/page_alloc.c
-   :internal:
-
-.. kernel-doc:: mm/mempool.c
-   :export:
-
-.. kernel-doc:: mm/dmapool.c
-   :export:
-
-.. kernel-doc:: mm/page-writeback.c
-   :export:
-
-.. kernel-doc:: mm/truncate.c
-   :export:
-
 Kernel IPC facilities
 =====================
 
@@ -437,4 +387,3 @@ Read-Copy Update (RCU)
 .. kernel-doc:: include/linux/rcu_sync.h
 
 .. kernel-doc:: kernel/rcu/sync.c
-
diff --git a/Documentation/core-api/mm-api.rst b/Documentation/core-api/mm-api.rst
new file mode 100644 (file)
index 0000000..46ae353
--- /dev/null
@@ -0,0 +1,78 @@
+======================
+Memory Management APIs
+======================
+
+User Space Memory Access
+========================
+
+.. kernel-doc:: arch/x86/include/asm/uaccess.h
+   :internal:
+
+.. kernel-doc:: arch/x86/lib/usercopy_32.c
+   :export:
+
+.. kernel-doc:: mm/util.c
+   :functions: get_user_pages_fast
+
+Memory Allocation Controls
+==========================
+
+Functions which need to allocate memory often use GFP flags to express
+how that memory should be allocated. The GFP acronym stands for "get
+free pages", the underlying memory allocation function. Not every GFP
+flag is allowed to every function which may allocate memory. Most
+users will want to use a plain ``GFP_KERNEL``.
+
+.. kernel-doc:: include/linux/gfp.h
+   :doc: Page mobility and placement hints
+
+.. kernel-doc:: include/linux/gfp.h
+   :doc: Watermark modifiers
+
+.. kernel-doc:: include/linux/gfp.h
+   :doc: Reclaim modifiers
+
+.. kernel-doc:: include/linux/gfp.h
+   :doc: Common combinations
+
+The Slab Cache
+==============
+
+.. kernel-doc:: include/linux/slab.h
+   :internal:
+
+.. kernel-doc:: mm/slab.c
+   :export:
+
+.. kernel-doc:: mm/util.c
+   :functions: kfree_const kvmalloc_node kvfree
+
+More Memory Management Functions
+================================
+
+.. kernel-doc:: mm/readahead.c
+   :export:
+
+.. kernel-doc:: mm/filemap.c
+   :export:
+
+.. kernel-doc:: mm/memory.c
+   :export:
+
+.. kernel-doc:: mm/vmalloc.c
+   :export:
+
+.. kernel-doc:: mm/page_alloc.c
+   :internal:
+
+.. kernel-doc:: mm/mempool.c
+   :export:
+
+.. kernel-doc:: mm/dmapool.c
+   :export:
+
+.. kernel-doc:: mm/page-writeback.c
+   :export:
+
+.. kernel-doc:: mm/truncate.c
+   :export:
diff --git a/Documentation/devicetree/bindings/arm/adapteva.txt b/Documentation/devicetree/bindings/arm/adapteva.txt
deleted file mode 100644 (file)
index 1d8af9e..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-Adapteva Platforms Device Tree Bindings
----------------------------------------
-
-Parallella board
-
-Required root node properties:
-    - compatible = "adapteva,parallella";
index 69880560c0f0219aa0a875396d0587b4274c97fc..b5c2b5c35766f8db4fb8a3dd66d9cf9b4a395209 100644 (file)
@@ -41,6 +41,14 @@ Boards with the Amlogic Meson GXL S905D SoC shall have the following properties:
   Required root node property:
     compatible: "amlogic,s905d", "amlogic,meson-gxl";
 
+Boards with the Amlogic Meson GXL S805X SoC shall have the following properties:
+  Required root node property:
+    compatible: "amlogic,s805x", "amlogic,meson-gxl";
+
+Boards with the Amlogic Meson GXL S905W SoC shall have the following properties:
+  Required root node property:
+    compatible: "amlogic,s905w", "amlogic,meson-gxl";
+
 Boards with the Amlogic Meson GXM S912 SoC shall have the following properties:
   Required root node property:
     compatible: "amlogic,s912", "amlogic,meson-gxm";
@@ -79,6 +87,11 @@ Board compatible values (alphabetically, grouped by SoC):
   - "amlogic,p230" (Meson gxl s905d)
   - "amlogic,p231" (Meson gxl s905d)
 
+  - "amlogic,p241" (Meson gxl s805x)
+
+  - "amlogic,p281" (Meson gxl s905w)
+  - "oranth,tx3-mini" (Meson gxl s905w)
+
   - "amlogic,q200" (Meson gxm s912)
   - "amlogic,q201" (Meson gxm s912)
   - "khadas,vim2" (Meson gxm s912)
diff --git a/Documentation/devicetree/bindings/arm/atmel-pmc.txt b/Documentation/devicetree/bindings/arm/atmel-pmc.txt
deleted file mode 100644 (file)
index 795cc78..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-* Power Management Controller (PMC)
-
-Required properties:
-- compatible: Should be "atmel,<chip>-pmc".
-       <chip> can be: at91rm9200, at91sam9260, at91sam9g45, at91sam9n12,
-       at91sam9x5, sama5d3
-
-- reg: Should contain PMC registers location and length
-
-Examples:
-       pmc: pmc@fffffc00 {
-               compatible = "atmel,at91rm9200-pmc";
-               reg = <0xfffffc00 0x100>;
-       };
index c052caad36e806907988fa20e8250f2dce7d90d6..104cc9b41df46bebb2d8db5cdd4fb7843a677f9c 100644 (file)
@@ -189,7 +189,11 @@ Power-Down (SRPD), among other things.
 
 Required properties:
 - compatible     : should contain one of these
+       "brcm,brcmstb-memc-ddr-rev-b.2.1"
        "brcm,brcmstb-memc-ddr-rev-b.2.2"
+       "brcm,brcmstb-memc-ddr-rev-b.2.3"
+       "brcm,brcmstb-memc-ddr-rev-b.3.0"
+       "brcm,brcmstb-memc-ddr-rev-b.3.1"
        "brcm,brcmstb-memc-ddr"
 - reg            : the MEMC DDR register range
 
index 7809fbe0cdb7d65e71640e605068eba9f151234f..9b5685a1d15d9821efb9dd6d34a29ae1f788e31f 100644 (file)
@@ -94,7 +94,7 @@ cpus {
        };
 
        idle-states {
-               entry-method = "arm,psci";
+               entry-method = "psci";
 
                CPU_SLEEP_0: cpu-sleep-0 {
                        compatible = "arm,idle-state";
index 29e1dc5d506dc4ce692abcaceb5eb691dc33f507..96dfccc0faa8d9471d52900150b6dea9ad96ff62 100644 (file)
@@ -183,6 +183,7 @@ described below.
                            "marvell,sheeva-v5"
                            "nvidia,tegra132-denver"
                            "nvidia,tegra186-denver"
+                           "nvidia,tegra194-carmel"
                            "qcom,krait"
                            "qcom,kryo"
                            "qcom,kryo385"
@@ -219,6 +220,7 @@ described below.
                            "qcom,kpss-acc-v1"
                            "qcom,kpss-acc-v2"
                            "renesas,apmu"
+                           "renesas,r9a06g032-smp"
                            "rockchip,rk3036-smp"
                            "rockchip,rk3066-smp"
                            "ste,dbx500-smp"
diff --git a/Documentation/devicetree/bindings/arm/freescale/m4if.txt b/Documentation/devicetree/bindings/arm/freescale/m4if.txt
new file mode 100644 (file)
index 0000000..93bd7b8
--- /dev/null
@@ -0,0 +1,12 @@
+* Freescale Multi Master Multi Memory Interface (M4IF) module
+
+Required properties:
+- compatible : Should be "fsl,imx51-m4if"
+- reg : Address and length of the register set for the device
+
+Example:
+
+m4if: m4if@83fd8000 {
+       compatible = "fsl,imx51-m4if";
+       reg = <0x83fd8000 0x1000>;
+};
diff --git a/Documentation/devicetree/bindings/arm/freescale/tigerp.txt b/Documentation/devicetree/bindings/arm/freescale/tigerp.txt
new file mode 100644 (file)
index 0000000..19e2aad
--- /dev/null
@@ -0,0 +1,12 @@
+* Freescale Tigerp platform module
+
+Required properties:
+- compatible : Should be "fsl,imx51-tigerp"
+- reg : Address and length of the register set for the device
+
+Example:
+
+tigerp: tigerp@83fa0000 {
+       compatible = "fsl,imx51-tigerp";
+       reg = <0x83fa0000 0x28>;
+};
index cdb9dd705754a82928ffb90b7d67faf493104a24..8a1baa2b9723aa4014701260ab2597f2b8215281 100644 (file)
@@ -53,6 +53,10 @@ i.MX6 Quad SABRE Automotive Board
 Required root node properties:
     - compatible = "fsl,imx6q-sabreauto", "fsl,imx6q";
 
+i.MX6SLL EVK board
+Required root node properties:
+    - compatible = "fsl,imx6sll-evk", "fsl,imx6sll";
+
 Generic i.MX boards
 -------------------
 
index 7a591333f2b199d8b9faf92f606bdf0d13060495..2c73847499abc8d73cfdd64c987d6896f804b5c7 100644 (file)
@@ -237,8 +237,8 @@ processor idle states, defined as device tree nodes, are listed.
                Value type: <stringlist>
                Usage and definition depend on ARM architecture version.
                        # On ARM v8 64-bit this property is required and must
-                         be one of:
-                          - "psci" (see bindings in [2])
+                         be:
+                          - "psci"
                        # On ARM 32-bit systems this property is optional
 
 The nodes describing the idle states (state) can only be defined within the
diff --git a/Documentation/devicetree/bindings/arm/insignal-boards.txt b/Documentation/devicetree/bindings/arm/insignal-boards.txt
deleted file mode 100644 (file)
index 524c3dc..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-* Insignal's Exynos4210 based Origen evaluation board
-
-Origen low-cost evaluation board is based on Samsung's Exynos4210 SoC.
-
-Required root node properties:
-    - compatible = should be one or more of the following.
-        (a) "samsung,smdkv310" - for Samsung's SMDKV310 eval board.
-        (b) "samsung,exynos4210"  - for boards based on Exynos4210 SoC.
index 48fac4ec91fc08fa21c5decaef92c045d885e3d3..8f260e5cfd1695dcce638fc7333eeca0a58d7035 100644 (file)
@@ -51,6 +51,9 @@ Supported boards:
 - Evaluation board for MT6797(Helio X20):
     Required root node properties:
       - compatible = "mediatek,mt6797-evb", "mediatek,mt6797";
+- Mediatek X20 Development Board:
+    Required root node properties:
+      - compatible = "archermind,mt6797-x20-dev", "mediatek,mt6797";
 - Reference board variant 1 for MT7622:
     Required root node properties:
       - compatible = "mediatek,mt7622-rfb1", "mediatek,mt7622";
@@ -63,9 +66,6 @@ Supported boards:
 - Reference board for MT7623n with eMMC:
     Required root node properties:
       - compatible = "mediatek,mt7623n-rfb-emmc", "mediatek,mt7623";
-- Reference  board for MT7623n with NAND:
-    Required root node properties:
-      - compatible = "mediatek,mt7623n-rfb-nand", "mediatek,mt7623";
 - Bananapi BPI-R2 board:
       - compatible = "bananapi,bpi-r2", "mediatek,mt7623";
 - MTK mt8127 tablet moose EVB:
index b4f8a16e7e3b35a746894fc12633893b7741da3c..6816adcdc15f5d83cada70c26293e5fd71fb4a6a 100644 (file)
@@ -7,6 +7,7 @@ Required properties:
               Should be "ti,omap2-l4-wkup" for OMAP2 family l4 wkup bus
               Should be "ti,omap3-l4-core" for OMAP3 family l4 core bus
               Should be "ti,omap4-l4-cfg" for OMAP4 family l4 cfg bus
+              Should be "ti,omap4-l4-per" for OMAP4 family l4 per bus
               Should be "ti,omap4-l4-wkup" for OMAP4 family l4 wkup bus
               Should be "ti,omap5-l4-cfg" for OMAP5 family l4 cfg bus
               Should be "ti,omap5-l4-wkup" for OMAP5 family l4 wkup bus
@@ -15,11 +16,21 @@ Required properties:
               Should be "ti,am3-l4-wkup" for AM33xx family l4 wkup bus
               Should be "ti,am4-l4-wkup" for AM43xx family l4 wkup bus
 - ranges : contains the IO map range for the bus
+- reg : registers link agent and interconnect agent and access protection
+- reg-names : "la" for link agent, "ia0" to "ia3" for one to three
+              interconnect agent instances, "ap" for access if it exists
 
 Examples:
 
-l4: l4@48000000 {
-       compatible "ti,omap2-l4", "simple-bus";
+l4: interconnect@48000000 {
+       compatible "ti,omap4-l4-per", "simple-bus";
+       reg = <0x48000000 0x800>,
+             <0x48000800 0x800>,
+             <0x48001000 0x400>,
+             <0x48001400 0x400>,
+             <0x48001800 0x400>,
+             <0x48001c00 0x400>;
+       reg-names = "ap", "la", "ia0", "ia1", "ia2", "ia3";
        #address-cells = <1>;
        #size-cells = <1>;
        ranges = <0 0x48000000 0x100000>;
index 1c1d62d03c4ff293100385581a6c2367570c05c3..acfd3c773dd0e40e6ec22ec7566fb433fe90c995 100644 (file)
@@ -1,5 +1,10 @@
 Rockchip platforms device tree bindings
 ---------------------------------------
+
+- 96boards RK3399 Ficus (ROCK960 Enterprise Edition)
+    Required root node properties:
+      - compatible = "vamrs,ficus", "rockchip,rk3399";
+
 - Amarula Vyasa RK3288 board
     Required root node properties:
       - compatible = "amarula,vyasa-rk3288", "rockchip,rk3288";
@@ -66,6 +71,15 @@ Rockchip platforms device tree bindings
     Required root node properties:
       - compatible = "geekbuying,geekbox", "rockchip,rk3368";
 
+- Google Bob (Asus Chromebook Flip C101PA):
+    Required root node properties:
+       compatible = "google,bob-rev13", "google,bob-rev12",
+                    "google,bob-rev11", "google,bob-rev10",
+                    "google,bob-rev9", "google,bob-rev8",
+                    "google,bob-rev7", "google,bob-rev6",
+                    "google,bob-rev5", "google,bob-rev4",
+                    "google,bob", "google,gru", "rockchip,rk3399";
+
 - Google Brain (dev-board):
     Required root node properties:
       - compatible = "google,veyron-brain-rev0", "google,veyron-brain",
index 6970f30a3770f8027a2509aab25f4fe75785667e..56021bf2a916a881388b573c40a13df0c65d4cf0 100644 (file)
@@ -1,7 +1,10 @@
-* Samsung's Exynos SoC based boards
+* Samsung's Exynos and S5P SoC based boards
 
 Required root node properties:
     - compatible = should be one or more of the following.
+       - "samsung,aries"       - for S5PV210-based Samsung Aries board.
+       - "samsung,fascinate4g" - for S5PV210-based Samsung Galaxy S Fascinate 4G (SGH-T959P) board.
+       - "samsung,galaxys"     - for S5PV210-based Samsung Galaxy S (i9000)  board.
        - "samsung,artik5"      - for Exynos3250-based Samsung ARTIK5 module.
        - "samsung,artik5-eval" - for Exynos3250-based Samsung ARTIK5 eval board.
        - "samsung,monk"        - for Exynos3250-based Samsung Simband board.
index d8cf740132c6d869eaaeaed6fb430b294c3ab9e3..89b4a389fbc7cb3e886a7ecab2ac240adb3592f7 100644 (file)
@@ -51,7 +51,8 @@ SoCs:
     compatible = "renesas,r8a77990"
   - R-Car D3 (R8A77995)
     compatible = "renesas,r8a77995"
-
+  - RZ/N1D (R9A06G032)
+    compatible = "renesas,r9a06g032"
 
 Boards:
 
@@ -112,6 +113,8 @@ Boards:
     compatible = "renesas,porter", "renesas,r8a7791"
   - RSKRZA1 (YR0K77210C000BE)
     compatible = "renesas,rskrza1", "renesas,r7s72100"
+  - RZN1D-DB (RZ/N1D Demo Board for the RZ/N1D 400 pins package)
+    compatible = "renesas,rzn1d400-db", "renesas,r9a06g032"
   - Salvator-X (RTP0RC7795SIPB0010S)
     compatible = "renesas,salvator-x", "renesas,r8a7795"
   - Salvator-X (RTP0RC7796SIPB0011S)
diff --git a/Documentation/devicetree/bindings/arm/ti/k3.txt b/Documentation/devicetree/bindings/arm/ti/k3.txt
new file mode 100644 (file)
index 0000000..6a059ca
--- /dev/null
@@ -0,0 +1,23 @@
+Texas Instruments K3 Multicore SoC architecture device tree bindings
+--------------------------------------------------------------------
+
+Platforms based on Texas Instruments K3 Multicore SoC architecture
+shall follow the following scheme:
+
+SoCs
+----
+
+Each device tree root node must specify which exact SoC in K3 Multicore SoC
+architecture it uses, using one of the following compatible values:
+
+- AM654
+  compatible = "ti,am654";
+
+Boards
+------
+
+In addition, each device tree root node must specify which one or more
+of the following board-specific compatible values:
+
+- AM654 EVM
+  compatible = "ti,am654-evm", "ti,am654";
index b9043bc35c145c677bff60316e049f95333d05e2..26fe5ecc4332631953cab9151708848e69eba6c6 100644 (file)
@@ -8,18 +8,38 @@ Required root node properties:
 
 Additional compatible strings:
 
-- Xilinx internal board cc108
+- Adapteva Parallella board
+  "adapteva,parallella"
+
+- Avnet MicroZed board
+  "avnet,zynq-microzed"
+  "xlnx,zynq-microzed"
+
+- Avnet ZedBoard board
+  "avnet,zynq-zed"
+  "xlnx,zynq-zed"
+
+- Digilent Zybo board
+  "digilent,zynq-zybo"
+
+- Digilent Zybo Z7 board
+  "digilent,zynq-zybo-z7"
+
+- Xilinx CC108 internal board
   "xlnx,zynq-cc108"
 
-- Xilinx internal board zc770 with different FMC cards
+- Xilinx ZC702 internal board
+  "xlnx,zynq-zc702"
+
+- Xilinx ZC706 internal board
+  "xlnx,zynq-zc706"
+
+- Xilinx ZC770 internal board, with different FMC cards
   "xlnx,zynq-zc770-xm010"
   "xlnx,zynq-zc770-xm011"
   "xlnx,zynq-zc770-xm012"
   "xlnx,zynq-zc770-xm013"
 
-- Digilent Zybo Z7 board
-  "digilent,zynq-zybo-z7"
-
 ---------------------------------------------------------------
 
 Xilinx Zynq UltraScale+ MPSoC Platforms Device Tree Bindings
index c760ecb8138136085eead51ab07c38074d989c4a..5d5bd456d9d96303e9cbabf4fed97e8cef6b3277 100644 (file)
@@ -17,7 +17,6 @@ Required properties:
   - "marvell,armada-380-ahci"
   - "marvell,armada-3700-ahci"
   - "snps,dwc-ahci"
-  - "snps,exynos5440-ahci"
   - "snps,spear-ahci"
   - "generic-ahci"
 - interrupts        : <interrupt mapping for SATA IRQ>
@@ -30,6 +29,7 @@ compatible:
 Optional properties:
 - dma-coherent      : Present if dma operations are coherent
 - clocks            : a list of phandle + clock specifier pairs
+- resets            : a list of phandle + reset specifier pairs
 - target-supply     : regulator for SATA target power
 - phys              : reference to the SATA PHY node
 - phy-names         : must be "sata-phy"
index e20eac7a30874f0db82adefa0cdf3a77ac09aec2..4268e17d24116cec8e26806823ebd5ca458cc925 100644 (file)
@@ -8,6 +8,7 @@ Required properties:
                          - "renesas,sata-r8a7791" for R-Car M2-W
                          - "renesas,sata-r8a7793" for R-Car M2-N
                          - "renesas,sata-r8a7795" for R-Car H3
+                         - "renesas,sata-r8a77965" for R-Car M3-N
                          - "renesas,rcar-gen2-sata" for a generic R-Car Gen2 compatible device
                          - "renesas,rcar-gen3-sata" for a generic R-Car Gen3 compatible device
                          - "renesas,rcar-sata" is deprecated
diff --git a/Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt b/Documentation/devicetree/bindings/bus/sun50i-de2-bus.txt
new file mode 100644 (file)
index 0000000..87dfb33
--- /dev/null
@@ -0,0 +1,37 @@
+Device tree bindings for Allwinner A64 DE2 bus
+
+The Allwinner A64 DE2 is on a special bus, which needs a SRAM region (SRAM C)
+to be claimed for enabling the access.
+
+Required properties:
+
+ - compatible:         Should contain "allwinner,sun50i-a64-de2"
+ - reg:                        A resource specifier for the register space
+ - #address-cells:     Must be set to 1
+ - #size-cells:                Must be set to 1
+ - ranges:             Must be set up to map the address space inside the
+                       DE2, for the sub-blocks of DE2.
+ - allwinner,sram:     the SRAM that needs to be claimed
+
+Example:
+
+       de2@1000000 {
+               compatible = "allwinner,sun50i-a64-de2";
+               reg = <0x1000000 0x400000>;
+               allwinner,sram = <&de2_sram 1>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0 0x1000000 0x400000>;
+
+               display_clocks: clock@0 {
+                       compatible = "allwinner,sun50i-a64-de2-clk";
+                       reg = <0x0 0x100000>;
+                       clocks = <&ccu CLK_DE>,
+                                <&ccu CLK_BUS_DE>;
+                       clock-names = "mod",
+                                     "bus";
+                       resets = <&ccu RST_BUS_DE>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+               };
+       };
index d8ed5b780ed9d31dec1ee7b59aa6758abde4b41d..91dc2333af012771e915981ed5df8bb8800d8d5b 100644 (file)
@@ -36,6 +36,7 @@ Required standard properties:
                "ti,sysc-omap-aes"
                "ti,sysc-mcasp"
                "ti,sysc-usb-host-fs"
+               "ti,sysc-dra7-mcan"
 
 - reg          shall have register areas implemented for the interconnect
                target module in question such as revision, sysc and syss
index 09968ee224d88c8f92e9602d6d23372b26bffd67..8f8f95056f3d4d456fd62726055052a1e60277d5 100644 (file)
@@ -17,14 +17,13 @@ Required properties:
        "atmel,at91sam9x5-clk-slow-rc-osc":
                at91 internal slow RC oscillator
 
-       "atmel,at91rm9200-pmc" or
-       "atmel,at91sam9g45-pmc" or
-       "atmel,at91sam9n12-pmc" or
-       "atmel,at91sam9x5-pmc" or
-       "atmel,sama5d3-pmc":
+       "atmel,<chip>-pmc":
                at91 PMC (Power Management Controller)
                All at91 specific clocks (clocks defined below) must be child
                node of the PMC node.
+               <chip> can be: at91rm9200, at91sam9260, at91sam9261,
+               at91sam9263, at91sam9g45, at91sam9n12, at91sam9rl, at91sam9x5,
+               sama5d2, sama5d3 or sama5d4.
 
        "atmel,at91sam9x5-clk-slow" (under sckc node)
        or
diff --git a/Documentation/devicetree/bindings/clock/exynos5440-clock.txt b/Documentation/devicetree/bindings/clock/exynos5440-clock.txt
deleted file mode 100644 (file)
index c7d227c..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-* Samsung Exynos5440 Clock Controller
-
-The Exynos5440 clock controller generates and supplies clock to various
-controllers within the Exynos5440 SoC.
-
-Required Properties:
-
-- compatible: should be "samsung,exynos5440-clock".
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-Each clock is assigned an identifier and client nodes 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.
-
-       clock: clock-controller@10010000 {
-               compatible = "samsung,exynos5440-clock";
-               reg = <0x160000 0x10000>;
-               #clock-cells = <1>;
-       };
diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-exynos5440.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-exynos5440.txt
deleted file mode 100644 (file)
index caff1a5..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-
-Exynos5440 cpufreq driver
--------------------
-
-Exynos5440 SoC cpufreq driver for CPU frequency scaling.
-
-Required properties:
-- interrupts: Interrupt to know the completion of cpu frequency change.
-- operating-points: Table of frequencies and voltage CPU could be transitioned into,
-       in the decreasing order. Frequency should be in KHz units and voltage
-       should be in microvolts.
-
-Optional properties:
-- clock-latency: Clock monitor latency in microsecond.
-
-All the required listed above must be defined under node cpufreq.
-
-Example:
---------
-       cpufreq@160000 {
-               compatible = "samsung,exynos5440-cpufreq";
-               reg = <0x160000 0x1000>;
-               interrupts = <0 57 0>;
-               operating-points = <
-                               1000000 975000
-                               800000  925000>;
-               clock-latency = <100000>;
-       };
index f79641bd5f18e013a69ff939aa81a3f8cb02de5f..45ffd6c417487692df9ff8507e2fd62ced32846b 100644 (file)
@@ -10,6 +10,9 @@ Required properties:
  - interrupts : framebuffer controller interrupt.
  - clocks: phandle to input clocks
 
+Optional properties:
+ - lcd-supply: A phandle to a power regulator that controls the LCD voltage.
+
 Required nodes:
  - port: connection to the LCD panel (see video-interfaces.txt)
         This node must have its properties bus-width and remote-endpoint set.
diff --git a/Documentation/devicetree/bindings/display/marvell,pxa300-gcu.txt b/Documentation/devicetree/bindings/display/marvell,pxa300-gcu.txt
new file mode 100644 (file)
index 0000000..9cfae5c
--- /dev/null
@@ -0,0 +1,17 @@
+PXA3xx GCU Controller
+---------------------
+
+Required properties:
+ - compatible : "marvell,pxa300-gcu"
+ - reg : should contain the register range (address and length).
+ - interrupts : Controller interrupt.
+ - clocks: phandle to the PXA specific input clock.
+
+Example for PXA300:
+
+       display-controller@54000000 {
+               compatible = "marvell,pxa300-gcu";
+               reg = <0x54000000 0x1000>;
+               interrupts = <39>;
+               clocks = <&clks CLK_PXA300_GCU>;
+       };
index 61d833abafbff92bf0ad4b5daff3c25b54e7b670..aededdbc262b241304a0651be8d418c061f89e05 100644 (file)
@@ -72,6 +72,8 @@ Optional properties:
 
   - wp-gpios: GPIO to which the write-protect pin of the chip is connected.
 
+  - address-width: number of address bits (one of 8, 16).
+
 Example:
 
 eeprom@52 {
diff --git a/Documentation/devicetree/bindings/i2c/i2c-fsi.txt b/Documentation/devicetree/bindings/i2c/i2c-fsi.txt
new file mode 100644 (file)
index 0000000..b1be2ce
--- /dev/null
@@ -0,0 +1,40 @@
+Device-tree bindings for FSI-attached I2C master and busses
+-----------------------------------------------------------
+
+Required properties:
+ - compatible = "ibm,i2c-fsi";
+ - reg = < address size >;             : The FSI CFAM address and address
+                                         space size.
+ - #address-cells = <1>;               : Number of address cells in child
+                                         nodes.
+ - #size-cells = <0>;                  : Number of size cells in child nodes.
+ - child nodes                         : Nodes to describe busses off the I2C
+                                         master.
+
+Child node required properties:
+ - reg = < port number >               : The port number on the I2C master.
+
+Child node optional properties:
+ - child nodes                         : Nodes to describe devices on the I2C
+                                         bus.
+
+Examples:
+
+    i2c@1800 {
+        compatible = "ibm,i2c-fsi";
+        reg = < 0x1800 0x400 >;
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        i2c-bus@0 {
+            reg = <0>;
+        };
+
+        i2c-bus@1 {
+            reg = <1>;
+
+            eeprom@50 {
+                compatible = "vendor,dev-name";
+            };
+        };
+    };
index 00e4365d720685679824b8d6659fd59a58845ec2..091c8dfd322910e14712d4a818e9879538abf3d9 100644 (file)
@@ -3,7 +3,6 @@
 Required properties:
 - compatible :
   - "fsl,imx7ulp-lpi2c" for LPI2C compatible with the one integrated on i.MX7ULP soc
-  - "fsl,imx8dv-lpi2c" for LPI2C compatible with the one integrated on i.MX8DV soc
 - reg : address and length of the lpi2c master registers
 - interrupts : lpi2c interrupt
 - clocks : lpi2c clock specifier
@@ -11,7 +10,7 @@ Required properties:
 Examples:
 
 lpi2c7: lpi2c7@40a50000 {
-       compatible = "fsl,imx8dv-lpi2c";
+       compatible = "fsl,imx7ulp-lpi2c";
        reg = <0x40A50000 0x10000>;
        interrupt-parent = <&intc>;
        interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/Documentation/devicetree/bindings/i2c/i2c-owl.txt b/Documentation/devicetree/bindings/i2c/i2c-owl.txt
new file mode 100644 (file)
index 0000000..b743fe4
--- /dev/null
@@ -0,0 +1,27 @@
+Actions Semiconductor Owl I2C controller
+
+Required properties:
+
+- compatible        : Should be "actions,s900-i2c".
+- reg               : Offset and length of the register set for the device.
+- #address-cells    : Should be 1.
+- #size-cells       : Should be 0.
+- interrupts        : A single interrupt specifier.
+- clocks            : Phandle of the clock feeding the I2C controller.
+
+Optional properties:
+
+- clock-frequency   : Desired I2C bus clock frequency in Hz. As only Normal and
+                      Fast modes are supported, possible values are 100000 and
+                      400000.
+Examples:
+
+        i2c0: i2c@e0170000 {
+                compatible = "actions,s900-i2c";
+                reg = <0 0xe0170000 0 0x1000>;
+                #address-cells = <1>;
+                #size-cells = <0>;
+                interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+                clocks = <&clock CLK_I2C0>;
+                clock-frequency = <100000>;
+        };
index 7ce8fae55537046beb460436c025fb7bed2cddd2..39cd21d95810628b259f22247aebc654cb0e7fa6 100644 (file)
@@ -4,6 +4,7 @@ Required properties:
 - compatible:
        "renesas,i2c-r8a7743" if the device is a part of a R8A7743 SoC.
        "renesas,i2c-r8a7745" if the device is a part of a R8A7745 SoC.
+       "renesas,i2c-r8a774a1" if the device is a part of a R8A774A1 SoC.
        "renesas,i2c-r8a7778" if the device is a part of a R8A7778 SoC.
        "renesas,i2c-r8a7779" if the device is a part of a R8A7779 SoC.
        "renesas,i2c-r8a7790" if the device is a part of a R8A7790 SoC.
@@ -16,11 +17,13 @@ Required properties:
        "renesas,i2c-r8a77965" if the device is a part of a R8A77965 SoC.
        "renesas,i2c-r8a77970" if the device is a part of a R8A77970 SoC.
        "renesas,i2c-r8a77980" if the device is a part of a R8A77980 SoC.
+       "renesas,i2c-r8a77990" if the device is a part of a R8A77990 SoC.
        "renesas,i2c-r8a77995" if the device is a part of a R8A77995 SoC.
        "renesas,rcar-gen1-i2c" for a generic R-Car Gen1 compatible device.
        "renesas,rcar-gen2-i2c" for a generic R-Car Gen2 or RZ/G1 compatible
                                device.
-       "renesas,rcar-gen3-i2c" for a generic R-Car Gen3 compatible device.
+       "renesas,rcar-gen3-i2c" for a generic R-Car Gen3 or RZ/G2 compatible
+                               device.
        "renesas,i2c-rcar" (deprecated)
 
        When compatible with the generic version, nodes must list the
index fc7e178027467bcdfad86c7cea1e50bd6114ff56..872673adff5aae3db366d1e202b8f4a5118ce825 100644 (file)
@@ -6,6 +6,7 @@ Required properties:
                        - "renesas,iic-r8a7740" (R-Mobile A1)
                        - "renesas,iic-r8a7743" (RZ/G1M)
                        - "renesas,iic-r8a7745" (RZ/G1E)
+                       - "renesas,iic-r8a774a1" (RZ/G2M)
                        - "renesas,iic-r8a7790" (R-Car H2)
                        - "renesas,iic-r8a7791" (R-Car M2-W)
                        - "renesas,iic-r8a7792" (R-Car V2H)
@@ -17,7 +18,8 @@ Required properties:
                        - "renesas,iic-sh73a0" (SH-Mobile AG5)
                        - "renesas,rcar-gen2-iic" (generic R-Car Gen2 or RZ/G1
                                                        compatible device)
-                       - "renesas,rcar-gen3-iic" (generic R-Car Gen3 compatible device)
+                       - "renesas,rcar-gen3-iic" (generic R-Car Gen3 or RZ/G2
+                                                       compatible device)
                        - "renesas,rmobile-iic" (generic device)
 
                        When compatible with a generic R-Car version, nodes
index 697ca2f26d1b5d8b0d649709234958a2d0f3ada4..a046ed374d808d668195082afc950c5b14beff62 100644 (file)
@@ -13,6 +13,7 @@ Required properties:
     - "renesas,irqc-r8a7792" (R-Car V2H)
     - "renesas,irqc-r8a7793" (R-Car M2-N)
     - "renesas,irqc-r8a7794" (R-Car E2)
+    - "renesas,intc-ex-r8a774a1" (RZ/G2M)
     - "renesas,intc-ex-r8a7795" (R-Car H3)
     - "renesas,intc-ex-r8a7796" (R-Car M3-W)
     - "renesas,intc-ex-r8a77965" (R-Car M3-N)
index b0a8af51c388c51f544b4b4cc391563a08e82ca9..265b223cd9780158a8415e96ce7dfb16c192237a 100644 (file)
@@ -11,7 +11,7 @@ The RISC-V supervisor ISA manual specifies three interrupt sources that are
 attached to every HLIC: software interrupts, the timer interrupt, and external
 interrupts.  Software interrupts are used to send IPIs between cores.  The
 timer interrupt comes from an architecturally mandated real-time timer that is
-controller via Supervisor Binary Interface (SBI) calls and CSR reads.  External
+controlled via Supervisor Binary Interface (SBI) calls and CSR reads.  External
 interrupts connect all other device interrupts to the HLIC, which are routed
 via the platform-level interrupt controller (PLIC).
 
@@ -25,7 +25,15 @@ in the system.
 
 Required properties:
 - compatible : "riscv,cpu-intc"
-- #interrupt-cells : should be <1>
+- #interrupt-cells : should be <1>.  The interrupt sources are defined by the
+  RISC-V supervisor ISA manual, with only the following three interrupts being
+  defined for supervisor mode:
+    - Source 1 is the supervisor software interrupt, which can be sent by an SBI
+      call and is reserved for use by software.
+    - Source 5 is the supervisor timer interrupt, which can be configured by
+      SBI calls and implements a one-shot timer.
+    - Source 9 is the supervisor external interrupt, which chains to all other
+      device interrupts.
 - interrupt-controller : Identifies the node as an interrupt controller
 
 Furthermore, this interrupt-controller MUST be embedded inside the cpu
@@ -38,7 +46,7 @@ An example device tree entry for a HLIC is show below.
                ...
                cpu1-intc: interrupt-controller {
                        #interrupt-cells = <1>;
-                       compatible = "riscv,cpu-intc", "sifive,fu540-c000-cpu-intc";
+                       compatible = "sifive,fu540-c000-cpu-intc", "riscv,cpu-intc";
                        interrupt-controller;
                };
        };
index 53c20cae309f21b0e2e67303c83041ec7ba1e5c8..df5db732138d10658b5d659f25ca1ea3df28e025 100644 (file)
@@ -40,6 +40,7 @@ video decode local arbiter, all these ports are according to the video HW.
 Required properties:
 - compatible : must be one of the following string:
        "mediatek,mt2701-m4u" for mt2701 which uses generation one m4u HW.
+       "mediatek,mt2712-m4u" for mt2712 which uses generation two m4u HW.
        "mediatek,mt8173-m4u" for mt8173 which uses generation two m4u HW.
 - reg : m4u register base and size.
 - interrupts : the interrupt of m4u.
@@ -50,8 +51,9 @@ Required properties:
        according to the local arbiter index, like larb0, larb1, larb2...
 - iommu-cells : must be 1. This is the mtk_m4u_id according to the HW.
        Specifies the mtk_m4u_id as defined in
-       dt-binding/memory/mt2701-larb-port.h for mt2701 and
-       dt-binding/memory/mt8173-larb-port.h for mt8173
+       dt-binding/memory/mt2701-larb-port.h for mt2701,
+       dt-binding/memory/mt2712-larb-port.h for mt2712, and
+       dt-binding/memory/mt8173-larb-port.h for mt8173.
 
 Example:
        iommu: iommu@10205000 {
index ffadb7c6f1f3a8329503f9c9bcc34aceffdf12b7..c6e2d855fe131fc17454ff08ed5bc799848c3d10 100644 (file)
@@ -19,7 +19,10 @@ Required Properties:
     - "renesas,ipmmu-r8a7794" for the R8A7794 (R-Car E2) IPMMU.
     - "renesas,ipmmu-r8a7795" for the R8A7795 (R-Car H3) IPMMU.
     - "renesas,ipmmu-r8a7796" for the R8A7796 (R-Car M3-W) IPMMU.
+    - "renesas,ipmmu-r8a77965" for the R8A77965 (R-Car M3-N) IPMMU.
     - "renesas,ipmmu-r8a77970" for the R8A77970 (R-Car V3M) IPMMU.
+    - "renesas,ipmmu-r8a77980" for the R8A77980 (R-Car V3H) IPMMU.
+    - "renesas,ipmmu-r8a77990" for the R8A77990 (R-Car E3) IPMMU.
     - "renesas,ipmmu-r8a77995" for the R8A77995 (R-Car D3) IPMMU.
     - "renesas,ipmmu-vmsa" for generic R-Car Gen2 or RZ/G1 VMSA-compatible
                           IPMMU.
index aa614b2d7cab5dcea3a761d5d4281cc53efc71ad..615abdd0eb0de6db2a35ee61b727f71d31c5cee2 100644 (file)
@@ -2,8 +2,9 @@ SMI (Smart Multimedia Interface) Common
 
 The hardware block diagram please check bindings/iommu/mediatek,iommu.txt
 
-Mediatek SMI have two generations of HW architecture, mt8173 uses the second
-generation of SMI HW while mt2701 uses the first generation HW of SMI.
+Mediatek SMI have two generations of HW architecture, mt2712 and mt8173 use
+the second generation of SMI HW while mt2701 uses the first generation HW of
+SMI.
 
 There's slight differences between the two SMI, for generation 2, the
 register which control the iommu port is at each larb's register base. But
@@ -15,6 +16,7 @@ not needed for SMI generation 2.
 Required properties:
 - compatible : must be one of :
        "mediatek,mt2701-smi-common"
+       "mediatek,mt2712-smi-common"
        "mediatek,mt8173-smi-common"
 - reg : the register and size of the SMI block.
 - power-domains : a phandle to the power domain of this local arbiter.
index ddf46b8856a565da83744c4402ec9ae738e67b9e..083155cdc2a0e787df4510b919bf8d97ec1cce15 100644 (file)
@@ -4,8 +4,9 @@ The hardware block diagram please check bindings/iommu/mediatek,iommu.txt
 
 Required properties:
 - compatible : must be one of :
-               "mediatek,mt8173-smi-larb"
                "mediatek,mt2701-smi-larb"
+               "mediatek,mt2712-smi-larb"
+               "mediatek,mt8173-smi-larb"
 - reg : the register and size of this local arbiter.
 - mediatek,smi : a phandle to the smi_common node.
 - power-domains : a phandle to the power domain of this local arbiter.
@@ -15,7 +16,7 @@ Required properties:
            the register.
   - "smi" : It's the clock for transfer data and command.
 
-Required property for mt2701:
+Required property for mt2701 and mt2712:
 - mediatek,larb-id :the hardware id of this larb.
 
 Example:
index 132e0007d7d682062bf18a08445d89c1b2ef081a..e9cb3ec5e50295ee1e047bf26eafb45861a002c3 100644 (file)
@@ -16,6 +16,8 @@ Required properties:
    * "allwinner,sun9i-a80-mmc"
    * "allwinner,sun50i-a64-emmc"
    * "allwinner,sun50i-a64-mmc"
+   * "allwinner,sun50i-h6-emmc", "allwinner.sun50i-a64-emmc"
+   * "allwinner,sun50i-h6-mmc", "allwinner.sun50i-a64-mmc"
  - reg : mmc controller base registers
  - clocks : a list with 4 phandle + clock specifier pairs
  - clock-names : must contain "ahb", "mmc", "output" and "sample"
index 41089369f89134b3fb42c98766a46986f1806cd4..b3acebe08eb0a9d4e3d4ac315cd513e340c65f16 100644 (file)
@@ -19,6 +19,10 @@ Required properties:
 - slaves               : Specifies number for slaves
 - active_slave         : Specifies the slave to use for time stamping,
                          ethtool and SIOCGMIIPHY
+- cpsw-phy-sel         : Specifies the phandle to the CPSW phy mode selection
+                         device. See also cpsw-phy-sel.txt for it's binding.
+                         Note that in legacy cases cpsw-phy-sel may be
+                         a child device instead of a phandle.
 
 Optional properties:
 - ti,hwmods            : Must be "cpgmac0"
@@ -75,6 +79,7 @@ Examples:
                cpts_clock_mult = <0x80000000>;
                cpts_clock_shift = <29>;
                syscon = <&cm>;
+               cpsw-phy-sel = <&phy_sel>;
                cpsw_emac0: slave@0 {
                        phy_id = <&davinci_mdio>, <0>;
                        phy-mode = "rgmii-txid";
@@ -103,6 +108,7 @@ Examples:
                cpts_clock_mult = <0x80000000>;
                cpts_clock_shift = <29>;
                syscon = <&cm>;
+               cpsw-phy-sel = <&phy_sel>;
                cpsw_emac0: slave@0 {
                        phy_id = <&davinci_mdio>, <0>;
                        phy-mode = "rgmii-txid";
index cfe724398a12b68204abe29e5989547a7066b01a..5bb3a18cc38db84cb04be2c6bf081842e762a3ef 100644 (file)
@@ -19,8 +19,6 @@ Required properties:
 - reset-names: must be "stmmaceth"
 - phy-mode: See ethernet.txt
 - phy-handle: See ethernet.txt
-- #address-cells: shall be 1
-- #size-cells: shall be 0
 - syscon: A phandle to the device containing the EMAC or GMAC clock register
 
 Optional properties:
@@ -86,8 +84,6 @@ emac: ethernet@1c0b000 {
        reset-names = "stmmaceth";
        clocks = <&ccu CLK_BUS_EMAC>;
        clock-names = "stmmaceth";
-       #address-cells = <1>;
-       #size-cells = <0>;
 
        phy-handle = <&int_mii_phy>;
        phy-mode = "mii";
@@ -137,8 +133,6 @@ emac: ethernet@1c0b000 {
        reset-names = "stmmaceth";
        clocks = <&ccu CLK_BUS_EMAC>;
        clock-names = "stmmaceth";
-       #address-cells = <1>;
-       #size-cells = <0>;
 
        phy-handle = <&ext_rgmii_phy>;
        phy-mode = "rgmii";
@@ -191,8 +185,6 @@ emac: ethernet@1c0b000 {
        reset-names = "stmmaceth";
        clocks = <&ccu CLK_BUS_EMAC>;
        clock-names = "stmmaceth";
-       #address-cells = <1>;
-       #size-cells = <0>;
 
        phy-handle = <&ext_rgmii_phy>;
        phy-mode = "rgmii";
index 5b937403fed62f565793850f392b39aadbec4898..92f399ec22b87503029b8a86e40e50ef17c16434 100644 (file)
@@ -2,7 +2,7 @@
 
 Required properties:
 - compatible: Should be "nxp,pn544-i2c".
-- clock-frequency: I²C work frequency.
+- clock-frequency: I²C work frequency.
 - reg: address on the bus
 - interrupts: GPIO interrupt to which the chip is connected
 - enable-gpios: Output GPIO pin used for enabling/disabling the PN544
index 76db9f13ad96c08b77f5dae0af4ea616254ee811..abc36274227c7299bf5ec088e21ebdeed25a3950 100644 (file)
@@ -16,6 +16,7 @@ Required properties:
              "renesas,ether-r8a7794"  if the device is a part of R8A7794 SoC.
              "renesas,gether-r8a77980" if the device is a part of R8A77980 SoC.
              "renesas,ether-r7s72100" if the device is a part of R7S72100 SoC.
+             "renesas,ether-r7s9210" if the device is a part of R7S9210 SoC.
              "renesas,rcar-gen1-ether" for a generic R-Car Gen1 device.
              "renesas,rcar-gen2-ether" for a generic R-Car Gen2 or RZ/G1
                                        device.
diff --git a/Documentation/devicetree/bindings/power/reset/qcom,pon.txt b/Documentation/devicetree/bindings/power/reset/qcom,pon.txt
new file mode 100644 (file)
index 0000000..651491b
--- /dev/null
@@ -0,0 +1,45 @@
+Qualcomm PON Device
+
+The Power On device for Qualcomm PM8xxx is MFD supporting pwrkey
+and resin along with the Android reboot-mode.
+
+This DT node has pwrkey and resin as sub nodes.
+
+Required Properties:
+-compatible: "qcom,pm8916-pon"
+-reg: Specifies the physical address of the pon register
+
+Optional subnode:
+-pwrkey: Specifies the subnode pwrkey and should follow the
+ qcom,pm8941-pwrkey.txt description.
+-resin: Specifies the subnode resin and should follow the
+ qcom,pm8xxx-pwrkey.txt description.
+
+The rest of the properties should follow the generic reboot-mode description
+found in reboot-mode.txt
+
+Example:
+
+       pon@800 {
+               compatible = "qcom,pm8916-pon";
+
+               reg = <0x800>;
+               mode-bootloader = <0x2>;
+               mode-recovery = <0x1>;
+
+               pwrkey {
+                       compatible = "qcom,pm8941-pwrkey";
+                       interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>;
+                       debounce = <15625>;
+                       bias-pull-up;
+                       linux,code = <KEY_POWER>;
+               };
+
+               resin {
+                       compatible = "qcom,pm8941-resin";
+                       interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
+                       debounce = <15625>;
+                       bias-pull-up;
+                       linux,code = <KEY_VOLUMEDOWN>;
+               };
+       };
diff --git a/Documentation/devicetree/bindings/power/supply/maxim,ds2760.txt b/Documentation/devicetree/bindings/power/supply/maxim,ds2760.txt
new file mode 100644 (file)
index 0000000..55967a0
--- /dev/null
@@ -0,0 +1,26 @@
+Devicetree bindings for Maxim DS2760
+====================================
+
+The ds2760 is a w1 slave device and must hence have its sub-node in DT
+under a w1 bus master node.
+
+The device exposes a power supply, so the details described in
+Documentation/devicetree/bindings/power/supply/power_supply.txt apply.
+
+Required properties:
+- compatible: must be "maxim,ds2760"
+
+Optional properties:
+- power-supplies:      Refers to one or more power supplies connected to
+                       this battery.
+- maxim,pmod-enabled:  This boolean property enables the DS2760 to enter
+                       sleep mode when the DQ line goes low for greater
+                       than 2 seconds and leave sleep Mode when the DQ
+                       line goes high.
+- maxim,cache-time-ms: Time im milliseconds to cache the data for. When
+                       this time expires, the values are read again from
+                       the hardware. Defaults to 1000.
+- rated-capacity-microamp-hours:
+                       The rated capacity of the battery, in mAh.
+                       If not specified, the value stored in the
+                       non-volatile chip memory is used.
index c40e8926facf2d66091ec7684e059f5392b3709c..4e78e51018ebd917a265e3fa3cf71c901eb50646 100644 (file)
@@ -2,7 +2,11 @@ SBS sbs-battery
 ~~~~~~~~~~
 
 Required properties :
- - compatible : "sbs,sbs-battery"
+ - compatible: "<vendor>,<part-number>", "sbs,sbs-battery" as fallback. The
+     part number compatible string might be used in order to take care of
+     vendor specific registers.
+     Known <vendor>,<part-number>:
+       ti,bq20z75
 
 Optional properties :
  - sbs,i2c-retry-count : The number of times to retry i2c transactions on i2c
@@ -14,9 +18,9 @@ Optional properties :
 
 Example:
 
-       bq20z75@b {
-               compatible = "sbs,sbs-battery";
-               reg = < 0xb >;
+       battery@b {
+               compatible = "ti,bq20z75", "sbs,sbs-battery";
+               reg = <0xb>;
                sbs,i2c-retry-count = <2>;
                sbs,poll-retry-count = <10>;
                sbs,battery-detect-gpios = <&gpio-controller 122 1>;
index 3899d6a557c15af8482f3c0574404e437b462e5d..576ad002bc833bd1ffb1d088d9da04aff0acba98 100644 (file)
@@ -16,7 +16,10 @@ modes in device tree.
 
 
 Required properties:
-- compatible: Should be "fsl,vf610-ftm-pwm".
+- compatible : should be "fsl,<soc>-ftm-pwm" and one of the following
+   compatible strings:
+  - "fsl,vf610-ftm-pwm" for PWM compatible with the one integrated on VF610
+  - "fsl,imx8qm-ftm-pwm" for PWM compatible with the one integrated on i.MX8QM
 - 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.
index ef8bd3cb67abb6ee8e94e43541d5638fc894ad15..991728cb46cb8cf24a2793ecc1ec8a417aa2df0b 100644 (file)
@@ -5,11 +5,13 @@ Required properties:
    - "mediatek,mt2712-pwm": found on mt2712 SoC.
    - "mediatek,mt7622-pwm": found on mt7622 SoC.
    - "mediatek,mt7623-pwm": found on mt7623 SoC.
+   - "mediatek,mt7628-pwm": found on mt7628 SoC.
  - reg: physical base address and length of the controller's registers.
  - #pwm-cells: must be 2. See pwm.txt in this directory for a description of
    the cell format.
  - clocks: phandle and clock specifier of the PWM reference clock.
- - clock-names: must contain the following:
+ - clock-names: must contain the following, except for MT7628 which
+                has no clocks
    - "top": the top clock generator
    - "main": clock used by the PWM core
    - "pwm1-8": the eight per PWM clocks for mt2712
index 35a3b9761ee5892f3e4c89eac7674ff282704c00..e1ef6afbe3a74a89d9040b9d6642cd2c22aa2a0c 100644 (file)
@@ -12,6 +12,7 @@ Required Properties:
  - "renesas,pwm-r8a7795": for R-Car H3
  - "renesas,pwm-r8a7796": for R-Car M3-W
  - "renesas,pwm-r8a77965": for R-Car M3-N
+ - "renesas,pwm-r8a77990": for R-Car E3
  - "renesas,pwm-r8a77995": for R-Car D3
 - reg: base address and length of the registers block for the PWM.
 - #pwm-cells: should be 2. See pwm.txt in this directory for a description of
index 16291f2a46881b65b11486f840f6547418f0bfd2..bac4afa3b1976500d68361fcc4666a0aec646eee 100644 (file)
@@ -49,7 +49,7 @@ compatible (optional) - standard definition
     - may contain the following strings:
         - shared-dma-pool: This indicates a region of memory meant to be
           used as a shared pool of DMA buffers for a set of devices. It can
-          be used by an operating system to instanciate the necessary pool
+          be used by an operating system to instantiate the necessary pool
           management subsystem if necessary.
         - vendor specific string in the form <vendor>,[<device>-]<usage>
 no-map (optional) - empty property
diff --git a/Documentation/devicetree/bindings/reset/amlogic,meson-axg-audio-arb.txt b/Documentation/devicetree/bindings/reset/amlogic,meson-axg-audio-arb.txt
new file mode 100644 (file)
index 0000000..26e542e
--- /dev/null
@@ -0,0 +1,21 @@
+* Amlogic audio memory arbiter controller
+
+The Amlogic Audio ARB is a simple device which enables or
+disables the access of Audio FIFOs to DDR on AXG based SoC.
+
+Required properties:
+- compatible: 'amlogic,meson-axg-audio-arb'
+- reg: physical base address of the controller and length of memory
+       mapped region.
+- clocks: phandle to the fifo peripheral clock provided by the audio
+         clock controller.
+- #reset-cells: must be 1.
+
+Example on the A113 SoC:
+
+arb: reset-controller@280 {
+       compatible = "amlogic,meson-axg-audio-arb";
+       reg = <0x0 0x280 0x0 0x4>;
+       #reset-cells = <1>;
+       clocks = <&clkc_audio AUD_CLKID_DDR_ARB>;
+};
diff --git a/Documentation/devicetree/bindings/reset/qcom,aoss-reset.txt b/Documentation/devicetree/bindings/reset/qcom,aoss-reset.txt
new file mode 100644 (file)
index 0000000..510c748
--- /dev/null
@@ -0,0 +1,52 @@
+Qualcomm AOSS Reset Controller
+======================================
+
+This binding describes a reset-controller found on AOSS-CC (always on subsystem)
+for Qualcomm SDM845 SoCs.
+
+Required properties:
+- compatible:
+       Usage: required
+       Value type: <string>
+       Definition: must be:
+                   "qcom,sdm845-aoss-cc"
+
+- reg:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: must specify the base address and size of the register
+                   space.
+
+- #reset-cells:
+       Usage: required
+       Value type: <uint>
+       Definition: must be 1; cell entry represents the reset index.
+
+Example:
+
+aoss_reset: reset-controller@c2a0000 {
+       compatible = "qcom,sdm845-aoss-cc";
+       reg = <0xc2a0000 0x31000>;
+       #reset-cells = <1>;
+};
+
+Specifying reset lines connected to IP modules
+==============================================
+
+Device nodes that need access to reset lines should
+specify them as a reset phandle in their corresponding node as
+specified in reset.txt.
+
+For list of all valid reset indicies see
+<dt-bindings/reset/qcom,sdm845-aoss.h>
+
+Example:
+
+modem-pil@4080000 {
+       ...
+
+       resets = <&aoss_reset AOSS_CC_MSS_RESTART>;
+       reset-names = "mss_restart";
+
+       ...
+};
index 93efed629900c65f9c9b1d74265cb4d2c7936245..101743dda2235766b19564061a66282a35d02e0a 100644 (file)
@@ -118,3 +118,59 @@ Example:
 
                other nodes ...
        };
+
+
+USB3 core reset
+---------------
+
+USB3 core reset belongs to USB3 glue layer. Before using the core reset,
+it is necessary to control the clocks and resets to enable this layer.
+These clocks and resets should be described in each property.
+
+Required properties:
+- compatible: Should be
+    "socionext,uniphier-pro4-usb3-reset" - for Pro4 SoC
+    "socionext,uniphier-pxs2-usb3-reset" - for PXs2 SoC
+    "socionext,uniphier-ld20-usb3-reset" - for LD20 SoC
+    "socionext,uniphier-pxs3-usb3-reset" - for PXs3 SoC
+- #reset-cells: Should be 1.
+- reg: Specifies offset and length of the register set for the device.
+- clocks: A list of phandles to the clock gate for USB3 glue layer.
+       According to the clock-names, appropriate clocks are required.
+- clock-names: Should contain
+    "gio", "link" - for Pro4 SoC
+    "link"        - for others
+- resets: A list of phandles to the reset control for USB3 glue layer.
+       According to the reset-names, appropriate resets are required.
+- reset-names: Should contain
+    "gio", "link" - for Pro4 SoC
+    "link"        - for others
+
+Example:
+
+       usb-glue@65b00000 {
+               compatible = "socionext,uniphier-ld20-dwc3-glue",
+                            "simple-mfd";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0 0x65b00000 0x400>;
+
+               usb_rst: reset@0 {
+                       compatible = "socionext,uniphier-ld20-usb3-reset";
+                       reg = <0x0 0x4>;
+                       #reset-cells = <1>;
+                       clock-names = "link";
+                       clocks = <&sys_clk 14>;
+                       reset-names = "link";
+                       resets = <&sys_rst 14>;
+               };
+
+               regulator {
+                       ...
+               };
+
+               phy {
+                       ...
+               };
+               ...
+       };
diff --git a/Documentation/devicetree/bindings/rtc/isil,isl1219.txt b/Documentation/devicetree/bindings/rtc/isil,isl1219.txt
new file mode 100644 (file)
index 0000000..c3efd48
--- /dev/null
@@ -0,0 +1,29 @@
+Intersil ISL1219 I2C RTC/Alarm chip with event in
+
+ISL1219 has additional pins EVIN and #EVDET for tamper detection.
+
+Required properties supported by the device:
+
+ - "compatible": must be "isil,isl1219"
+ - "reg": I2C bus address of the device
+
+Optional properties:
+
+ - "interrupt-names": list which may contains "irq" and "evdet"
+ - "interrupts": list of interrupts for "irq" and "evdet"
+ - "isil,ev-evienb": if present EV.EVIENB bit is set to the specified
+                     value for proper operation.
+
+
+Example isl1219 node with #IRQ pin connected to SoC gpio1 pin12
+ and #EVDET pin connected to SoC gpio2 pin 24:
+
+       isl1219: rtc@68 {
+               compatible = "isil,isl1219";
+               reg = <0x68>;
+               interrupt-names = "irq", "evdet";
+               interrupts-extended = <&gpio1 12 IRQ_TYPE_EDGE_FALLING>,
+                       <&gpio2 24 IRQ_TYPE_EDGE_FALLING>;
+               isil,ev-evienb = <1>;
+       };
+
index 226cc93df87530119d46be14bc3d485f643b4f63..eebfbe04207a0e02f8e4d517f4dfb4ce0678a1e0 100644 (file)
@@ -13,6 +13,7 @@ Required properties:
        "maxim,ds3231",
        "st,m41t0",
        "st,m41t00",
+       "st,m41t11",
        "microchip,mcp7940x",
        "microchip,mcp7941x",
        "pericom,pt7c4338",
index bf80e3f96f8c6b12b011357fd2e2dba49d34d8c3..f9987c30f0d52c75eeafdbf3d3c50982ebd9b5f6 100644 (file)
@@ -19,6 +19,7 @@ IP Pairing
 Required properties in pwrap device node.
 - compatible:
        "mediatek,mt2701-pwrap" for MT2701/7623 SoCs
+       "mediatek,mt6797-pwrap" for MT6797 SoCs
        "mediatek,mt7622-pwrap" for MT7622 SoCs
        "mediatek,mt8135-pwrap" for MT8135 SoCs
        "mediatek,mt8173-pwrap" for MT8173 SoCs
index 93b982e9419fd9c6bdadd361c9266efb24f95422..feef39b4a4fdb71934961714c1c790f8f1852e32 100644 (file)
@@ -17,20 +17,18 @@ Example:
 
        /* upstream device */
 
-       ssp0: ssp@41000000 {
+       ssp1: ssp@41000000 {
                compatible = "mrvl,pxa3xx-ssp";
                reg = <0x41000000 0x40>;
                interrupts = <24>;
                clock-names = "pxa27x-ssp.0";
-               dmas = <&dma 13
-                       &dma 14>;
-               dma-names = "rx", "tx";
        };
 
        /* DAI as user */
 
        ssp_dai0: ssp_dai@0 {
                compatible = "mrvl,pxa-ssp-dai";
-               port = <&ssp0>;
+               port = <&ssp1>;
+               #sound-dai-cells = <0>;
        };
 
index d087f04a4d7f649dfdfab372d89b4cd7867c839a..c51ade86578c6508bf29c11af8653c68211d2ac3 100644 (file)
@@ -10,8 +10,14 @@ Controller Node
 
 Required properties:
 - compatible : should be:
-    - "allwinner,sun4i-a10-sram-controller"
-    - "allwinner,sun50i-a64-sram-controller"
+    - "allwinner,sun4i-a10-sram-controller" (deprecated)
+    - "allwinner,sun4i-a10-system-control"
+    - "allwinner,sun5i-a13-system-control"
+    - "allwinner,sun7i-a20-system-control", "allwinner,sun4i-a10-system-control"
+    - "allwinner,sun8i-a23-system-control"
+    - "allwinner,sun8i-h3-system-control"
+    - "allwinner,sun50i-a64-sram-controller" (deprecated)
+    - "allwinner,sun50i-a64-system-control"
 - reg : sram controller register offset + length
 
 SRAM nodes
@@ -26,8 +32,25 @@ once again the representation described in the mmio-sram binding.
 
 The valid sections compatible for A10 are:
     - allwinner,sun4i-a10-sram-a3-a4
+    - allwinner,sun4i-a10-sram-c1
     - allwinner,sun4i-a10-sram-d
 
+The valid sections compatible for A13 are:
+    - allwinner,sun5i-a13-sram-a3-a4, allwinner,sun4i-a10-sram-a3-a4
+    - allwinner,sun5i-a13-sram-c1, allwinner,sun4i-a10-sram-c1
+    - allwinner,sun5i-a13-sram-d, allwinner,sun4i-a10-sram-d
+
+The valid sections compatible for A20 are:
+    - allwinner,sun7i-a20-sram-a3-a4, allwinner,sun4i-a10-sram-a3-a4
+    - allwinner,sun7i-a20-sram-c1, allwinner,sun4i-a10-sram-c1
+    - allwinner,sun7i-a20-sram-d, allwinner,sun4i-a10-sram-d
+
+The valid sections compatible for A23/A33 are:
+    - allwinner,sun8i-a23-sram-c1, allwinner,sun4i-a10-sram-c1
+
+The valid sections compatible for H3 are:
+    - allwinner,sun8i-h3-sram-c1, allwinner,sun4i-a10-sram-c1
+
 The valid sections compatible for A64 are:
     - allwinner,sun50i-a64-sram-c
 
@@ -47,8 +70,8 @@ This valid values for this argument are:
 
 Example
 -------
-sram-controller@1c00000 {
-       compatible = "allwinner,sun4i-a10-sram-controller";
+system-control@1c00000 {
+       compatible = "allwinner,sun4i-a10-system-control";
        reg = <0x01c00000 0x30>;
        #address-cells = <1>;
        #size-cells = <1>;
index cc553f0952c5a5e6b68da0121f9da34b19b6114a..eb7ee91556a5cf25e983f23625b58345706ba8eb 100644 (file)
@@ -97,8 +97,8 @@ get assigned to trip points of the zone. The cooling devices are expected
 to be loaded in the target system.
 
 Required properties:
-- cooling-device:      A phandle of a cooling device with its specifier,
-  Type: phandle +      referring to which cooling device is used in this
+- cooling-device:      A list of phandles of cooling devices with their specifiers,
+  Type: phandle +      referring to which cooling devices are used in this
     cooling specifier  binding. In the cooling specifier, the first cell
                        is the minimum cooling state and the second cell
                        is the maximum cooling state used in this map.
@@ -276,12 +276,7 @@ thermal-zones {
                        };
                        map1 {
                                trip = <&cpu_alert1>;
-                               cooling-device = <&fan0 5 THERMAL_NO_LIMIT>;
-                       };
-                       map2 {
-                               trip = <&cpu_alert1>;
-                               cooling-device =
-                                   <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               cooling-device = <&fan0 5 THERMAL_NO_LIMIT>, <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
                        };
                };
        };
diff --git a/Documentation/devicetree/bindings/timer/ti,davinci-timer.txt b/Documentation/devicetree/bindings/timer/ti,davinci-timer.txt
new file mode 100644 (file)
index 0000000..29bf91c
--- /dev/null
@@ -0,0 +1,37 @@
+* Device tree bindings for Texas Instruments DaVinci timer
+
+This document provides bindings for the 64-bit timer in the DaVinci
+architecture devices. The timer can be configured as a general-purpose 64-bit
+timer, dual general-purpose 32-bit timers. When configured as dual 32-bit
+timers, each half can operate in conjunction (chain mode) or independently
+(unchained mode) of each other.
+
+The timer is a free running up-counter and can generate interrupts when the
+counter reaches preset counter values.
+
+Also see ../watchdog/davinci-wdt.txt for timers that are configurable as
+watchdog timers.
+
+Required properties:
+
+- compatible : should be "ti,da830-timer".
+- reg : specifies base physical address and count of the registers.
+- interrupts : interrupts generated by the timer.
+- interrupt-names: should be "tint12", "tint34", "cmpint0", "cmpint1",
+                  "cmpint2", "cmpint3", "cmpint4", "cmpint5", "cmpint6",
+                  "cmpint7" ("cmpintX" may be omitted if not present in the
+                  hardware).
+- clocks : the clock feeding the timer clock.
+
+Example:
+
+       clocksource: timer@20000 {
+               compatible = "ti,da830-timer";
+               reg = <0x20000 0x1000>;
+               interrupts = <21>, <22>, <74>, <75>, <76>, <77>, <78>, <79>,
+                            <80>, <81>;
+               interrupt-names = "tint12", "tint34", "cmpint0", "cmpint1",
+                                 "cmpint2", "cmpint3", "cmpint4", "cmpint5",
+                                 "cmpint6", "cmpint7";
+               clocks = <&pll0_auxclk>;
+       };
index 2f3620547249696e65e68999468487418cb34088..2c3fc512e7466fe0d7577db7d7c74b803739585c 100644 (file)
@@ -142,6 +142,7 @@ geekbuying  GeekBuying
 gef    GE Fanuc Intelligent Platforms Embedded Systems, Inc.
 GEFanuc        GE Fanuc Intelligent Platforms Embedded Systems, Inc.
 geniatech      Geniatech, Inc.
+giantec        Giantec Semiconductor, Inc.
 giantplus      Giantplus Technology Co., Ltd.
 globalscale    Globalscale Technologies, Inc.
 gmt    Global Mixed-mode Technology, Inc.
@@ -200,6 +201,7 @@ koe Kaohsiung Opto-Electronics Inc.
 kosagi Sutajio Ko-Usagi PTE Ltd.
 kyo    Kyocera Corporation
 lacie  LaCie
+laird  Laird PLC
 lantiq Lantiq Semiconductor
 lattice        Lattice Semiconductor
 lego   LEGO Systems A/S
@@ -279,6 +281,7 @@ opalkelly   Opal Kelly Incorporated
 opencores      OpenCores.org
 openrisc       OpenRISC.io
 option Option NV
+oranth Shenzhen Oranth Technology Co., Ltd.
 ORCL   Oracle Corporation
 orisetech      Orise Technology
 ortustech      Ortus Technology Co., Ltd.
@@ -322,6 +325,7 @@ rohm        ROHM Semiconductor Co., Ltd
 roofull        Shenzhen Roofull Technology Co, Ltd
 samsung        Samsung Semiconductor
 samtec Samtec/Softing company
+sancloud       Sancloud Ltd
 sandisk        Sandisk Corporation
 sbs    Smart Battery System
 schindler      Schindler
@@ -401,6 +405,7 @@ upisemi     uPI Semiconductor Corp.
 urt    United Radiant Technology Corporation
 usi    Universal Scientific Industrial Co., Ltd.
 v3     V3 Semiconductor
+vamrs  Vamrs Ltd.
 variscite      Variscite Ltd.
 via    VIA Technologies, Inc.
 virtio Virtual I/O Device Specification, developed by the OASIS consortium
index 37091902a0210328e76582426eaec0eaa3a7ae3d..3d6554eac240ce174e3d2073fa290a6b15bfd0fe 100644 (file)
@@ -13,10 +13,15 @@ Optional properties:
  - linux,open-drain: if specified, the data pin is considered in
                     open-drain mode.
 
+Also refer to the generic w1.txt document.
+
 Examples:
 
        onewire {
                compatible = "w1-gpio";
-               gpios = <&gpio 126 0>, <&gpio 105 0>;
-       };
+               gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
 
+               battery {
+                       // ...
+               };
+       };
diff --git a/Documentation/devicetree/bindings/w1/w1.txt b/Documentation/devicetree/bindings/w1/w1.txt
new file mode 100644 (file)
index 0000000..05f26b2
--- /dev/null
@@ -0,0 +1,25 @@
+Generic devicetree bindings for onewire (w1) busses
+===================================================
+
+Onewire busses are described through nodes of their master bus controller.
+Slave devices are listed as sub-nodes of such master devices. For now, only
+one slave is allowed per bus master.
+
+
+Example:
+
+       charger: charger {
+               compatible = "gpio-charger";
+               charger-type = "mains";
+               gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
+       };
+
+       onewire {
+               compatible = "w1-gpio";
+               gpios = <&gpio 100 0>, <&gpio 101 0>;
+
+               battery {
+                       compatible = "maxim,ds2760";
+                       power-supplies = <&charger>;
+               };
+       };
index 5d47a262474cfe0e4b32d1d814c6ac8bd3a20d45..9407212a85a8cac6918c56a27380bdb101e7af31 100644 (file)
@@ -7,6 +7,7 @@ Required properties:
               Examples with soctypes are:
                 - "renesas,r8a7743-wdt" (RZ/G1M)
                 - "renesas,r8a7745-wdt" (RZ/G1E)
+                - "renesas,r8a774a1-wdt" (RZ/G2M)
                 - "renesas,r8a7790-wdt" (R-Car H2)
                 - "renesas,r8a7791-wdt" (R-Car M2-W)
                 - "renesas,r8a7792-wdt" (R-Car V2H)
@@ -21,8 +22,8 @@ Required properties:
                 - "renesas,r7s72100-wdt" (RZ/A1)
                The generic compatible string must be:
                 - "renesas,rza-wdt" for RZ/A
-                - "renesas,rcar-gen2-wdt" for R-Car Gen2 and RZ/G
-                - "renesas,rcar-gen3-wdt" for R-Car Gen3
+                - "renesas,rcar-gen2-wdt" for R-Car Gen2 and RZ/G1
+                - "renesas,rcar-gen3-wdt" for R-Car Gen3 and RZ/G2
 
 - reg : Should contain WDT registers location and length
 - clocks : the clock feeding the watchdog timer.
index 4adc056f763565f415f3c5ec82fa5a0b9eec01fc..70e180e6b93dcc74d25fb6133bfaeb018166b870 100644 (file)
@@ -118,8 +118,7 @@ PIO data read/write
 All bmdma-style drivers must implement this hook. This is the low-level
 operation that actually copies the data bytes during a PIO data
 transfer. Typically the driver will choose one of
-:c:func:`ata_sff_data_xfer_noirq`, :c:func:`ata_sff_data_xfer`, or
-:c:func:`ata_sff_data_xfer32`.
+:c:func:`ata_sff_data_xfer`, or :c:func:`ata_sff_data_xfer32`.
 
 ATA command execute
 ~~~~~~~~~~~~~~~~~~~
index 2c00b072a4c8ca382f84af09ebea29150645380d..1e1057958dd3e68722df575e90d5f1b76ef1f29a 100644 (file)
@@ -66,17 +66,17 @@ early userspace image can be built by an unprivileged user.
 
 As a technical note, when directories and files are specified, the
 entire CONFIG_INITRAMFS_SOURCE is passed to
-scripts/gen_initramfs_list.sh.  This means that CONFIG_INITRAMFS_SOURCE
+usr/gen_initramfs_list.sh.  This means that CONFIG_INITRAMFS_SOURCE
 can really be interpreted as any legal argument to
 gen_initramfs_list.sh.  If a directory is specified as an argument then
 the contents are scanned, uid/gid translation is performed, and
 usr/gen_init_cpio file directives are output.  If a directory is
-specified as an argument to scripts/gen_initramfs_list.sh then the
+specified as an argument to usr/gen_initramfs_list.sh then the
 contents of the file are simply copied to the output.  All of the output
 directives from directory scanning and file contents copying are
 processed by usr/gen_init_cpio.
 
-See also 'scripts/gen_initramfs_list.sh -h'.
+See also 'usr/gen_initramfs_list.sh -h'.
 
 Where's this all leading?
 =========================
index d4d642e1ce9ce4597e9d93759748a6ef8c9302b1..62af30511a95247549b7334093122e35884cbab8 100644 (file)
@@ -18,9 +18,10 @@ made available by the underlying graphics card are also possible.
 A. Configuration
 
        The framebuffer console can be enabled by using your favorite kernel
-configuration tool.  It is under Device Drivers->Graphics Support->Support for
-framebuffer devices->Framebuffer Console Support. Select 'y' to compile
-support statically, or 'm' for module support.  The module will be fbcon.
+configuration tool.  It is under Device Drivers->Graphics Support->Frame
+buffer Devices->Console display driver support->Framebuffer Console Support.
+Select 'y' to compile support statically or 'm' for module support.  The
+module will be fbcon.
 
        In order for fbcon to activate, at least one framebuffer driver is
 required, so choose from any of the numerous drivers available. For x86
@@ -29,10 +30,10 @@ always be available. However, using a chipset-specific driver will give you
 more speed and features, such as the ability to change the video mode
 dynamically.
 
-       To display the penguin logo, choose any logo available in Logo
-Configuration->Boot up logo.
+       To display the penguin logo, choose any logo available in Graphics
+support->Bootup logo.
 
-       Also, you will need to select at least one compiled-in fonts, but if
+       Also, you will need to select at least one compiled-in font, but if
 you don't do anything, the kernel configuration tool will select one for you,
 usually an 8x16 font.
 
@@ -135,16 +136,16 @@ C. Boot options
 
        The angle can be changed anytime afterwards by 'echoing' the same
        numbers to any one of the 2 attributes found in
-        /sys/class/graphics/fbcon
+       /sys/class/graphics/fbcon:
 
                rotate     - rotate the display of the active console
                rotate_all - rotate the display of all consoles
 
-       Console rotation will only become available if Console Rotation
-       Support is compiled in your kernel.
+       Console rotation will only become available if Framebuffer Console
+       Rotation support is compiled in your kernel.
 
        NOTE: This is purely console rotation.  Any other applications that
-       use the framebuffer will remain at their 'normal'orientation.
+       use the framebuffer will remain at their 'normal' orientation.
        Actually, the underlying fb driver is totally ignorant of console
        rotation.
 
@@ -164,7 +165,7 @@ C. Boot options
 
 C. Attaching, Detaching and Unloading
 
-Before going on how to attach, detach and unload the framebuffer console, an
+Before going on to how to attach, detach and unload the framebuffer console, an
 illustration of the dependencies may help.
 
 The console layer, as with most subsystems, needs a driver that interfaces with
@@ -182,7 +183,7 @@ because fbcon is an intermediate layer between the console and the drivers:
 
 console ---> fbcon ---> fbdev drivers ---> hardware
 
-The fbdev drivers cannot be unloaded if it's bound to fbcon, and fbcon cannot
+The fbdev drivers cannot be unloaded if bound to fbcon, and fbcon cannot
 be unloaded if it's bound to the console layer.
 
 So to unload the fbdev drivers, one must first unbind fbcon from the console,
@@ -232,7 +233,7 @@ restored properly. The following is one of the several methods that you can do:
        echo 0 > /sys/class/vtconsole/vtcon1/bind
 
 6. That's it, you're back to VGA mode. And if you compiled fbcon as a module,
-   you can unload it by 'rmmod fbcon'
+   you can unload it by 'rmmod fbcon'.
 
 7. To reattach fbcon:
 
@@ -290,7 +291,7 @@ Samples:
 ========
 
 Here are 2 sample bash scripts that you can use to bind or unbind the
-framebuffer console driver if you are in an X86 box:
+framebuffer console driver if you are on an X86 box:
 
 ---------------------------------------------------------------------------
 #!/bin/bash
index 9e6f19eaef896a1b9466a525a65292eb10bfe206..efea228ccd8af2c6a218c58fda67c709c81ac8f3 100644 (file)
@@ -21,8 +21,7 @@ prototypes:
        char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
        struct vfsmount *(*d_automount)(struct path *path);
        int (*d_manage)(const struct path *, bool);
-       struct dentry *(*d_real)(struct dentry *, const struct inode *,
-                                unsigned int, unsigned int);
+       struct dentry *(*d_real)(struct dentry *, const struct inode *);
 
 locking rules:
                rename_lock     ->d_lock        may block       rcu-walk
index 69f8de99573974749263a33d75904ad5d37971de..e5edd29687b50a74f8946ca215f639bb71b434fa 100644 (file)
@@ -157,6 +157,24 @@ data_flush             Enable data flushing before checkpoint in order to
                        persist data of regular and symlink.
 fault_injection=%d     Enable fault injection in all supported types with
                        specified injection rate.
+fault_type=%d          Support configuring fault injection type, should be
+                       enabled with fault_injection option, fault type value
+                       is shown below, it supports single or combined type.
+                       Type_Name               Type_Value
+                       FAULT_KMALLOC           0x000000001
+                       FAULT_KVMALLOC          0x000000002
+                       FAULT_PAGE_ALLOC                0x000000004
+                       FAULT_PAGE_GET          0x000000008
+                       FAULT_ALLOC_BIO         0x000000010
+                       FAULT_ALLOC_NID         0x000000020
+                       FAULT_ORPHAN            0x000000040
+                       FAULT_BLOCK             0x000000080
+                       FAULT_DIR_DEPTH         0x000000100
+                       FAULT_EVICT_INODE       0x000000200
+                       FAULT_TRUNCATE          0x000000400
+                       FAULT_IO                        0x000000800
+                       FAULT_CHECKPOINT                0x000001000
+                       FAULT_DISCARD           0x000002000
 mode=%s                Control block allocation mode which supports "adaptive"
                        and "lfs". In "lfs" mode, there should be no random
                        writes towards main area.
index 72615a2c07529ab487e3c9aa4604ed9f0755e66d..51c136c821bfb0a190e7daa67ebdc2e6faaf878b 100644 (file)
@@ -10,10 +10,6 @@ union-filesystems).  An overlay-filesystem tries to present a
 filesystem which is the result over overlaying one filesystem on top
 of the other.
 
-The result will inevitably fail to look exactly like a normal
-filesystem for various technical reasons.  The expectation is that
-many use cases will be able to ignore these differences.
-
 
 Overlay objects
 ---------------
@@ -266,6 +262,30 @@ rightmost one and going left.  In the above example lower1 will be the
 top, lower2 the middle and lower3 the bottom layer.
 
 
+Metadata only copy up
+--------------------
+
+When metadata only copy up feature is enabled, overlayfs will only copy
+up metadata (as opposed to whole file), when a metadata specific operation
+like chown/chmod is performed. Full file will be copied up later when
+file is opened for WRITE operation.
+
+In other words, this is delayed data copy up operation and data is copied
+up when there is a need to actually modify data.
+
+There are multiple ways to enable/disable this feature. A config option
+CONFIG_OVERLAY_FS_METACOPY can be set/unset to enable/disable this feature
+by default. Or one can enable/disable it at module load time with module
+parameter metacopy=on/off. Lastly, there is also a per mount option
+metacopy=on/off to enable/disable this feature per mount.
+
+Do not use metacopy=on with untrusted upper/lower directories. Otherwise
+it is possible that an attacker can create a handcrafted file with
+appropriate REDIRECT and METACOPY xattrs, and gain access to file on lower
+pointed by REDIRECT. This should not be possible on local system as setting
+"trusted." xattrs will require CAP_SYS_ADMIN. But it should be possible
+for untrusted layers like from a pen drive.
+
 Sharing and copying layers
 --------------------------
 
@@ -284,7 +304,7 @@ though it will not result in a crash or deadlock.
 Mounting an overlay using an upper layer path, where the upper layer path
 was previously used by another mounted overlay in combination with a
 different lower layer path, is allowed, unless the "inodes index" feature
-is enabled.
+or "metadata only copy up" feature is enabled.
 
 With the "inodes index" feature, on the first time mount, an NFS file
 handle of the lower layer root directory, along with the UUID of the lower
@@ -297,6 +317,10 @@ lower root origin, mount will fail with ESTALE.  An overlayfs mount with
 does not support NFS export, lower filesystem does not have a valid UUID or
 if the upper filesystem does not support extended attributes.
 
+For "metadata only copy up" feature there is no verification mechanism at
+mount time. So if same upper is mounted with different set of lower, mount
+probably will succeed but expect the unexpected later on. So don't do it.
+
 It is quite a common practice to copy overlay layers to a different
 directory tree on the same or different underlying filesystem, and even
 to a different machine.  With the "inodes index" feature, trying to mount
@@ -306,27 +330,40 @@ the copied layers will fail the verification of the lower root file handle.
 Non-standard behavior
 ---------------------
 
-The copy_up operation essentially creates a new, identical file and
-moves it over to the old name.  Any open files referring to this inode
-will access the old data.
+Overlayfs can now act as a POSIX compliant filesystem with the following
+features turned on:
+
+1) "redirect_dir"
+
+Enabled with the mount option or module option: "redirect_dir=on" or with
+the kernel config option CONFIG_OVERLAY_FS_REDIRECT_DIR=y.
+
+If this feature is disabled, then rename(2) on a lower or merged directory
+will fail with EXDEV ("Invalid cross-device link").
+
+2) "inode index"
+
+Enabled with the mount option or module option "index=on" or with the
+kernel config option CONFIG_OVERLAY_FS_INDEX=y.
 
-The new file may be on a different filesystem, so both st_dev and st_ino
-of the real file may change.  The values of st_dev and st_ino returned by
-stat(2) on an overlay object are often not the same as the real file
-stat(2) values to prevent the values from changing on copy_up.
+If this feature is disabled and a file with multiple hard links is copied
+up, then this will "break" the link.  Changes will not be propagated to
+other names referring to the same inode.
 
-Unless "xino" feature is enabled, when overlay layers are not all on the
-same underlying filesystem, the value of st_dev may be different for two
-non-directory objects in the same overlay filesystem and the value of
-st_ino for directory objects may be non persistent and could change even
-while the overlay filesystem is still mounted.
+3) "xino"
 
-Unless "inode index" feature is enabled, if a file with multiple hard
-links is copied up, then this will "break" the link.  Changes will not be
-propagated to other names referring to the same inode.
+Enabled with the mount option "xino=auto" or "xino=on", with the module
+option "xino_auto=on" or with the kernel config option
+CONFIG_OVERLAY_FS_XINO_AUTO=y.  Also implicitly enabled by using the same
+underlying filesystem for all layers making up the overlay.
 
-Unless "redirect_dir" feature is enabled, rename(2) on a lower or merged
-directory will fail with EXDEV.
+If this feature is disabled or the underlying filesystem doesn't have
+enough free bits in the inode number, then overlayfs will not be able to
+guarantee that the values of st_ino and st_dev returned by stat(2) and the
+value of d_ino returned by readdir(3) will act like on a normal filesystem.
+E.g. the value of st_dev may be different for two objects in the same
+overlay filesystem and the value of st_ino for directory objects may not be
+persistent and could change even while the overlay filesystem is mounted.
 
 
 Changes to underlying filesystems
index 1605acbb23b6631f11d4979017e361360c4208a2..22b4b00dee31290bde37b3abc63f4a0807f973cc 100644 (file)
@@ -870,6 +870,7 @@ Committed_AS:   100056 kB
 VmallocTotal:   112216 kB
 VmallocUsed:       428 kB
 VmallocChunk:   111088 kB
+Percpu:          62080 kB
 HardwareCorrupted:   0 kB
 AnonHugePages:   49152 kB
 ShmemHugePages:      0 kB
@@ -962,6 +963,8 @@ Committed_AS: The amount of memory presently allocated on the system.
 VmallocTotal: total size of vmalloc memory area
  VmallocUsed: amount of vmalloc area which is used
 VmallocChunk: largest contiguous block of vmalloc area which is free
+      Percpu: Memory allocated to the percpu allocator used to back percpu
+              allocations. This stat excludes the cost of metadata.
 
 ..............................................................................
 
index b176928e69631f5efe3cb37506b3eb375cc3e23a..79637d227e856ceb1d1c9fa9e306ff11679154d6 100644 (file)
@@ -164,7 +164,7 @@ Documentation/early-userspace/README for more details.)
 The kernel does not depend on external cpio tools.  If you specify a
 directory instead of a configuration file, the kernel's build infrastructure
 creates a configuration file from that directory (usr/Makefile calls
-scripts/gen_initramfs_list.sh), and proceeds to package up that directory
+usr/gen_initramfs_list.sh), and proceeds to package up that directory
 using the config file (by feeding it to usr/gen_init_cpio, which is created
 from usr/gen_init_cpio.c).  The kernel's build-time cpio creation code is
 entirely self-contained, and the kernel's boot-time extractor is also
index 85907d5b9c2c5877136d97900a257e2987109c2c..4b2084d0f1fb26c9b86bd7e2e587590bc1c1b31a 100644 (file)
@@ -989,8 +989,7 @@ struct dentry_operations {
        char *(*d_dname)(struct dentry *, char *, int);
        struct vfsmount *(*d_automount)(struct path *);
        int (*d_manage)(const struct path *, bool);
-       struct dentry *(*d_real)(struct dentry *, const struct inode *,
-                                unsigned int, unsigned int);
+       struct dentry *(*d_real)(struct dentry *, const struct inode *);
 };
 
   d_revalidate: called when the VFS needs to revalidate a dentry. This
@@ -1124,22 +1123,15 @@ struct dentry_operations {
        dentry being transited from.
 
   d_real: overlay/union type filesystems implement this method to return one of
-       the underlying dentries hidden by the overlay.  It is used in three
+       the underlying dentries hidden by the overlay.  It is used in two
        different modes:
 
-       Called from open it may need to copy-up the file depending on the
-       supplied open flags.  This mode is selected with a non-zero flags
-       argument.  In this mode the d_real method can return an error.
-
        Called from file_dentry() it returns the real dentry matching the inode
        argument.  The real dentry may be from a lower layer already copied up,
        but still referenced from the file.  This mode is selected with a
-       non-NULL inode argument.  This will always succeed.
-
-       With NULL inode and zero flags the topmost real underlying dentry is
-       returned.  This will always succeed.
+       non-NULL inode argument.
 
-       This method is never called with both non-NULL inode and non-zero flags.
+       With NULL inode the topmost real underlying dentry is returned.
 
 Each dentry has a pointer to its parent dentry, as well as a hash list
 of child dentries. Child dentries are basically like files in a
index 72d16f08e431c674c62738641d7c28926d6331cb..b8df81f6d6bcf995e098ebb4dce0a57a483bba66 100644 (file)
@@ -32,7 +32,7 @@ Supported chips:
     Datasheet: Publicly available at the Texas Instruments website
                http://www.ti.com/
 
-Author: Lothar Felten <l-felten@ti.com>
+Author: Lothar Felten <lothar.felten@gmail.com>
 
 Description
 -----------
diff --git a/Documentation/hwmon/raspberrypi-hwmon b/Documentation/hwmon/raspberrypi-hwmon
new file mode 100644 (file)
index 0000000..3c92e2c
--- /dev/null
@@ -0,0 +1,22 @@
+Kernel driver raspberrypi-hwmon
+===============================
+
+Supported boards:
+  * Raspberry Pi A+ (via GPIO on SoC)
+  * Raspberry Pi B+ (via GPIO on SoC)
+  * Raspberry Pi 2 B (via GPIO on SoC)
+  * Raspberry Pi 3 B (via GPIO on port expander)
+  * Raspberry Pi 3 B+ (via PMIC)
+
+Author: Stefan Wahren <stefan.wahren@i2se.com>
+
+Description
+-----------
+
+This driver periodically polls a mailbox property of the VC4 firmware to detect
+undervoltage conditions.
+
+Sysfs entries
+-------------
+
+in0_lcrit_alarm                Undervoltage alarm
index 966610aa4620fa8ce19e52fffd2d44c5a2128367..203002054120568135a01f7e4ab343a5223279bd 100644 (file)
@@ -50,10 +50,14 @@ bounce buffer. But you don't need to care about that detail, just use the
 returned buffer. If NULL is returned, the threshold was not met or a bounce
 buffer could not be allocated. Fall back to PIO in that case.
 
-In any case, a buffer obtained from above needs to be released. It ensures data
-is copied back to the message and a potentially used bounce buffer is freed::
+In any case, a buffer obtained from above needs to be released. Another helper
+function ensures a potentially used bounce buffer is freed::
 
-       i2c_release_dma_safe_msg_buf(msg, dma_buf);
+       i2c_put_dma_safe_msg_buf(dma_buf, msg, xferred);
+
+The last argument 'xferred' controls if the buffer is synced back to the
+message or not. No syncing is needed in cases setting up DMA had an error and
+there was no data transferred.
 
 The bounce buffer handling from the core is generic and simple. It will always
 allocate a new bounce buffer. If you want a more sophisticated handling (e.g.
index 65514c25131877a77b5b0a85bbb8797129b87dca..d1ee484a787d1b476cf13bcf7d7b53ac084fb63e 100644 (file)
@@ -21,24 +21,21 @@ Supported adapters:
   * Intel DH89xxCC (PCH)
   * Intel Panther Point (PCH)
   * Intel Lynx Point (PCH)
-  * Intel Lynx Point-LP (PCH)
   * Intel Avoton (SOC)
   * Intel Wellsburg (PCH)
   * Intel Coleto Creek (PCH)
   * Intel Wildcat Point (PCH)
-  * Intel Wildcat Point-LP (PCH)
   * Intel BayTrail (SOC)
   * Intel Braswell (SOC)
-  * Intel Sunrise Point-H (PCH)
-  * Intel Sunrise Point-LP (PCH)
-  * Intel Kaby Lake-H (PCH)
+  * Intel Sunrise Point (PCH)
+  * Intel Kaby Lake (PCH)
   * Intel DNV (SOC)
   * Intel Broxton (SOC)
   * Intel Lewisburg (PCH)
   * Intel Gemini Lake (SOC)
-  * Intel Cannon Lake-H (PCH)
-  * Intel Cannon Lake-LP (PCH)
+  * Intel Cannon Lake (PCH)
   * Intel Cedar Fork (PCH)
+  * Intel Ice Lake (PCH)
    Datasheets: Publicly available at the Intel website
 
 On Intel Patsburg and later chipsets, both the normal host SMBus controller
index 4e713f4cdb2f9cfc23a206918937c964b0a70113..9caaf7df1b2ff5ae6044c843b8ee2b111731fd7e 100644 (file)
@@ -4,7 +4,7 @@ Supported adapters:
   * OpenCores.org I2C controller by Richard Herveille (see datasheet link)
     https://opencores.org/project/i2c/overview
 
-Author: Peter Korsgaard <jacmet@sunsite.dk>
+Author: Peter Korsgaard <peter@korsgaard.com>
 
 Description
 -----------
index e0c4f775e2390ffe2ffb6d64d1436777b5a4ecd2..a4ce62090fd5a8987502f338dc8bd2a4d4321cb0 100644 (file)
@@ -34,21 +34,48 @@ I2C specification version 4, section 3.1.16) using the helpers of the Linux I2C
 core (see 'struct bus_recovery_info'). However, the bus recovery will not
 succeed because SDA is still pinned low until you manually release it again
 with "echo 1 > sda". A test with an automatic release can be done with the
-'incomplete_transfer' file.
+following class of fault injectors.
 
-"incomplete_transfer"
----------------------
+Introduction to incomplete transfers
+------------------------------------
+
+The following fault injectors create situations where SDA will be held low by a
+device. Bus recovery should be able to fix these situations. But please note:
+there are I2C client devices which detect a stuck SDA on their side and release
+it on their own after a few milliseconds. Also, there might be an external
+device deglitching and monitoring the I2C bus. It could also detect a stuck SDA
+and will init a bus recovery on its own. If you want to implement bus recovery
+in a bus master driver, make sure you checked your hardware setup for such
+devices before. And always verify with a scope or logic analyzer!
+
+"incomplete_address_phase"
+--------------------------
 
 This file is write only and you need to write the address of an existing I2C
-client device to it. Then, a transfer to this device will be started, but it
-will stop at the ACK phase after the address of the client has been
+client device to it. Then, a read transfer to this device will be started, but
+it will stop at the ACK phase after the address of the client has been
 transmitted. Because the device will ACK its presence, this results in SDA
 being pulled low by the device while SCL is high. So, similar to the "sda" file
 above, the bus master under test should detect this condition and try a bus
 recovery. This time, however, it should succeed and the device should release
-SDA after toggling SCL. Please note: there are I2C client devices which detect
-a stuck SDA on their side and release it on their own after a few milliseconds.
-Also, there are external devices deglitching and monitoring the I2C bus. They
-can also detect a stuck SDA and will init a bus recovery on their own. If you
-want to implement bus recovery in a bus master driver, make sure you checked
-your hardware setup carefully before.
+SDA after toggling SCL.
+
+"incomplete_write_byte"
+-----------------------
+
+Similar to above, this file is write only and you need to write the address of
+an existing I2C client device to it.
+
+The injector will again stop at one ACK phase, so the device will keep SDA low
+because it acknowledges data. However, there are two differences compared to
+'incomplete_address_phase':
+
+a) the message sent out will be a write message
+b) after the address byte, a 0x00 byte will be transferred. Then, stop at ACK.
+
+This is a highly delicate state, the device is set up to write any data to
+register 0x00 (if it has registers) when further clock pulses happen on SCL.
+This is why bus recovery (up to 9 clock pulses) must either check SDA or send
+additional STOP conditions to ensure the bus has been released. Otherwise
+random data will be written to a device!
+
index c54cb7cb9ff45fc49189161bc80d3586f0e91586..864e740811dadab3c8f7dafb4a240656a9e9d0bf 100644 (file)
@@ -545,7 +545,7 @@ make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-02 allnoconfig
 Practical solutions to kconfig recursive issue
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Developers who run into the recursive Kconfig issue have three options
+Developers who run into the recursive Kconfig issue have two options
 at their disposal. We document them below and also provide a list of
 historical issues resolved through these different solutions.
 
@@ -553,7 +553,6 @@ historical issues resolved through these different solutions.
   b) Match dependency semantics:
        b1) Swap all "select FOO" to "depends on FOO" or,
        b2) Swap all "depends on FOO" to "select FOO"
-  c) Consider the use of "imply" instead of "select"
 
 The resolution to a) can be tested with the sample Kconfig file
 Documentation/kbuild/Kconfig.recursion-issue-01 through the removal
index 766355b1d2212236c2501835aece0b402d7454ae..7b6a2b2bdc98db2e794a261ff7be17dc3df0ae26 100644 (file)
@@ -680,7 +680,7 @@ Both possibilities are described in the following.
 
        Example:
                #scripts/kconfig/Makefile
-               HOSTLOADLIBES_qconf := -L$(QTDIR)/lib
+               HOSTLDLIBS_qconf := -L$(QTDIR)/lib
 
        When linking qconf, it will be passed the extra option
        "-L$(QTDIR)/lib".
diff --git a/Documentation/networking/dpaa2/dpio-driver.rst b/Documentation/networking/dpaa2/dpio-driver.rst
new file mode 100644 (file)
index 0000000..1358810
--- /dev/null
@@ -0,0 +1,158 @@
+.. include:: <isonum.txt>
+
+DPAA2 DPIO (Data Path I/O) Overview
+===================================
+
+:Copyright: |copy| 2016-2018 NXP
+
+This document provides an overview of the Freescale DPAA2 DPIO
+drivers
+
+Introduction
+============
+
+A DPAA2 DPIO (Data Path I/O) is a hardware object that provides
+interfaces to enqueue and dequeue frames to/from network interfaces
+and other accelerators.  A DPIO also provides hardware buffer
+pool management for network interfaces.
+
+This document provides an overview the Linux DPIO driver, its
+subcomponents, and its APIs.
+
+See Documentation/networking/dpaa2/overview.rst for a general overview of DPAA2
+and the general DPAA2 driver architecture in Linux.
+
+Driver Overview
+---------------
+
+The DPIO driver is bound to DPIO objects discovered on the fsl-mc bus and
+provides services that:
+  A) allow other drivers, such as the Ethernet driver, to enqueue and dequeue
+     frames for their respective objects
+  B) allow drivers to register callbacks for data availability notifications
+     when data becomes available on a queue or channel
+  C) allow drivers to manage hardware buffer pools
+
+The Linux DPIO driver consists of 3 primary components--
+   DPIO object driver-- fsl-mc driver that manages the DPIO object
+
+   DPIO service-- provides APIs to other Linux drivers for services
+
+   QBman portal interface-- sends portal commands, gets responses
+::
+
+          fsl-mc          other
+           bus           drivers
+            |               |
+        +---+----+   +------+-----+
+        |DPIO obj|   |DPIO service|
+        | driver |---|  (DPIO)    |
+        +--------+   +------+-----+
+                            |
+                     +------+-----+
+                     |    QBman   |
+                     | portal i/f |
+                     +------------+
+                            |
+                         hardware
+
+
+The diagram below shows how the DPIO driver components fit with the other
+DPAA2 Linux driver components::
+                                                   +------------+
+                                                   | OS Network |
+                                                   |   Stack    |
+                 +------------+                    +------------+
+                 | Allocator  |. . . . . . .       |  Ethernet  |
+                 |(DPMCP,DPBP)|                    |   (DPNI)   |
+                 +-.----------+                    +---+---+----+
+                  .          .                         ^   |
+                 .            .           <data avail, |   |<enqueue,
+                .              .           tx confirm> |   | dequeue>
+    +-------------+             .                      |   |
+    | DPRC driver |              .    +--------+ +------------+
+    |   (DPRC)    |               . . |DPIO obj| |DPIO service|
+    +----------+--+                   | driver |-|  (DPIO)    |
+               |                      +--------+ +------+-----+
+               |<dev add/remove>                 +------|-----+
+               |                                 |   QBman    |
+          +----+--------------+                  | portal i/f |
+          |   MC-bus driver   |                  +------------+
+          |                   |                     |
+          | /soc/fsl-mc       |                     |
+          +-------------------+                     |
+                                                    |
+ =========================================|=========|========================
+                                        +-+--DPIO---|-----------+
+                                        |           |           |
+                                        |        QBman Portal   |
+                                        +-----------------------+
+
+ ============================================================================
+
+
+DPIO Object Driver (dpio-driver.c)
+----------------------------------
+
+   The dpio-driver component registers with the fsl-mc bus to handle objects of
+   type "dpio".  The implementation of probe() handles basic initialization
+   of the DPIO including mapping of the DPIO regions (the QBman SW portal)
+   and initializing interrupts and registering irq handlers.  The dpio-driver
+   registers the probed DPIO with dpio-service.
+
+DPIO service  (dpio-service.c, dpaa2-io.h)
+------------------------------------------
+
+   The dpio service component provides queuing, notification, and buffers
+   management services to DPAA2 drivers, such as the Ethernet driver.  A system
+   will typically allocate 1 DPIO object per CPU to allow queuing operations
+   to happen simultaneously across all CPUs.
+
+   Notification handling
+      dpaa2_io_service_register()
+
+      dpaa2_io_service_deregister()
+
+      dpaa2_io_service_rearm()
+
+   Queuing
+      dpaa2_io_service_pull_fq()
+
+      dpaa2_io_service_pull_channel()
+
+      dpaa2_io_service_enqueue_fq()
+
+      dpaa2_io_service_enqueue_qd()
+
+      dpaa2_io_store_create()
+
+      dpaa2_io_store_destroy()
+
+      dpaa2_io_store_next()
+
+   Buffer pool management
+      dpaa2_io_service_release()
+
+      dpaa2_io_service_acquire()
+
+QBman portal interface (qbman-portal.c)
+---------------------------------------
+
+   The qbman-portal component provides APIs to do the low level hardware
+   bit twiddling for operations such as:
+      -initializing Qman software portals
+
+      -building and sending portal commands
+
+      -portal interrupt configuration and processing
+
+   The qbman-portal APIs are not public to other drivers, and are
+   only used by dpio-service.
+
+Other (dpaa2-fd.h, dpaa2-global.h)
+----------------------------------
+
+   Frame descriptor and scatter-gather definitions and the APIs used to
+   manipulate them are defined in dpaa2-fd.h.
+
+   Dequeue result struct and parsing APIs are defined in dpaa2-global.h.
index 4c6586c87969e407deaefff55181660847ff2333..10bea113a7bc7b833db55da2efe757a984aba74f 100644 (file)
@@ -6,3 +6,4 @@ DPAA2 Documentation
    :maxdepth: 1
 
    overview
+   dpio-driver
index 61f918b10a0c74d7c8369009ce0b6447d31f903a..d1bf143b446f3b60bc374b40dc7b6818d1c21aa8 100644 (file)
@@ -86,7 +86,7 @@ pkg-config
 
 The build system, as of 4.18, requires pkg-config to check for installed
 kconfig tools and to determine flags settings for use in
-'make {menu,n,g,x}config'.  Previously pkg-config was being used but not
+'make {g,x}config'.  Previously pkg-config was being used but not
 verified or documented.
 
 Flex
index 25a4b4cf04a6d462f4b640a396ae178b561984e2..92999d4e0cb800cfad588f413a0a23210fe92861 100644 (file)
@@ -97,6 +97,11 @@ parameters may be changed at runtime by the command
                        allowing boot to proceed.  none ignores them, expecting
                        user space to do the scan.
 
+       scsi_mod.use_blk_mq=
+                       [SCSI] use blk-mq I/O path by default
+                       See SCSI_MQ_DEFAULT in drivers/scsi/Kconfig.
+                       Format: <y/n>
+
        sim710=         [SCSI,HW]
                        See header of drivers/scsi/sim710.c.
 
index 6c00c1e2743fa2048882514d8644a908fff3a475..819caf8ca05f8b4b16226c0f5d6f76068de09131 100644 (file)
@@ -34,7 +34,9 @@ Currently, these files are in /proc/sys/fs:
 - overflowgid
 - pipe-user-pages-hard
 - pipe-user-pages-soft
+- protected_fifos
 - protected_hardlinks
+- protected_regular
 - protected_symlinks
 - suid_dumpable
 - super-max
@@ -182,6 +184,24 @@ applied.
 
 ==============================================================
 
+protected_fifos:
+
+The intent of this protection is to avoid unintentional writes to
+an attacker-controlled FIFO, where a program expected to create a regular
+file.
+
+When set to "0", writing to FIFOs is unrestricted.
+
+When set to "1" don't allow O_CREAT open on FIFOs that we don't own
+in world writable sticky directories, unless they are owned by the
+owner of the directory.
+
+When set to "2" it also applies to group writable sticky directories.
+
+This protection is based on the restrictions in Openwall.
+
+==============================================================
+
 protected_hardlinks:
 
 A long-standing class of security issues is the hardlink-based
@@ -202,6 +222,22 @@ This protection is based on the restrictions in Openwall and grsecurity.
 
 ==============================================================
 
+protected_regular:
+
+This protection is similar to protected_fifos, but it
+avoids writes to an attacker-controlled regular file, where a program
+expected to create one.
+
+When set to "0", writing to regular files is unrestricted.
+
+When set to "1" don't allow O_CREAT open on regular files that we
+don't own in world writable sticky directories, unless they are
+owned by the owner of the directory.
+
+When set to "2" it also applies to group writable sticky directories.
+
+==============================================================
+
 protected_symlinks:
 
 A long-standing class of security issues is the symlink-based
index 59585030cbafa4e6a489980caf54234b5c91eeef..37a679501ddc68bc0ab26c58444794c0d30c8f40 100644 (file)
@@ -38,6 +38,7 @@ show up in /proc/sys/kernel:
 - hung_task_panic
 - hung_task_check_count
 - hung_task_timeout_secs
+- hung_task_check_interval_secs
 - hung_task_warnings
 - hyperv_record_panic_msg
 - kexec_load_disabled
@@ -355,7 +356,7 @@ This file shows up if CONFIG_DETECT_HUNG_TASK is enabled.
 
 hung_task_timeout_secs:
 
-Check interval. When a task in D state did not get scheduled
+When a task in D state did not get scheduled
 for more than this value report a warning.
 This file shows up if CONFIG_DETECT_HUNG_TASK is enabled.
 
@@ -364,6 +365,18 @@ Possible values to set are in range {0..LONG_MAX/HZ}.
 
 ==============================================================
 
+hung_task_check_interval_secs:
+
+Hung task check interval. If hung task checking is enabled
+(see hung_task_timeout_secs), the check is done every
+hung_task_check_interval_secs seconds.
+This file shows up if CONFIG_DETECT_HUNG_TASK is enabled.
+
+0 (default): means use hung_task_timeout_secs as checking interval.
+Possible values to set are in range {0..LONG_MAX/HZ}.
+
+==============================================================
+
 hung_task_warnings:
 
 The maximum number of warnings to report. During a check interval
@@ -451,7 +464,8 @@ Notes:
 1) kernel doesn't guarantee, that new object will have desired id. So,
 it's up to userspace, how to handle an object with "wrong" id.
 2) Toggle with non-default value will be set back to -1 by kernel after
-successful IPC object allocation.
+successful IPC object allocation. If an IPC object allocation syscall
+fails, it is undefined if the value remains unmodified or is reset to -1.
 
 ==============================================================
 
index e72853b6d7257b30c93eceff5eee014cfa146ae6..7d73882e2c273c57d1277c701b71a1774b22763c 100644 (file)
@@ -691,7 +691,7 @@ and don't use much of it.
 The default value is 0.
 
 See Documentation/vm/overcommit-accounting.rst and
-mm/mmap.c::__vm_enough_memory() for more information.
+mm/util.c::__vm_enough_memory() for more information.
 
 ==============================================================
 
index 7b83b176c662ce24a014299a69be27e28452a14d..c664064f76fb60ccc434988266776697660d0a5f 100644 (file)
@@ -835,11 +835,13 @@ struct kvm_clock_data {
 
 Capability: KVM_CAP_VCPU_EVENTS
 Extended by: KVM_CAP_INTR_SHADOW
-Architectures: x86
-Type: vm ioctl
+Architectures: x86, arm, arm64
+Type: vcpu ioctl
 Parameters: struct kvm_vcpu_event (out)
 Returns: 0 on success, -1 on error
 
+X86:
+
 Gets currently pending exceptions, interrupts, and NMIs as well as related
 states of the vcpu.
 
@@ -881,15 +883,64 @@ Only two fields are defined in the flags field:
 - KVM_VCPUEVENT_VALID_SMM may be set in the flags field to signal that
   smi contains a valid state.
 
+ARM/ARM64:
+
+If the guest accesses a device that is being emulated by the host kernel in
+such a way that a real device would generate a physical SError, KVM may make
+a virtual SError pending for that VCPU. This system error interrupt remains
+pending until the guest takes the exception by unmasking PSTATE.A.
+
+Running the VCPU may cause it to take a pending SError, or make an access that
+causes an SError to become pending. The event's description is only valid while
+the VPCU is not running.
+
+This API provides a way to read and write the pending 'event' state that is not
+visible to the guest. To save, restore or migrate a VCPU the struct representing
+the state can be read then written using this GET/SET API, along with the other
+guest-visible registers. It is not possible to 'cancel' an SError that has been
+made pending.
+
+A device being emulated in user-space may also wish to generate an SError. To do
+this the events structure can be populated by user-space. The current state
+should be read first, to ensure no existing SError is pending. If an existing
+SError is pending, the architecture's 'Multiple SError interrupts' rules should
+be followed. (2.5.3 of DDI0587.a "ARM Reliability, Availability, and
+Serviceability (RAS) Specification").
+
+SError exceptions always have an ESR value. Some CPUs have the ability to
+specify what the virtual SError's ESR value should be. These systems will
+advertise KVM_CAP_ARM_INJECT_SERROR_ESR. In this case exception.has_esr will
+always have a non-zero value when read, and the agent making an SError pending
+should specify the ISS field in the lower 24 bits of exception.serror_esr. If
+the system supports KVM_CAP_ARM_INJECT_SERROR_ESR, but user-space sets the events
+with exception.has_esr as zero, KVM will choose an ESR.
+
+Specifying exception.has_esr on a system that does not support it will return
+-EINVAL. Setting anything other than the lower 24bits of exception.serror_esr
+will return -EINVAL.
+
+struct kvm_vcpu_events {
+       struct {
+               __u8 serror_pending;
+               __u8 serror_has_esr;
+               /* Align it to 8 bytes */
+               __u8 pad[6];
+               __u64 serror_esr;
+       } exception;
+       __u32 reserved[12];
+};
+
 4.32 KVM_SET_VCPU_EVENTS
 
 Capability: KVM_CAP_VCPU_EVENTS
 Extended by: KVM_CAP_INTR_SHADOW
-Architectures: x86
-Type: vm ioctl
+Architectures: x86, arm, arm64
+Type: vcpu ioctl
 Parameters: struct kvm_vcpu_event (in)
 Returns: 0 on success, -1 on error
 
+X86:
+
 Set pending exceptions, interrupts, and NMIs as well as related states of the
 vcpu.
 
@@ -910,6 +961,13 @@ shall be written into the VCPU.
 
 KVM_VCPUEVENT_VALID_SMM can only be set if KVM_CAP_X86_SMM is available.
 
+ARM/ARM64:
+
+Set the pending SError exception state for this VCPU. It is not possible to
+'cancel' an Serror that has been made pending.
+
+See KVM_GET_VCPU_EVENTS for the data structure.
+
 
 4.33 KVM_GET_DEBUGREGS
 
@@ -4690,3 +4748,17 @@ This capability indicates that KVM supports paravirtualized Hyper-V TLB Flush
 hypercalls:
 HvFlushVirtualAddressSpace, HvFlushVirtualAddressSpaceEx,
 HvFlushVirtualAddressList, HvFlushVirtualAddressListEx.
+
+8.19 KVM_CAP_ARM_INJECT_SERROR_ESR
+
+Architectures: arm, arm64
+
+This capability indicates that userspace can specify (via the
+KVM_SET_VCPU_EVENTS ioctl) the syndrome value reported to the guest when it
+takes a virtual SError interrupt exception.
+If KVM advertises this capability, userspace can only specify the ISS field for
+the ESR syndrome. Other parts of the ESR, such as the EC are generated by the
+CPU when the exception is taken. If this virtual SError is taken to EL1 using
+AArch64, this value will be reported in the ISS field of ESR_ELx.
+
+See KVM_CAP_VCPU_EVENTS for more details.
index 2408ab720ef7bae0bcd4736bc30ee475fd00e8ce..ff290b43c8e513175990d76337653299f87d7a93 100644 (file)
@@ -100,6 +100,14 @@ Groups:
     Note that distributor fields are not banked, but return the same value
     regardless of the mpidr used to access the register.
 
+    GICD_IIDR.Revision is updated when the KVM implementation is changed in a
+    way directly observable by the guest or userspace.  Userspace should read
+    GICD_IIDR from KVM and write back the read value to confirm its expected
+    behavior is aligned with the KVM implementation.  Userspace should set
+    GICD_IIDR before setting any other registers to ensure the expected
+    behavior.
+
+
     The GICD_STATUSR and GICR_STATUSR registers are architecturally defined such
     that a write of a clear bit has no effect, whereas a write with a set bit
     clears that value.  To allow userspace to freely set the values of these two
index b3ce12643553f3edbe327029bbfe61ecaa8cc506..97b6518148f87befcc2dab5fb250459607154525 100644 (file)
@@ -49,9 +49,15 @@ Groups:
     index is specified with the vcpu_index field.  Note that most distributor
     fields are not banked, but return the same value regardless of the
     vcpu_index used to access the register.
-  Limitations:
-    - Priorities are not implemented, and registers are RAZ/WI
-    - Currently only implemented for KVM_DEV_TYPE_ARM_VGIC_V2.
+
+    GICD_IIDR.Revision is updated when the KVM implementation of an emulated
+    GICv2 is changed in a way directly observable by the guest or userspace.
+    Userspace should read GICD_IIDR from KVM and write back the read value to
+    confirm its expected behavior is aligned with the KVM implementation.
+    Userspace should set GICD_IIDR before setting any other registers (both
+    KVM_DEV_ARM_VGIC_GRP_DIST_REGS and KVM_DEV_ARM_VGIC_GRP_CPU_REGS) to ensure
+    the expected behavior. Unless GICD_IIDR has been set from userspace, writes
+    to the interrupt group registers (GICD_IGROUPR) are ignored.
   Errors:
     -ENXIO: Getting or setting this register is not yet supported
     -EBUSY: One or more VCPUs are running
@@ -94,9 +100,6 @@ Groups:
     use the lower 5 bits to communicate with the KVM device and must shift the
     value left by 3 places to obtain the actual priority mask level.
 
-  Limitations:
-    - Priorities are not implemented, and registers are RAZ/WI
-    - Currently only implemented for KVM_DEV_TYPE_ARM_VGIC_V2.
   Errors:
     -ENXIO: Getting or setting this register is not yet supported
     -EBUSY: One or more VCPUs are running
index 5df1b36431963624326adf99ff80bbe918fffebd..d870cb57c887a1c5fa773a8fd9d614c54cb3cce0 100644 (file)
@@ -842,6 +842,13 @@ S: Supported
 F:     drivers/mux/adgs1408.c
 F:     Documentation/devicetree/bindings/mux/adgs1408.txt
 
+ANALOG DEVICES INC ADP5061 DRIVER
+M:     Stefan Popa <stefan.popa@analog.com>
+L:     linux-pm@vger.kernel.org
+W:     http://ez.analog.com/community/linux-device-drivers
+S:     Supported
+F:     drivers/power/supply/adp5061.c
+
 ANALOG DEVICES INC ADV7180 DRIVER
 M:     Lars-Peter Clausen <lars@metafoo.de>
 L:     linux-media@vger.kernel.org
@@ -1288,11 +1295,6 @@ F:       arch/arm/mach-aspeed/
 F:     arch/arm/boot/dts/aspeed-*
 N:     aspeed
 
-ARM/ATMEL AT91 Clock Support
-M:     Boris Brezillon <boris.brezillon@bootlin.com>
-S:     Maintained
-F:     drivers/clk/at91
-
 ARM/CALXEDA HIGHBANK ARCHITECTURE
 M:     Rob Herring <robh@kernel.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1474,6 +1476,16 @@ T:       git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
 F:     arch/arm/mach-imx/*vf610*
 F:     arch/arm/boot/dts/vf*
 
+ARM/FREESCALE LAYERSCAPE ARM ARCHITECTURE
+M:     Shawn Guo <shawnguo@kernel.org>
+M:     Li Yang <leoyang.li@nxp.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
+F:     arch/arm/boot/dts/ls1021a*
+F:     arch/arm64/boot/dts/freescale/fsl-*
+F:     arch/arm64/boot/dts/freescale/qoriq-*
+
 ARM/GLOMATION GESBC9312SX MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -2002,6 +2014,7 @@ S:        Supported
 F:     arch/arm/boot/dts/emev2*
 F:     arch/arm/boot/dts/r7s*
 F:     arch/arm/boot/dts/r8a*
+F:     arch/arm/boot/dts/r9a*
 F:     arch/arm/boot/dts/sh*
 F:     arch/arm/configs/shmobile_defconfig
 F:     arch/arm/include/debug/renesas-scif.S
@@ -2120,6 +2133,15 @@ L:       linux-kernel@vger.kernel.org
 S:     Maintained
 F:     drivers/memory/*emif*
 
+ARM/TEXAS INSTRUMENTS K3 ARCHITECTURE
+M:     Tero Kristo <t-kristo@ti.com>
+M:     Nishanth Menon <nm@ti.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Supported
+F:     Documentation/devicetree/bindings/arm/ti/k3.txt
+F:     arch/arm64/boot/dts/ti/Makefile
+F:     arch/arm64/boot/dts/ti/k3-*
+
 ARM/TEXAS INSTRUMENT KEYSTONE ARCHITECTURE
 M:     Santosh Shilimkar <ssantosh@kernel.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -2289,6 +2311,7 @@ F:        drivers/clocksource/cadence_ttc_timer.c
 F:     drivers/i2c/busses/i2c-cadence.c
 F:     drivers/mmc/host/sdhci-of-arasan.c
 F:     drivers/edac/synopsys_edac.c
+F:     drivers/i2c/busses/i2c-xiic.c
 
 ARM64 PORT (AARCH64 ARCHITECTURE)
 M:     Catalin Marinas <catalin.marinas@arm.com>
@@ -4342,7 +4365,8 @@ F:        drivers/i2c/busses/i2c-diolan-u2c.c
 
 FILESYSTEM DIRECT ACCESS (DAX)
 M:     Matthew Wilcox <mawilcox@microsoft.com>
-M:     Ross Zwisler <ross.zwisler@linux.intel.com>
+M:     Ross Zwisler <zwisler@kernel.org>
+M:     Jan Kara <jack@suse.cz>
 L:     linux-fsdevel@vger.kernel.org
 S:     Supported
 F:     fs/dax.c
@@ -4352,7 +4376,7 @@ F:        include/trace/events/fs_dax.h
 DEVICE DIRECT ACCESS (DAX)
 M:     Dan Williams <dan.j.williams@intel.com>
 M:     Dave Jiang <dave.jiang@intel.com>
-M:     Ross Zwisler <ross.zwisler@linux.intel.com>
+M:     Ross Zwisler <zwisler@kernel.org>
 M:     Vishal Verma <vishal.l.verma@intel.com>
 L:     linux-nvdimm@lists.01.org
 S:     Supported
@@ -4500,7 +4524,7 @@ DPAA2 DATAPATH I/O (DPIO) DRIVER
 M:     Roy Pledge <Roy.Pledge@nxp.com>
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
-F:     drivers/staging/fsl-mc/bus/dpio
+F:     drivers/soc/fsl/dpio
 
 DPAA2 ETHERNET DRIVER
 M:     Ioana Radulescu <ruxandra.radulescu@nxp.com>
@@ -4730,7 +4754,7 @@ F:        include/linux/vga*
 DRM DRIVERS AND MISC GPU PATCHES
 M:     Gustavo Padovan <gustavo@padovan.org>
 M:     Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-M:     Sean Paul <seanpaul@chromium.org>
+M:     Sean Paul <sean@poorly.run>
 W:     https://01.org/linuxgraphics/gfx-docs/maintainer-tools/drm-misc.html
 S:     Maintained
 T:     git git://anongit.freedesktop.org/drm/drm-misc
@@ -5961,6 +5985,14 @@ F:       fs/crypto/
 F:     include/linux/fscrypt*.h
 F:     Documentation/filesystems/fscrypt.rst
 
+FSI-ATTACHED I2C DRIVER
+M:     Eddie James <eajames@linux.vnet.ibm.com>
+L:     linux-i2c@vger.kernel.org
+L:     openbmc@lists.ozlabs.org (moderated for non-subscribers)
+S:     Maintained
+F:     drivers/i2c/busses/i2c-fsi.c
+F:     Documentation/devicetree/bindings/i2c/i2c-fsi.txt
+
 FSNOTIFY: FILESYSTEM NOTIFICATION INFRASTRUCTURE
 M:     Jan Kara <jack@suse.cz>
 R:     Amir Goldstein <amir73il@gmail.com>
@@ -8224,9 +8256,9 @@ F:        drivers/ata/pata_arasan_cf.c
 
 LIBATA PATA DRIVERS
 M:     Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
-M:     Tejun Heo <tj@kernel.org>
+M:     Jens Axboe <axboe@kernel.dk>
 L:     linux-ide@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
 S:     Maintained
 F:     drivers/ata/pata_*.c
 F:     drivers/ata/ata_generic.c
@@ -8242,9 +8274,9 @@ F:        drivers/ata/sata_gemini.h
 
 LIBATA SATA AHCI PLATFORM devices support
 M:     Hans de Goede <hdegoede@redhat.com>
-M:     Tejun Heo <tj@kernel.org>
+M:     Jens Axboe <axboe@kernel.dk>
 L:     linux-ide@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
 S:     Maintained
 F:     drivers/ata/ahci_platform.c
 F:     drivers/ata/libahci_platform.c
@@ -8258,9 +8290,9 @@ S:        Maintained
 F:     drivers/ata/sata_promise.*
 
 LIBATA SUBSYSTEM (Serial and Parallel ATA drivers)
-M:     Tejun Heo <tj@kernel.org>
+M:     Jens Axboe <axboe@kernel.dk>
 L:     linux-ide@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
 S:     Maintained
 F:     drivers/ata/
 F:     include/linux/ata.h
@@ -8273,7 +8305,7 @@ S:        Maintained
 F:     tools/lib/lockdep/
 
 LIBNVDIMM BLK: MMIO-APERTURE DRIVER
-M:     Ross Zwisler <ross.zwisler@linux.intel.com>
+M:     Ross Zwisler <zwisler@kernel.org>
 M:     Dan Williams <dan.j.williams@intel.com>
 M:     Vishal Verma <vishal.l.verma@intel.com>
 M:     Dave Jiang <dave.jiang@intel.com>
@@ -8286,7 +8318,7 @@ F:        drivers/nvdimm/region_devs.c
 LIBNVDIMM BTT: BLOCK TRANSLATION TABLE
 M:     Vishal Verma <vishal.l.verma@intel.com>
 M:     Dan Williams <dan.j.williams@intel.com>
-M:     Ross Zwisler <ross.zwisler@linux.intel.com>
+M:     Ross Zwisler <zwisler@kernel.org>
 M:     Dave Jiang <dave.jiang@intel.com>
 L:     linux-nvdimm@lists.01.org
 Q:     https://patchwork.kernel.org/project/linux-nvdimm/list/
@@ -8294,7 +8326,7 @@ S:        Supported
 F:     drivers/nvdimm/btt*
 
 LIBNVDIMM PMEM: PERSISTENT MEMORY DRIVER
-M:     Ross Zwisler <ross.zwisler@linux.intel.com>
+M:     Ross Zwisler <zwisler@kernel.org>
 M:     Dan Williams <dan.j.williams@intel.com>
 M:     Vishal Verma <vishal.l.verma@intel.com>
 M:     Dave Jiang <dave.jiang@intel.com>
@@ -8313,7 +8345,7 @@ F:        Documentation/devicetree/bindings/pmem/pmem-region.txt
 
 LIBNVDIMM: NON-VOLATILE MEMORY DEVICE SUBSYSTEM
 M:     Dan Williams <dan.j.williams@intel.com>
-M:     Ross Zwisler <ross.zwisler@linux.intel.com>
+M:     Ross Zwisler <zwisler@kernel.org>
 M:     Vishal Verma <vishal.l.verma@intel.com>
 M:     Dave Jiang <dave.jiang@intel.com>
 L:     linux-nvdimm@lists.01.org
@@ -10556,6 +10588,7 @@ F:      arch/arm/plat-omap/
 F:     arch/arm/configs/omap1_defconfig
 F:     drivers/i2c/busses/i2c-omap.c
 F:     include/linux/platform_data/i2c-omap.h
+F:     include/linux/platform_data/ams-delta-fiq.h
 
 OMAP2+ SUPPORT
 M:     Tony Lindgren <tony@atomide.com>
@@ -10756,7 +10789,7 @@ F:      arch/*/boot/dts/
 F:     include/dt-bindings/
 
 OPENCORES I2C BUS DRIVER
-M:     Peter Korsgaard <jacmet@sunsite.dk>
+M:     Peter Korsgaard <peter@korsgaard.com>
 L:     linux-i2c@vger.kernel.org
 S:     Maintained
 F:     Documentation/i2c/busses/i2c-ocores
@@ -12014,6 +12047,14 @@ L:     netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/ethernet/qualcomm/emac/
 
+QUALCOMM GENERIC INTERFACE I2C DRIVER
+M:     Alok Chauhan <alokc@codeaurora.org>
+M:     Karthikeyan Ramasubramanian <kramasub@codeaurora.org>
+L:     linux-i2c@vger.kernel.org
+L:     linux-arm-msm@vger.kernel.org
+S:     Supported
+F:     drivers/i2c/busses/i2c-qcom-geni.c
+
 QUALCOMM HEXAGON ARCHITECTURE
 M:     Richard Kuo <rkuo@codeaurora.org>
 L:     linux-hexagon@vger.kernel.org
@@ -13184,7 +13225,7 @@ L:      linux-input@vger.kernel.org
 L:     platform-driver-x86@vger.kernel.org
 S:     Maintained
 F:     drivers/input/touchscreen/silead.c
-F:     drivers/platform/x86/silead_dmi.c
+F:     drivers/platform/x86/touchscreen_dmi.c
 
 SILICON MOTION SM712 FRAME BUFFER DRIVER
 M:     Sudip Mukherjee <sudipm.mukherjee@gmail.com>
@@ -14371,6 +14412,7 @@ F:      drivers/media/radio/radio-raremono.c
 THERMAL
 M:     Zhang Rui <rui.zhang@intel.com>
 M:     Eduardo Valentin <edubezval@gmail.com>
+R:     Daniel Lezcano <daniel.lezcano@linaro.org>
 L:     linux-pm@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal.git
index a0650bf79606124437148caac0b055b1fc1fe607..4d5c883a98e5a018b4ac301cd420a5745886d500 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 VERSION = 4
-PATCHLEVEL = 18
+PATCHLEVEL = 19
 SUBLEVEL = 0
-EXTRAVERSION =
+EXTRAVERSION = -rc3
 NAME = Merciless Moray
 
 # *DOCUMENTATION*
@@ -440,7 +440,7 @@ KBUILD_CFLAGS_KERNEL :=
 KBUILD_AFLAGS_MODULE  := -DMODULE
 KBUILD_CFLAGS_MODULE  := -DMODULE
 KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds
-LDFLAGS :=
+KBUILD_LDFLAGS :=
 GCC_PLUGINS_CFLAGS :=
 
 export ARCH SRCARCH CONFIG_SHELL HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC
@@ -448,7 +448,7 @@ export CPP AR NM STRIP OBJCOPY OBJDUMP KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS
 export MAKE LEX YACC AWK GENKSYMS INSTALLKERNEL PERL PYTHON PYTHON2 PYTHON3 UTS_MACHINE
 export HOSTCXX KBUILD_HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
 
-export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
+export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS
 export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
 export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN
 export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
@@ -507,9 +507,13 @@ KBUILD_AFLAGS += $(call cc-option, -no-integrated-as)
 endif
 
 RETPOLINE_CFLAGS_GCC := -mindirect-branch=thunk-extern -mindirect-branch-register
+RETPOLINE_VDSO_CFLAGS_GCC := -mindirect-branch=thunk-inline -mindirect-branch-register
 RETPOLINE_CFLAGS_CLANG := -mretpoline-external-thunk
+RETPOLINE_VDSO_CFLAGS_CLANG := -mretpoline
 RETPOLINE_CFLAGS := $(call cc-option,$(RETPOLINE_CFLAGS_GCC),$(call cc-option,$(RETPOLINE_CFLAGS_CLANG)))
+RETPOLINE_VDSO_CFLAGS := $(call cc-option,$(RETPOLINE_VDSO_CFLAGS_GCC),$(call cc-option,$(RETPOLINE_VDSO_CFLAGS_CLANG)))
 export RETPOLINE_CFLAGS
+export RETPOLINE_VDSO_CFLAGS
 
 KBUILD_CFLAGS  += $(call cc-option,-fno-PIE)
 KBUILD_AFLAGS  += $(call cc-option,-fno-PIE)
@@ -754,12 +758,28 @@ ifdef CONFIG_FUNCTION_TRACER
 ifndef CC_FLAGS_FTRACE
 CC_FLAGS_FTRACE := -pg
 endif
-export CC_FLAGS_FTRACE
+ifdef CONFIG_FTRACE_MCOUNT_RECORD
+  # gcc 5 supports generating the mcount tables directly
+  ifeq ($(call cc-option-yn,-mrecord-mcount),y)
+    CC_FLAGS_FTRACE    += -mrecord-mcount
+    export CC_USING_RECORD_MCOUNT := 1
+  endif
+  ifdef CONFIG_HAVE_NOP_MCOUNT
+    ifeq ($(call cc-option-yn, -mnop-mcount),y)
+      CC_FLAGS_FTRACE  += -mnop-mcount
+      CC_FLAGS_USING   += -DCC_USING_NOP_MCOUNT
+    endif
+  endif
+endif
 ifdef CONFIG_HAVE_FENTRY
-CC_USING_FENTRY        := $(call cc-option, -mfentry -DCC_USING_FENTRY)
+  ifeq ($(call cc-option-yn, -mfentry),y)
+    CC_FLAGS_FTRACE    += -mfentry
+    CC_FLAGS_USING     += -DCC_USING_FENTRY
+  endif
 endif
-KBUILD_CFLAGS  += $(CC_FLAGS_FTRACE) $(CC_USING_FENTRY)
-KBUILD_AFLAGS  += $(CC_USING_FENTRY)
+export CC_FLAGS_FTRACE
+KBUILD_CFLAGS  += $(CC_FLAGS_FTRACE) $(CC_FLAGS_USING)
+KBUILD_AFLAGS  += $(CC_FLAGS_USING)
 ifdef CONFIG_DYNAMIC_FTRACE
        ifdef CONFIG_HAVE_C_RECORDMCOUNT
                BUILD_C_RECORDMCOUNT := y
@@ -774,8 +794,8 @@ KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
 endif
 
 ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
-KBUILD_CFLAGS_KERNEL   += $(call cc-option,-ffunction-sections,)
-KBUILD_CFLAGS_KERNEL   += $(call cc-option,-fdata-sections,)
+KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections
+LDFLAGS_vmlinux += --gc-sections
 endif
 
 # arch Makefile may override CC so keep this after arch Makefile is included
@@ -787,6 +807,9 @@ KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
 # disable pointer signed / unsigned warnings in gcc 4.0
 KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign)
 
+# disable stringop warnings in gcc 8+
+KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation)
+
 # disable invalid "can't wrap" optimizations for signed / pointers
 KBUILD_CFLAGS  += $(call cc-option,-fno-strict-overflow)
 
@@ -841,10 +864,6 @@ LDFLAGS_BUILD_ID := $(call ld-option, --build-id)
 KBUILD_LDFLAGS_MODULE += $(LDFLAGS_BUILD_ID)
 LDFLAGS_vmlinux += $(LDFLAGS_BUILD_ID)
 
-ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION
-LDFLAGS_vmlinux        += $(call ld-option, --gc-sections,)
-endif
-
 ifeq ($(CONFIG_STRIP_ASM_SYMS),y)
 LDFLAGS_vmlinux        += $(call ld-option, -X,)
 endif
@@ -1008,7 +1027,7 @@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink)
 
 # Final link of vmlinux with optional arch pass after final link
 cmd_link-vmlinux =                                                 \
-       $(CONFIG_SHELL) $< $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) ;    \
+       $(CONFIG_SHELL) $< $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_vmlinux) ;    \
        $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
 
 vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(vmlinux-deps) FORCE
@@ -1338,16 +1357,12 @@ distclean: mrproper
 
 # Packaging of the kernel to various formats
 # ---------------------------------------------------------------------------
-# rpm target kept for backward compatibility
 package-dir    := scripts/package
 
 %src-pkg: FORCE
        $(Q)$(MAKE) $(build)=$(package-dir) $@
 %pkg: include/config/kernel.release FORCE
        $(Q)$(MAKE) $(build)=$(package-dir) $@
-rpm: rpm-pkg
-       @echo "  WARNING: \"rpm\" target will be removed after Linux 4.18"
-       @echo "           Please use \"rpm-pkg\" instead."
 
 
 # Brief documentation of the typical targets used
index c6148166a7b4b0df1873ab55f299f148d9a8d6a9..6801123932a503ba64bcf1c9dfbb7877fff0f094 100644 (file)
@@ -362,6 +362,9 @@ config HAVE_ARCH_JUMP_LABEL
 config HAVE_RCU_TABLE_FREE
        bool
 
+config HAVE_RCU_TABLE_INVALIDATE
+       bool
+
 config ARCH_HAVE_NMI_SAFE_CMPXCHG
        bool
 
@@ -841,6 +844,24 @@ config REFCOUNT_FULL
          against various use-after-free conditions that can be used in
          security flaw exploits.
 
+config HAVE_ARCH_COMPILER_H
+       bool
+       help
+         An architecture can select this if it provides an
+         asm/compiler.h header that should be included after
+         linux/compiler-*.h in order to override macro definitions that those
+         headers generally provide.
+
+config HAVE_ARCH_PREL32_RELOCATIONS
+       bool
+       help
+         May be selected by an architecture if it supports place-relative
+         32-bit relocations, both in the toolchain and in the module loader,
+         in which case relative references can be used in special sections
+         for PCI fixup, initcalls etc which are only half the size on 64 bit
+         architectures, and don't require runtime relocation on relocatable
+         kernels.
+
 source "kernel/gcov/Kconfig"
 
 source "scripts/gcc-plugins/Kconfig"
index c210a25dd6daad4a99f40ce729cde4db707de6cf..cff52d8ffdb12656070a4c5e73f5dad376cd9f86 100644 (file)
@@ -530,24 +530,19 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path,
 SYSCALL_DEFINE1(osf_utsname, char __user *, name)
 {
        int error;
+       char tmp[5 * 32];
 
        down_read(&uts_sem);
-       error = -EFAULT;
-       if (copy_to_user(name + 0, utsname()->sysname, 32))
-               goto out;
-       if (copy_to_user(name + 32, utsname()->nodename, 32))
-               goto out;
-       if (copy_to_user(name + 64, utsname()->release, 32))
-               goto out;
-       if (copy_to_user(name + 96, utsname()->version, 32))
-               goto out;
-       if (copy_to_user(name + 128, utsname()->machine, 32))
-               goto out;
+       memcpy(tmp + 0 * 32, utsname()->sysname, 32);
+       memcpy(tmp + 1 * 32, utsname()->nodename, 32);
+       memcpy(tmp + 2 * 32, utsname()->release, 32);
+       memcpy(tmp + 3 * 32, utsname()->version, 32);
+       memcpy(tmp + 4 * 32, utsname()->machine, 32);
+       up_read(&uts_sem);
 
-       error = 0;
- out:
-       up_read(&uts_sem);      
-       return error;
+       if (copy_to_user(name, tmp, sizeof(tmp)))
+               return -EFAULT;
+       return 0;
 }
 
 SYSCALL_DEFINE0(getpagesize)
@@ -567,18 +562,21 @@ SYSCALL_DEFINE2(osf_getdomainname, char __user *, name, int, namelen)
 {
        int len, err = 0;
        char *kname;
+       char tmp[32];
 
-       if (namelen > 32)
+       if (namelen < 0 || namelen > 32)
                namelen = 32;
 
        down_read(&uts_sem);
        kname = utsname()->domainname;
        len = strnlen(kname, namelen);
-       if (copy_to_user(name, kname, min(len + 1, namelen)))
-               err = -EFAULT;
+       len = min(len + 1, namelen);
+       memcpy(tmp, kname, len);
        up_read(&uts_sem);
 
-       return err;
+       if (copy_to_user(name, tmp, len))
+               return -EFAULT;
+       return 0;
 }
 
 /*
@@ -739,13 +737,14 @@ SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count)
        };
        unsigned long offset;
        const char *res;
-       long len, err = -EINVAL;
+       long len;
+       char tmp[__NEW_UTS_LEN + 1];
 
        offset = command-1;
        if (offset >= ARRAY_SIZE(sysinfo_table)) {
                /* Digital UNIX has a few unpublished interfaces here */
                printk("sysinfo(%d)", command);
-               goto out;
+               return -EINVAL;
        }
 
        down_read(&uts_sem);
@@ -753,13 +752,11 @@ SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count)
        len = strlen(res)+1;
        if ((unsigned long)len > (unsigned long)count)
                len = count;
-       if (copy_to_user(buf, res, len))
-               err = -EFAULT;
-       else
-               err = 0;
+       memcpy(tmp, res, len);
        up_read(&uts_sem);
- out:
-       return err;
+       if (copy_to_user(buf, tmp, len))
+               return -EFAULT;
+       return 0;
 }
 
 SYSCALL_DEFINE5(osf_getsysinfo, unsigned long, op, void __user *, buffer,
index 6d5eb8267e429fa3eac927b053c31944500a74da..b4441b0764d71aff87b67fba665163b57bdb20b6 100644 (file)
@@ -9,6 +9,7 @@
 config ARC
        def_bool y
        select ARC_TIMERS
+       select ARCH_HAS_PTE_SPECIAL
        select ARCH_HAS_SYNC_DMA_FOR_CPU
        select ARCH_HAS_SYNC_DMA_FOR_DEVICE
        select ARCH_HAS_SG_CHAIN
@@ -28,8 +29,12 @@ config ARC
        select GENERIC_SMP_IDLE_THREAD
        select HAVE_ARCH_KGDB
        select HAVE_ARCH_TRACEHOOK
+       select HAVE_DEBUG_STACKOVERFLOW
        select HAVE_FUTEX_CMPXCHG if FUTEX
+       select HAVE_GENERIC_DMA_COHERENT
        select HAVE_IOREMAP_PROT
+       select HAVE_KERNEL_GZIP
+       select HAVE_KERNEL_LZMA
        select HAVE_KPROBES
        select HAVE_KRETPROBES
        select HAVE_MEMBLOCK
@@ -44,11 +49,6 @@ config ARC
        select OF_EARLY_FLATTREE
        select OF_RESERVED_MEM
        select PERF_USE_VMALLOC if ARC_CACHE_VIPT_ALIASING
-       select HAVE_DEBUG_STACKOVERFLOW
-       select HAVE_GENERIC_DMA_COHERENT
-       select HAVE_KERNEL_GZIP
-       select HAVE_KERNEL_LZMA
-       select ARCH_HAS_PTE_SPECIAL
 
 config ARCH_HAS_CACHE_LINE_SIZE
        def_bool y
index 6c1b20dd76ad902655d7317eb44580923d98c690..99cce77ab98f2d79c3dbef3130bff70b91ea076d 100644 (file)
@@ -43,10 +43,7 @@ ifdef CONFIG_ARC_CURR_IN_REG
 LINUXINCLUDE   +=  -include ${src}/arch/arc/include/asm/current.h
 endif
 
-upto_gcc44    :=  $(call cc-ifversion, -le, 0404, y)
-atleast_gcc44 :=  $(call cc-ifversion, -ge, 0404, y)
-
-cflags-$(atleast_gcc44)                        += -fsection-anchors
+cflags-y                               += -fsection-anchors
 
 cflags-$(CONFIG_ARC_HAS_LLSC)          += -mlock
 cflags-$(CONFIG_ARC_HAS_SWAPE)         += -mswape
@@ -82,11 +79,6 @@ cflags-$(disable_small_data)         += -mno-sdata -fcall-used-gp
 cflags-$(CONFIG_CPU_BIG_ENDIAN)                += -mbig-endian
 ldflags-$(CONFIG_CPU_BIG_ENDIAN)       += -EB
 
-# STAR 9000518362: (fixed with binutils shipping with gcc 4.8)
-# arc-linux-uclibc-ld (buildroot) or arceb-elf32-ld (EZChip) don't accept
-# --build-id w/o "-marclinux". Default arc-elf32-ld is OK
-ldflags-$(upto_gcc44)                  += -marclinux
-
 LIBGCC := $(shell $(CC) $(cflags-y) --print-libgcc-file-name)
 
 # Modules with short calls might break for calls into builtin-kernel
@@ -95,7 +87,7 @@ KBUILD_CFLAGS_MODULE  += -mlong-calls -mno-millicode
 # Finally dump eveything into kernel build system
 KBUILD_CFLAGS  += $(cflags-y)
 KBUILD_AFLAGS  += $(KBUILD_CFLAGS)
-LDFLAGS                += $(ldflags-y)
+KBUILD_LDFLAGS += $(ldflags-y)
 
 head-y         := arch/arc/kernel/head.o
 
index dc91c663bcc02e2cdc116f40ad31757d711ac485..d75d65ddf8e31db78c58fa9882b90c2e6be2ed4b 100644 (file)
                };
        };
 
+       /*
+        * Mark DMA peripherals connected via IOC port as dma-coherent. We do
+        * it via overlay because peripherals defined in axs10x_mb.dtsi are
+        * used for both AXS101 and AXS103 boards and only AXS103 has IOC (so
+        * only AXS103 board has HW-coherent DMA peripherals)
+        * We don't need to mark pgu@17000 as dma-coherent because it uses
+        * external DMA buffer located outside of IOC aperture.
+        */
+       axs10x_mb {
+               ethernet@0x18000 {
+                       dma-coherent;
+               };
+
+               ehci@0x40000 {
+                       dma-coherent;
+               };
+
+               ohci@0x60000 {
+                       dma-coherent;
+               };
+
+               mmc@0x15000 {
+                       dma-coherent;
+               };
+       };
+
        /*
         * The DW APB ICTL intc on MB is connected to CPU intc via a
         * DT "invisible" DW APB GPIO block, configured to simply pass thru
index 69ff4895f2ba4b558f2bdfed547ef0ec27288174..a05bb737ea6392f5e77cd3830dceb8afe620943e 100644 (file)
                };
        };
 
+       /*
+        * Mark DMA peripherals connected via IOC port as dma-coherent. We do
+        * it via overlay because peripherals defined in axs10x_mb.dtsi are
+        * used for both AXS101 and AXS103 boards and only AXS103 has IOC (so
+        * only AXS103 board has HW-coherent DMA peripherals)
+        * We don't need to mark pgu@17000 as dma-coherent because it uses
+        * external DMA buffer located outside of IOC aperture.
+        */
+       axs10x_mb {
+               ethernet@0x18000 {
+                       dma-coherent;
+               };
+
+               ehci@0x40000 {
+                       dma-coherent;
+               };
+
+               ohci@0x60000 {
+                       dma-coherent;
+               };
+
+               mmc@0x15000 {
+                       dma-coherent;
+               };
+       };
+
        /*
         * This INTC is actually connected to DW APB GPIO
         * which acts as a wire between MB INTC and CPU INTC.
index 47b74fbc403c21cc2f493f6f84d6216b7c5ef5c1..37bafd44e36d0fed9b85e80ea356cd78df0c1872 100644 (file)
@@ -9,6 +9,10 @@
  */
 
 / {
+       aliases {
+               ethernet = &gmac;
+       };
+
        axs10x_mb {
                compatible = "simple-bus";
                #address-cells = <1>;
@@ -68,7 +72,7 @@
                        };
                };
 
-               ethernet@0x18000 {
+               gmac: ethernet@0x18000 {
                        #interrupt-cells = <1>;
                        compatible = "snps,dwmac";
                        reg = < 0x18000 0x2000 >;
@@ -81,6 +85,7 @@
                        max-speed = <100>;
                        resets = <&creg_rst 5>;
                        reset-names = "stmmaceth";
+                       mac-address = [00 00 00 00 00 00]; /* Filled in by U-Boot */
                };
 
                ehci@0x40000 {
index 006aa3de5348f31c7462f52f173ad2e74434d062..ef149f59929ae394a30695fa0940060acef15817 100644 (file)
                bootargs = "earlycon=uart8250,mmio32,0xf0005000,115200n8 console=ttyS0,115200n8 debug print-fatal-signals=1";
        };
 
+       aliases {
+               ethernet = &gmac;
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                        #clock-cells = <0>;
                };
 
-               ethernet@8000 {
+               gmac: ethernet@8000 {
                        #interrupt-cells = <1>;
                        compatible = "snps,dwmac";
                        reg = <0x8000 0x2000>;
                        phy-handle = <&phy0>;
                        resets = <&cgu_rst HSDK_ETH_RESET>;
                        reset-names = "stmmaceth";
+                       mac-address = [00 00 00 00 00 00]; /* Filled in by U-Boot */
+                       dma-coherent;
 
                        mdio {
                                #address-cells = <1>;
                        compatible = "snps,hsdk-v1.0-ohci", "generic-ohci";
                        reg = <0x60000 0x100>;
                        interrupts = <15>;
+                       dma-coherent;
                };
 
                ehci@40000 {
                        compatible = "snps,hsdk-v1.0-ehci", "generic-ehci";
                        reg = <0x40000 0x100>;
                        interrupts = <15>;
+                       dma-coherent;
                };
 
                mmc@a000 {
                        clock-names = "biu", "ciu";
                        interrupts = <12>;
                        bus-width = <4>;
+                       dma-coherent;
                };
        };
 
index a635ea972304e3531b205c23a0e3ef814608e313..41bc08be6a3b4202bbe27f74fdc8e01a56e4c3cd 100644 (file)
@@ -1,5 +1,3 @@
-CONFIG_DEFAULT_HOSTNAME="ARCLinux"
-# CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_CROSS_MEMORY_ATTACH is not set
@@ -63,7 +61,6 @@ CONFIG_MOUSE_PS2_TOUCHKIT=y
 CONFIG_MOUSE_SERIAL=y
 CONFIG_MOUSE_SYNAPTICS_USB=y
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_DW=y
index aa507e423075b16be125d95fbb29b55b5b08683c..1e1c4a8011b523dc88b89fb39e90dfeab5a3154b 100644 (file)
@@ -1,5 +1,3 @@
-CONFIG_DEFAULT_HOSTNAME="ARCLinux"
-# CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_CROSS_MEMORY_ATTACH is not set
@@ -64,7 +62,6 @@ CONFIG_MOUSE_PS2_TOUCHKIT=y
 CONFIG_MOUSE_SERIAL=y
 CONFIG_MOUSE_SYNAPTICS_USB=y
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_DW=y
index eba07f4686545ed00383756ae53ba404b2b2b25e..6b0c0cfd5c304fd6ae58fc3fd92d9cb53e086d2d 100644 (file)
@@ -1,5 +1,3 @@
-CONFIG_DEFAULT_HOSTNAME="ARCLinux"
-# CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_CROSS_MEMORY_ATTACH is not set
@@ -65,7 +63,6 @@ CONFIG_MOUSE_PS2_TOUCHKIT=y
 CONFIG_MOUSE_SERIAL=y
 CONFIG_MOUSE_SYNAPTICS_USB=y
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_DW=y
index 098b19fbaa51f0116e7f0328eb3a17feb72f0123..240dd2cd514855ae96010f0e487c76b8bd37a6f9 100644 (file)
@@ -1,4 +1,3 @@
-CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -57,7 +56,6 @@ CONFIG_MOUSE_PS2_TOUCHKIT=y
 # CONFIG_SERIO_SERPORT is not set
 CONFIG_SERIO_ARC_PS2=y
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=1
index 0104c404d8970ee44ecb0ced17fe137363e4cf5b..14ae7e5acc7c9cc381ebd9be04ad36a24b282a20 100644 (file)
@@ -1,4 +1,3 @@
-CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -60,7 +59,6 @@ CONFIG_MOUSE_PS2_TOUCHKIT=y
 # CONFIG_SERIO_SERPORT is not set
 CONFIG_SERIO_ARC_PS2=y
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=1
index 6491be0ddbc9e9cfd457dccc452d5bebf28c1183..1dec2b4bc5e6ea70696249d6815dfe69e73eb21c 100644 (file)
@@ -1,4 +1,3 @@
-CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 CONFIG_SYSVIPC=y
 # CONFIG_CROSS_MEMORY_ATTACH is not set
 CONFIG_NO_HZ_IDLE=y
index 7c9c706ae7f66eb29d4cf48ca0b95d5dd44630f5..31ba224bbfb474985b49930dea193c6bbb1a5f37 100644 (file)
@@ -59,7 +59,6 @@ CONFIG_NETCONSOLE=y
 # 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_NR_UARTS=1
index 99e05cf63fca2c6d953b952386b0cf1649ae7332..8e0b8b134cd9ed89652b88aea3bade03881e95c9 100644 (file)
@@ -1,5 +1,4 @@
 # CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -44,7 +43,6 @@ CONFIG_LXT_PHY=y
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_ARC=y
 CONFIG_SERIAL_ARC_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
index 0dc4f9b737e7a4f48b41ae7caaedaa2ce89c5b40..739b90e5e8931f1e5f1443aa19b3e0fac93a155b 100644 (file)
@@ -1,5 +1,4 @@
 # CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -45,7 +44,6 @@ CONFIG_DEVTMPFS=y
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_ARC=y
 CONFIG_SERIAL_ARC_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
index be3c30a15e54c09db51112ca88fd9b32d73a0d34..b5895bdf3a9393027d9fed716c4b83f86a9e4915 100644 (file)
@@ -1,5 +1,4 @@
 # CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
 # CONFIG_CROSS_MEMORY_ATTACH is not set
 CONFIG_HIGH_RES_TIMERS=y
@@ -44,7 +43,6 @@ CONFIG_DEVTMPFS=y
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_ARC=y
 CONFIG_SERIAL_ARC_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
index 3a74b9b217723d2c2c75a91510ef1aadeab7b89a..f14eeff7d3084948c16d8905677ec25a629ccdcc 100644 (file)
@@ -1,5 +1,4 @@
 # CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 # CONFIG_CROSS_MEMORY_ATTACH is not set
@@ -48,7 +47,6 @@ CONFIG_MOUSE_PS2_TOUCHKIT=y
 # CONFIG_SERIO_SERPORT is not set
 CONFIG_SERIO_ARC_PS2=y
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=1
index ea2834b4dc1dad187193549b7b146da413726c37..025298a483056b1ca782e83056f8b0a44d193809 100644 (file)
@@ -1,5 +1,4 @@
 # CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 # CONFIG_CROSS_MEMORY_ATTACH is not set
@@ -47,7 +46,6 @@ CONFIG_MOUSE_PS2_TOUCHKIT=y
 # CONFIG_SERIO_SERPORT is not set
 CONFIG_SERIO_ARC_PS2=y
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=1
index 80a5a1b4924bcf086ed57c34d7778304288f35a2..df7b77b13b823dc0c8d41f543181b12a20212cbd 100644 (file)
@@ -1,4 +1,3 @@
-CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 # CONFIG_CROSS_MEMORY_ATTACH is not set
@@ -58,7 +57,6 @@ CONFIG_MOUSE_PS2_TOUCHKIT=y
 # CONFIG_SERIO_SERPORT is not set
 CONFIG_SERIO_ARC_PS2=y
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=1
index 2cc87f909747c1818385de9ba99c0bbeda6197b8..a7f65313f84a56a3ddc0307c669bbfbcf4c0386f 100644 (file)
@@ -57,7 +57,6 @@ CONFIG_STMMAC_ETH=y
 # CONFIG_SERIO is not set
 # CONFIG_VT 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_NR_UARTS=1
index f629493929ea620a50630ba49842383ecc3662a4..db47c3541f15931b2927fd1bd27749f2568e9761 100644 (file)
@@ -1,5 +1,4 @@
 # CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_CROSS_MEMORY_ATTACH is not set
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
@@ -53,7 +52,6 @@ CONFIG_NATIONAL_PHY=y
 CONFIG_MOUSE_PS2_TOUCHKIT=y
 CONFIG_SERIO_ARC_PS2=y
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_DW=y
index 21f0ca26a05d5cffeb58541aa127ed1154a3ec98..a8ac5e917d9a5895a4bc3ba30be01fd222ecec71 100644 (file)
@@ -1,5 +1,4 @@
 # CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_DEFAULT_HOSTNAME="ARCLinux"
 # CONFIG_CROSS_MEMORY_ATTACH is not set
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
index 4e0072730241220c84ddc5019bba91c856de6f34..158af079838d007480f66b7d7ffe08d72b16c2d7 100644 (file)
@@ -84,7 +84,7 @@ static inline int atomic_fetch_##op(int i, atomic_t *v)                       \
        "1:     llock   %[orig], [%[ctr]]               \n"             \
        "       " #asm_op " %[val], %[orig], %[i]       \n"             \
        "       scond   %[val], [%[ctr]]                \n"             \
-       "                                               \n"             \
+       "       bnz     1b                              \n"             \
        : [val] "=&r"   (val),                                          \
          [orig] "=&r" (orig)                                           \
        : [ctr] "r"     (&v->counter),                                  \
diff --git a/arch/arc/include/asm/dma-mapping.h b/arch/arc/include/asm/dma-mapping.h
new file mode 100644 (file)
index 0000000..c946c0a
--- /dev/null
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier:  GPL-2.0
+// (C) 2018 Synopsys, Inc. (www.synopsys.com)
+
+#ifndef ASM_ARC_DMA_MAPPING_H
+#define ASM_ARC_DMA_MAPPING_H
+
+#include <asm-generic/dma-mapping.h>
+
+void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+                       const struct iommu_ops *iommu, bool coherent);
+#define arch_setup_dma_ops arch_setup_dma_ops
+
+#endif
index 783b20354f8bf7889075ec4219310eb9b6f4fbf7..e8d9fb4523462a9807358fea19c4e7668cc1126d 100644 (file)
@@ -83,9 +83,6 @@ done:
 static void show_faulting_vma(unsigned long address, char *buf)
 {
        struct vm_area_struct *vma;
-       struct inode *inode;
-       unsigned long ino = 0;
-       dev_t dev = 0;
        char *nm = buf;
        struct mm_struct *active_mm = current->active_mm;
 
@@ -99,12 +96,10 @@ static void show_faulting_vma(unsigned long address, char *buf)
         * if the container VMA is not found
         */
        if (vma && (vma->vm_start <= address)) {
-               struct file *file = vma->vm_file;
-               if (file) {
-                       nm = file_path(file, buf, PAGE_SIZE - 1);
-                       inode = file_inode(vma->vm_file);
-                       dev = inode->i_sb->s_dev;
-                       ino = inode->i_ino;
+               if (vma->vm_file) {
+                       nm = file_path(vma->vm_file, buf, PAGE_SIZE - 1);
+                       if (IS_ERR(nm))
+                               nm = "?";
                }
                pr_info("    @off 0x%lx in [%s]\n"
                        "    VMA: 0x%08lx to 0x%08lx\n",
index 25c631942500ffe2802654f6690d9a223e2fbfaf..f2701c13a66b209571ff89b71ac6c93cabb9835d 100644 (file)
@@ -65,7 +65,7 @@ char *arc_cache_mumbojumbo(int c, char *buf, int len)
 
        n += scnprintf(buf + n, len - n, "Peripherals\t: %#lx%s%s\n",
                       perip_base,
-                      IS_AVAIL3(ioc_exists, ioc_enable, ", IO-Coherency "));
+                      IS_AVAIL3(ioc_exists, ioc_enable, ", IO-Coherency (per-device) "));
 
        return buf;
 }
@@ -896,15 +896,6 @@ static void __dma_cache_wback_slc(phys_addr_t start, unsigned long sz)
        slc_op(start, sz, OP_FLUSH);
 }
 
-/*
- * DMA ops for systems with IOC
- * IOC hardware snoops all DMA traffic keeping the caches consistent with
- * memory - eliding need for any explicit cache maintenance of DMA buffers
- */
-static void __dma_cache_wback_inv_ioc(phys_addr_t start, unsigned long sz) {}
-static void __dma_cache_inv_ioc(phys_addr_t start, unsigned long sz) {}
-static void __dma_cache_wback_ioc(phys_addr_t start, unsigned long sz) {}
-
 /*
  * Exported DMA API
  */
@@ -1153,6 +1144,19 @@ noinline void __init arc_ioc_setup(void)
 {
        unsigned int ioc_base, mem_sz;
 
+       /*
+        * As for today we don't support both IOC and ZONE_HIGHMEM enabled
+        * simultaneously. This happens because as of today IOC aperture covers
+        * only ZONE_NORMAL (low mem) and any dma transactions outside this
+        * region won't be HW coherent.
+        * If we want to use both IOC and ZONE_HIGHMEM we can use
+        * bounce_buffer to handle dma transactions to HIGHMEM.
+        * Also it is possible to modify dma_direct cache ops or increase IOC
+        * aperture size if we are planning to use HIGHMEM without PAE.
+        */
+       if (IS_ENABLED(CONFIG_HIGHMEM))
+               panic("IOC and HIGHMEM can't be used simultaneously");
+
        /* Flush + invalidate + disable L1 dcache */
        __dc_disable();
 
@@ -1264,11 +1268,7 @@ void __init arc_cache_init_master(void)
        if (is_isa_arcv2() && ioc_enable)
                arc_ioc_setup();
 
-       if (is_isa_arcv2() && ioc_enable) {
-               __dma_cache_wback_inv = __dma_cache_wback_inv_ioc;
-               __dma_cache_inv = __dma_cache_inv_ioc;
-               __dma_cache_wback = __dma_cache_wback_ioc;
-       } else if (is_isa_arcv2() && l2_line_sz && slc_enable) {
+       if (is_isa_arcv2() && l2_line_sz && slc_enable) {
                __dma_cache_wback_inv = __dma_cache_wback_inv_slc;
                __dma_cache_inv = __dma_cache_inv_slc;
                __dma_cache_wback = __dma_cache_wback_slc;
@@ -1277,6 +1277,12 @@ void __init arc_cache_init_master(void)
                __dma_cache_inv = __dma_cache_inv_l1;
                __dma_cache_wback = __dma_cache_wback_l1;
        }
+       /*
+        * In case of IOC (say IOC+SLC case), pointers above could still be set
+        * but end up not being relevant as the first function in chain is not
+        * called at all for @dma_direct_ops
+        *     arch_sync_dma_for_cpu() -> dma_cache_*() -> __dma_cache_*()
+        */
 }
 
 void __ref arc_cache_init(void)
index ec47e6079f5d08371a65ea21277b2985bec989d5..c75d5c3470e3595ce7af09f00346d5f82fc92a4c 100644 (file)
@@ -6,20 +6,17 @@
  * published by the Free Software Foundation.
  */
 
-/*
- * DMA Coherent API Notes
- *
- * I/O is inherently non-coherent on ARC. So a coherent DMA buffer is
- * implemented by accessing it using a kernel virtual address, with
- * Cache bit off in the TLB entry.
- *
- * The default DMA address == Phy address which is 0x8000_0000 based.
- */
-
 #include <linux/dma-noncoherent.h>
 #include <asm/cache.h>
 #include <asm/cacheflush.h>
 
+/*
+ * ARCH specific callbacks for generic noncoherent DMA ops (dma/noncoherent.c)
+ *  - hardware IOC not available (or "dma-coherent" not set for device in DT)
+ *  - But still handle both coherent and non-coherent requests from caller
+ *
+ * For DMA coherent hardware (IOC) generic code suffices
+ */
 void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
                gfp_t gfp, unsigned long attrs)
 {
@@ -27,42 +24,29 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
        struct page *page;
        phys_addr_t paddr;
        void *kvaddr;
-       int need_coh = 1, need_kvaddr = 0;
-
-       page = alloc_pages(gfp, order);
-       if (!page)
-               return NULL;
+       bool need_coh = !(attrs & DMA_ATTR_NON_CONSISTENT);
 
        /*
-        * IOC relies on all data (even coherent DMA data) being in cache
-        * Thus allocate normal cached memory
-        *
-        * The gains with IOC are two pronged:
-        *   -For streaming data, elides need for cache maintenance, saving
-        *    cycles in flush code, and bus bandwidth as all the lines of a
-        *    buffer need to be flushed out to memory
-        *   -For coherent data, Read/Write to buffers terminate early in cache
-        *   (vs. always going to memory - thus are faster)
+        * __GFP_HIGHMEM flag is cleared by upper layer functions
+        * (in include/linux/dma-mapping.h) so we should never get a
+        * __GFP_HIGHMEM here.
         */
-       if ((is_isa_arcv2() && ioc_enable) ||
-           (attrs & DMA_ATTR_NON_CONSISTENT))
-               need_coh = 0;
+       BUG_ON(gfp & __GFP_HIGHMEM);
 
-       /*
-        * - A coherent buffer needs MMU mapping to enforce non-cachability
-        * - A highmem page needs a virtual handle (hence MMU mapping)
-        *   independent of cachability
-        */
-       if (PageHighMem(page) || need_coh)
-               need_kvaddr = 1;
+       page = alloc_pages(gfp, order);
+       if (!page)
+               return NULL;
 
        /* This is linear addr (0x8000_0000 based) */
        paddr = page_to_phys(page);
 
        *dma_handle = paddr;
 
-       /* This is kernel Virtual address (0x7000_0000 based) */
-       if (need_kvaddr) {
+       /*
+        * A coherent buffer needs MMU mapping to enforce non-cachability.
+        * kvaddr is kernel Virtual address (0x7000_0000 based).
+        */
+       if (need_coh) {
                kvaddr = ioremap_nocache(paddr, size);
                if (kvaddr == NULL) {
                        __free_pages(page, order);
@@ -93,12 +77,8 @@ void arch_dma_free(struct device *dev, size_t size, void *vaddr,
 {
        phys_addr_t paddr = dma_handle;
        struct page *page = virt_to_page(paddr);
-       int is_non_coh = 1;
-
-       is_non_coh = (attrs & DMA_ATTR_NON_CONSISTENT) ||
-                       (is_isa_arcv2() && ioc_enable);
 
-       if (PageHighMem(page) || !is_non_coh)
+       if (!(attrs & DMA_ATTR_NON_CONSISTENT))
                iounmap((void __force __iomem *)vaddr);
 
        __free_pages(page, get_order(size));
@@ -185,3 +165,23 @@ void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
                break;
        }
 }
+
+/*
+ * Plug in coherent or noncoherent dma ops
+ */
+void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+                       const struct iommu_ops *iommu, bool coherent)
+{
+       /*
+        * IOC hardware snoops all DMA traffic keeping the caches consistent
+        * with memory - eliding need for any explicit cache maintenance of
+        * DMA buffers - so we can use dma_direct cache ops.
+        */
+       if (is_isa_arcv2() && ioc_enable && coherent) {
+               set_dma_ops(dev, &dma_direct_ops);
+               dev_info(dev, "use dma_direct_ops cache ops\n");
+       } else {
+               set_dma_ops(dev, &dma_noncoherent_ops);
+               dev_info(dev, "use dma_noncoherent_ops cache ops\n");
+       }
+}
index f69613fd4e6878f9ce8d35b4fa14d49621fe7d1b..e8cd55a5b04c0570a4ed66b522446b8eee4d202d 100644 (file)
@@ -603,13 +603,16 @@ config ARCH_S3C24XX
 config ARCH_DAVINCI
        bool "TI DaVinci"
        select ARCH_HAS_HOLES_MEMORYMODEL
-       select CLKDEV_LOOKUP
+       select COMMON_CLK
        select CPU_ARM926T
        select GENERIC_ALLOCATOR
        select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_CHIP
        select GPIOLIB
        select HAVE_IDE
+       select PM_GENERIC_DOMAINS if PM
+       select PM_GENERIC_DOMAINS_OF if PM && OF
+       select RESET_CONTROLLER
        select USE_OF
        select ZONE_DMA
        help
index b48dc083d1b15ce052ecadad082dc5b33bbf30bf..f6fcb8a7988902cdbc34b5fcbbec1e36e2116abf 100644 (file)
@@ -204,6 +204,14 @@ choice
                depends on ARCH_BCM_HR2
                select DEBUG_UART_8250
 
+       config DEBUG_BCM_IPROC_UART3
+               bool "Kernel low-level debugging on BCM IPROC UART3"
+               depends on ARCH_BCM_CYGNUS
+               select DEBUG_UART_8250
+               help
+                 Say Y here if you want the debug print routines to direct
+                 their output to the third serial port on these devices.
+
        config DEBUG_BCM_KONA_UART
                bool "Kernel low-level debugging messages via BCM KONA UART"
                depends on ARCH_BCM_MOBILE
@@ -1562,14 +1570,15 @@ config DEBUG_UART_PHYS
        default 0x18000400 if DEBUG_BCM_HR2
        default 0x18010000 if DEBUG_SIRFATLAS7_UART0
        default 0x18020000 if DEBUG_SIRFATLAS7_UART1
+       default 0x18023000 if DEBUG_BCM_IPROC_UART3
        default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1
        default 0x20001000 if DEBUG_HIP01_UART
        default 0x20060000 if DEBUG_RK29_UART0
        default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
        default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
        default 0x20201000 if DEBUG_BCM2835
-       default 0x3f201000 if DEBUG_BCM2836
        default 0x3e000000 if DEBUG_BCM_KONA_UART
+       default 0x3f201000 if DEBUG_BCM2836
        default 0x4000e400 if DEBUG_LL_UART_EFM32
        default 0x40028000 if DEBUG_AT91_SAMV7_USART1
        default 0x40081000 if DEBUG_LPC18XX_UART0
@@ -1682,6 +1691,7 @@ config DEBUG_UART_VIRT
        default 0xf1002000 if DEBUG_MT8127_UART0
        default 0xf1006000 if DEBUG_MT6589_UART0
        default 0xf1009000 if DEBUG_MT8135_UART3
+       default 0xf1023000 if DEBUG_BCM_IPROC_UART3
        default 0xf11f1000 if DEBUG_VERSATILE
        default 0xf1600000 if DEBUG_INTEGRATOR
        default 0xf1c28000 if DEBUG_SUNXI_UART0
@@ -1797,7 +1807,7 @@ config DEBUG_UART_8250_WORD
                DEBUG_KEYSTONE_UART0 || DEBUG_KEYSTONE_UART1 || \
                DEBUG_ALPINE_UART0 || \
                DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \
-               DEBUG_DAVINCI_DA8XX_UART2 || \
+               DEBUG_DAVINCI_DA8XX_UART2 || DEBUG_BCM_IPROC_UART3 || \
                DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2
 
 config DEBUG_UART_8250_PALMCHIP
index e7d703d8fac3af887a3914a6b7c29d732582ae51..d1516f85f25d3500c402e315b6f35c60bde2d253 100644 (file)
@@ -43,12 +43,12 @@ ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
 KBUILD_CPPFLAGS        += -mbig-endian
 CHECKFLAGS     += -D__ARMEB__
 AS             += -EB
-LDFLAGS                += -EB
+KBUILD_LDFLAGS += -EB
 else
 KBUILD_CPPFLAGS        += -mlittle-endian
 CHECKFLAGS     += -D__ARMEL__
 AS             += -EL
-LDFLAGS                += -EL
+KBUILD_LDFLAGS += -EL
 endif
 
 #
@@ -219,7 +219,6 @@ machine-$(CONFIG_ARCH_TANGO)                += tango
 machine-$(CONFIG_ARCH_TEGRA)           += tegra
 machine-$(CONFIG_ARCH_U300)            += u300
 machine-$(CONFIG_ARCH_U8500)           += ux500
-machine-$(CONFIG_ARCH_UNIPHIER)                += uniphier
 machine-$(CONFIG_ARCH_VERSATILE)       += versatile
 machine-$(CONFIG_ARCH_VEXPRESS)                += vexpress
 machine-$(CONFIG_ARCH_VT8500)          += vt8500
index 37a3de760d40f4f27ad4cdbad5ff41973bdda75c..b5bd3de87c331ed9f7e85d43767c46c3831dfbcc 100644 (file)
@@ -38,6 +38,7 @@ dtb-$(CONFIG_SOC_AT91SAM9) += \
        at91-ariettag25.dtb \
        at91-cosino_mega2560.dtb \
        at91-kizboxmini.dtb \
+       at91-wb45n.dtb \
        at91sam9g15ek.dtb \
        at91sam9g25ek.dtb \
        at91sam9g35ek.dtb \
@@ -50,7 +51,10 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
        at91-sama5d2_ptc_ek.dtb \
        at91-sama5d2_xplained.dtb \
        at91-sama5d3_xplained.dtb \
+       at91-dvk_som60.dtb \
+       at91-gatwick.dtb \
        at91-tse850-3.dtb \
+       at91-wb50n.dtb \
        sama5d31ek.dtb \
        sama5d33ek.dtb \
        sama5d34ek.dtb \
@@ -73,6 +77,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
        bcm2835-rpi-b-rev2.dtb \
        bcm2835-rpi-b-plus.dtb \
        bcm2835-rpi-a-plus.dtb \
+       bcm2835-rpi-cm1-io1.dtb \
        bcm2836-rpi-2-b.dtb \
        bcm2837-rpi-3-b.dtb \
        bcm2837-rpi-3-b-plus.dtb \
@@ -200,6 +205,7 @@ dtb-$(CONFIG_ARCH_GEMINI) += \
        gemini-dlink-dns-313.dtb \
        gemini-nas4220b.dtb \
        gemini-rut1xx.dtb \
+       gemini-sl93512r.dtb \
        gemini-sq201.dtb \
        gemini-wbd111.dtb \
        gemini-wbd222.dtb
@@ -345,7 +351,8 @@ dtb-$(CONFIG_SOC_IMX27) += \
        imx27-phytec-phycore-rdk.dtb \
        imx27-phytec-phycard-s-rdk.dtb
 dtb-$(CONFIG_SOC_IMX31) += \
-       imx31-bug.dtb
+       imx31-bug.dtb \
+       imx31-lite.dtb
 dtb-$(CONFIG_SOC_IMX35) += \
        imx35-eukrea-mbimxsd35-baseboard.dtb \
        imx35-pdk.dtb
@@ -358,10 +365,14 @@ dtb-$(CONFIG_SOC_IMX51) += \
        imx51-digi-connectcore-jsk.dtb \
        imx51-eukrea-mbimxsd51-baseboard.dtb \
        imx51-ts4800.dtb \
-       imx51-zii-rdu1.dtb
+       imx51-zii-rdu1.dtb \
+       imx51-zii-scu2-mezz.dtb \
+       imx51-zii-scu3-esb.dtb
 dtb-$(CONFIG_SOC_IMX53) += \
        imx53-ard.dtb \
        imx53-cx9020.dtb \
+       imx53-kp-ddc.dtb \
+       imx53-kp-hsc.dtb \
        imx53-m53evk.dtb \
        imx53-mba53.dtb \
        imx53-ppd.dtb \
@@ -400,6 +411,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
        imx6dl-hummingboard2-emmc-som-v15.dtb \
        imx6dl-hummingboard2-som-v15.dtb \
        imx6dl-icore.dtb \
+       imx6dl-icore-mipi.dtb \
        imx6dl-icore-rqs.dtb \
        imx6dl-mamoj.dtb \
        imx6dl-nit6xlite.dtb \
@@ -521,6 +533,8 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
 dtb-$(CONFIG_SOC_IMX6SL) += \
        imx6sl-evk.dtb \
        imx6sl-warp.dtb
+dtb-$(CONFIG_SOC_IMX6SLL) += \
+       imx6sll-evk.dtb
 dtb-$(CONFIG_SOC_IMX6SX) += \
        imx6sx-nitrogen6sx.dtb \
        imx6sx-sabreauto.dtb \
@@ -533,6 +547,7 @@ dtb-$(CONFIG_SOC_IMX6SX) += \
        imx6sx-udoo-neo-full.dtb
 dtb-$(CONFIG_SOC_IMX6UL) += \
        imx6ul-14x14-evk.dtb \
+       imx6ul-ccimx6ulsbcexpress.dtb \
        imx6ul-geam.dtb \
        imx6ul-isiot-emmc.dtb \
        imx6ul-isiot-nand.dtb \
@@ -567,8 +582,10 @@ dtb-$(CONFIG_SOC_VF610) += \
        vf610-cosmic.dtb \
        vf610m4-cosmic.dtb \
        vf610-twr.dtb \
+       vf610-zii-cfu1.dtb \
        vf610-zii-dev-rev-b.dtb \
-       vf610-zii-dev-rev-c.dtb
+       vf610-zii-dev-rev-c.dtb \
+       vf610-zii-ssmb-spu3.dtb
 dtb-$(CONFIG_ARCH_MXS) += \
        imx23-evk.dtb \
        imx23-olinuxino.dtb \
@@ -695,10 +712,12 @@ dtb-$(CONFIG_SOC_AM33XX) += \
        am335x-pepper.dtb \
        am335x-phycore-rdk.dtb \
        am335x-pocketbeagle.dtb \
+       am335x-sancloud-bbe.dtb \
        am335x-shc.dtb \
        am335x-sbc-t335.dtb \
        am335x-sl50.dtb \
-       am335x-wega-rdk.dtb
+       am335x-wega-rdk.dtb \
+       am335x-osd3358-sm-red.dtb
 dtb-$(CONFIG_ARCH_OMAP4) += \
        omap4-droid4-xt894.dtb \
        omap4-duovero-parlor.dtb \
@@ -819,6 +838,7 @@ dtb-$(CONFIG_ARCH_RENESAS) += \
        r8a7793-gose.dtb \
        r8a7794-alt.dtb \
        r8a7794-silk.dtb \
+       r9a06g032-rzn1d400-db.dtb \
        sh73a0-kzm9g.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += \
        rv1108-evb.dtb \
@@ -859,6 +879,8 @@ dtb-$(CONFIG_ARCH_S3C64XX) += \
        s3c6410-smdk6410.dtb
 dtb-$(CONFIG_ARCH_S5PV210) += \
        s5pv210-aquila.dtb \
+       s5pv210-fascinate4g.dtb \
+       s5pv210-galaxys.dtb \
        s5pv210-goni.dtb \
        s5pv210-smdkc110.dtb \
        s5pv210-smdkv210.dtb \
@@ -1039,7 +1061,7 @@ dtb-$(CONFIG_ARCH_TANGO) += \
        tango4-vantage-1172.dtb
 dtb-$(CONFIG_ARCH_TEGRA_2x_SOC) += \
        tegra20-harmony.dtb \
-       tegra20-iris-512.dtb \
+       tegra20-colibri-iris.dtb \
        tegra20-medcom-wide.dtb \
        tegra20-paz00.dtb \
        tegra20-plutux.dtb \
@@ -1109,6 +1131,7 @@ dtb-$(CONFIG_ARCH_ZYNQ) += \
        zynq-zc770-xm012.dtb \
        zynq-zc770-xm013.dtb \
        zynq-zed.dtb \
+       zynq-zturn.dtb \
        zynq-zybo.dtb \
        zynq-zybo-z7.dtb
 dtb-$(CONFIG_MACH_ARMADA_370) += \
@@ -1138,6 +1161,7 @@ dtb-$(CONFIG_MACH_ARMADA_38X) += \
        armada-388-clearfog-pro.dtb \
        armada-388-db.dtb \
        armada-388-gp.dtb \
+       armada-388-helios4.dtb \
        armada-388-rd.dtb
 dtb-$(CONFIG_MACH_ARMADA_39X) += \
        armada-398-db.dtb
@@ -1168,7 +1192,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
        mt7623a-rfb-emmc.dtb \
        mt7623a-rfb-nand.dtb \
        mt7623n-rfb-emmc.dtb \
-       mt7623n-rfb-nand.dtb \
        mt7623n-bananapi-bpi-r2.dtb \
        mt8127-moose.dtb \
        mt8135-evbp1.dtb
index ed7a5a3daa423cf6c935a2c25d56845949e0d9fd..8c6fc4161ad701d09e99612559a6b04a94ea6a83 100644 (file)
                compatible = "ti,wl1835";
                reg = <2>;
                interrupt-parent = <&gpio3>;
-               interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <7 IRQ_TYPE_EDGE_RISING>;
        };
 };
 
index 1356fd6f8da3f8d4b8643ab2686dc0c6181a4f52..c87d01297a013b60b8752594b13b89392ce95e7a 100644 (file)
                compatible = "ti,wl1835";
                reg = <2>;
                interrupt-parent = <&gpio3>;
-               interrupts = <17 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <17 IRQ_TYPE_EDGE_RISING>;
        };
 };
 
index 0c096a795e3703651ec8127042610186a121f487..bf1a40e45c97b1b3a0cbbfa6ea583509f4e5bb8a 100644 (file)
                compatible = "ti,wl1271";
                reg = <2>;
                interrupt-parent = <&gpio0>;
-               interrupts = <31 IRQ_TYPE_LEVEL_HIGH>; /* gpio 31 */
+               interrupts = <31 IRQ_TYPE_EDGE_RISING>; /* gpio 31 */
                ref-clock-frequency = <38400000>;
        };
 };
diff --git a/arch/arm/boot/dts/am335x-osd3358-sm-red.dts b/arch/arm/boot/dts/am335x-osd3358-sm-red.dts
new file mode 100644 (file)
index 0000000..4d96901
--- /dev/null
@@ -0,0 +1,457 @@
+//SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2018 Octavo Systems LLC - http://www.octavosystems.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 "am33xx.dtsi"
+#include "am335x-osd335x-common.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include <dt-bindings/display/tda998x.h>
+
+/ {
+       model = "Octavo Systems OSD3358-SM-RED";
+       compatible = "oct,osd3358-sm-refdesign", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
+};
+
+&ldo3_reg {
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <1800000>;
+       regulator-always-on;
+};
+
+&mmc1 {
+       vmmc-supply = <&vmmcsd_fixed>;
+};
+
+&mmc2 {
+       vmmc-supply = <&vmmcsd_fixed>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&emmc_pins>;
+       bus-width = <8>;
+       status = "okay";
+};
+
+&am33xx_pinmux {
+       nxp_hdmi_bonelt_pins: nxp-hdmi-bonelt-pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3)    /* xdma_event_intr0 */
+                       AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0)             /* lcd_data0.lcd_data0 */
+                       AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0)             /* lcd_data1.lcd_data1 */
+                       AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0)             /* lcd_data2.lcd_data2 */
+                       AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0)             /* lcd_data3.lcd_data3 */
+                       AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0)             /* lcd_data4.lcd_data4 */
+                       AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0)             /* lcd_data5.lcd_data5 */
+                       AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0)             /* lcd_data6.lcd_data6 */
+                       AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0)             /* lcd_data7.lcd_data7 */
+                       AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0)             /* lcd_data8.lcd_data8 */
+                       AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0)             /* lcd_data9.lcd_data9 */
+                       AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0)             /* lcd_data10.lcd_data10 */
+                       AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0)             /* lcd_data11.lcd_data11 */
+                       AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0)             /* lcd_data12.lcd_data12 */
+                       AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0)             /* lcd_data13.lcd_data13 */
+                       AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0)             /* lcd_data14.lcd_data14 */
+                       AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0)             /* lcd_data15.lcd_data15 */
+                       AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* lcd_vsync.lcd_vsync */
+                       AM33XX_IOPAD(0x8e4, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* lcd_hsync.lcd_hsync */
+                       AM33XX_IOPAD(0x8e8, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* lcd_pclk.lcd_pclk */
+                       AM33XX_IOPAD(0x8ec, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* lcd_ac_bias_en.lcd_ac_bias_en */
+               >;
+       };
+
+       nxp_hdmi_bonelt_off_pins: nxp-hdmi-bonelt-off-pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3)    /* xdma_event_intr0 */
+               >;
+       };
+
+       mcasp0_pins: mcasp0-pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLUP | MUX_MODE0) /* mcasp0_ahcklx.mcasp0_ahclkx */
+                       AM33XX_IOPAD(0x99c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2*/
+                       AM33XX_IOPAD(0x994, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */
+                       AM33XX_IOPAD(0x990, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */
+                       AM33XX_IOPAD(0x86c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.GPIO1_27 */
+               >;
+       };
+
+       flash_enable: flash-enable {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x944, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* rmii1_ref_clk.gpio0_29 */
+               >;
+       };
+
+       imu_interrupt: imu-interrupt {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)             /* mii1_rx_er.gpio3_2 */
+               >;
+       };
+
+       ethernet_interrupt: ethernet-interrupt{
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE7)             /* mii1_col.gpio3_0 */
+               >;
+       };
+};
+
+&lcdc {
+       status = "okay";
+
+       /* If you want to get 24 bit RGB and 16 BGR mode instead of
+        * current 16 bit RGB and 24 BGR modes, set the propety
+        * below to "crossed" and uncomment the video-ports -property
+        * in tda19988 node.
+        * AM335x errata for wiring:
+        * http://www.ti.com/lit/er/sprz360i/sprz360i.pdf
+        */
+
+       blue-and-red-wiring = "straight";
+
+       port {
+               lcdc_0: endpoint {
+                       remote-endpoint = <&hdmi_0>;
+               };
+       };
+};
+
+&i2c0 {
+       tda19988: hdmi-encoder@70 {
+               compatible = "nxp,tda998x";
+               reg = <0x70>;
+
+               pinctrl-names = "default", "off";
+               pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
+               pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
+
+               /* Convert 24bit BGR to RGB, e.g. cross red and blue wiring */
+               /* video-ports = <0x234501>; */
+
+               #sound-dai-cells = <0>;
+               audio-ports = < TDA998x_I2S     0x03>;
+
+               port {
+                       hdmi_0: endpoint {
+                               remote-endpoint = <&lcdc_0>;
+                       };
+               };
+       };
+
+       mpu9250: imu@68 {
+               compatible = "invensense,mpu6050";
+               reg = <0x68>;
+               interrupt-parent = <&gpio3>;
+               interrupts = <21 IRQ_TYPE_EDGE_RISING>;
+               i2c-gate {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ax8975@c {
+                               compatible = "ak,ak8975";
+                               reg = <0x0c>;
+                       };
+               };
+               /*invensense,int_config = <0x10>;
+               invensense,level_shifter = <0>;
+               invensense,orientation = [01 00 00 00 01 00 00 00 01];
+               invensense,sec_slave_type = <0>;
+               invensense,key = [4e cc 7e eb f6 1e 35 22 00 34 0d 65 32 e9 94 89];*/
+       };
+
+       bmp280: pressure@78 {
+               compatible = "bosch,bmp280";
+               reg = <0x76>;
+       };
+};
+
+&rtc {
+       system-power-controller;
+};
+
+&mcasp0 {
+       #sound-dai-cells = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcasp0_pins>;
+       status = "okay";
+       op-mode = <0>;  /* MCASP_IIS_MODE */
+       tdm-slots = <2>;
+       serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
+                       0 0 1 0
+               >;
+       tx-num-evt = <32>;
+       rx-num-evt = <32>;
+};
+
+/ {
+       clk_mcasp0_fixed: clk-mcasp0-fixed {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <24576000>;
+       };
+
+       clk_mcasp0: clk-mcasp0 {
+               #clock-cells = <0>;
+               compatible = "gpio-gate-clock";
+               clocks = <&clk_mcasp0_fixed>;
+               enable-gpios = <&gpio1 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */
+       };
+
+       sound {
+               compatible = "simple-audio-card";
+               simple-audio-card,name = "TI BeagleBone Black";
+               simple-audio-card,format = "i2s";
+               simple-audio-card,bitclock-master = <&dailink0_master>;
+               simple-audio-card,frame-master = <&dailink0_master>;
+
+               dailink0_master: simple-audio-card,cpu {
+                       sound-dai = <&mcasp0>;
+                       clocks = <&clk_mcasp0>;
+               };
+
+               simple-audio-card,codec {
+                       sound-dai = <&tda19988>;
+               };
+       };
+
+       chosen {
+               stdout-path = &uart0;
+       };
+
+       leds {
+               pinctrl-names = "default";
+               pinctrl-0 = <&user_leds_s0>;
+
+               compatible = "gpio-leds";
+
+               led2 {
+                       label = "beaglebone:green:usr0";
+                       gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+                       default-state = "off";
+               };
+
+               led3 {
+                       label = "beaglebone:green:usr1";
+                       gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "mmc0";
+                       default-state = "off";
+               };
+
+               led4 {
+                       label = "beaglebone:green:usr2";
+                       gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "cpu0";
+                       default-state = "off";
+               };
+
+               led5 {
+                       label = "beaglebone:green:usr3";
+                       gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "mmc1";
+                       default-state = "off";
+               };
+       };
+
+       vmmcsd_fixed: fixedregulator0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vmmcsd_fixed";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+};
+
+&am33xx_pinmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&clkout2_pin>;
+
+       user_leds_s0: user-leds-s0 {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpmc_a5.gpio1_21 */
+                       AM33XX_IOPAD(0x858, PIN_OUTPUT_PULLUP | MUX_MODE7)      /* gpmc_a6.gpio1_22 */
+                       AM33XX_IOPAD(0x85c, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpmc_a7.gpio1_23 */
+                       AM33XX_IOPAD(0x860, PIN_OUTPUT_PULLUP | MUX_MODE7)      /* gpmc_a8.gpio1_24 */
+               >;
+       };
+
+       i2c2_pins: pinmux-i2c2-pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x978, PIN_INPUT_PULLUP | MUX_MODE3)       /* uart1_ctsn.i2c2_sda */
+                       AM33XX_IOPAD(0x97c, PIN_INPUT_PULLUP | MUX_MODE3)       /* uart1_rtsn.i2c2_scl */
+               >;
+       };
+
+       uart0_pins: pinmux-uart0-pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)       /* uart0_rxd.uart0_rxd */
+                       AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* uart0_txd.uart0_txd */
+               >;
+       };
+
+       clkout2_pin: pinmux-clkout2-pin {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x9b4, PIN_OUTPUT_PULLDOWN | MUX_MODE3)    /* xdma_event_intr1.clkout2 */
+               >;
+       };
+
+       cpsw_default: cpsw-default {
+               pinctrl-single,pins = <
+                       /* Slave 1 */
+                       AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txen.rgmii1_tctl */
+                       AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE2)             /* mii1_rxdv.rgmii1_rctl */
+                       AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd3.rgmii1_txd3 */
+                       AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd2.rgmii1_txd2 */
+                       AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd1.rgmii1_txd1 */
+                       AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd0.rgmii1_txd0 */
+                       AM33XX_IOPAD(0x92c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txclk.rgmii1_txclk */
+                       AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE2)             /* mii1_rxclk.rgmii1_rxclk */
+                       AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE2)             /* mii1_rxd3.rgmii1_rxd3 */
+                       AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE2)             /* mii1_rxd2.rgmii1_rxd2 */
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE2)             /* mii1_rxd1.rgmii1_rxd1 */
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE2)             /* mii1_rxd0.rgmii1_rxd0 */
+               >;
+       };
+
+       cpsw_sleep: cpsw-sleep {
+               pinctrl-single,pins = <
+                       /* Slave 1 reset value */
+                       AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
+
+       davinci_mdio_default: davinci-mdio-default {
+               pinctrl-single,pins = <
+                       /* MDIO */
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* mdio_data.mdio_data */
+                       AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)                      /* mdio_clk.mdio_clk */
+               >;
+       };
+
+       davinci_mdio_sleep: davinci-mdio-sleep {
+               pinctrl-single,pins = <
+                       /* MDIO reset value */
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
+
+       mmc1_pins: pinmux-mmc1-pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* (C15) spi0_cs1.gpio0[6] */
+                       AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0) /* (G16) mmc0_dat0.mmc0_dat0 */
+                       AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0) /* (G15) mmc0_dat1.mmc0_dat1 */
+                       AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0) /* (F18) mmc0_dat2.mmc0_dat2 */
+                       AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0) /* (F17) mmc0_dat3.mmc0_dat3 */
+                       AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0) /* (G18) mmc0_cmd.mmc0_cmd */
+                       AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0) /* (G17) mmc0_clk.mmc0_clk */
+               >;
+       };
+
+       emmc_pins: pinmux-emmc-pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+                       AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+                       AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+                       AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+                       AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+                       AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+                       AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
+                       AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
+                       AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
+                       AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
+               >;
+       };
+};
+
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins>;
+
+       status = "okay";
+};
+
+&usb {
+       status = "okay";
+};
+
+&usb_ctrl_mod {
+       status = "okay";
+};
+
+&usb0_phy {
+       status = "okay";
+};
+
+&usb1_phy {
+       status = "okay";
+};
+
+&usb0 {
+       status = "okay";
+       dr_mode = "peripheral";
+       interrupts-extended = <&intc 18 &tps 0>;
+       interrupt-names = "mc", "vbus";
+};
+
+&usb1 {
+       status = "okay";
+       dr_mode = "host";
+};
+
+&cppi41dma  {
+       status = "okay";
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_pins>;
+       status = "okay";
+       clock-frequency = <100000>;
+};
+
+&cpsw_emac0 {
+       phy_id = <&davinci_mdio>, <4>;
+       phy-mode = "rgmii-txid";
+};
+
+&mac {
+       slaves = <1>;
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&cpsw_default>;
+       pinctrl-1 = <&cpsw_sleep>;
+       status = "okay";
+};
+
+&davinci_mdio {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&davinci_mdio_default>;
+       pinctrl-1 = <&davinci_mdio_sleep>;
+       status = "okay";
+};
+
+&mmc1 {
+       status = "okay";
+       bus-width = <0x4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
+};
+
+&rtc {
+       clocks = <&clk_32768_ck>, <&l4_per_clkctrl AM3_CLKDIV32K_CLKCTRL 0>;
+       clock-names = "ext-clk", "int-clk";
+};
diff --git a/arch/arm/boot/dts/am335x-sancloud-bbe.dts b/arch/arm/boot/dts/am335x-sancloud-bbe.dts
new file mode 100644 (file)
index 0000000..7b8e741
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include "am335x-bone-common.dtsi"
+#include "am335x-boneblack-common.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       model = "SanCloud BeagleBone Enhanced";
+       compatible = "sancloud,am335x-boneenhanced", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
+};
+
+&am33xx_pinmux {
+       pinctrl-names = "default";
+
+       cpsw_default: cpsw_default {
+               pinctrl-single,pins = <
+                       /* Slave 1 */
+                       AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txen.rgmii1_tctl */
+                       AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxdv.rgmii1_rctl */
+                       AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd3.rgmii1_td3 */
+                       AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd2.rgmii1_td2 */
+                       AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd1.rgmii1_td1 */
+                       AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txd0.rgmii1_td0 */
+                       AM33XX_IOPAD(0x92c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mii1_txclk.rgmii1_tclk */
+                       AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxclk.rgmii1_rclk */
+                       AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd3.rgmii1_rd3 */
+                       AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd2.rgmii1_rd2 */
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd1.rgmii1_rd1 */
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE2)     /* mii1_rxd0.rgmii1_rd0 */
+               >;
+       };
+
+       cpsw_sleep: cpsw_sleep {
+               pinctrl-single,pins = <
+                       /* Slave 1 reset value */
+                       AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
+
+       davinci_mdio_default: davinci_mdio_default {
+               pinctrl-single,pins = <
+                       /* MDIO */
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* mdio_data.mdio_data */
+                       AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)                      /* mdio_clk.mdio_clk */
+               >;
+       };
+
+       davinci_mdio_sleep: davinci_mdio_sleep {
+               pinctrl-single,pins = <
+                       /* MDIO reset value */
+                       AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+                       AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+               >;
+       };
+
+       usb_hub_ctrl: usb_hub_ctrl {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x944, PIN_OUTPUT_PULLUP | MUX_MODE7)     /* rmii1_refclk.gpio0_29 */
+               >;
+       };
+
+       mpu6050_pins: pinmux_mpu6050_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x968, PIN_INPUT | MUX_MODE7)    /* uart0_ctsn.gpio1_8 */
+               >;
+       };
+
+       lps3331ap_pins: pinmux_lps3331ap_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x868, PIN_INPUT | MUX_MODE7)     /* gpmc_a10.gpio1_26 */
+               >;
+       };
+};
+
+&mac {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&cpsw_default>;
+       pinctrl-1 = <&cpsw_sleep>;
+       status = "okay";
+};
+
+&davinci_mdio {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&davinci_mdio_default>;
+       pinctrl-1 = <&davinci_mdio_sleep>;
+       status = "okay";
+};
+
+&cpsw_emac0 {
+       phy_id = <&davinci_mdio>, <0>;
+       phy-mode = "rgmii-txid";
+};
+
+&i2c0 {
+       lps331ap: barometer@5c {
+               compatible = "st,lps331ap-press";
+               st,drdy-int-pin = <1>;
+               reg = <0x5c>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <26 IRQ_TYPE_EDGE_RISING>;
+       };
+
+       mpu6050: accelerometer@68 {
+               compatible = "invensense,mpu6050";
+               reg = <0x68>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <2 IRQ_TYPE_EDGE_RISING>;
+               orientation = <0xff 0 0 0 1 0 0 0 0xff>;
+       };
+
+       usb2512b: usb-hub@2c {
+               compatible = "microchip,usb2512b";
+               reg = <0x2c>;
+               reset-gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
+               /* wifi on port 4 */
+       };
+};
index 1bcc60424ecd1eeb7134e7eb973dfc64f3bb9edf..38d57b89f7d39a504644714735b46080ef990daf 100644 (file)
@@ -8,6 +8,8 @@
 /dts-v1/;
 
 #include "am33xx.dtsi"
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
        model = "Toby Churchill SL50 Series";
                pinctrl-0 = <&led_pins>;
 
                led0 {
-                       label = "sl50:green:usr0";
+                       label = "sl50:red:usr0";
                        gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
                        default-state = "off";
                };
 
                led1 {
-                       label = "sl50:red:usr1";
+                       label = "sl50:green:usr1";
                        gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
                        default-state = "off";
                };
 
                led2 {
-                       label = "sl50:green:usr2";
+                       label = "sl50:red:usr2";
                        gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
                        default-state = "off";
                };
 
                led3 {
-                       label = "sl50:red:usr3";
+                       label = "sl50:green:usr3";
                        gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;
                        default-state = "off";
                };
 
        backlight0: disp0 {
                compatible = "pwm-backlight";
-               pwms = <&ehrpwm1 0 500000 0>;
-               brightness-levels = <0 10 20 30 40 50 60 70 80 90 99>;
-               default-brightness-level = <6>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&backlight0_pins>;
+               pwms = <&ehrpwm1 0 500000 PWM_POLARITY_INVERTED>;
+               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>;
+               enable-gpios = <&gpio2 4 GPIO_ACTIVE_HIGH>;
+               power-supply = <&vdd_sys_reg>;
        };
 
        backlight1: disp1 {
                compatible = "pwm-backlight";
-               pwms = <&ehrpwm1 1 500000 0>;
-               brightness-levels = <0 10 20 30 40 50 60 70 80 90 99>;
-               default-brightness-level = <6>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&backlight1_pins>;
+               pwms = <&ehrpwm1 1 500000 PWM_POLARITY_INVERTED>;
+               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>;
+               enable-gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
+               power-supply = <&vdd_sys_reg>;
        };
 
        clocks {
                #size-cells = <0>;
 
                /* audio external oscillator */
-               tlv320aic3x_mclk: oscillator@0 {
+               audio_mclk_fixed: oscillator@0 {
                        compatible = "fixed-clock";
                        #clock-cells = <0>;
                        clock-frequency  = <24576000>;  /* 24.576MHz */
                };
+
+               audio_mclk: audio_mclk_gate@0 {
+                       compatible = "gpio-gate-clock";
+                       #clock-cells = <0>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&audio_mclk_pins>;
+                       clocks = <&audio_mclk_fixed>;
+                       enable-gpios = <&gpio1 27 0>;
+               };
+       };
+
+       panel: lcd_panel {
+               compatible = "ti,tilcdc,panel";
+               pinctrl-names = "default";
+               pinctrl-0 = <&lcd_pins>;
+
+               panel-info {
+                       ac-bias = <255>;
+                       ac-bias-intrpt = <0>;
+                       dma-burst-sz = <16>;
+                       bpp = <16>;
+                       fdd = <0x80>;
+                       tft-alt-mode = <0>;
+                       mono-8bit-mode = <0>;
+                       sync-edge = <0>;
+                       sync-ctrl = <1>;
+                       raster-order = <0>;
+                       fifo-th = <0>;
+               };
+
+               display-timings {
+                       native-mode = <&timing0>;
+                       timing0: 960x128 {
+                               clock-frequency = <18000000>;
+                               hactive = <960>;
+                               vactive = <272>;
+
+                               hback-porch = <40>;
+                               hfront-porch = <16>;
+                               hsync-len = <24>;
+                               hsync-active = <0>;
+
+                               vback-porch = <3>;
+                               vfront-porch = <8>;
+                               vsync-len = <4>;
+                               vsync-active = <0>;
+                       };
+               };
        };
 
        sound {
-               compatible = "ti,da830-evm-audio";
-               ti,model = "AM335x-SL50";
-               ti,audio-codec = <&audio_codec>;
-               ti,mcasp-controller = <&mcasp0>;
+               compatible = "audio-graph-card";
+               label = "sound-card";
+               pinctrl-names = "default";
+               pinctrl-0 = <&audio_pa_pins>;
+
+               widgets = "Headphone", "Headphone Jack",
+                         "Speaker", "Speaker External",
+                         "Line", "Line In",
+                         "Microphone", "Microphone Jack";
 
-               clocks = <&tlv320aic3x_mclk>;
-               clock-names = "mclk";
+               routing = "Headphone Jack",     "HPLOUT",
+                         "Headphone Jack",     "HPROUT",
+                         "Amplifier",          "MONO_LOUT",
+                         "Speaker External",   "Amplifier",
+                         "LINE1R",             "Line In",
+                         "LINE1L",             "Line In",
+                         "MIC3L",              "Microphone Jack",
+                         "MIC3R",              "Microphone Jack",
+                         "Microphone Jack",    "Mic Bias";
 
-               ti,audio-routing =
-                       "Headphone Jack",       "HPLOUT",
-                       "Headphone Jack",       "HPROUT",
-                       "LINE1R",               "Line In",
-                       "LINE1L",               "Line In";
+               dais = <&cpu_port>;
+
+               pa-gpios = <&gpio3 18 GPIO_ACTIVE_HIGH>;
        };
 
        emmc_pwrseq: pwrseq@0 {
                reset-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
        };
 
+       vdd_sys_reg: regulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd_sys_reg";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
+
        vmmcsd_fixed: fixedregulator0 {
                compatible = "regulator-fixed";
                regulator-name = "vmmcsd_fixed";
        pinctrl-names = "default";
        pinctrl-0 = <&lwb_pins>;
 
+       audio_pins: pinmux_audio_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_ahcklx.mcasp0_ahclkx */
+                       AM33XX_IOPAD(0x994, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_fsx.mcasp0_fsx */
+                       AM33XX_IOPAD(0x990, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_aclkx.mcasp0_aclkx */
+                       AM33XX_IOPAD(0x998, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_axr0.mcasp0_axr0 */
+                       AM33XX_IOPAD(0x99c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mcasp0_ahclkr.mcasp0_axr2 */
+               >;
+       };
+
+       audio_pa_pins: pinmux_audio_pa_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x9a0, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* SoundPA_en - mcasp0_aclkr.gpio3_18 */
+               >;
+       };
+
+       audio_mclk_pins: pinmux_audio_mclk_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* gpmc_a11.gpio1_27 */
+               >;
+       };
+
+       backlight0_pins: pinmux_backlight0_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE7)     /* gpmc_wen.gpio2_4 */
+               >;
+       };
+
+       backlight1_pins: pinmux_backlight1_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x828, PIN_OUTPUT | MUX_MODE7)     /* gpmc_ad10.gpio0_26 */
+               >;
+       };
+
+       lcd_pins: pinmux_lcd_pins {
+               pinctrl-single,pins = <
+                       AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0)     /* lcd_data0.lcd_data0 */
+                       AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0)     /* lcd_data1.lcd_data1 */
+                       AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0)     /* lcd_data2.lcd_data2 */
+                       AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0)     /* lcd_data3.lcd_data3 */
+                       AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0)     /* lcd_data4.lcd_data4 */
+                       AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0)     /* lcd_data5.lcd_data5 */
+                       AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0)     /* lcd_data6.lcd_data6 */
+                       AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0)     /* lcd_data7.lcd_data7 */
+                       AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0)     /* lcd_data8.lcd_data8 */
+                       AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0)     /* lcd_data9.lcd_data9 */
+                       AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0)     /* lcd_data10.lcd_data10 */
+                       AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0)     /* lcd_data11.lcd_data11 */
+                       AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0)     /* lcd_data12.lcd_data12 */
+                       AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0)     /* lcd_data13.lcd_data13 */
+                       AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0)     /* lcd_data14.lcd_data14 */
+                       AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0)     /* lcd_data15.lcd_data15 */
+                       AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* lcd_vsync.lcd_vsync */
+                       AM33XX_IOPAD(0x8e4, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* lcd_hsync.lcd_hsync */
+                       AM33XX_IOPAD(0x8e8, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* lcd_pclk.lcd_pclk */
+                       AM33XX_IOPAD(0x8ec, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* lcd_ac_bias_en.lcd_ac_bias_en */
+               >;
+       };
+
        led_pins: pinmux_led_pins {
                pinctrl-single,pins = <
                        AM33XX_IOPAD(0x854, PIN_OUTPUT | MUX_MODE7)     /* gpmc_a5.gpio1_21 */
                        /* MDIO */
                        AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)       /* mdio_data.mdio_data */
                        AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)                      /* mdio_clk.mdio_clk */
+                       /* Ethernet */
+                       AM33XX_IOPAD(0x838, PIN_INPUT_PULLUP | MUX_MODE7)       /* Ethernet_nRST - gpmc_ad14.gpio1_14 */
                >;
        };
 
                >;
        };
 
-       audio_pins: pinmux_audio_pins {
+       ehrpwm1_pins: pinmux_ehrpwm1a_pins {
                pinctrl-single,pins = <
-                       AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_ahcklx.mcasp0_ahclkx */
-                       AM33XX_IOPAD(0x994, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_fsx.mcasp0_fsx */
-                       AM33XX_IOPAD(0x990, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_aclkx.mcasp0_aclkx */
-                       AM33XX_IOPAD(0x998, PIN_INPUT_PULLDOWN | MUX_MODE0)     /* mcasp0_axr0.mcasp0_axr0 */
-                       AM33XX_IOPAD(0x99c, PIN_OUTPUT_PULLDOWN | MUX_MODE2)    /* mcasp0_ahclkr.mcasp0_axr2 */
+                       AM33XX_IOPAD(0x848, PIN_OUTPUT | MUX_MODE6)     /* gpmc_a2.ehrpwm1a */
+                       AM33XX_IOPAD(0x84c, PIN_OUTPUT | MUX_MODE6)     /* gpmc_a3.ehrpwm1b */
                >;
        };
 
-       ehrpwm1_pins: pinmux_ehrpwm1a_pins {
+       rtc0_irq_pins: pinmux_rtc0_irq_pins {
                pinctrl-single,pins = <
-                       AM33XX_IOPAD(0x848, PIN_OUTPUT | MUX_MODE6)     /* gpmc_a2.ehrpwm1a */
-                       AM33XX_IOPAD(0x84c, PIN_OUTPUT | MUX_MODE6)     /* gpmc_a3.ehrpwm1b */
+                       AM33XX_IOPAD(0x824, PIN_INPUT_PULLUP | MUX_MODE7)     /* gpmc_ad9.gpio0_23 */
                >;
        };
 
 
        lwb_pins: pinmux_lwb_pins {
                pinctrl-single,pins = <
-                       AM33XX_IOPAD(0x9a4, PIN_OUTPUT | MUX_MODE7)     /* SoundPA_en - mcasp0_fsr.gpio3_19 */
-                       AM33XX_IOPAD(0x828, PIN_OUTPUT | MUX_MODE7)     /* nKbdOnC - gpmc_ad10.gpio0_26 */
                        AM33XX_IOPAD(0x830, PIN_INPUT_PULLUP | MUX_MODE7)       /* nKbdInt - gpmc_ad12.gpio1_12 */
                        AM33XX_IOPAD(0x834, PIN_INPUT_PULLUP | MUX_MODE7)       /* nKbdReset - gpmc_ad13.gpio1_13 */
-                       AM33XX_IOPAD(0x838, PIN_INPUT_PULLUP | MUX_MODE7)       /* nDispReset - gpmc_ad14.gpio1_14 */
                        AM33XX_IOPAD(0x844, PIN_INPUT_PULLUP | MUX_MODE7)       /* USB1_enPower - gpmc_a1.gpio1_17 */
                        /* PDI Bus - Battery system */
                        AM33XX_IOPAD(0x840, PIN_INPUT_PULLUP | MUX_MODE7)       /* nBattReset  gpmc_a0.gpio1_16 */
                        AM33XX_IOPAD(0x83c, PIN_INPUT_PULLUP | MUX_MODE7)       /* BattPDIData gpmc_ad15.gpio1_15 */
+                       /* FPGA */
+                       AM33XX_IOPAD(0x820, PIN_INPUT_PULLUP | MUX_MODE7)       /* FPGA_DONE - gpmc_ad8.gpio0_22 */
+                       AM33XX_IOPAD(0x840, PIN_INPUT_PULLUP | MUX_MODE7)       /* FPGA_NRST - gpmc_a0.gpio1_16 */
+                       AM33XX_IOPAD(0x844, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* FPGA_RUN - gpmc_a1.gpio1_17 */
+                       AM33XX_IOPAD(0x864, PIN_INPUT_PULLUP | MUX_MODE7)       /* ENFPGA - gpmc_a9.gpio1_25 */
+                       AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE7)     /* FPGA_PROGRAM - gpmc_a10.gpio1_26 */
                >;
        };
 };
                reg = <0x24>;
        };
 
-       bq32000: rtc@68 {
-               compatible = "ti,bq32000";
-               trickle-resistor-ohms = <1120>;
+       rtc0: rtc@68 {
+               compatible = "dallas,ds1339";
+               pinctrl-names = "default";
+               pinctrl-0 = <&rtc0_irq_pins>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <23 IRQ_TYPE_EDGE_FALLING>; /* gpio 23 */
+               wakeup-source;
+               trickle-resistor-ohms = <2000>;
                reg = <0x68>;
        };
 
        audio_codec: tlv320aic3106@1b {
                status = "okay";
                compatible = "ti,tlv320aic3106";
+               #sound-dai-cells = <0>;
                reg = <0x1b>;
+               ai3x-micbias-vg = <2>;  /* 2.5V */
 
                AVDD-supply = <&ldo4_reg>;
                IOVDD-supply = <&ldo4_reg>;
                DRVDD-supply = <&ldo4_reg>;
                DVDD-supply = <&ldo3_reg>;
+
+               codec_port: port {
+                       codec_endpoint: endpoint {
+                               remote-endpoint = <&cpu_endpoint>;
+                               clocks = <&audio_mclk>;
+                       };
+               };
        };
 
        /* Ambient Light Sensor */
 
 &usb0 {
        status = "okay";
-       dr_mode = "peripheral";
+       dr_mode = "otg";
 };
 
 &usb1 {
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&audio_pins>;
-
+       #sound-dai-cells = <0>;
        op-mode = <0>;  /* MCASP_ISS_MODE */
        tdm-slots = <2>;
-       serial-dir = <
-               2 0 1 0
-               0 0 0 0
-               0 0 0 0
-               0 0 0 0
+       /* 4 serializers */
+       serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
+               0 0 1 2
        >;
-       tx-num-evt = <1>;
-       rx-num-evt = <1>;
+       tx-num-evt = <32>;
+       rx-num-evt = <32>;
+
+       cpu_port: port {
+               cpu_endpoint: endpoint {
+                       remote-endpoint = <&codec_endpoint>;
+
+                       dai-format = "dsp_b";
+                       bitclock-master = <&codec_port>;
+                       frame-master = <&codec_port>;
+                       bitclock-inversion;
+                       clocks = <&audio_mclk>;
+               };
+       };
 };
 
 &uart0 {
 };
 
 &cpsw_emac0 {
-       phy_id = <&davinci_mdio>, <0>;
-       phy-mode = "mii";
-};
-
-&cpsw_emac1 {
-       phy_id = <&davinci_mdio>, <1>;
        phy-mode = "mii";
+       phy-handle = <&ethphy0>;
 };
 
 &mac {
        pinctrl-names = "default", "sleep";
        pinctrl-0 = <&davinci_mdio_default>;
        pinctrl-1 = <&davinci_mdio_sleep>;
+       reset-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+       reset-delay-us = <100>;   /* PHY datasheet states 100us min */
+
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
 };
 
 &sham {
        pinctrl-names = "default";
        pinctrl-0 = <&ehrpwm1_pins>;
 };
+
+&lcdc {
+       status = "okay";
+};
+
+&tscadc {
+       status = "okay";
+};
+
+&am335x_adc {
+       ti,adc-channels = <0 1 2 3 4 5 6 7>;
+};
index 9cd62bc2ca352c54b49d5617e48005ee9ed0f4ce..d3dd6a16e70a706f214bf5ab54bdff396ed2c2bc 100644 (file)
@@ -29,8 +29,8 @@
                serial3 = &uart3;
                serial4 = &uart4;
                serial5 = &uart5;
-               d_can0 = &dcan0;
-               d_can1 = &dcan1;
+               d-can0 = &dcan0;
+               d-can1 = &dcan1;
                usb0 = &usb0;
                usb1 = &usb1;
                phy0 = &usb0_phy;
index 98aadb0f81c5e04153f0ac4ad4f5fdea1bd0bf2f..1d158cfda15f2653fe829aa4faf610f5a926f883 100644 (file)
                status = "okay";
                pinctrl-names = "default";
                enable-gpios = <&gpio6 16 GPIO_ACTIVE_HIGH>;    /* gpio176, lcd INI */
+               vcc-supply = <&vdd_io_reg>;
 
                port {
                        lcd_in: endpoint {
        bl: backlight {
                compatible = "pwm-backlight";
                pinctrl-names = "default";
+               power-supply = <&vdd_io_reg>;
                pinctrl-0 = <&backlight_pins>;
                pwms = <&pwm11 0 5000000 0>;
                brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
                ti,timers = <&timer11>;
                #pwm-cells = <3>;
        };
+
+       /* HS USB Host PHY on PORT 1 */
+       hsusb1_phy: hsusb1_phy {
+               compatible = "usb-nop-xceiv";
+               reset-gpios = <&gpio2 25 GPIO_ACTIVE_LOW>; /* gpio_57 */
+               #phy-cells = <0>;
+       };
 };
 
 &davinci_emac {
                reg = <0x21>;
                gpio-controller;
                #gpio-cells = <2>;
+               vcc-supply = <&vdd_io_reg>;
        };
 };
 
        cd-gpios = <&gpio4 31 GPIO_ACTIVE_HIGH>; /* gpio_127 */
 };
 
-&mmc2 {
+&mmc3 {
       status = "disabled";
 };
 
-&mmc3 {
-      status = "disabled";
+&usbhshost {
+       port1-mode = "ehci-phy";
+};
+
+&usbhsehci {
+       phys = <&hsusb1_phy>;
 };
 
 &omap3_pmx_core {
+       pinctrl-names = "default";
+       pinctrl-0 = <&hsusb1_rst_pins>;
 
        leds_pins: pinmux_leds_pins {
                pinctrl-single,pins = <
                        OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0)       /* dss_data15.dss_data15 */
                >;
        };
+
+       hsusb1_rst_pins: pinmux_hsusb1_rst_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x20ba, PIN_OUTPUT | MUX_MODE4)       /* gpmc_ncs6.gpio_57 */
+               >;
+       };
+};
+
+&omap3_pmx_core2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&hsusb1_pins>;
+
+       hsusb1_pins: pinmux_hsusb1_pins {
+               pinctrl-single,pins = <
+                       OMAP3430_CORE2_IOPAD(0x25d8, PIN_OUTPUT | MUX_MODE3)    /* etk_clk.hsusb1_stp */
+                       OMAP3430_CORE2_IOPAD(0x25da, PIN_OUTPUT | MUX_MODE3)    /* etk_ctl.hsusb1_clk */
+                       OMAP3430_CORE2_IOPAD(0x25ec, PIN_INPUT | MUX_MODE3)     /* etk_d8.hsusb1_dir */
+                       OMAP3430_CORE2_IOPAD(0x25ee, PIN_INPUT | MUX_MODE3)     /* etk_d9.hsusb1_nxt */
+                       OMAP3430_CORE2_IOPAD(0x25dc, PIN_INPUT | MUX_MODE3)     /* etk_d0.hsusb1_data0 */
+                       OMAP3430_CORE2_IOPAD(0x25de, PIN_INPUT | MUX_MODE3)     /* etk_d1.hsusb1_data1 */
+                       OMAP3430_CORE2_IOPAD(0x25e0, PIN_INPUT | MUX_MODE3)     /* etk_d2.hsusb1_data2 */
+                       OMAP3430_CORE2_IOPAD(0x25ea, PIN_INPUT | MUX_MODE3)     /* etk_d7.hsusb1_data3 */
+                       OMAP3430_CORE2_IOPAD(0x25e4, PIN_INPUT | MUX_MODE3)     /* etk_d4.hsusb1_data4 */
+                       OMAP3430_CORE2_IOPAD(0x25e6, PIN_INPUT | MUX_MODE3)     /* etk_d5.hsusb1_data5 */
+                       OMAP3430_CORE2_IOPAD(0x25e8, PIN_INPUT | MUX_MODE3)     /* etk_d6.hsusb1_data6 */
+                       OMAP3430_CORE2_IOPAD(0x25e2, PIN_INPUT | MUX_MODE3)     /* etk_d3.hsusb1_data7 */
+               >;
+       };
 };
index a6d5ff73c163074b03f21ea77aed21103f84d096..dae6e458e59fe7e4b49c65c78ed5224169a4407c 100644 (file)
                        cpu0-supply = <&vdd_core_reg>;
                };
        };
+
+       wl12xx_buffer: wl12xx_buf {
+               compatible = "regulator-fixed";
+               regulator-name = "wl1271_buf";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&wl12xx_buffer_pins>;
+               gpio = <&gpio5 1 GPIO_ACTIVE_LOW>; /* gpio 129 */
+               regulator-always-on;
+               vin-supply = <&vdd_1v8_reg>;
+       };
+
+       wl12xx_vmmc2: wl12xx_vmmc2 {
+               compatible = "regulator-fixed";
+               regulator-name = "vwl1271";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&wl12xx_wkup_pins>;
+               gpio = <&gpio1 3 GPIO_ACTIVE_HIGH >; /* gpio 3 */
+               startup-delay-us = <70000>;
+               enable-active-high;
+               regulator-always-on;
+               vin-supply = <&wl12xx_buffer>;
+       };
 };
 
 &gpmc {
@@ -64,7 +90,6 @@
                regulators {
                        vdd_core_reg: VDCDC1 {
                                regulator-name = "vdd_core";
-                               compatible = "regulator-fixed";
                                regulator-always-on;
                                regulator-min-microvolt = <1200000>;
                                regulator-max-microvolt = <1200000>;
@@ -72,7 +97,6 @@
 
                        vdd_io_reg: VDCDC2 {
                                regulator-name = "vdd_io";
-                               compatible = "regulator-fixed";
                                regulator-always-on;
                                regulator-min-microvolt = <3300000>;
                                regulator-max-microvolt = <3300000>;
 
                        vdd_1v8_reg: VDCDC3 {
                                regulator-name = "vdd_1v8";
-                               compatible = "regulator-fixed";
                                regulator-always-on;
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <1800000>;
 
                        vdd_usb18_reg: LDO1 {
                                regulator-name = "vdd_usb18";
-                               compatible = "regulator-fixed";
                                regulator-always-on;
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <1800000>;
 
                        vdd_usb33_reg: LDO2 {
                                regulator-name = "vdd_usb33";
-                               compatible = "regulator-fixed";
                                regulator-always-on;
                                regulator-min-microvolt = <3300000>;
                                regulator-max-microvolt = <3300000>;
        };
 };
 
+&mmc2 {
+       interrupts-extended = <&intc 86 /* &omap3_pmx_core 0x12c */>;
+
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins>;
+       vmmc-supply = <&wl12xx_vmmc2>;
+       non-removable;
+       bus-width = <4>;
+       cap-power-off-card;
+       #address-cells = <1>;
+       #size-cells = <0>;
+       wlcore: wlcore@2 {
+               compatible = "ti,wl1271";
+               reg = <2>;
+               interrupt-parent = <&gpio6>;
+               interrupts = <10 IRQ_TYPE_LEVEL_HIGH>; /* gpio_170 */
+               ref-clock-frequency = <26000000>;
+               tcxo-clock-frequency = <26000000>;
+       };
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+
+       bluetooth {
+               compatible = "ti,wl1271-st";
+               enable-gpios = <&gpio2 24 GPIO_ACTIVE_HIGH>; /* gpio 56 */
+               max-speed = <3000000>;
+       };
+};
+
 &omap3_pmx_core {
 
+       wl12xx_buffer_pins: pinmux_wl12xx_buffer_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2156, PIN_OUTPUT | MUX_MODE4)  /* mmc1_dat7.gpio_129 */
+               >;
+       };
+
+       mmc2_pins: pinmux_mmc2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0)  /* mmc2_clk.mmc2_clk */
+                       OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0)  /* mmc2_cmd.mmc2_cmd */
+                       OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0)  /* mmc2_dat0.mmc2_dat0 */
+                       OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0)  /* mmc2_dat1.mmc2_dat1 */
+                       OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0)  /* mmc2_dat2.mmc2_dat2 */
+                       OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0)  /* mmc2_dat3.mmc2_dat3 */
+                       OMAP3_CORE1_IOPAD(0x2164, PIN_OUTPUT | MUX_MODE1) /* mmc2_dat4.mmc2_dir_dat0 */
+                       OMAP3_CORE1_IOPAD(0x2166, PIN_OUTPUT | MUX_MODE1) /* mmc2_dat5.mmc2_dir_dat1 */
+                       OMAP3_CORE1_IOPAD(0x2168, PIN_OUTPUT | MUX_MODE1) /* mmc2_dat6.mmc2_dir_cmd */
+                       OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT | MUX_MODE1) /* mmc2_dat7.mmc2_clkin */
+                       OMAP3_CORE1_IOPAD(0x21c6, PIN_INPUT_PULLUP | MUX_MODE4) /* hdq_sio.gpio_170 */
+               >;
+       };
+
        rtc_pins: pinmux_rtc_pins {
                pinctrl-single,pins = <
                        OMAP3_CORE1_IOPAD(0x20b6, PIN_INPUT_PULLUP | MUX_MODE4) /* gpmc_ncs4.gpio_55 */
                        OMAP3_CORE1_IOPAD(0x20d2, PIN_INPUT | MUX_MODE4) /* gpmc_wait3.gpio_65 */
                >;
        };
+
+       uart2_pins: pinmux_uart2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT_PULLUP | MUX_MODE0)         /* uart2_cts */
+                       OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT_PULLUP | MUX_MODE0)        /* uart2_rts */
+                       OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0)               /* uart2_tx */
+                       OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0)                /* uart2_rx */
+                       OMAP3_CORE1_IOPAD(0x20b8, PIN_INPUT | MUX_MODE0)                /* gpio_56 */
+               >;
+       };
+};
+
+&omap3_pmx_wkup {
+
+       wl12xx_wkup_pins: pinmux_wl12xx_wkup_pins {
+               pinctrl-single,pins = <
+                       OMAP3_WKUP_IOPAD(0x2a0c, PIN_OUTPUT | MUX_MODE4)        /* sys_boot1.gpio_3 */
+               >;
+       };
 };
index f0cbd86312dce5ddc1867d9eb2dc54059450a090..d4b7c59eec6853f2f836b5b3ffd686988ad0f6b1 100644 (file)
                        ti,hwmods = "rtc";
                        clocks = <&clk_32768_ck>;
                        clock-names = "int-clk";
+                       system-power-controller;
                        status = "disabled";
                };
 
index 60414b1ca4044f38d71877d61cf0da8e34d54db9..5b97c20c5ed49c2de9432742442a322e4e127728 100644 (file)
                compatible = "ti,wl1835";
                reg = <2>;
                interrupt-parent = <&gpio1>;
-               interrupts = <23 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <23 IRQ_TYPE_EDGE_RISING>;
        };
 };
 
index 5bb9d68d6e90a411b117c3a9b736f281dad6fdbc..d9a2049a1ea8ad49163c8028d85ab9af45a0af0b 100644 (file)
        };
 };
 
-&omap_dwc3_2 {
-       extcon = <&extcon_usb2>;
-};
-
 &extcon_usb2 {
        id-gpio = <&gpio5 7 GPIO_ACTIVE_HIGH>;
        vbus-gpio = <&gpio7 22 GPIO_ACTIVE_HIGH>;
index c6d858b310117ea6ea54b1393aaf6d4600f132ba..784639ddf4513a316971ec181b3a1ade74fe18f1 100644 (file)
        };
 };
 
-&omap_dwc3_2 {
-       extcon = <&extcon_usb2>;
-};
-
 &extcon_usb2 {
        id-gpio = <&gpio3 16 GPIO_ACTIVE_HIGH>;
        vbus-gpio = <&gpio3 26 GPIO_ACTIVE_HIGH>;
index ad87f1ae904db15c313678c5b59c68bb78fdb733..c9063ffca524c8022f97930964d7b03f4de38c4c 100644 (file)
        dr_mode = "host";
 };
 
+&omap_dwc3_2 {
+       extcon = <&extcon_usb2>;
+};
+
 &usb2 {
-       dr_mode = "peripheral";
+       extcon = <&extcon_usb2>;
+       dr_mode = "otg";
 };
 
 &mmc1 {
index 50ed4ae5c621af84fd5b0bccf12fcebba2384890..53b4bd35522ad92a2456fe3196cc8778b2afe1a7 100644 (file)
@@ -3,11 +3,6 @@
  * Device Tree file for SolidRun Clearfog Base revision A1 rev 2.0 (88F6828)
  *
  *  Copyright (C) 2015 Russell King
- *
- * This board is in development; the contents of this file work with
- * the A1 rev 2.0 of the board, which does not represent final
- * production board.  Things will change, don't expect this file to
- * remain compatible info the future.
  */
 
 /dts-v1/;
index 24e4b5a509be9b9178d64ebf45124a0401f1c37b..ff890c09c3ede1f0b50583eb1833d348325ecd23 100644 (file)
@@ -3,11 +3,6 @@
  * Device Tree file for SolidRun Clearfog Pro revision A1 rev 2.0 (88F6828)
  *
  *  Copyright (C) 2015 Russell King
- *
- * This board is in development; the contents of this file work with
- * the A1 rev 2.0 of the board, which does not represent final
- * production board.  Things will change, don't expect this file to
- * remain compatible info the future.
  */
 #include "armada-388-clearfog.dts"
 
index 5fd0f6f61e77679c45889fdc7316998fe5e19bd3..89a354b43978fab38a9535c3ee958035c5ba9e3f 100644 (file)
@@ -3,11 +3,6 @@
  * Device Tree file for SolidRun Clearfog Pro revision A1 rev 2.0 (88F6828)
  *
  *  Copyright (C) 2015 Russell King
- *
- * This board is in development; the contents of this file work with
- * the A1 rev 2.0 of the board, which does not represent final
- * production board.  Things will change, don't expect this file to
- * remain compatible info the future.
  */
 
 /dts-v1/;
 &spi1 {
        /*
         * Add SPI CS pins for clearfog:
-        * CS0: W25Q32 (not populated on uSOM)
+        * CS0: W25Q32
         * CS1:
         * CS2: mikrobus
         */
index 0d9dfdfe977e24e59c72f8200adc429af1337654..7c6ad2afb0947afc85ea34ff5d470df9bfbd3ef9 100644 (file)
@@ -3,11 +3,6 @@
  * Device Tree include file for SolidRun Clearfog 88F6828 based boards
  *
  *  Copyright (C) 2015 Russell King
- *
- * This board is in development; the contents of this file work with
- * the A1 rev 2.0 of the board, which does not represent final
- * production board.  Things will change, don't expect this file to
- * remain compatible info the future.
  */
 
 #include "armada-388.dtsi"
 &spi1 {
        /*
         * Add SPI CS pins for clearfog:
-        * CS0: W25Q32 (not populated on uSOM)
+        * CS0: W25Q32
         * CS1: PIC microcontroller (Pro models)
         * CS2: mikrobus
         */
diff --git a/arch/arm/boot/dts/armada-388-helios4.dts b/arch/arm/boot/dts/armada-388-helios4.dts
new file mode 100644 (file)
index 0000000..705adfa
--- /dev/null
@@ -0,0 +1,313 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Device Tree file for Helios4
+ * based on SolidRun Clearfog revision A1 rev 2.0 (88F6828)
+ *
+ *  Copyright (C) 2017 Aditya Prayoga <aditya@kobol.io>
+ *
+ */
+
+/dts-v1/;
+#include "armada-388.dtsi"
+#include "armada-38x-solidrun-microsom.dtsi"
+
+/ {
+       model = "Helios4";
+       compatible = "kobol,helios4", "marvell,armada388",
+               "marvell,armada385", "marvell,armada380";
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x80000000>; /* 2 GB */
+       };
+
+       aliases {
+               /* So that mvebu u-boot can update the MAC addresses */
+               ethernet1 = &eth0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       reg_12v: regulator-12v {
+               compatible = "regulator-fixed";
+               regulator-name = "power_brick_12V";
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+               regulator-always-on;
+       };
+
+       reg_3p3v: regulator-3p3v {
+               compatible = "regulator-fixed";
+               regulator-name = "3P3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               vin-supply = <&reg_12v>;
+       };
+
+       reg_5p0v_hdd: regulator-5v-hdd {
+               compatible = "regulator-fixed";
+               regulator-name = "5V_HDD";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+               vin-supply = <&reg_12v>;
+       };
+
+       reg_5p0v_usb: regulator-5v-usb {
+               compatible = "regulator-fixed";
+               regulator-name = "USB-PWR";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-boot-on;
+               regulator-always-on;
+               enable-active-high;
+               gpio = <&expander0 6 GPIO_ACTIVE_HIGH>;
+               vin-supply = <&reg_12v>;
+       };
+
+       system-leds {
+               compatible = "gpio-leds";
+               status-led {
+                       label = "helios4:green:status";
+                       gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "heartbeat";
+                       default-state = "on";
+               };
+
+               fault-led {
+                       label = "helios4:red:fault";
+                       gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
+                       default-state = "keep";
+               };
+       };
+
+       io-leds {
+               compatible = "gpio-leds";
+               sata1-led {
+                       label = "helios4:green:ata1";
+                       gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "ata1";
+                       default-state = "off";
+               };
+               sata2-led {
+                       label = "helios4:green:ata2";
+                       gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "ata2";
+                       default-state = "off";
+               };
+               sata3-led {
+                       label = "helios4:green:ata3";
+                       gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "ata3";
+                       default-state = "off";
+               };
+               sata4-led {
+                       label = "helios4:green:ata4";
+                       gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "ata4";
+                       default-state = "off";
+               };
+               usb-led {
+                       label = "helios4:green:usb";
+                       gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "usb-host";
+                       default-state = "off";
+               };
+       };
+
+       fan1: j10-pwm {
+               compatible = "pwm-fan";
+               pwms = <&gpio1 9 40000>;        /* Target freq:25 kHz */
+       };
+
+       fan2: j17-pwm {
+               compatible = "pwm-fan";
+               pwms = <&gpio1 23 40000>;       /* Target freq:25 kHz */
+       };
+
+       usb2_phy: usb2-phy {
+               compatible = "usb-nop-xceiv";
+               vbus-regulator = <&reg_5p0v_usb>;
+       };
+
+       usb3_phy: usb3-phy {
+               compatible = "usb-nop-xceiv";
+       };
+
+       soc {
+               internal-regs {
+                       i2c@11000 {
+                               clock-frequency = <400000>;
+                               pinctrl-0 = <&i2c0_pins>;
+                               pinctrl-names = "default";
+                               status = "okay";
+
+                               /*
+                                * PCA9655 GPIO expander, up to 1MHz clock.
+                                *  0-Board Revision bit 0 #
+                                *  1-Board Revision bit 1 #
+                                *  5-USB3 overcurrent
+                                *  6-USB3 power
+                                */
+                               expander0: gpio-expander@20 {
+                                       /*
+                                        * This is how it should be:
+                                        * compatible = "onnn,pca9655",
+                                        *       "nxp,pca9555";
+                                        * but you can't do this because of
+                                        * the way I2C works.
+                                        */
+                                       compatible = "nxp,pca9555";
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       reg = <0x20>;
+                                       pinctrl-names = "default";
+                                       pinctrl-0 = <&pca0_pins>;
+                                       interrupt-parent = <&gpio0>;
+                                       interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+
+                                       board_rev_bit_0 {
+                                               gpio-hog;
+                                               gpios = <0 GPIO_ACTIVE_LOW>;
+                                               input;
+                                               line-name = "board-rev-0";
+                                       };
+                                       board_rev_bit_1 {
+                                               gpio-hog;
+                                               gpios = <1 GPIO_ACTIVE_LOW>;
+                                               input;
+                                               line-name = "board-rev-1";
+                                       };
+                                       usb3_ilimit {
+                                               gpio-hog;
+                                               gpios = <5 GPIO_ACTIVE_HIGH>;
+                                               input;
+                                               line-name = "usb-overcurrent-status";
+                                       };
+                               };
+
+                               temp_sensor: temp@4c {
+                                       compatible = "ti,lm75";
+                                       reg = <0x4c>;
+                                       vcc-supply = <&reg_3p3v>;
+                               };
+                       };
+
+                       i2c@11100 {
+                               /*
+                                * External I2C Bus for user peripheral
+                                */
+                               clock-frequency = <400000>;
+                               pinctrl-0 = <&helios_i2c1_pins>;
+                               pinctrl-names = "default";
+                               status = "okay";
+                       };
+
+                       sata@a8000 {
+                               status = "okay";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               sata0: sata-port@0 {
+                                       reg = <0>;
+                               };
+
+                               sata1: sata-port@1 {
+                                       reg = <1>;
+                               };
+                       };
+
+                       sata@e0000 {
+                               status = "okay";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               sata2: sata-port@0 {
+                                       reg = <0>;
+                               };
+
+                               sata3: sata-port@1 {
+                                       reg = <1>;
+                               };
+                       };
+
+                       spi@10680 {
+                               pinctrl-0 = <&spi1_pins
+                                            &microsom_spi1_cs_pins>;
+                               pinctrl-names = "default";
+                               status = "okay";
+                       };
+
+                       sdhci@d8000 {
+                               bus-width = <4>;
+                               cd-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+                               no-1-8-v;
+                               pinctrl-0 = <&helios_sdhci_pins
+                                            &helios_sdhci_cd_pins>;
+                               pinctrl-names = "default";
+                               status = "okay";
+                               vmmc = <&reg_3p3v>;
+                               wp-inverted;
+                       };
+
+                       usb@58000 {
+                               usb-phy = <&usb2_phy>;
+                               status = "okay";
+                       };
+
+                       usb3@f0000 {
+                               status = "okay";
+                       };
+
+                       usb3@f8000 {
+                               status = "okay";
+                       };
+
+                       pinctrl@18000 {
+                               pca0_pins: pca0-pins {
+                                       marvell,pins = "mpp23";
+                                       marvell,function = "gpio";
+                               };
+                               microsom_phy0_int_pins: microsom-phy0-int-pins {
+                                       marvell,pins = "mpp18";
+                                       marvell,function = "gpio";
+                               };
+                               helios_i2c1_pins: i2c1-pins {
+                                       marvell,pins = "mpp26", "mpp27";
+                                       marvell,function = "i2c1";
+                               };
+                               helios_sdhci_cd_pins: helios-sdhci-cd-pins {
+                                       marvell,pins = "mpp20";
+                                       marvell,function = "gpio";
+                               };
+                               helios_sdhci_pins: helios-sdhci-pins {
+                                       marvell,pins = "mpp21", "mpp28",
+                                                      "mpp37", "mpp38",
+                                                      "mpp39", "mpp40";
+                                       marvell,function = "sd0";
+                               };
+                               helios_led_pins: helios-led-pins {
+                                       marvell,pins = "mpp24", "mpp25",
+                                                      "mpp49", "mpp50",
+                                                      "mpp52", "mpp53",
+                                                      "mpp54";
+                                       marvell,function = "gpio";
+                               };
+                               helios_fan_pins: helios-fan-pins {
+                                       marvell,pins = "mpp41", "mpp43",
+                                                      "mpp48", "mpp55";
+                                       marvell,function = "gpio";
+                               };
+                               microsom_spi1_cs_pins: spi1-cs-pins {
+                                       marvell,pins = "mpp59";
+                                       marvell,function = "spi1";
+                               };
+                       };
+               };
+       };
+};
index 2d1cea131e71cfb27404f5d57aac2279c1186977..3a7f9c1ac346bf18aceb1e5529bee9d2a6529cdb 100644 (file)
@@ -3,11 +3,6 @@
  * Device Tree file for SolidRun Armada 38x Microsom
  *
  *  Copyright (C) 2015 Russell King
- *
- * This board is in development; the contents of this file work with
- * the A1 rev 2.0 of the board, which does not represent final
- * production board.  Things will change, don't expect this file to
- * remain compatible info the future.
  */
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/gpio/gpio.h>
@@ -99,7 +94,6 @@
                compatible = "w25q32", "jedec,spi-nor";
                reg = <0>; /* Chip select 0 */
                spi-max-frequency = <3000000>;
-               status = "disabled";
        };
 };
 
index ede11c597673677461cd69e527f864685f87b829..2375449c02d054ae6e17a3aae2a8d00e6f984ecb 100644 (file)
        };
 };
 
-&ehci0 {
+/*
+ * Enable port A as device (via the virtual hub) and port B as
+ * host by default on the eval board. This can be easily changed
+ * by replacing the override below with &ehci0 { ... } to enable
+ * host on both ports.
+ */
+&vhub {
        status = "okay";
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usb2ah_default>;
 };
 
 &ehci1 {
        status = "okay";
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usb2bh_default>;
 };
 
 &uhci {
        status = "okay";
-
-       /* No pinctrl, this follows the above EHCI settings */
 };
index 0b9b37d4d6ef1a921015cfce81ea6b20e0ee90de..7d28c03a9e0bccf7352a61d7e5016727c936b8de 100644 (file)
@@ -21,9 +21,9 @@
                #size-cells = <1>;
                ranges;
 
-               vga_memory: framebuffer@bf000000 {
+               vga_memory: framebuffer@9f000000 {
                        no-map;
-                       reg = <0xbf000000 0x01000000>; /* 16M */
+                       reg = <0x9f000000 0x01000000>; /* 16M */
                };
 
                flash_memory: region@98000000 {
index 75df1573380e923ac7f9bacdd5b8edb381a897c8..b23a983f95a5379f9224d3dd602a1e2ee0df094d 100644 (file)
                        reg = <0x1e6c0080 0x80>;
                };
 
+               cvic: copro-interrupt-controller@1e6c2000 {
+                       compatible = "aspeed,ast2400-cvic", "aspeed-cvic";
+                       valid-sources = <0x7fffffff>;
+                       reg = <0x1e6c2000 0x80>;
+               };
+
                mac0: ethernet@1e660000 {
                        compatible = "aspeed,ast2400-mac", "faraday,ftgmac100";
                        reg = <0x1e660000 0x180>;
                        reg = <0x1e6a1000 0x100>;
                        interrupts = <5>;
                        clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usb2h_default>;
                        status = "disabled";
                };
 
                        #ports = <3>;
                        clocks = <&syscon ASPEED_CLK_GATE_USBUHCICLK>;
                        status = "disabled";
+                       /*
+                        * No default pinmux, it will follow EHCI, use an explicit pinmux
+                        * override if you don't enable EHCI
+                        */
+               };
+
+               vhub: usb-vhub@1e6a0000 {
+                       compatible = "aspeed,ast2400-usb-vhub";
+                       reg = <0x1e6a0000 0x300>;
+                       interrupts = <5>;
+                       clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usb2d_default>;
+                       status = "disabled";
                };
 
                apb {
                                status = "disabled";
                        };
 
-                       sram@1e720000 {
+                       sram: sram@1e720000 {
                                compatible = "mmio-sram";
                                reg = <0x1e720000 0x8000>;      // 32K
                        };
                                #address-cells = <1>;
                                #size-cells = <0>;
                                reg = <0x1e786000 0x1000>;
-                               clocks = <&syscon ASPEED_CLK_APB>;
+                               clocks = <&syscon ASPEED_CLK_24M>;
                                resets = <&syscon ASPEED_RESET_PWM>;
                                status = "disabled";
                        };
index 17f2714d18a7ec09e4722d557831379e38157b89..87fdc146ff525af94c8db648f8f46b8c3c1084d4 100644 (file)
                        reg = <0x1e6c0080 0x80>;
                };
 
+               cvic: copro-interrupt-controller@1e6c2000 {
+                       compatible = "aspeed,ast2500-cvic", "aspeed-cvic";
+                       valid-sources = <0xffffffff>;
+                       copro-sw-interrupts = <1>;
+                       reg = <0x1e6c2000 0x80>;
+               };
+
                mac0: ethernet@1e660000 {
                        compatible = "aspeed,ast2500-mac", "faraday,ftgmac100";
                        reg = <0x1e660000 0x180>;
                        reg = <0x1e6a1000 0x100>;
                        interrupts = <5>;
                        clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usb2ah_default>;
                        status = "disabled";
                };
 
                        reg = <0x1e6a3000 0x100>;
                        interrupts = <13>;
                        clocks = <&syscon ASPEED_CLK_GATE_USBPORT2CLK>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usb2bh_default>;
                        status = "disabled";
                };
 
                        #ports = <2>;
                        clocks = <&syscon ASPEED_CLK_GATE_USBUHCICLK>;
                        status = "disabled";
+                       /*
+                        * No default pinmux, it will follow EHCI, use an explicit pinmux
+                        * override if you don't enable EHCI
+                        */
+               };
+
+               vhub: usb-vhub@1e6a0000 {
+                       compatible = "aspeed,ast2500-usb-vhub";
+                       reg = <0x1e6a0000 0x300>;
+                       interrupts = <5>;
+                       clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usb2ad_default>;
+                       status = "disabled";
                };
 
                apb {
                                status = "disabled";
                        };
 
-                       sram@1e720000 {
+                       sram: sram@1e720000 {
                                compatible = "mmio-sram";
                                reg = <0x1e720000 0x9000>;      // 36K
                        };
                                #address-cells = <1>;
                                #size-cells = <0>;
                                reg = <0x1e786000 0x1000>;
-                               clocks = <&syscon ASPEED_CLK_APB>;
+                               clocks = <&syscon ASPEED_CLK_24M>;
                                resets = <&syscon ASPEED_RESET_PWM>;
                                status = "disabled";
                        };
                groups = "USB2AH";
        };
 
+       pinctrl_usb2ad_default: usb2ad_default {
+               function = "USB2AD";
+               groups = "USB2AD";
+       };
+
        pinctrl_usb11bhid_default: usb11bhid_default {
                function = "USB11BHID";
                groups = "USB11BHID";
diff --git a/arch/arm/boot/dts/at91-dvk_som60.dts b/arch/arm/boot/dts/at91-dvk_som60.dts
new file mode 100644 (file)
index 0000000..ededd5b
--- /dev/null
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * at91-dvk_som60.dts - Device Tree file for the DVK SOM60 board
+ *
+ *  Copyright (C) 2018 Laird,
+ *               2018 Ben Whitten <ben.whitten@lairdtech.com>
+ *
+ */
+/dts-v1/;
+#include "at91-som60.dtsi"
+#include "at91-dvk_su60_somc.dtsi"
+#include "at91-dvk_su60_somc_lcm.dtsi"
+
+/ {
+       model = "Laird DVK SOM60";
+       compatible = "laird,dvk-som60", "laird,som60", "atmel,sama5d36", "atmel,sama5d3", "atmel,sama5";
+
+       chosen {
+               stdout-path = &dbgu;
+               tick-timer = &pit;
+       };
+};
+
+&mmc0 {
+       status = "okay";
+};
+
+&spi0 {
+       status = "okay";
+};
+
+&ssc0 {
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+};
+
+&i2c1 {
+       status = "okay";
+};
+
+&usart1 {
+       status = "okay";
+};
+
+&usart2 {
+       status = "okay";
+};
+
+&usart3 {
+       status = "okay";
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&dbgu {
+       status = "okay";
+};
+
+&pit {
+       status = "okay";
+};
+
+&adc0 {
+       status = "okay";
+};
+
+&can1 {
+       status = "okay";
+};
+
+&macb0 {
+       status = "okay";
+};
+
+&macb1 {
+       status = "okay";
+};
+
+&usb0 {
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
+
+&usb2 {
+       status = "okay";
+};
+
diff --git a/arch/arm/boot/dts/at91-dvk_su60_somc.dtsi b/arch/arm/boot/dts/at91-dvk_su60_somc.dtsi
new file mode 100644 (file)
index 0000000..bb86f17
--- /dev/null
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * at91-dvk_su60_somc.dtsi - Device Tree file for the DVK SOM60 base board
+ *
+ *  Copyright (C) 2018 Laird,
+ *               2018 Ben Whitten <ben.whitten@lairdtech.com>
+ *
+ */
+
+/ {
+       sound {
+               compatible = "atmel,asoc-wm8904";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pck2_as_audio_mck>;
+
+               atmel,model = "wm8904 @ DVK-SOM60";
+               atmel,audio-routing =
+                       "Headphone Jack", "HPOUTL",
+                       "Headphone Jack", "HPOUTR",
+                       "IN2L", "Line In Jack",
+                       "IN2R", "Line In Jack",
+                       "Mic", "MICBIAS",
+                       "IN1L", "Mic";
+
+               atmel,ssc-controller = <&ssc0>;
+               atmel,audio-codec = <&wm8904>;
+
+               status = "okay";
+       };
+};
+
+&mmc0 {
+       status = "okay";
+
+       pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_cd>;
+       slot@0 {
+               bus-width = <4>;
+               cd-gpios = <&pioE 31 GPIO_ACTIVE_HIGH>;
+               cd-inverted;
+       };
+};
+
+&spi0 {
+       status = "okay";
+
+       /* spi0.0: 4M Flash Macronix MX25R4035FM1IL0 */
+       spi-flash@0 {
+               compatible = "mxicy,mx25u4035", "jedec,spi-nor";
+               spi-max-frequency = <33000000>;
+               reg = <0>;
+       };
+};
+
+&ssc0 {
+       atmel,clk-from-rk-pin;
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+
+       wm8904: wm8904@1a {
+               compatible = "wlf,wm8904";
+               reg = <0x1a>;
+               clocks = <&pck2>;
+               clock-names = "mclk";
+       };
+};
+
+&i2c1 {
+       status = "okay";
+
+       eeprom@87 {
+               compatible = "giantec,gt24c32a", "atmel,24c32";
+               reg = <87>;
+               pagesize = <32>;
+       };
+};
+
+&usart1 {
+       status = "okay";
+};
+
+&usart2 {
+       status = "okay";
+};
+
+&usart3 {
+       status = "okay";
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&dbgu {
+       status = "okay";
+};
+
+&pit {
+       status = "okay";
+};
+
+&adc0 {
+       status = "okay";
+};
+
+&can1 {
+       status = "okay";
+};
+
+&macb0 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       status = "okay";
+
+       ethernet-phy@7 {
+               reg = <7>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_geth_int>;
+               interrupt-parent = <&pioB>;
+               interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
+               txen-skew-ps = <800>;
+               txc-skew-ps = <3000>;
+               rxdv-skew-ps = <400>;
+               rxc-skew-ps = <3000>;
+               rxd0-skew-ps = <400>;
+               rxd1-skew-ps = <400>;
+               rxd2-skew-ps = <400>;
+               rxd3-skew-ps = <400>;
+       };
+};
+
+&macb1 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       status = "okay";
+
+       ethernet-phy@1 {
+               reg = <1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_eth_int>;
+               interrupt-parent = <&pioC>;
+               interrupts = <10 IRQ_TYPE_EDGE_FALLING>;
+       };
+};
+
+&usb0 {
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
+
+&usb2 {
+       status = "okay";
+};
+
diff --git a/arch/arm/boot/dts/at91-dvk_su60_somc_lcm.dtsi b/arch/arm/boot/dts/at91-dvk_su60_somc_lcm.dtsi
new file mode 100644 (file)
index 0000000..4b9176d
--- /dev/null
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * at91-dvk_su60_somc_lcm.dtsi - Device Tree file for the DVK SOM60 LCD board
+ *
+ *  Copyright (C) 2018 Laird,
+ *               2018 Ben Whitten <ben.whitten@lairdtech.com>
+ *
+ */
+
+/ {
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&hlcdc_pwm 0 50000 0>;
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <6>;
+               status = "okay";
+       };
+
+       panel: panel {
+               compatible = "winstar,wf70gtiagdng0", "innolux,at070tn92", "simple-panel";
+               backlight = <&backlight>;
+               power-supply = <&vcc_lcd_reg>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "okay";
+
+               port@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0>;
+
+                       panel_input: endpoint@0 {
+                               reg = <0>;
+                               remote-endpoint = <&hlcdc_panel_output>;
+                       };
+               };
+       };
+
+       vcc_lcd_reg: fixedregulator_lcd {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC LCM";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-boot-on;
+               regulator-always-on;
+               status = "okay";
+       };
+};
+
+&pinctrl {
+       board {
+               pinctrl_lcd_ctp_int: lcd_ctp_int {
+                        atmel,pins =
+                                <AT91_PIOC 28 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+               };
+       };
+};
+
+&i2c1 {
+       status = "okay";
+
+       ft5426@56 {
+               compatible = "focaltech,ft5426", "edt,edt-ft5406";
+               reg = <56>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_lcd_ctp_int>;
+
+               interrupt-parent = <&pioC>;
+               interrupts = <28 IRQ_TYPE_EDGE_FALLING>;
+
+               touchscreen-size-x = <800>;
+               touchscreen-size-y = <480>;
+       };
+};
+
+&hlcdc {
+       status = "okay";
+
+       hlcdc-display-controller {
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>;
+
+               port@0 {
+                       hlcdc_panel_output: endpoint@0 {
+                               reg = <0>;
+                               remote-endpoint = <&panel_input>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/at91-gatwick.dts b/arch/arm/boot/dts/at91-gatwick.dts
new file mode 100644 (file)
index 0000000..5a81cab
--- /dev/null
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * at91-gatwick.dts - Device Tree file for the Gatwick board
+ *
+ *  Copyright (C) 2018 Laird
+ *
+ */
+/dts-v1/;
+#include "at91-wb50n.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+       model = "Laird Workgroup Bridge 50N - Project Gatwick";
+       compatible = "laird,gatwick", "laird,wb50n", "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               autorepeat;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_key_gpio>;
+
+               reset-button {
+                       label = "Reset Button";
+                       linux,code = <KEY_SETUP>;
+                       gpios = <&pioE 31 GPIO_ACTIVE_LOW>;
+                       wakeup-source;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               ethernet {
+                       label = "gatwick:yellow:ethernet";
+                       gpios = <&pioA 10 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               wifi {
+                       label = "gatwick:green:wifi";
+                       gpios = <&pioA 28 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               ble {
+                       label = "gatwick:blue:ble";
+                       gpios = <&pioA 22 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               lora {
+                       label = "gatwick:orange:lora";
+                       gpios = <&pioA 26 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               blank {
+                       label = "gatwick:green:blank";
+                       gpios = <&pioA 24 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               user {
+                       label = "gatwick:yellow:user";
+                       gpios = <&pioA 12 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+       };
+};
+
+&pinctrl {
+       board {
+               pinctrl_key_gpio: key_gpio_0 {
+                 atmel,pins =
+                         <AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PE31 GPIO with pullup deglitch */
+         };
+       };
+};
+
+&mmc0 {
+       status = "okay";
+};
+
+&macb1 {
+       status = "okay";
+};
+
+&dbgu {
+       status = "okay";
+};
+
+/* FTDI USART */
+&usart0 {
+       status = "okay";
+};
+
+/* GPS USART */
+&usart1 {
+       pinctrl-0 = <&pinctrl_usart1>;
+       status = "okay";
+};
+
+&spi1 {
+       status = "okay";
+
+       spidev@0 {
+               compatible = "semtech,sx1301";
+               reg = <0>;
+               spi-max-frequency = <8000000>;
+       };
+};
+
+&usb1 {
+       status = "okay";
+       /delete-property/atmel,oc-gpio;
+};
+
+&usb2 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/at91-som60.dtsi b/arch/arm/boot/dts/at91-som60.dtsi
new file mode 100644 (file)
index 0000000..241682a
--- /dev/null
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * at91-som60.dtsi - Device Tree file for the SOM60 module
+ *
+ *  Copyright (C) 2018 Laird,
+ *               2018 Ben Whitten <ben.whitten@lairdtech.com>
+ *
+ */
+#include "sama5d36.dtsi"
+
+/ {
+       model = "Laird SOM60";
+       compatible = "laird,som60", "atmel,sama5d36", "atmel,sama5d3", "atmel,sama5";
+
+       chosen {
+               stdout-path = &dbgu;
+       };
+
+       memory {
+               reg = <0x20000000 0x8000000>;
+       };
+
+       clocks {
+               slow_xtal {
+                       clock-frequency = <32768>;
+               };
+
+               main_xtal {
+                       clock-frequency = <12000000>;
+               };
+       };
+};
+
+&pinctrl {
+       board {
+               pinctrl_mmc0_cd: mmc0_cd {
+                       atmel,pins =
+                               <AT91_PIOE 31 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;
+               };
+
+               pinctrl_mmc0_en: mmc0_en {
+                       atmel,pins =
+                               <AT91_PIOE 30 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+               };
+
+               pinctrl_nand0_wp: nand0_wp {
+                       atmel,pins =
+                               <AT91_PIOE 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;
+               };
+
+               pinctrl_usb_vbus: usb_vbus {
+                       atmel,pins =
+                               <AT91_PIOE 20 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+                               /* Conflicts with USART2_SCK */
+               };
+
+               pinctrl_usart2_sck: usart2_sck {
+                       atmel,pins =
+                               <AT91_PIOE 20 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                               /* Conflicts with USB_VBUS */
+               };
+
+               pinctrl_usb_oc: usb_oc {
+                       atmel,pins =
+                               <AT91_PIOE 15 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;
+                               /* Conflicts with USART3_SCK */
+               };
+
+               pinctrl_usart3_sck: usart3_sck {
+                       atmel,pins =
+                               <AT91_PIOE 15 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+                               /* Conflicts with USB_OC */
+               };
+
+               pinctrl_usba_vbus: usba_vbus {
+                  atmel,pins =
+                               <AT91_PIOC 14 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;
+               };
+
+               pinctrl_geth_int: geth_int {
+                       atmel,pins =
+                               <AT91_PIOB 25 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;
+                               /* Conflicts with USART1_SCK */
+               };
+
+               pinctrl_usart1_sck: usart1_sck {
+                       atmel,pins =
+                               <AT91_PIOB 25 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+                               /* Conflicts with GETH_INT */
+               };
+
+               pinctrl_eth_int: eth_int {
+                       atmel,pins =
+                               <AT91_PIOC 10 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;
+               };
+
+               pinctrl_pck2_as_audio_mck: pck2_as_audio_mck {
+                       atmel,pins =
+                               <AT91_PIOC 15 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+               };
+       };
+};
+
+&mmc0 {
+       slot@0 {
+               reg = <0>;
+               bus-width = <8>;
+       };
+};
+
+&mmc1 {
+       status = "okay";
+       slot@0 {
+               reg = <0>;
+               bus-width = <4>;
+       };
+};
+
+&spi0 {
+       cs-gpios = <&pioD 13 0>, <0>, <0>, <0>;
+};
+
+&usart0 {
+       atmel,use-dma-rx;
+       atmel,use-dma-tx;
+       status = "okay";
+       pinctrl-0 = <&pinctrl_usart0 &pinctrl_usart0_rts_cts>;
+};
+
+&usart1 {
+       pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>;
+};
+
+&usart2 {
+       pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rts_cts>;
+};
+
+&usart3 {
+       pinctrl-0 = <&pinctrl_usart3 &pinctrl_usart3_rts_cts>;
+};
+
+&adc0 {
+       pinctrl-0 = <
+               &pinctrl_adc0_adtrg
+               &pinctrl_adc0_ad0
+               &pinctrl_adc0_ad1
+               &pinctrl_adc0_ad2
+               &pinctrl_adc0_ad3
+               &pinctrl_adc0_ad4
+               &pinctrl_adc0_ad5
+               >;
+};
+
+&macb0 {
+       phy-mode = "rgmii";
+};
+
+&macb1 {
+       phy-mode = "rmii";
+};
+
+&ebi {
+       pinctrl-0 = <&pinctrl_ebi_nand_addr>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&nand_controller {
+       status = "okay";
+
+       nand: nand@3 {
+               reg = <0x3 0x0 0x2>;
+               atmel,rb = <0>;
+               nand-bus-width = <8>;
+               nand-ecc-mode = "hw";
+               nand-ecc-strength = <8>;
+               nand-ecc-step-size = <512>;
+               nand-on-flash-bbt;
+               label = "atmel_nand";
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       ubootspl@0 {
+                               label = "u-boot-spl";
+                               reg = <0x0 0x20000>;
+                       };
+
+                       uboot@20000 {
+                               label = "u-boot";
+                               reg = <0x20000 0x80000>;
+                       };
+
+                       ubootenv@a0000 {
+                               label = "u-boot-env";
+                               reg = <0xa0000 0x20000>;
+                       };
+
+                       ubootenv@c0000 {
+                               label = "u-boot-env";
+                               reg = <0xc0000 0x20000>;
+                       };
+
+                       ubi@e0000 {
+                               label = "ubi";
+                               reg = <0xe0000 0xfe00000>;
+                       };
+               };
+       };
+};
+
+&usb0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usba_vbus>;
+       atmel,vbus-gpio = <&pioC 14 GPIO_ACTIVE_HIGH>;
+};
+
+&usb1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usb_vbus &pinctrl_usb_oc>;
+       num-ports = <3>;
+       atmel,vbus-gpio = <0
+               &pioE 20 GPIO_ACTIVE_HIGH
+               0>;
+       atmel,oc-gpio = <0
+               &pioE 15 GPIO_ACTIVE_LOW
+               0>;
+};
diff --git a/arch/arm/boot/dts/at91-wb45n.dts b/arch/arm/boot/dts/at91-wb45n.dts
new file mode 100644 (file)
index 0000000..5b9512a
--- /dev/null
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * at91-wb45n.dts - Device Tree file for WB45NBT board
+ *
+ *  Copyright (C) 2018 Laird
+ *
+ */
+/dts-v1/;
+#include "at91-wb45n.dtsi"
+
+/ {
+       model = "Laird Workgroup Bridge 45N - Atmel AT91SAM (dt)";
+       compatible = "laird,wb45n", "laird,wbxx", "atmel,at91sam9x5", "atmel,at91sam9";
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               irqbtn@18 {
+                       reg = <18>;
+                       label = "IRQBTN";
+                       linux,code = <99>;
+                       gpios = <&pioB 18 GPIO_ACTIVE_LOW>;
+                       gpio-key,wakeup = <1>;
+               };
+       };
+};
+
+&watchdog {
+       status = "okay";
+};
+
+&usb0 {
+       status = "okay";
+};
+
+&mmc0 {
+       status = "okay";
+};
+
+&spi0 {
+       status = "okay";
+};
+
+&macb0 {
+       status = "okay";
+};
+
+&dbgu {
+       status = "okay";
+};
+
+&usart0 {
+       status = "okay";
+};
+
+&usart3 {
+       status = "okay";
+};
+
+&i2c1 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/at91-wb45n.dtsi b/arch/arm/boot/dts/at91-wb45n.dtsi
new file mode 100644 (file)
index 0000000..ebe61a2
--- /dev/null
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * at91-wb45n.dtsi - Device Tree file for WB45NBT board
+ *
+ *  Copyright (C) 2018 Laird
+ *
+ */
+
+#include "at91sam9g25.dtsi"
+
+/ {
+       model = "Laird Workgroup Bridge 45N - Atmel AT91SAM (dt)";
+       compatible = "laird,wb45n", "laird,wbxx", "atmel,at91sam9x5", "atmel,at91sam9";
+
+       chosen {
+               bootargs = "ubi.mtd=6 root=ubi0:rootfs rootfstype=ubifs rw";
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory {
+               reg = <0x20000000 0x4000000>;
+       };
+
+       atheros {
+               compatible = "atheros,ath6kl";
+               atheros,board-id = "SD32";
+       };
+};
+
+&reset_controller {
+       compatible = "atmel,sama5d3-rstc";
+};
+
+&shutdown_controller {
+       atmel,wakeup-mode = "low";
+};
+
+&slow_xtal {
+       clock-frequency = <32768>;
+};
+
+&main_xtal {
+       clock-frequency = <12000000>;
+};
+
+&ebi {
+       status = "okay";
+       nand_controller: nand-controller {
+               pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb &pinctrl_nand_oe_we>;
+               pinctrl-names = "default";
+               status = "okay";
+
+               nand@3 {
+                       reg = <0x3 0x0 0x800000>;
+                       rb-gpios = <&pioD 5 GPIO_ACTIVE_HIGH>;
+                       cs-gpios = <&pioD 4 GPIO_ACTIVE_HIGH>;
+                       nand-bus-width = <8>;
+                       nand-ecc-mode = "hw";
+                       nand-ecc-strength = <4>;
+                       nand-ecc-step-size = <512>;
+                       nand-on-flash-bbt;
+                       label = "atmel_nand";
+
+                       partitions {
+                               compatible = "fixed-partitions";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+
+                               at91bootstrap@0 {
+                                       label = "at91bs";
+                                       reg = <0x0 0x20000>;
+                               };
+
+                               uboot@20000 {
+                                       label = "u-boot";
+                                       reg = <0x20000 0x80000>;
+                               };
+
+                               ubootenv@a0000 {
+                                       label = "u-boot-env";
+                                       reg = <0xa0000 0x20000>;
+                               };
+
+                               ubootenv@c0000 {
+                                       label = "redund-env";
+                                       reg = <0xc0000 0x20000>;
+                               };
+
+                               kernel-a@e0000 {
+                                       label = "kernel-a";
+                                       reg = <0xe0000 0x280000>;
+                               };
+
+                               kernel-b@360000 {
+                                       label = "kernel-b";
+                                       reg = <0x360000 0x280000>;
+                               };
+
+                               rootfs-a@5e0000 {
+                                       label = "rootfs-a";
+                                       reg = <0x5e0000 0x2600000>;
+                               };
+
+                               rootfs-b@2be0000 {
+                                       label = "rootfs-b";
+                                       reg = <0x2be0000 0x2600000>;
+                               };
+
+                               user@51e0000 {
+                                       label = "user";
+                                       reg = <0x51e0000 0x2dc0000>;
+                               };
+
+                               logs@7fa0000 {
+                                       label = "logs";
+                                       reg = <0x7fa0000 0x60000>;
+                               };
+
+                       };
+               };
+       };
+};
+
+&usb0 {
+       num-ports = <2>;
+       atmel,vbus-gpio = <
+               &pioB 12 GPIO_ACTIVE_HIGH
+               &pioA 31 GPIO_ACTIVE_HIGH
+               >;
+       atmel,oc-gpio = <&pioB 13 GPIO_ACTIVE_LOW>;
+};
+
+&macb0 {
+       phy-mode = "rmii";
+};
+
+&spi0 {
+       cs-gpios = <&pioA 14 0>, <&pioA 7 0>, <0>, <0>;
+};
+
+&usb2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_board_usb2>;
+       atmel,vbus-gpio = <&pioB 11 GPIO_ACTIVE_HIGH>;
+};
+
+&mmc0 {
+       pinctrl-0 = <
+               &pinctrl_mmc0_slot0_clk_cmd_dat0
+               &pinctrl_mmc0_slot0_dat1_3>;
+       slot@0 {
+               reg = <0>;
+               bus-width = <4>;
+       };
+};
+
+&pinctrl {
+       usb2 {
+               pinctrl_board_usb2: usb2-board {
+                       atmel,pins =
+                               <AT91_PIOB 11 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;          /* PB11 gpio vbus sense, deglitch */
+               };
+       };
+};
+
diff --git a/arch/arm/boot/dts/at91-wb50n.dts b/arch/arm/boot/dts/at91-wb50n.dts
new file mode 100644 (file)
index 0000000..8cecc70
--- /dev/null
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * at91-wb50n.dts - Device Tree file for wb50n evaluation board
+ *
+ *  Copyright (C) 2018 Laird
+ *
+ */
+
+/dts-v1/;
+#include "at91-wb50n.dtsi"
+
+/ {
+       model = "Laird Workgroup Bridge 50N - Atmel SAMA5D";
+       compatible = "laird,wb50n", "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               btn0@10 {
+                       reg = <10>;
+                       label = "BTNESC";
+                       linux,code = <1>; /* ESC button */
+                       gpios = <&pioA 10 GPIO_ACTIVE_LOW>;
+                       gpio-key,wakeup = <1>;
+               };
+
+               irqbtn@31 {
+                       reg = <31>;
+                       label = "IRQBTN";
+                       linux,code = <99>; /* SysReq button */
+                       gpios = <&pioE 31 GPIO_ACTIVE_LOW>;
+                       gpio-key,wakeup = <1>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led0 {
+                       label = "wb50n:blue:led0";
+                       gpios = <&pioA 12 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               led1 {
+                       label = "wb50n:green:led1";
+                       gpios = <&pioA 24 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               led2 {
+                       label = "wb50n:red:led2";
+                       gpios = <&pioA 26 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+       };
+};
+
+&watchdog {
+       status = "okay";
+};
+
+&mmc0 {
+       status = "okay";
+};
+
+&macb1 {
+       status = "okay";
+};
+
+&dbgu {
+       status = "okay";
+};
+
+/* On BB40 this port is labeled UART1 */
+&usart0 {
+       status = "okay";
+};
+
+/* On BB40 this port is labeled UART0 */
+&usart1 {
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+};
+
+&spi1 {
+       status = "okay";
+
+       spidev@0 {
+               compatible = "spidev";
+               reg = <0>;
+               spi-max-frequency = <8000000>;
+       };
+};
+
+&usb0 {
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
+
+&usb2 {
+       status = "okay";
+};
+
diff --git a/arch/arm/boot/dts/at91-wb50n.dtsi b/arch/arm/boot/dts/at91-wb50n.dtsi
new file mode 100644 (file)
index 0000000..85692c8
--- /dev/null
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * at91-wb50n.dtsi - Device Tree include file for wb50n cpu module
+ *
+ *  Copyright (C) 2018 Laird
+ *
+ */
+
+#include "sama5d31.dtsi"
+
+/ {
+       model = "Laird Workgroup Bridge 50N - Atmel SAMA5D";
+       compatible = "laird,wb50n", "atmel,sama5d31", "atmel,sama5d3", "atmel,sama5";
+
+       chosen {
+               bootargs = "ubi.mtd=6 root=ubi0:rootfs rootfstype=ubifs rw";
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory {
+               reg = <0x20000000 0x4000000>;
+       };
+};
+
+&pinctrl {
+       board {
+               pinctrl_mmc0_cd: mmc0_cd {
+                       atmel,pins = <AT91_PIOC 26 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PC26 GPIO with pullup deglitch */
+               };
+
+               pinctrl_usba_vbus: usba_vbus {
+                       atmel,pins = <AT91_PIOB 13 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PB13 GPIO with deglitch */
+               };
+       };
+};
+
+&slow_xtal {
+       clock-frequency = <32768>;
+};
+
+&main_xtal {
+       clock-frequency = <12000000>;
+};
+
+&slow_osc {
+       atmel,osc-bypass;
+};
+
+&usart1_clk {
+       atmel,clk-output-range = <0 132000000>;
+};
+
+&mmc0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_cd>;
+       cd-gpios = <&pioC 26 GPIO_ACTIVE_LOW>;
+       slot@0 {
+               reg = <0>;
+               bus-width = <4>;
+       };
+};
+
+&mmc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3>;
+       status = "okay";
+       atheros@0 {
+               compatible = "atheros,ath6kl";
+               atheros,board-id = "SD32";
+               reg = <0>;
+               bus-width = <4>;
+       };
+};
+
+&macb1 {
+       phy-mode = "rmii";
+};
+
+&dbgu {
+       dmas = <0>, <0>;        /*  Do not use DMA for dbgu */
+};
+
+/* On BB40 this port is labeled UART1 */
+&usart0 {
+       atmel,use-dma-rx;
+       atmel,use-dma-tx;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usart0 &pinctrl_usart0_rts_cts>;
+};
+
+/* On BB40 this port is labeled UART0 */
+&usart1 {
+       atmel,use-dma-rx;
+       atmel,use-dma-tx;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>;
+       dtr-gpios = <&pioD 13 GPIO_ACTIVE_LOW>;
+       dsr-gpios = <&pioD 11 GPIO_ACTIVE_LOW>;
+       dcd-gpios = <&pioD 7 GPIO_ACTIVE_LOW>;
+       rng-gpios = <&pioD 8 GPIO_ACTIVE_LOW>;
+};
+
+/* USART3 is direct-connect to the Bluetooth UART on the radio SIP */
+&usart3 {
+       atmel,use-dma-rx;
+       atmel,use-dma-tx;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usart3 &pinctrl_usart3_rts_cts>;
+       status = "okay";
+};
+
+&spi1 {
+       cs-gpios = <&pioC 25 0>, <0>, <0>, <0>;
+};
+
+&ebi {
+       pinctrl-0 = <&pinctrl_ebi_nand_addr>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&nand_controller {
+       status = "okay";
+
+       nand: nand@3 {
+               reg = <0x3 0x0 0x2>;
+               atmel,rb = <0>;
+               nand-bus-width = <8>;
+               nand-ecc-mode = "hw";
+               nand-ecc-strength = <8>;
+               nand-ecc-step-size = <512>;
+               nand-on-flash-bbt;
+               label = "atmel_nand";
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       at91bootstrap@0 {
+                               label = "at91bs";
+                               reg = <0x0 0x20000>;
+                       };
+
+                       uboot@20000 {
+                               label = "u-boot";
+                               reg = <0x20000 0x80000>;
+                       };
+
+                       ubootenv@a0000 {
+                               label = "u-boot-env";
+                               reg = <0xa0000 0x20000>;
+                       };
+
+                       ubootenv@c0000 {
+                               label = "u-boot-env";
+                               reg = <0xc0000 0x20000>;
+                       };
+
+                       kernel-a@e0000 {
+                               label = "kernel-a";
+                               reg = <0xe0000 0x500000>;
+                       };
+
+                       kernel-b@5e0000 {
+                               label = "kernel-b";
+                               reg = <0x5e0000 0x500000>;
+                       };
+
+                       rootfs-a@ae0000 {
+                               label = "rootfs-a";
+                               reg = <0xae0000 0x3000000>;
+                       };
+
+                       rootfs-b@3ae0000 {
+                               label = "rootfs-b";
+                               reg = <0x3ae0000 0x3000000>;
+                       };
+
+                       user@6ae0000 {
+                               label = "user";
+                               reg = <0x6ae0000 0x14e0000>;
+                       };
+               };
+       };
+};
+
+&usb0 {
+       atmel,vbus-gpio = <&pioB 13 GPIO_ACTIVE_LOW>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usba_vbus>;
+};
+
+&usb1 {
+       num-ports = <3>;
+       atmel,vbus-gpio = <&pioA 2 GPIO_ACTIVE_LOW>;
+       atmel,oc-gpio = <&pioA 4 GPIO_ACTIVE_LOW>;
+};
index 53c63d0a418a47ab67624d52dcc558c0b0071809..33f09d5ea0201ed80cd3456363e8f0070ca8470d 100644 (file)
                        };
 
                        pmc: pmc@fffffc00 {
-                               compatible = "atmel,at91rm9200-pmc", "syscon";
+                               compatible = "atmel,at91sam9261-pmc", "syscon";
                                reg = <0xfffffc00 0x100>;
                                interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
                                interrupt-controller;
index 87fb0660ab5d6790c44342276c1211bcc2f9422d..af68a86c99731f4c93e18310f8fb814d36215bff 100644 (file)
@@ -93,7 +93,7 @@
                        };
 
                        pmc: pmc@fffffc00 {
-                               compatible = "atmel,at91rm9200-pmc", "syscon";
+                               compatible = "atmel,at91sam9263-pmc", "syscon";
                                reg = <0xfffffc00 0x100>;
                                interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
                                interrupt-controller;
index bd001cca25a465e6cbb4e8c0dee7f6bf873eb001..8fb22030f00bc2b761fa0604fe317a1212f82cf3 100644 (file)
                        };
 
                        pmc: pmc@fffffc00 {
-                               compatible = "atmel,at91sam9g45-pmc", "syscon";
+                               compatible = "atmel,at91sam9rl-pmc", "syscon";
                                reg = <0xfffffc00 0x100>;
                                interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
                                interrupt-controller;
index a3c3c3128148b67e67f671c991a17cca53528a23..11c0ef102ab1a2ce5d10d0221ce54b080015faeb 100644 (file)
                                };
                        };
 
-                       rstc@fffffe00 {
+                       reset_controller: rstc@fffffe00 {
                                compatible = "atmel,at91sam9g45-rstc";
                                reg = <0xfffffe00 0x10>;
                                clocks = <&clk32k>;
                        };
 
-                       shdwc@fffffe10 {
+                       shutdown_controller: shdwc@fffffe10 {
                                compatible = "atmel,at91sam9x5-shdwc";
                                reg = <0xfffffe10 0x10>;
                                clocks = <&clk32k>;
                                clock-names = "dma_clk";
                        };
 
-                       pinctrl@fffff400 {
+                       pinctrl: pinctrl@fffff400 {
                                #address-cells = <1>;
                                #size-cells = <1>;
                                compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus";
                                };
                        };
 
-                       watchdog@fffffe40 {
+                       watchdog: watchdog@fffffe40 {
                                compatible = "atmel,at91sam9260-wdt";
                                reg = <0xfffffe40 0x10>;
                                interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
index 2c4df2d2d4a6e1165fe27565a19d681c47a32cfa..253df7170a4e263bec22d589ddf6d34d0bccdacf 100644 (file)
        model = "Broadcom Cygnus SoC";
        interrupt-parent = <&gic>;
 
+       aliases {
+               ethernet0 = &eth0;
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                        status = "disabled";
                };
 
+               rng: rng@18032000 {
+                       compatible = "brcm,iproc-rng200";
+                       reg = <0x18032000 0x28>;
+               };
+
                sdhci0: sdhci@18041000 {
                        compatible = "brcm,sdhci-iproc-cygnus";
                        reg = <0x18041000 0x100>;
diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts b/arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts
new file mode 100644 (file)
index 0000000..4764a25
--- /dev/null
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+#include "bcm2835-rpi-cm1.dtsi"
+#include "bcm283x-rpi-usb-host.dtsi"
+
+/ {
+       compatible = "raspberrypi,compute-module", "brcm,bcm2835";
+       model = "Raspberry Pi Compute Module IO board rev1";
+};
+
+&gpio {
+       /*
+        * This is based on the official GPU firmware DT blob.
+        *
+        * Legend:
+        * "NC" = not connected (no rail from the SoC)
+        * "FOO" = GPIO line named "FOO" on the schematic
+        * "FOO_N" = GPIO line named "FOO" on schematic, active low
+        */
+       gpio-line-names = "GPIO0",
+                         "GPIO1",
+                         "GPIO2",
+                         "GPIO3",
+                         "GPIO4",
+                         "GPIO5",
+                         "GPIO6",
+                         "GPIO7",
+                         "GPIO8",
+                         "GPIO9",
+                         "GPIO10",
+                         "GPIO11",
+                         "GPIO12",
+                         "GPIO13",
+                         "GPIO14",
+                         "GPIO15",
+                         "GPIO16",
+                         "GPIO17",
+                         "GPIO18",
+                         "GPIO19",
+                         "GPIO20",
+                         "GPIO21",
+                         "GPIO22",
+                         "GPIO23",
+                         "GPIO24",
+                         "GPIO25",
+                         "GPIO26",
+                         "GPIO27",
+                         "GPIO28",
+                         "GPIO29",
+                         "GPIO30",
+                         "GPIO31",
+                         "GPIO32",
+                         "GPIO33",
+                         "GPIO34",
+                         "GPIO35",
+                         "GPIO36",
+                         "GPIO37",
+                         "GPIO38",
+                         "GPIO39",
+                         "GPIO40",
+                         "GPIO41",
+                         "GPIO42",
+                         "GPIO43",
+                         "GPIO44",
+                         "GPIO45",
+                         "HDMI_HPD_N",
+                         /* Also used as ACT LED */
+                         "EMMC_EN_N",
+                         /* Used by eMMC */
+                         "SD_CLK_R",
+                         "SD_CMD_R",
+                         "SD_DATA0_R",
+                         "SD_DATA1_R",
+                         "SD_DATA2_R",
+                         "SD_DATA3_R";
+
+       pinctrl-0 = <&gpioout &alt0>;
+};
+
+&hdmi {
+       hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_gpio14>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi b/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi
new file mode 100644 (file)
index 0000000..ef22c2d
--- /dev/null
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+#include "bcm2835.dtsi"
+#include "bcm2835-rpi.dtsi"
+
+/ {
+       leds {
+               act {
+                       gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       reg_3v3: fixed-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       reg_1v8: fixed-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+       };
+};
+
+&sdhost {
+       non-removable;
+       vmmc-supply = <&reg_3v3>;
+       vqmmc-supply = <&reg_1v8>;
+};
index 7704bb029605ed94f3ea8aad77dfe301e4b0beac..beb6c502dadc7bc09537f37e6d7b12e44ec466b7 100644 (file)
                };
        };
 
+       arm-pmu {
+               compatible = "arm,cortex-a53-pmu";
+               interrupt-parent = <&local_intc>;
+               interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
        timer {
                compatible = "arm,armv7-timer";
                interrupt-parent = <&local_intc>;
index 61315cf734efebf9f44bd72ffac55b99deda5a7b..31b29646b14cf0725cf312002f23ffe2074006e6 100644 (file)
                        clock-frequency = <1000000>;
                };
 
+               txp@7e004000 {
+                       compatible = "brcm,bcm2835-txp";
+                       reg = <0x7e004000 0x20>;
+                       interrupts = <1 11>;
+               };
+
                dma: dma@7e007000 {
                        compatible = "brcm,bcm2835-dma";
                        reg = <0x7e007000 0xf00>;
index ff2e551b9058448e4fd889ee11e5f12f88914666..79d454ff3be4205f9cb816f7c5a819f91c6e140f 100644 (file)
@@ -90,3 +90,7 @@
                };
        };
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 3bcc03788f38f8f89e135712e5e7c2cc272e8005..99365bb8c41ed39cce31583a2e7a3ae78113bfa7 100644 (file)
@@ -80,3 +80,7 @@
                };
        };
 };
+
+&usb3_phy {
+       status = "okay";
+};
index a587384f8e401ecea027400f35acda26defedc8f..bc330b1f6de094f0cd4bd94623f5ee929a337188 100644 (file)
 &spi_nor {
        status = "okay";
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 6c8f0ad823326c56250cfa06fa95e3c00d5ae633..258d2b251900cd4b6ade3a6198b24a71655f6d23 100644 (file)
@@ -38,3 +38,7 @@
                };
        };
 };
+
+&usb3_phy {
+       status = "okay";
+};
index ebda45fe9ea4d4905467c4ea7892926bc8dda5eb..e7fdaed99bd0acd0607b5caf8cbbebb4aab0528f 100644 (file)
@@ -57,3 +57,7 @@
 &spi_nor {
        status = "okay";
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 9dd0e22c906afb4b6740a7e99c1fbcfc34a5a691..42bafc6440130be6f729b1f69f1228b7cc72659e 100644 (file)
@@ -64,3 +64,7 @@
 &spi_nor {
        status = "okay";
 };
+
+&usb3_phy {
+       status = "okay";
+};
index d7c34fa72b4b7525303ba5e06b93e0c9c00b4b82..dce35eb79dbe55c3a14e4e8993b2c58a368c544c 100644 (file)
@@ -91,3 +91,7 @@
 &spi_nor {
        status = "okay";
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 2642494c97a1bf99238c40ff0bd877b37c57b96b..b7a024b7951bcada9c3eae17087048f0b2609020 100644 (file)
@@ -83,3 +83,7 @@
 &spi_nor {
        status = "okay";
 };
+
+&usb3_phy {
+       status = "okay";
+};
index e7b09b7b7d25700d841841e56c3de720b0ceabde..f7f834cd3448d0b4f7ea54869285a50f9455d409 100644 (file)
                };
        };
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 16314fcc6e568cdfa580bd0f235297aa60817d3e..76a2bab3bc6f519644389da2b84147955fe4e4ba 100644 (file)
@@ -74,3 +74,7 @@
                };
        };
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 328aa90240ce7346079695a3b8bf8d5425d1626d..69e3570e03dd2c207cc6ad4b4f27d9c2420415d4 100644 (file)
                };
        };
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 8ea46eed26e231e803f8b085523f5f53b853ebeb..0f6f0fe13bfb461f12cb9d9abfb9edfd00c71be1 100644 (file)
                };
        };
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 5eeac7302329605fadff558c0fc8fdc2b7ab9301..f7708974499671bc989ef1003f7e9dc7d3ebc151 100644 (file)
@@ -57,3 +57,7 @@
 &spi_nor {
        status = "okay";
 };
+
+&usb3_phy {
+       status = "okay";
+};
index da4d9ec62fc65e9fa72dc798453d78a1828938c5..4d427863756fefcfafa1bfba5efd35f19bce477a 100644 (file)
 &spi_nor {
        status = "okay";
 };
+
+&usb3_phy {
+       status = "okay";
+};
index c94c732188fbe05c51cd331c1f89bb118b8812c2..5f663f848db1fabb66c0fd8eb376f9601481296a 100644 (file)
@@ -99,3 +99,7 @@
 &usb2 {
        vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 22271818f901f428d99418fc7dfd40f00e684221..2033411240c78ce9ffdf0c70d36a7b9b3dbfb703 100644 (file)
@@ -62,3 +62,7 @@
                };
        };
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 79a9633ec4174c78e23ca3b3ca63b670b676290e..77d1687b4228b60950628de95a4f7d14c0b81325 100644 (file)
 &spi_nor {
        status = "okay";
 };
+
+&usb3_phy {
+       status = "okay";
+};
index db744a5e122da7ddf7a921c086e91d810ba9ab32..983149b55269c3be51227a4b645f9a8c9a9e843f 100644 (file)
@@ -39,3 +39,7 @@
                };
        };
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 9e267d38df4c4d2e4631de4b1297826226f74c46..ca41481b44bd1ff296b0de84dec67868a053225e 100644 (file)
 &usb3 {
        vcc-gpio = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
 };
+
+&usb3_phy {
+       status = "okay";
+};
index d266131652addd105eb8750255a2f825a6c724a6..aa69e656d395367fad0fc3beeb1633463ac9bd46 100644 (file)
 &usb3 {
        vcc-gpio = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
 };
+
+&usb3_phy {
+       status = "okay";
+};
index f5bf6586ae07e9e73d6b442f36c2decf33d54073..c7143a9daa1a961c1c013ec688c5c15c9dd4d127 100644 (file)
 &spi_nor {
        status = "okay";
 };
+
+&usb3_phy {
+       status = "okay";
+};
index d173bcd93b918bc37d4d280b934487109c13c03b..03c1ab188576fd84862da334dac560d533f23bbc 100644 (file)
 &spi_nor {
        status = "okay";
 };
+
+&usb3_phy {
+       status = "okay";
+};
index f47afe36d8579f378ca09a9d3d9838505359d08d..36efe410dcd71a54ae6f802e405fb9b60296b58f 100644 (file)
                        linux,code = <KEY_WPS_BUTTON>;
                        gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
                };
+
+               rfkill {
+                               label = "WiFi";
+                               linux,code = <KEY_RFKILL>;
+                               gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
+               };
+
+               reset {
+                               label = "Reset";
+                               linux,code = <KEY_RESTART>;
+                               gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               wps {
+                       label = "bcm53xx:white:wps";
+                       gpios = <&chipcommon 22 GPIO_ACTIVE_LOW>;
+               };
+
+               usb2 {
+                       label = "bcm53xx:green:usb2";
+                       gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
+                       trigger-sources = <&ohci_port2>, <&ehci_port2>;
+                       linux,default-trigger = "usbport";
+               };
+
+               usb3 {
+                       label = "bcm53xx:green:usb3";
+                       gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
+                       trigger-sources = <&ohci_port1>, <&ehci_port1>,
+                                         <&xhci_port1>;
+                       linux,default-trigger = "usbport";
+               };
+
+               power {
+                       label = "bcm53xx:white:power";
+                       gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
+               };
+
+               wifi-disabled {
+                       label = "bcm53xx:amber:wifi-disabled";
+                       gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
+               };
+
+               wifi-enabled {
+                       label = "bcm53xx:white:wifi-enabled";
+                       gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
+               };
+
+               bluebar1 {
+                       label = "bcm53xx:white:bluebar1";
+                       gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
+               };
+
+               bluebar2 {
+                       label = "bcm53xx:white:bluebar2";
+                       gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
+               };
+
+               bluebar3 {
+                       label = "bcm53xx:white:bluebar3";
+                       gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
+               };
+
+               bluebar4 {
+                       label = "bcm53xx:white:bluebar4";
+                       gpios = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
+               };
+
+               bluebar5 {
+                       label = "bcm53xx:white:bluebar5";
+                       gpios = <&chipcommon 19 GPIO_ACTIVE_HIGH>;
+               };
+
+               bluebar6 {
+                       label = "bcm53xx:white:bluebar6";
+                       gpios = <&chipcommon 20 GPIO_ACTIVE_HIGH>;
+               };
+
+               bluebar7 {
+                       label = "bcm53xx:white:bluebar7";
+                       gpios = <&chipcommon 21 GPIO_ACTIVE_HIGH>;
+               };
+
+               bluebar8 {
+                       label = "bcm53xx:white:bluebar8";
+                       gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       mdio-bus-mux {
+               /* BIT(9) = 1 => external mdio */
+               mdio_ext: mdio@200 {
+                       reg = <0x200>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+       };
+
+       mdio-mii-mux {
+               compatible = "mdio-mux-mmioreg";
+               mdio-parent-bus = <&mdio_ext>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x1800c1c0 0x4>;
+
+               /* BIT(6) = mdc, BIT(7) = mdio */
+               mux-mask = <0xc0>;
+
+               mdio-mii@0 {
+                       /* Enable MII function */
+                       reg = <0x0>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       switch@0  {
+                               compatible = "brcm,bcm53125";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reset-gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
+                               reset-names = "robo_reset";
+                               reg = <0>;
+                               dsa,member = <1 0>;
+
+                               ports {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       port@0 {
+                                               reg = <0>;
+                                               label = "lan1";
+                                       };
+
+                                       port@1 {
+                                               reg = <1>;
+                                               label = "lan5";
+                                       };
+
+                                       port@2 {
+                                               reg = <2>;
+                                               label = "lan2";
+                                       };
+
+                                       port@3 {
+                                               reg = <3>;
+                                               label = "lan6";
+                                       };
+
+                                       port@4 {
+                                               reg = <4>;
+                                               label = "lan3";
+                                       };
+
+                                       sw1_p8: port@8 {
+                                               reg = <8>;
+                                               ethernet = <&sw0_p0>;
+                                               label = "cpu";
+
+                                               fixed-link {
+                                                       speed = <1000>;
+                                                       full-duplex;
+                                               };
+                                       };
+                               };
+                       };
+               };
+       };
+};
+
+&usb2 {
+       vcc-gpio = <&chipcommon 13 GPIO_ACTIVE_HIGH>;
+};
+
+&usb3 {
+       vcc-gpio = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
+};
+
+&srab {
+       compatible = "brcm,bcm53012-srab", "brcm,bcm5301x-srab";
+       status = "okay";
+       dsa,member = <0 0>;
+
+       ports {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               port@1 {
+                       reg = <1>;
+                       label = "lan7";
+               };
+
+               port@2 {
+                       reg = <2>;
+                       label = "lan4";
+               };
+
+               port@3 {
+                       reg = <3>;
+                       label = "lan8";
+               };
+
+               port@4 {
+                       reg = <4>;
+                       label = "wan";
+               };
+
+               port@8 {
+                       reg = <8>;
+                       ethernet = <&gmac2>;
+                       label = "cpu";
+
+                       fixed-link {
+                               speed = <1000>;
+                               full-duplex;
+                       };
+               };
+
+               sw0_p0: port@0 {
+                       reg = <0>;
+                       label = "extsw";
+
+                       fixed-link {
+                               speed = <1000>;
+                               full-duplex;
+                       };
+               };
        };
 };
+
+&usb3_phy {
+       status = "okay";
+};
index a5cef51cfe4f31b601eedb218043c74c9505aa64..3e5e9972cd976b061e3a9a97a381683aa3bf120f 100644 (file)
@@ -60,3 +60,7 @@
 &spi_nor {
        status = "okay";
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 7496aabf8f77ca591d5ae94e85481e5a472b6e43..7acbecd429502cc6b336279fab55ac3e4435e3fd 100644 (file)
@@ -60,3 +60,7 @@
 &spi_nor {
        status = "okay";
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 53aaa5212610fb6efe8b42a50fa00c7ec6c24078..f4558d9d276956128abc7a936ea763187455002c 100644 (file)
 &spi_nor {
        status = "okay";
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 0e718edc065afb001f8c5b6b30b5cf3d8f94adbe..30719380b6c0e1af3b3a7d1468c2e4a1444a2b88 100644 (file)
@@ -91,3 +91,7 @@
                };
        };
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 4840a782fc053266257438c44529bc432b22a9c5..f7c3e274b354b8c3ff5946fe36164953aa7a408e 100644 (file)
@@ -7,9 +7,10 @@
 #include "bcm4708.dtsi"
 
 / {
-       usb3_phy: usb3-phy {
-               compatible = "brcm,ns-bx-usb3-phy";
-       };
+};
+
+&usb3_phy {
+       compatible = "brcm,ns-bx-usb3-phy";
 };
 
 &uart0 {
index ef995e50ee12bfd8b3d90d9e07062a41e04f4ff3..bc607d11eef8e958f654ced7c22e7a409a5fbdff 100644 (file)
                clock-names = "phy-ref-clk";
        };
 
-       usb3_phy: usb3-phy {
-               compatible = "brcm,ns-ax-usb3-phy";
-               reg = <0x18105000 0x1000>, <0x18003000 0x1000>;
-               reg-names = "dmp", "ccb-mii";
-               #phy-cells = <0>;
-       };
-
        axi@18000000 {
                compatible = "brcm,bus-axi";
                reg = <0x18000000 0x1000>;
                reg = <0x18003000 0x8>;
                #size-cells = <1>;
                #address-cells = <0>;
-               status = "disabled";
+       };
+
+       mdio-bus-mux {
+               compatible = "mdio-mux-mmioreg";
+               mdio-parent-bus = <&mdio>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x18003000 0x4>;
+               mux-mask = <0x200>;
+
+               mdio@0 {
+                       reg = <0x0>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       usb3_phy: usb3-phy@10 {
+                               compatible = "brcm,ns-ax-usb3-phy";
+                               reg = <0x10>;
+                               usb3-dmp-syscon = <&usb3_dmp>;
+                               #phy-cells = <0>;
+                               status = "disabled";
+                       };
+               };
+       };
+
+       usb3_dmp: syscon@18105000 {
+               reg = <0x18105000 0x1000>;
        };
 
        i2c0: i2c@18009000 {
index 16007d72c346ab76d48c4c73d356a353af0e4133..453a2a37dabd3ccbe04d5668cc762aa52213f568 100644 (file)
                };
        };
 
+       timer {
+               compatible = "arm,armv7-timer";
+               interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+       };
+
        clocks {
                #address-cells = <1>;
                #size-cells = <1>;
index 2e08c895f2818cefbb799a5011190bfd724c0225..934f07adfe3c00b025097cfc4cb911ddfa061645 100644 (file)
@@ -42,3 +42,7 @@
                reg = <0x00000000 0x08000000>;
        };
 };
+
+&usb3_phy {
+       status = "okay";
+};
index c37616c67edcc0810d46c93bfcb78eacdf05c5ed..31e4dd098776a490e0f0578f94e4c12697e0776f 100644 (file)
@@ -42,3 +42,7 @@
                reg = <0x00000000 0x08000000>;
        };
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 40e694bfe5cabedfbda67e6632fc388214ccad2e..17f63c7a04374ab1f23909c318cb01f56a16966f 100644 (file)
@@ -90,3 +90,7 @@
                };
        };
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 3076e81699cf86d01b19b5206036392fe1234e67..11b0f5ed99e6fc977c23dd38e6db1c61323467d6 100644 (file)
@@ -95,3 +95,7 @@
                reg = <0x00700000 0x00900000>;
        };
 };
+
+&usb3_phy {
+       status = "okay";
+};
index 79c168e2714b7e6c3c4490f180d1c44ebd38f0ea..e798055d6989d374609fd3cc49da44b0ea01ccb4 100644 (file)
 &uart1 {
        status = "okay";
 };
+
+&usb3_phy {
+       status = "okay";
+};
index db67377af2664670322da8ca2e54c2c8de341eb7..d2f7d984bba5cf94692ab338addce40ea2201e04 100644 (file)
                        device_type = "cpu";
                        next-level-cache = <&l2>;
                        reg = <1>;
+
+                       clocks = <&chip_clk CLKID_CPU>;
+                       clock-latency = <100000>;
+                       operating-points = <
+                               /* kHz    uV */
+                               1200000 1200000
+                               1000000 1200000
+                               800000  1200000
+                               600000  1200000
+                       >;
                };
        };
 
index 516a7ce257915d637f47ea26883ec69e90b406d2..99d6872a6dfcca9f9abd21ca21fbfa0f11ae6d52 100644 (file)
                        device_type = "cpu";
                        next-level-cache = <&l2>;
                        reg = <1>;
+
+                       clocks = <&chip_clk CLKID_CPU>;
+                       clock-latency = <100000>;
+                       /* Can be modified by the bootloader */
+                       operating-points = <
+                               /* kHz    uV */
+                               1200000 1200000
+                               1000000 1200000
+                               800000  1200000
+                               600000  1200000
+                       >;
                };
 
                cpu2: cpu@2 {
                        device_type = "cpu";
                        next-level-cache = <&l2>;
                        reg = <2>;
+
+                       clocks = <&chip_clk CLKID_CPU>;
+                       clock-latency = <100000>;
+                       /* Can be modified by the bootloader */
+                       operating-points = <
+                               /* kHz    uV */
+                               1200000 1200000
+                               1000000 1200000
+                               800000  1200000
+                               600000  1200000
+                       >;
                };
 
                cpu3: cpu@3 {
                        device_type = "cpu";
                        next-level-cache = <&l2>;
                        reg = <3>;
+
+                       clocks = <&chip_clk CLKID_CPU>;
+                       clock-latency = <100000>;
+                       /* Can be modified by the bootloader */
+                       operating-points = <
+                               /* kHz    uV */
+                               1200000 1200000
+                               1000000 1200000
+                               800000  1200000
+                               600000  1200000
+                       >;
                };
        };
 
index 14dff3e188ed5fa83a801c96ddd42adb9e60aad3..0102ffc5aa53e457b42d67608e477387da63b056 100644 (file)
        };
 };
 
+&ref_clk {
+       clock-frequency = <24000000>;
+};
+
 &edma0 {
        ti,edma-reserved-slot-ranges = <32 50>;
 };
index 0e82bb988fde6c97f6d77ffb9f2afe28e4978af7..f9b75790584503a70a4a4a95c2cc04b70cf6e9e0 100644 (file)
                spi0 = &spi1;
        };
 
+       backlight: backlight-pwm {
+               pinctrl-names = "default";
+               pinctrl-0 = <&ecap2_pins>;
+               power-supply = <&backlight_lcd>;
+               compatible = "pwm-backlight";
+               /*
+                * The PWM here corresponds to production hardware. The
+                * schematic needs to be 1015171 (15 March 2010), Rev A
+                * or newer.
+                */
+               pwms = <&ecap2 0 50000 0>;
+               brightness-levels = <0 10 20 30 40 50 60 70 80 90 99>;
+               default-brightness-level = <7>;
+       };
+
+       panel {
+               compatible = "ti,tilcdc,panel";
+               pinctrl-names = "default";
+               pinctrl-0 = <&lcd_pins>;
+               /*
+                * The vpif and the LCD are mutually exclusive.
+                * To enable VPIF, change the status below to 'disabled' then
+                * then change the status of the vpif below to 'okay'
+                */
+               status = "okay";
+               enable-gpios = <&gpio 40 GPIO_ACTIVE_HIGH>; /* lcd_panel_pwr */
+
+               panel-info {
+                       ac-bias         = <255>;
+                       ac-bias-intrpt  = <0>;
+                       dma-burst-sz    = <16>;
+                       bpp             = <16>;
+                       fdd             = <0x80>;
+                       sync-edge       = <0>;
+                       sync-ctrl       = <1>;
+                       raster-order    = <0>;
+                       fifo-th         = <0>;
+               };
+
+               display-timings {
+                       native-mode = <&timing0>;
+                       timing0: 480x272 {
+                               clock-frequency = <9000000>;
+                               hactive = <480>;
+                               vactive = <272>;
+                               hfront-porch = <3>;
+                               hback-porch = <2>;
+                               hsync-len = <42>;
+                               vback-porch = <3>;
+                               vfront-porch = <4>;
+                               vsync-len = <11>;
+                               hsync-active = <0>;
+                               vsync-active = <0>;
+                               de-active = <1>;
+                               pixelclk-active = <1>;
+                       };
+               };
+       };
+
        vbat: fixedregulator0 {
                compatible = "regulator-fixed";
                regulator-name = "vbat";
                regulator-boot-on;
        };
 
+       backlight_lcd: backlight-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd_backlight_pwr";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio 47 GPIO_ACTIVE_HIGH>; /* lcd_backlight_pwr */
+               enable-active-high;
+       };
+
        sound {
                compatible = "simple-audio-card";
                simple-audio-card,name = "DA850/OMAP-L138 EVM";
        };
 };
 
+&ecap2 {
+       status = "okay";
+};
+
+&ref_clk {
+       clock-frequency = <24000000>;
+};
+
 &pmx_core {
        status = "okay";
 
        };
 };
 
+&sata {
+       status = "okay";
+};
+
 &serial0 {
        status = "okay";
 };
        status = "okay";
 };
 
+&lcdc {
+       status = "okay";
+};
+
 &i2c0 {
        status = "okay";
        clock-frequency = <100000>;
 &vpif {
        pinctrl-names = "default";
        pinctrl-0 = <&vpif_capture_pins>, <&vpif_display_pins>;
-       status = "okay";
+       /*
+        * The vpif and the LCD are mutually exclusive.
+        * To enable VPIF, disable the ti,tilcdc,panel then
+        * change the status below to 'okay'
+        */
+       status = "disabled";
 };
index 0edf769ea95c93c1449dfef12b71213251d7c973..0177e3ed20febdf3d2aa820ccd0bfd3e2a708099 100644 (file)
        };
 };
 
+&ref_clk {
+       clock-frequency = <24000000>;
+};
+
 &pmx_core {
        status = "okay";
 
        status = "okay";
 };
 
+&sata_refclk {
+       status = "okay";
+       clock-frequency = <100000000>;
+};
+
 &sata {
        status = "okay";
 };
index ee3932475ce7b906d0e6305de117d51277f857e6..c4729d0e6c196e73b635d8499ec8f2108429ee31 100644 (file)
                rechargeable-gpios = <&gpio 136 GPIO_ACTIVE_LOW>;
        };
 
+       bt_slow_clk: bt-clock {
+               pinctrl-names = "default";
+               pinctrl-0 = <&ecap2_pins>, <&bt_clock_bias>;
+               compatible = "pwm-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+               pwms = <&ecap2 0 30518 0>;
+       };
+
        /* ARM local RAM */
        memory@ffff0000 {
                compatible = "syscon", "simple-mfd";
        };
 };
 
+&ref_clk {
+       clock-frequency = <24000000>;
+};
+
 &pmx_core {
        status = "okay";
 
                        bias-disable;
                };
        };
+
+       bt_clock_bias: bt-clock-bias-groups {
+               disable {
+                       groups = "cp2";
+                       bias-disable;
+               };
+       };
+
+       bt_pic_bias: bt-pic-bias-groups {
+               disable {
+                       groups = "cp20";
+                       bias-disable;
+               };
+       };
 };
 
 /* Input port 1 */
        pinctrl-0 = <&serial1_rxtx_pins>;
 };
 
+&serial2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&serial2_rxtx_pins>, <&serial2_rtscts_pins>, <&bt_pic_bias>;
+       status = "okay";
+
+       bluetooth {
+               compatible = "ti,cc2560";
+               clocks = <&bt_slow_clk>;
+               clock-names = "ext_clock";
+               enable-gpios = <&gpio 73 GPIO_ACTIVE_HIGH>;
+               max-speed = <2000000>;
+               nvmem-cells = <&bdaddr>;
+               nvmem-cell-names = "bd-address";
+       };
+};
+
 &rtc0 {
        status = "okay";
 };
                pagesize = <64>;
                read-only;
                reg = <0x50>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               bdaddr: bdaddr@3f06 {
+                       reg = <0x3f06 0x06>;
+               };
        };
 };
 
        };
 };
 
+&ecap2 {
+       status = "okay";
+};
+
 &ehrpwm0 {
        status = "okay";
 };
                gpios = <6 GPIO_ACTIVE_HIGH>;
                output-high;
        };
+
+       /* Don't impede Bluetooth clock signal */
+       bt_clock_en {
+               gpio-hog;
+               gpios = <5 GPIO_ACTIVE_HIGH>;
+               input;
+       };
+
+       /*
+        * There is a PIC microcontroller for interfacing with an Apple MFi
+        * chip. This interferes with normal Bluetooth operation, so we need
+        * to make sure it is turned off. Note: The publicly available
+        * schematics from LEGO don't show that these pins are connected to
+        * anything, but they are present in the source code from LEGO.
+        */
+
+       bt_pic_en {
+               gpio-hog;
+               gpios = <51 GPIO_ACTIVE_HIGH>;
+               output-low;
+       };
+
+       bt_pic_rst {
+               gpio-hog;
+               gpios = <78 GPIO_ACTIVE_HIGH>;
+               output-high;
+       };
+
+       bt_pic_cts {
+               gpio-hog;
+               gpios = <87 GPIO_ACTIVE_HIGH>;
+               input;
+       };
 };
 
 &usb_phy {
index 0f4f817a9e229c58f973f935a6f5906b1e0f8979..47aa53ba6b92236d4616992aeea113a81bfb8c97 100644 (file)
                        reg = <0xfffee000 0x2000>;
                };
        };
+       clocks: clocks {
+               ref_clk: ref_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-output-names = "ref_clk";
+               };
+               sata_refclk: sata_refclk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-output-names = "sata_refclk";
+                       status = "disabled";
+               };
+               usb_refclkin: usb_refclkin {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-output-names = "usb_refclkin";
+                       status = "disabled";
+               };
+       };
        dsp: dsp@11800000 {
                compatible = "ti,da850-dsp";
                reg = <0x11800000 0x40000>,
@@ -42,6 +61,8 @@
                reg-names = "l2sram", "l1pram", "l1dram", "host1cfg", "chipsig";
                interrupt-parent = <&intc>;
                interrupts = <28>;
+               clocks = <&psc0 15>;
+               resets = <&psc0 15>;
                status = "disabled";
        };
        soc@1c00000 {
                ranges = <0x0 0x01c00000 0x400000>;
                interrupt-parent = <&intc>;
 
+               psc0: clock-controller@10000 {
+                       compatible = "ti,da850-psc0";
+                       reg = <0x10000 0x1000>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+                       #power-domain-cells = <1>;
+                       clocks = <&pll0_sysclk 1>, <&pll0_sysclk 2>,
+                                <&pll0_sysclk 4>, <&pll0_sysclk 6>,
+                                <&async1_clk>;
+                       clock-names = "pll0_sysclk1", "pll0_sysclk2",
+                                     "pll0_sysclk4", "pll0_sysclk6",
+                                     "async1";
+               };
+               pll0: clock-controller@11000 {
+                       compatible = "ti,da850-pll0";
+                       reg = <0x11000 0x1000>;
+                       clocks = <&ref_clk>, <&pll1_sysclk 3>;
+                       clock-names = "clksrc", "extclksrc";
+
+                       pll0_pllout: pllout {
+                               #clock-cells = <0>;
+                       };
+                       pll0_sysclk: sysclk {
+                               #clock-cells = <1>;
+                       };
+                       pll0_auxclk: auxclk {
+                               #clock-cells = <0>;
+                       };
+                       pll0_obsclk: obsclk {
+                               #clock-cells = <0>;
+                       };
+               };
                pmx_core: pinmux@14120 {
                        compatible = "pinctrl-single";
                        reg = <0x14120 0x50>;
                        usb_phy: usb-phy {
                                compatible = "ti,da830-usb-phy";
                                #phy-cells = <1>;
+                               clocks = <&usb_phy_clk 0>, <&usb_phy_clk 1>;
+                               clock-names = "usb0_clk48", "usb1_clk48";
                                status = "disabled";
                        };
+                       usb_phy_clk: usb-phy-clocks {
+                               compatible = "ti,da830-usb-phy-clocks";
+                               #clock-cells = <1>;
+                               clocks = <&psc1 1>, <&usb_refclkin>,
+                                        <&pll0_auxclk>;
+                               clock-names = "fck", "usb_refclkin", "auxclk";
+                       };
+                       ehrpwm_tbclk: ehrpwm_tbclk {
+                               compatible = "ti,da830-tbclksync";
+                               #clock-cells = <0>;
+                               clocks = <&psc1 17>;
+                               clock-names = "fck";
+                       };
+                       div4p5_clk: div4.5 {
+                               compatible = "ti,da830-div4p5ena";
+                               #clock-cells = <0>;
+                               clocks = <&pll0_pllout>;
+                               clock-names = "pll0_pllout";
+                       };
+                       async1_clk: async1 {
+                               compatible = "ti,da850-async1-clksrc";
+                               #clock-cells = <0>;
+                               clocks = <&pll0_sysclk 3>, <&div4p5_clk>;
+                               clock-names = "pll0_sysclk3", "div4.5";
+                       };
+                       async3_clk: async3 {
+                               compatible = "ti,da850-async3-clksrc";
+                               #clock-cells = <0>;
+                               clocks = <&pll0_sysclk 2>, <&pll1_sysclk 2>;
+                               clock-names = "pll0_sysclk2", "pll1_sysclk2";
+                       };
                };
                edma0: edma@0 {
                        compatible = "ti,edma3-tpcc";
                        #dma-cells = <2>;
 
                        ti,tptcs = <&edma0_tptc0 7>, <&edma0_tptc1 0>;
+                       power-domains = <&psc0 0>;
                };
                edma0_tptc0: tptc@8000 {
                        compatible = "ti,edma3-tptc";
                        reg =   <0x8000 0x400>;
                        interrupts = <13>;
                        interrupt-names = "edm3_tcerrint";
+                       power-domains = <&psc0 1>;
                };
                edma0_tptc1: tptc@8400 {
                        compatible = "ti,edma3-tptc";
                        reg =   <0x8400 0x400>;
                        interrupts = <32>;
                        interrupt-names = "edm3_tcerrint";
+                       power-domains = <&psc0 2>;
                };
                edma1: edma@230000 {
                        compatible = "ti,edma3-tpcc";
                        #dma-cells = <2>;
 
                        ti,tptcs = <&edma1_tptc0 7>;
+                       power-domains = <&psc1 0>;
                };
                edma1_tptc0: tptc@238000 {
                        compatible = "ti,edma3-tptc";
                        reg =   <0x238000 0x400>;
                        interrupts = <95>;
                        interrupt-names = "edm3_tcerrint";
+                       power-domains = <&psc1 21>;
                };
                serial0: serial@42000 {
                        compatible = "ti,da830-uart", "ns16550a";
                        reg-io-width = <4>;
                        reg-shift = <2>;
                        interrupts = <25>;
+                       clocks = <&psc0 9>;
+                       power-domains = <&psc0 9>;
                        status = "disabled";
                };
                serial1: serial@10c000 {
                        reg-io-width = <4>;
                        reg-shift = <2>;
                        interrupts = <53>;
+                       clocks = <&psc1 12>;
+                       power-domains = <&psc1 12>;
                        status = "disabled";
                };
                serial2: serial@10d000 {
                        reg-io-width = <4>;
                        reg-shift = <2>;
                        interrupts = <61>;
+                       clocks = <&psc1 13>;
+                       power-domains = <&psc1 13>;
                        status = "disabled";
                };
                rtc0: rtc@23000 {
                        reg = <0x23000 0x1000>;
                        interrupts = <19
                                      19>;
+                       clocks = <&pll0_auxclk>;
+                       clock-names = "int-clk";
                        status = "disabled";
                };
                i2c0: i2c@22000 {
                        interrupts = <15>;
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       clocks = <&pll0_auxclk>;
                        status = "disabled";
                };
                i2c1: i2c@228000 {
                        interrupts = <51>;
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       clocks = <&psc1 11>;
+                       power-domains = <&psc1 11>;
                        status = "disabled";
                };
+               clocksource: timer@20000 {
+                       compatible = "ti,da830-timer";
+                       reg = <0x20000 0x1000>;
+                       interrupts = <12>, <13>;
+                       interrupt-names = "tint12", "tint34";
+                       clocks = <&pll0_auxclk>;
+               };
                wdt: wdt@21000 {
                        compatible = "ti,davinci-wdt";
                        reg = <0x21000 0x1000>;
+                       clocks = <&pll0_auxclk>;
                        status = "disabled";
                };
                mmc0: mmc@40000 {
                        interrupts = <16>;
                        dmas = <&edma0 16 0>, <&edma0 17 0>;
                        dma-names = "rx", "tx";
+                       clocks = <&psc0 5>;
                        status = "disabled";
                };
                vpif: video@217000 {
                        compatible = "ti,da850-vpif";
                        reg = <0x217000 0x1000>;
                        interrupts = <92>;
+                       power-domains = <&psc1 9>;
                        status = "disabled";
 
                        /* VPIF capture port */
                        interrupts = <72>;
                        dmas = <&edma1 28 0>, <&edma1 29 0>;
                        dma-names = "rx", "tx";
+                       clocks = <&psc1 18>;
                        status = "disabled";
                };
                ehrpwm0: pwm@300000 {
                                     "ti,am33xx-ehrpwm";
                        #pwm-cells = <3>;
                        reg = <0x300000 0x2000>;
+                       clocks = <&psc1 17>, <&ehrpwm_tbclk>;
+                       clock-names = "fck", "tbclk";
+                       power-domains = <&psc1 17>;
                        status = "disabled";
                };
                ehrpwm1: pwm@302000 {
                                     "ti,am33xx-ehrpwm";
                        #pwm-cells = <3>;
                        reg = <0x302000 0x2000>;
+                       clocks = <&psc1 17>, <&ehrpwm_tbclk>;
+                       clock-names = "fck", "tbclk";
+                       power-domains = <&psc1 17>;
                        status = "disabled";
                };
                ecap0: ecap@306000 {
                                     "ti,am33xx-ecap";
                        #pwm-cells = <3>;
                        reg = <0x306000 0x80>;
+                       clocks = <&psc1 20>;
+                       clock-names = "fck";
+                       power-domains = <&psc1 20>;
                        status = "disabled";
                };
                ecap1: ecap@307000 {
                                     "ti,am33xx-ecap";
                        #pwm-cells = <3>;
                        reg = <0x307000 0x80>;
+                       clocks = <&psc1 20>;
+                       clock-names = "fck";
+                       power-domains = <&psc1 20>;
                        status = "disabled";
                };
                ecap2: ecap@308000 {
                                     "ti,am33xx-ecap";
                        #pwm-cells = <3>;
                        reg = <0x308000 0x80>;
+                       clocks = <&psc1 20>;
+                       clock-names = "fck";
+                       power-domains = <&psc1 20>;
                        status = "disabled";
                };
                spi0: spi@41000 {
                        interrupts = <20>;
                        dmas = <&edma0 14 0>, <&edma0 15 0>;
                        dma-names = "rx", "tx";
+                       clocks = <&psc0 4>;
+                       power-domains = <&psc0 4>;
                        status = "disabled";
                };
                spi1: spi@30e000 {
                        interrupts = <56>;
                        dmas = <&edma0 18 0>, <&edma0 19 0>;
                        dma-names = "rx", "tx";
+                       clocks = <&psc1 10>;
+                       power-domains = <&psc1 10>;
                        status = "disabled";
                };
                usb0: usb@200000 {
                        dr_mode = "otg";
                        phys = <&usb_phy 0>;
                        phy-names = "usb-phy";
+                       clocks = <&psc1 1>;
+                       clock-ranges;
                        status = "disabled";
 
                        #address-cells = <1>;
                                interrupts = <58>;
                                #dma-cells = <2>;
                                #dma-channels = <4>;
+                               power-domains = <&psc1 1>;
                                status = "okay";
                        };
                };
                        compatible = "ti,da850-ahci";
                        reg = <0x218000 0x2000>, <0x22c018 0x4>;
                        interrupts = <67>;
+                       clocks = <&psc1 8>, <&sata_refclk>;
+                       clock-names = "fck", "refclk";
                        status = "disabled";
                };
+               pll1: clock-controller@21a000 {
+                       compatible = "ti,da850-pll1";
+                       reg = <0x21a000 0x1000>;
+                       clocks = <&ref_clk>;
+                       clock-names = "clksrc";
+
+                       pll1_sysclk: sysclk {
+                               #clock-cells = <1>;
+                       };
+                       pll1_obsclk: obsclk {
+                               #clock-cells = <0>;
+                       };
+               };
                mdio: mdio@224000 {
                        compatible = "ti,davinci_mdio";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        reg = <0x224000 0x1000>;
+                       clocks = <&psc1 5>;
+                       clock-names = "fck";
+                       power-domains = <&psc1 5>;
                        status = "disabled";
                };
                eth0: ethernet@220000 {
                                        35
                                        36
                                        >;
+                       clocks = <&psc1 5>;
+                       power-domains = <&psc1 5>;
                        status = "disabled";
                };
                usb1: usb@225000 {
                        interrupts = <59>;
                        phys = <&usb_phy 1>;
                        phy-names = "usb-phy";
+                       clocks = <&psc1 2>;
                        status = "disabled";
                };
                gpio: gpio@226000 {
                        interrupts = <42 43 44 45 46 47 48 49 50>;
                        ti,ngpio = <144>;
                        ti,davinci-gpio-unbanked = <0>;
+                       clocks = <&psc1 3>;
+                       clock-names = "gpio";
                        status = "disabled";
                        interrupt-controller;
                        #interrupt-cells = <2>;
                                      <&pmx_core 142 147 1>,
                                      <&pmx_core 143 146 1>;
                };
+               psc1: clock-controller@227000 {
+                       compatible = "ti,da850-psc1";
+                       reg = <0x227000 0x1000>;
+                       #clock-cells = <1>;
+                       #power-domain-cells = <1>;
+                       clocks = <&pll0_sysclk 2>, <&pll0_sysclk 4>,
+                                <&async3_clk>;
+                       clock-names = "pll0_sysclk2", "pll0_sysclk4", "async3";
+                       assigned-clocks = <&async3_clk>;
+                       assigned-clock-parents = <&pll1_sysclk 2>;
+               };
                pinconf: pin-controller@22c00c {
                        compatible = "ti,da850-pupd";
                        reg = <0x22c00c 0x8>;
                        reg-names = "mpu", "dat";
                        interrupts = <54>;
                        interrupt-names = "common";
+                       power-domains = <&psc1 7>;
                        status = "disabled";
                        dmas = <&edma0 1 1>,
                                <&edma0 0 1>;
                        reg = <0x213000 0x1000>;
                        interrupts = <52>;
                        max-pixelclock = <37500>;
+                       clocks = <&psc1 16>;
+                       clock-names = "fck";
+                       power-domains = <&psc1 16>;
                        status = "disabled";
                };
        };
                reg = <0x68000000 0x00008000>;
                ranges = <0 0 0x60000000 0x08000000
                          1 0 0x68000000 0x00008000>;
+               clocks = <&psc0 3>;
+               clock-names = "aemif";
+               clock-ranges;
                status = "disabled";
        };
        memctrl: memory-controller@b0000000 {
index 33230c8b295172fccb929bd694a63b143e3043f8..7e18147dc5635b414a4d51a179234adf41f9243e 100644 (file)
                id-gpio = <&pcf_gpio_21 1 GPIO_ACTIVE_HIGH>;
        };
 
+       extcon_usb2: extcon_usb2 {
+               compatible = "linux,extcon-usb-gpio";
+               id-gpio = <&pcf_gpio_21 2 GPIO_ACTIVE_HIGH>;
+       };
+
        sound0: sound0 {
                compatible = "simple-audio-card";
                simple-audio-card,name = "DRA7xx-EVM";
        extcon = <&extcon_usb1>;
 };
 
+&omap_dwc3_2 {
+       extcon = <&extcon_usb2>;
+};
+
 &usb2 {
        dr_mode = "host";
+       extcon = <&extcon_usb2>;
 };
 
 &atl {
index 0894593860d6dd622b169c10c9f5a9c75354483a..6ed5f915627000010fe9883259c18cb132fd7c96 100644 (file)
                enable-active-high;
        };
 
-       extcon_usb2: extcon_usb2 {
-               compatible = "linux,extcon-usb-gpio";
-               id-gpio = <&pcf_gpio_21 2 GPIO_ACTIVE_HIGH>;
-       };
-
        vtt_fixed: fixedregulator-vtt {
                compatible = "regulator-fixed";
                regulator-name = "vtt_fixed";
        vdd-supply = <&smps123_reg>;
 };
 
-&omap_dwc3_2 {
-       extcon = <&extcon_usb2>;
-};
-
 &elm {
        status = "okay";
 };
index e03495a799ce8d034feab58e263177794e706013..a0ddf497e8cddcd2fd1c906244167bc373be93e3 100644 (file)
                        };
                };
 
-               dcan1: can@481cc000 {
+               dcan1: can@4ae3c000 {
                        compatible = "ti,dra7-d_can";
                        ti,hwmods = "dcan1";
                        reg = <0x4ae3c000 0x2000>;
                        status = "disabled";
                };
 
-               dcan2: can@481d0000 {
+               dcan2: can@48480000 {
                        compatible = "ti,dra7-d_can";
                        ti,hwmods = "dcan2";
                        reg = <0x48480000 0x2000>;
index b7aeaeeead3b80701c06cf7b20f965204d0e3d26..c471bf3277b4fd2aeb6077eb3ad4470c14b87187 100644 (file)
        /* Supplied by VDA_1V8_PHY */
        vdda_video-supply = <&lp8732_ldo1_reg>;
 };
+
+&extcon_usb1 {
+       vbus-gpio = <&pcf_lcd 14 GPIO_ACTIVE_HIGH>;
+};
+
+&extcon_usb2 {
+       vbus-gpio = <&pcf_lcd 15 GPIO_ACTIVE_HIGH>;
+};
index df174f5c15d1d4161721ef9ec06b91806f56e548..e297b923b71a703a6ce27139de9e18d857db62be 100644 (file)
 
 &usb2 {
        dr_mode = "host";
+       extcon = <&extcon_usb2>;
 };
 
 &mmc1 {
index 91e93ab588caa4b85ac773a746d729262d5c7394..8f9df09155d8020a2c8734e20102c4a105a05761 100644 (file)
                        compatible = "arm,cortex-a15";
                        reg = <1>;
                        operating-points-v2 = <&cpu0_opp_table>;
+
+                       clocks = <&dpll_mpu_ck>;
+                       clock-names = "cpu";
+
+                       clock-latency = <300000>; /* From omap-cpufreq driver */
+
+                       /* cooling options */
+                       #cooling-cells = <2>; /* min followed by max */
+
+                       vbb-supply = <&abb_mpu>;
                };
        };
 
index c07f0051844dcace1d6093371d89c037cc4a7b6b..5a46163d465f5180b0b220c1feea4fc40e6a54a3 100644 (file)
        phys = <&pcie1_phy>, <&pcie2_phy>;
        phy-names = "pcie-phy0", "pcie-phy1";
 };
+
+&extcon_usb1 {
+       vbus-gpio = <&pcf_lcd 14 GPIO_ACTIVE_HIGH>;
+};
+
+&extcon_usb2 {
+       vbus-gpio = <&pcf_lcd 15 GPIO_ACTIVE_HIGH>;
+};
+
+&m_can0 {
+       can-transceiver {
+               max-bitrate = <5000000>;
+       };
+};
index 1c88c581ff18879a4991f3a77634e3b998d56b3d..613e4dc0ed3ec26225173c9f62657c3d5150889b 100644 (file)
 / {
        compatible = "ti,dra762", "ti,dra7";
 
+       ocp {
+               target-module@42c01900 {
+                       compatible = "ti,sysc-dra7-mcan", "ti,sysc";
+                       ranges = <0x0 0x42c00000 0x2000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x42c01900 0x4>,
+                             <0x42c01904 0x4>,
+                             <0x42c01908 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP4_SOFTRESET |
+                                        SYSC_DRA7_MCAN_ENAWAKEUP)>;
+                       ti,syss-mask = <1>;
+                       clocks = <&wkupaon_clkctrl DRA7_ADC_CLKCTRL 0>;
+                       clock-names = "fck";
+
+                       m_can0: mcan@1a00 {
+                               compatible = "bosch,m_can";
+                               reg = <0x1a00 0x4000>, <0x0 0x18FC>;
+                               reg-names = "m_can", "message_ram";
+                               interrupt-parent = <&gic>;
+                               interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "int0", "int1";
+                               clocks = <&mcan_clk>, <&l3_iclk_div>;
+                               clock-names = "cclk", "hclk";
+                               bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>;
+                       };
+               };
+       };
+
 };
 
 /* MCAN interrupts are hard-wired to irqs 67, 68 */
 &crossbar_mpu {
        ti,irqs-skip = <10 67 68 133 139 140>;
 };
+
+&scm_conf_clocks {
+       dpll_gmac_h14x2_ctrl_ck: dpll_gmac_h14x2_ctrl_ck@3fc {
+               #clock-cells = <0>;
+               compatible = "ti,divider-clock";
+               clocks = <&dpll_gmac_x2_ck>;
+               ti,max-div = <63>;
+               reg = <0x03fc>;
+               ti,bit-shift=<20>;
+               ti,latch-bit=<26>;
+               assigned-clocks = <&dpll_gmac_h14x2_ctrl_ck>;
+               assigned-clock-rates = <80000000>;
+       };
+
+       dpll_gmac_h14x2_ctrl_mux_ck: dpll_gmac_h14x2_ctrl_mux_ck@3fc {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&dpll_gmac_ck>, <&dpll_gmac_h14x2_ctrl_ck>;
+               reg = <0x3fc>;
+               ti,bit-shift = <29>;
+               ti,latch-bit=<26>;
+               assigned-clocks = <&dpll_gmac_h14x2_ctrl_mux_ck>;
+               assigned-clock-parents = <&dpll_gmac_h14x2_ctrl_ck>;
+       };
+
+       mcan_clk: mcan_clk@3fc {
+               #clock-cells = <0>;
+               compatible = "ti,gate-clock";
+               clocks = <&dpll_gmac_h14x2_ctrl_mux_ck>;
+               ti,bit-shift = <27>;
+               reg = <0x3fc>;
+       };
+};
index 0af44b7eadb9a5567b0f8decc32c445f53aceace..1bb8e5c9d029009b93f49c3adb4aec1b41fab03d 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the KZM9D board
  *
  * 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/;
 
index fec1241b858ff96f316cd5988f3cbb8ba778fb62..373ea872076929abfe24edadc9716ce72b35aed5 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the EMEV2 SoC
  *
  * Copyright (C) 2012 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.
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
index 962af97c188315c5cd525f8d3513b89eb8059835..27a1ee28c3bb8a1b13b46808df12d4739cc94c22 100644 (file)
                        compatible = "arm,cortex-a7";
                        reg = <1>;
                        clock-frequency = <1000000000>;
+                       clocks = <&cmu CLK_ARM_CLK>;
+                       clock-names = "cpu";
+                       #cooling-cells = <2>;
+
+                       operating-points = <
+                               1000000 1150000
+                               900000  1112500
+                               800000  1075000
+                               700000  1037500
+                               600000  1000000
+                               500000  962500
+                               400000  925000
+                               300000  887500
+                               200000  850000
+                               100000  850000
+                       >;
                };
        };
 
                        interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cmu CLK_TMU_APBIF>;
                        clock-names = "tmu_apbif";
-                       #include "exynos4412-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                        status = "disabled";
                };
 
index dfe41b69874571c01c43ba2114cd41e1ace99c90..6085e92ac2d73925796e5d28e9a2b5832afd8729 100644 (file)
                        reg = <0x100C0000 0x100>;
                        interrupts = <2 4>;
                        status = "disabled";
-                       #include "exynos4412-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                };
 
                jpeg_codec: jpeg-codec@11840000 {
index 88fb47cef9a8f8ef890e14738189ae546795a08c..b6091c27f155dc3a65b5bdf83402fceb71812320 100644 (file)
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <0x901>;
+                       clocks = <&clock CLK_ARM_CLK>;
+                       clock-names = "cpu";
+                       clock-latency = <160000>;
+
+                       operating-points = <
+                               1200000 1250000
+                               1000000 1150000
+                               800000  1075000
+                               500000  975000
+                               400000  975000
+                               200000  950000
+                       >;
+                       #cooling-cells = <2>; /* min followed by max */
                };
        };
 
index dc11ca1673e8b21f9c49e7982813a6e2fd3e0d1a..c0476c290977439a0274e7ef3ddfbe795c21099f 100644 (file)
@@ -94,6 +94,8 @@
 
        gpio-keys {
                compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&gpio_keys>;
 
                key-down {
                        gpios = <&gpx3 3 GPIO_ACTIVE_LOW>;
                        compatible = "maxim,max77693";
                        interrupt-parent = <&gpx1>;
                        interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&max77693_irq>;
                        reg = <0x66>;
 
                        regulators {
                        compatible = "maxim,max17047";
                        interrupt-parent = <&gpx2>;
                        interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&max77693_fuel_irq>;
                        reg = <0x36>;
 
                        maxim,over-heat-temp = <700>;
                compatible = "maxim,max77686";
                interrupt-parent = <&gpx0>;
                interrupts = <7 IRQ_TYPE_NONE>;
+               pinctrl-0 = <&max77686_irq>;
+               pinctrl-names = "default";
                reg = <0x09>;
                #clock-cells = <1>;
 
        pinctrl-names = "default";
        pinctrl-0 = <&sleep1>;
 
+       gpio_keys: gpio-keys {
+               samsung,pins = "gpx0-1", "gpx2-2", "gpx2-7", "gpx3-3";
+               samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+       };
+
+       max77686_irq: max77686-irq {
+               samsung,pins = "gpx0-7";
+               samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+       };
+
+       max77693_irq: max77693-irq {
+               samsung,pins = "gpx1-5";
+               samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+       };
+
+       max77693_fuel_irq: max77693-fuel-irq {
+               samsung,pins = "gpx2-3";
+               samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+       };
+
+       sdhci2_cd: sdhci2-cd-irq {
+               samsung,pins = "gpx3-4";
+               samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+       };
+
        hdmi_hpd: hdmi-hpd {
                samsung,pins = "gpx3-7";
                samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
        bus-width = <4>;
        cd-gpios = <&gpx3 4 GPIO_ACTIVE_HIGH>;
        cd-inverted;
-       pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4>;
+       pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sdhci2_cd>;
        pinctrl-names = "default";
        vmmc-supply = <&ldo21_reg>;
        status = "okay";
diff --git a/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi b/arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi
deleted file mode 100644 (file)
index 489b58c..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Device tree sources for Exynos4412 TMU sensor configuration
- *
- * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.com>
- */
-
-#include <dt-bindings/thermal/thermal_exynos.h>
-
-#thermal-sensor-cells = <0>;
-samsung,tmu_gain = <8>;
-samsung,tmu_reference_voltage = <16>;
-samsung,tmu_noise_cancel_mode = <4>;
-samsung,tmu_efuse_value = <55>;
-samsung,tmu_min_efuse_value = <40>;
-samsung,tmu_max_efuse_value = <100>;
-samsung,tmu_first_point_trim = <25>;
-samsung,tmu_second_point_trim = <85>;
-samsung,tmu_default_temp_offset = <50>;
-samsung,tmu_cal_type = <TYPE_ONE_POINT_TRIMMING>;
index 7b43c10c510bf92f73536c36fac989f5864f666d..51f72f0327e5241c4403908d270f96771efa4e5e 100644 (file)
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <0xA01>;
+                       clocks = <&clock CLK_ARM_CLK>;
+                       clock-names = "cpu";
                        operating-points-v2 = <&cpu0_opp_table>;
+                       #cooling-cells = <2>; /* min followed by max */
                };
 
                cpu@a02 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <0xA02>;
+                       clocks = <&clock CLK_ARM_CLK>;
+                       clock-names = "cpu";
                        operating-points-v2 = <&cpu0_opp_table>;
+                       #cooling-cells = <2>; /* min followed by max */
                };
 
                cpu@a03 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <0xA03>;
+                       clocks = <&clock CLK_ARM_CLK>;
+                       clock-names = "cpu";
                        operating-points-v2 = <&cpu0_opp_table>;
+                       #cooling-cells = <2>; /* min followed by max */
                };
        };
 
index 5d2f0a06fbeff6bf38e9eb52851bd0fc59241a3d..67f9b4504a42157de299ec9839f93bc212585c0a 100644 (file)
                pwm: pwm@12dd0000 {
                        compatible = "samsung,exynos4210-pwm";
                        reg = <0x12DD0000 0x100>;
+                       interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
                        samsung,pwm-outputs = <0>, <1>, <2>, <3>;
                        #pwm-cells = <3>;
                };
index 2daf505b3d08e2f0877fcfc72e3ea8ef0860795a..da163a40af1598c5f2755d588ccf0a5598b578fe 100644 (file)
                        compatible = "arm,cortex-a15";
                        reg = <1>;
                        clock-frequency = <1700000000>;
+                       clocks = <&clock CLK_ARM_CLK>;
+                       clock-names = "cpu";
+                       clock-latency = <140000>;
+
+                       operating-points = <
+                               1700000 1300000
+                               1600000 1250000
+                               1500000 1225000
+                               1400000 1200000
+                               1300000 1150000
+                               1200000 1125000
+                               1100000 1100000
+                               1000000 1075000
+                                900000 1050000
+                                800000 1025000
+                                700000 1012500
+                                600000 1000000
+                                500000  975000
+                                400000  950000
+                                300000  937500
+                                200000  925000
+                       >;
+                       #cooling-cells = <2>; /* min followed by max */
                };
        };
 
                        interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clock CLK_TMU>;
                        clock-names = "tmu_apbif";
-                       #include "exynos4412-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                };
 
                sata: sata@122f0000 {
index 20e789ea136f42ca32af515b24c216ee8dbc1c7e..57fc9c949e54a807d3d6742c1970d1bbfe0258cd 100644 (file)
@@ -93,7 +93,7 @@
                        interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clock CLK_TMU>;
                        clock-names = "tmu_apbif";
-                       #include "exynos4412-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                };
 
                tmu_cpu1: tmu@10064000 {
                        interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clock CLK_TMU>;
                        clock-names = "tmu_apbif";
-                       #include "exynos4412-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                };
 
                tmu_cpu2: tmu@10068000 {
                        interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clock CLK_TMU>;
                        clock-names = "tmu_apbif";
-                       #include "exynos4412-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                };
 
                tmu_cpu3: tmu@1006c000 {
                        interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clock CLK_TMU>;
                        clock-names = "tmu_apbif";
-                       #include "exynos4412-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                };
 
                mmc_0: mmc@12200000 {
index a8e4494713048eae3277f4cceeb692222b284c84..0ee6e92a3c2987ca9543f3d26e7d75459667ffee 100644 (file)
@@ -38,6 +38,7 @@
                        device_type = "cpu";
                        compatible = "arm,cortex-a15";
                        reg = <0x1>;
+                       clocks = <&clock CLK_ARM_CLK>;
                        clock-frequency = <1800000000>;
                        cci-control-port = <&cci_control1>;
                        operating-points-v2 = <&cluster_a15_opp_table>;
@@ -49,6 +50,7 @@
                        device_type = "cpu";
                        compatible = "arm,cortex-a15";
                        reg = <0x2>;
+                       clocks = <&clock CLK_ARM_CLK>;
                        clock-frequency = <1800000000>;
                        cci-control-port = <&cci_control1>;
                        operating-points-v2 = <&cluster_a15_opp_table>;
@@ -60,6 +62,7 @@
                        device_type = "cpu";
                        compatible = "arm,cortex-a15";
                        reg = <0x3>;
+                       clocks = <&clock CLK_ARM_CLK>;
                        clock-frequency = <1800000000>;
                        cci-control-port = <&cci_control1>;
                        operating-points-v2 = <&cluster_a15_opp_table>;
@@ -83,6 +86,7 @@
                        device_type = "cpu";
                        compatible = "arm,cortex-a7";
                        reg = <0x101>;
+                       clocks = <&clock CLK_KFC_CLK>;
                        clock-frequency = <1000000000>;
                        cci-control-port = <&cci_control0>;
                        operating-points-v2 = <&cluster_a7_opp_table>;
@@ -94,6 +98,7 @@
                        device_type = "cpu";
                        compatible = "arm,cortex-a7";
                        reg = <0x102>;
+                       clocks = <&clock CLK_KFC_CLK>;
                        clock-frequency = <1000000000>;
                        cci-control-port = <&cci_control0>;
                        operating-points-v2 = <&cluster_a7_opp_table>;
                        device_type = "cpu";
                        compatible = "arm,cortex-a7";
                        reg = <0x103>;
+                       clocks = <&clock CLK_KFC_CLK>;
                        clock-frequency = <1000000000>;
                        cci-control-port = <&cci_control0>;
                        operating-points-v2 = <&cluster_a7_opp_table>;
diff --git a/arch/arm/boot/dts/exynos5420-tmu-sensor-conf.dtsi b/arch/arm/boot/dts/exynos5420-tmu-sensor-conf.dtsi
deleted file mode 100644 (file)
index fbc77cb..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Device tree sources for Exynos5420 TMU sensor configuration
- *
- * Copyright (c) 2014 Lukasz Majewski <l.majewski@samsung.com>
- * Copyright (c) 2017 Krzysztof Kozlowski <krzk@kernel.org>
- */
-
-#include <dt-bindings/thermal/thermal_exynos.h>
-
-#thermal-sensor-cells = <0>;
-samsung,tmu_gain = <8>;
-samsung,tmu_reference_voltage = <16>;
-samsung,tmu_noise_cancel_mode = <4>;
-samsung,tmu_efuse_value = <55>;
-samsung,tmu_min_efuse_value = <0>;
-samsung,tmu_max_efuse_value = <100>;
-samsung,tmu_first_point_trim = <25>;
-samsung,tmu_second_point_trim = <85>;
-samsung,tmu_default_temp_offset = <50>;
-samsung,tmu_cal_type = <TYPE_ONE_POINT_TRIMMING>;
index f4e8c5823bc2cc5371a90a7fa220580038fd40de..aaff1588076136728926c96c6c07e749b6d7064c 100644 (file)
                        interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clock CLK_TMU>;
                        clock-names = "tmu_apbif";
-                       #include "exynos5420-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                };
 
                tmu_cpu1: tmu@10064000 {
                        interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clock CLK_TMU>;
                        clock-names = "tmu_apbif";
-                       #include "exynos5420-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                };
 
                tmu_cpu2: tmu@10068000 {
                        interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clock CLK_TMU>, <&clock CLK_TMU>;
                        clock-names = "tmu_apbif", "tmu_triminfo_apbif";
-                       #include "exynos5420-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                };
 
                tmu_cpu3: tmu@1006c000 {
                        interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clock CLK_TMU>, <&clock CLK_TMU_GPU>;
                        clock-names = "tmu_apbif", "tmu_triminfo_apbif";
-                       #include "exynos5420-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                };
 
                tmu_gpu: tmu@100a0000 {
                        interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clock CLK_TMU_GPU>, <&clock CLK_TMU>;
                        clock-names = "tmu_apbif", "tmu_triminfo_apbif";
-                       #include "exynos5420-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                };
 
                sysmmu_g2dr: sysmmu@10a60000 {
index 7c130a00d1a8b6fe6027b6302edd9ac16d81ded9..e4a5857c135f67adc3affdb2cbab494d2a392247 100644 (file)
@@ -37,6 +37,7 @@
                        device_type = "cpu";
                        compatible = "arm,cortex-a7";
                        reg = <0x101>;
+                       clocks = <&clock CLK_KFC_CLK>;
                        clock-frequency = <1000000000>;
                        cci-control-port = <&cci_control0>;
                        operating-points-v2 = <&cluster_a7_opp_table>;
@@ -48,6 +49,7 @@
                        device_type = "cpu";
                        compatible = "arm,cortex-a7";
                        reg = <0x102>;
+                       clocks = <&clock CLK_KFC_CLK>;
                        clock-frequency = <1000000000>;
                        cci-control-port = <&cci_control0>;
                        operating-points-v2 = <&cluster_a7_opp_table>;
@@ -59,6 +61,7 @@
                        device_type = "cpu";
                        compatible = "arm,cortex-a7";
                        reg = <0x103>;
+                       clocks = <&clock CLK_KFC_CLK>;
                        clock-frequency = <1000000000>;
                        cci-control-port = <&cci_control0>;
                        operating-points-v2 = <&cluster_a7_opp_table>;
@@ -69,8 +72,8 @@
                cpu4: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a15";
-                       clocks = <&clock CLK_ARM_CLK>;
                        reg = <0x0>;
+                       clocks = <&clock CLK_ARM_CLK>;
                        clock-frequency = <1800000000>;
                        cci-control-port = <&cci_control1>;
                        operating-points-v2 = <&cluster_a15_opp_table>;
@@ -82,6 +85,7 @@
                        device_type = "cpu";
                        compatible = "arm,cortex-a15";
                        reg = <0x1>;
+                       clocks = <&clock CLK_ARM_CLK>;
                        clock-frequency = <1800000000>;
                        cci-control-port = <&cci_control1>;
                        operating-points-v2 = <&cluster_a15_opp_table>;
@@ -93,6 +97,7 @@
                        device_type = "cpu";
                        compatible = "arm,cortex-a15";
                        reg = <0x2>;
+                       clocks = <&clock CLK_ARM_CLK>;
                        clock-frequency = <1800000000>;
                        cci-control-port = <&cci_control1>;
                        operating-points-v2 = <&cluster_a15_opp_table>;
                        device_type = "cpu";
                        compatible = "arm,cortex-a15";
                        reg = <0x3>;
+                       clocks = <&clock CLK_ARM_CLK>;
                        clock-frequency = <1800000000>;
                        cci-control-port = <&cci_control1>;
                        operating-points-v2 = <&cluster_a15_opp_table>;
diff --git a/arch/arm/boot/dts/gemini-sl93512r.dts b/arch/arm/boot/dts/gemini-sl93512r.dts
new file mode 100644 (file)
index 0000000..ebefb72
--- /dev/null
@@ -0,0 +1,328 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree file for the Storm Semiconductor SL93512R_BRD
+ * Gemini reference design, also initially called
+ * "Gemini324 EV-Board" before Storm acquired Storlink Semiconductor.
+ * The series were later acquired by Cortina Systems.
+ */
+
+/dts-v1/;
+
+#include "gemini.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+       model = "Storlink Semiconductor Gemini324 EV-Board / Storm Semiconductor SL93512R_BRD";
+       compatible = "storlink,gemini324", "storm,sl93512r", "cortina,gemini";
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       memory@0 {
+               /* 64 MB Samsung K4H511638B */
+               device_type = "memory";
+               reg = <0x00000000 0x4000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,19200n8 root=/dev/sda1 rw rootwait";
+               stdout-path = &uart0;
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+
+               button-wps {
+                       debounce-interval = <50>;
+                       wakeup-source;
+                       linux,code = <KEY_WPS_BUTTON>;
+                       label = "WPS";
+                       /* Conflict with NAND flash */
+                       gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+               };
+
+               button-setup {
+                       debounce-interval = <50>;
+                       wakeup-source;
+                       linux,code = <KEY_SETUP>;
+                       label = "factory reset";
+                       /* Conflict with NAND flash */
+                       gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               led-green-harddisk {
+                       label = "sq201:green:harddisk";
+                       /* Conflict with LCD (no problem) */
+                       gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+                       linux,default-trigger = "disk-activity";
+               };
+               led-green-wireless {
+                       label = "sq201:green:wireless";
+                       /* Conflict with NAND flash CE0 (no problem) */
+                       gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       mdio0: mdio {
+               compatible = "virtual,mdio-gpio";
+               /* Uses MDC and MDIO */
+               gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */
+                       <&gpio0 21 GPIO_ACTIVE_HIGH>; /* MDIO */
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               /* This is a Marvell 88E1111 ethernet transciever */
+               phy0: ethernet-phy@1 {
+                       reg = <1>;
+               };
+       };
+
+       spi {
+               compatible = "spi-gpio";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               /* Check pin collisions */
+               gpio-sck = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+               gpio-miso = <&gpio1 30 GPIO_ACTIVE_HIGH>;
+               gpio-mosi = <&gpio1 29 GPIO_ACTIVE_HIGH>;
+               cs-gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>;
+               num-chipselects = <1>;
+
+               switch@0 {
+                       compatible = "vitesse,vsc7385";
+                       reg = <0>;
+                       /* Specified for 2.5 MHz or below */
+                       spi-max-frequency = <2500000>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       ports {
+                               #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";
+                               };
+                               vsc: port@6 {
+                                       reg = <6>;
+                                       label = "cpu";
+                                       ethernet = <&gmac1>;
+                                       phy-mode = "rgmii";
+                                       fixed-link {
+                                               speed = <1000>;
+                                               full-duplex;
+                                               pause;
+                                       };
+                               };
+                       };
+               };
+       };
+
+
+       soc {
+               flash@30000000 {
+                       status = "okay";
+                       /* 16MB of flash */
+                       reg = <0x30000000 0x01000000>;
+
+                       partition@0 {
+                               label = "BOOT";
+                               reg = <0x00000000 0x00020000>;
+                               read-only;
+                       };
+                       partition@120000 {
+                               label = "Kern";
+                               reg = <0x00020000 0x00300000>;
+                       };
+                       partition@320000 {
+                               label = "Ramdisk";
+                               reg = <0x00320000 0x00600000>;
+                       };
+                       partition@920000 {
+                               label = "Application";
+                               reg = <0x00920000 0x00600000>;
+                       };
+                       partition@f20000 {
+                               label = "VCTL";
+                               reg = <0x00f20000 0x00020000>;
+                               read-only;
+                       };
+                       partition@f40000 {
+                               label = "CurConf";
+                               reg = <0x00f40000 0x000a0000>;
+                               read-only;
+                       };
+                       partition@fe0000 {
+                               label = "FIS directory";
+                               reg = <0x00fe0000 0x00020000>;
+                               read-only;
+                       };
+               };
+
+               syscon: syscon@40000000 {
+                       pinctrl {
+                               /*
+                                * gpio0egrp cover line 16 used by HD LED
+                                * gpio0fgrp cover line 17, 18 used by wireless LED and reset button
+                                * gpio0hgrp cover line 21, 22 used by MDIO for Marvell PHY
+                                * gpio0kgrp cover line 31 used by USB LED
+                                */
+                               gpio0_default_pins: pinctrl-gpio0 {
+                                       mux {
+                                               function = "gpio0";
+                                               groups = "gpio0egrp",
+                                               "gpio0fgrp",
+                                               "gpio0hgrp";
+                                       };
+                               };
+                               /*
+                                * gpio1dgrp cover lines used by SPI for
+                                * the Vitesse chip (28-31)
+                                */
+                               gpio1_default_pins: pinctrl-gpio1 {
+                                       mux {
+                                               function = "gpio1";
+                                               groups = "gpio1dgrp";
+                                       };
+                               };
+                               pinctrl-gmii {
+                                       mux {
+                                               function = "gmii";
+                                               groups = "gmii_gmac0_grp", "gmii_gmac1_grp";
+                                       };
+                                       /* Control pad skew comes from sl_switch.c in the vendor code */
+                                       conf0 {
+                                               pins = "P10 GMAC1 TXC";
+                                               skew-delay = <5>;
+                                       };
+                                       conf1 {
+                                               pins = "V11 GMAC1 TXEN";
+                                               skew-delay = <7>;
+                                       };
+                                       conf2 {
+                                               pins = "T11 GMAC1 RXC";
+                                               skew-delay = <8>;
+                                       };
+                                       conf3 {
+                                               pins = "U11 GMAC1 RXDV";
+                                               skew-delay = <7>;
+                                       };
+                                       conf4 {
+                                               pins = "V7 GMAC0 TXC";
+                                               skew-delay = <10>;
+                                       };
+                                       conf5 {
+                                               pins = "P8 GMAC0 TXEN";
+                                               skew-delay = <7>; /* 5 at another place? */
+                                       };
+                                       conf6 {
+                                               pins = "T8 GMAC0 RXC";
+                                               skew-delay = <15>;
+                                       };
+                                       conf7 {
+                                               pins = "R8 GMAC0 RXDV";
+                                               skew-delay = <0>;
+                                       };
+                                       conf8 {
+                                               /* The data lines all have default skew */
+                                               pins = "U8 GMAC0 RXD0", "V8 GMAC0 RXD1",
+                                                      "P9 GMAC0 RXD2", "R9 GMAC0 RXD3",
+                                                      "R11 GMAC1 RXD0", "P11 GMAC1 RXD1",
+                                                      "V12 GMAC1 RXD2", "U12 GMAC1 RXD3",
+                                                      "R10 GMAC1 TXD0", "T10 GMAC1 TXD1",
+                                                      "U10 GMAC1 TXD2", "V10 GMAC1 TXD3";
+                                               skew-delay = <7>;
+                                       };
+                                       /* Appears in sl351x_gmac.c in the vendor code */
+                                       conf9 {
+                                               pins = "U7 GMAC0 TXD0", "T7 GMAC0 TXD1",
+                                                      "R7 GMAC0 TXD2", "P7 GMAC0 TXD3";
+                                               skew-delay = <5>;
+                                       };
+                               };
+                       };
+               };
+
+               /* Both interfaces brought out on SATA connectors */
+               sata: sata@46000000 {
+                       cortina,gemini-ata-muxmode = <0>;
+                       cortina,gemini-enable-sata-bridge;
+                       status = "okay";
+               };
+
+               gpio0: gpio@4d000000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&gpio0_default_pins>;
+               };
+
+               gpio1: gpio@4e000000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&gpio1_default_pins>;
+               };
+
+               pci@50000000 {
+                       status = "okay";
+                       interrupt-map-mask = <0xf800 0 0 7>;
+                       interrupt-map =
+                               <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */
+                               <0x4800 0 0 2 &pci_intc 1>,
+                               <0x4800 0 0 3 &pci_intc 2>,
+                               <0x4800 0 0 4 &pci_intc 3>,
+                               <0x5000 0 0 1 &pci_intc 1>, /* Slot 10 */
+                               <0x5000 0 0 2 &pci_intc 2>,
+                               <0x5000 0 0 3 &pci_intc 3>,
+                               <0x5000 0 0 4 &pci_intc 0>,
+                               <0x5800 0 0 1 &pci_intc 2>, /* Slot 11 */
+                               <0x5800 0 0 2 &pci_intc 3>,
+                               <0x5800 0 0 3 &pci_intc 0>,
+                               <0x5800 0 0 4 &pci_intc 1>,
+                               <0x6000 0 0 1 &pci_intc 3>, /* Slot 12 */
+                               <0x6000 0 0 2 &pci_intc 0>,
+                               <0x6000 0 0 3 &pci_intc 1>,
+                               <0x6000 0 0 4 &pci_intc 2>;
+               };
+
+               ethernet@60000000 {
+                       status = "okay";
+
+                       ethernet-port@0 {
+                               phy-mode = "rgmii";
+                               phy-handle = <&phy0>;
+                       };
+                       ethernet-port@1 {
+                               phy-mode = "rgmii";
+                               fixed-link {
+                                       speed = <1000>;
+                                       full-duplex;
+                                       pause;
+                               };
+                       };
+               };
+
+               ata@63000000 {
+                       status = "okay";
+               };
+
+               ata@63400000 {
+                       status = "okay";
+               };
+       };
+};
index e5cf9d1a98cd4f27da7e557c423acf57955bf1e2..3787cf3763c41f50e4edc474aeba9de49503c6bc 100644 (file)
                };
        };
 
+       mdio0: mdio {
+               compatible = "virtual,mdio-gpio";
+               /* Uses MDC and MDIO */
+               gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */
+                       <&gpio0 21 GPIO_ACTIVE_HIGH>; /* MDIO */
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               /* This is a Marvell 88E1111 ethernet transciever */
+               phy0: ethernet-phy@1 {
+                       reg = <1>;
+               };
+       };
+
+       spi {
+               compatible = "spi-gpio";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               /* Check pin collisions */
+               gpio-sck = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+               gpio-miso = <&gpio1 30 GPIO_ACTIVE_HIGH>;
+               gpio-mosi = <&gpio1 29 GPIO_ACTIVE_HIGH>;
+               cs-gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>;
+               num-chipselects = <1>;
+
+               switch@0 {
+                       compatible = "vitesse,vsc7395";
+                       reg = <0>;
+                       /* Specified for 2.5 MHz or below */
+                       spi-max-frequency = <2500000>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       ports {
+                               #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";
+                               };
+                               vsc: port@6 {
+                                       reg = <6>;
+                                       label = "cpu";
+                                       ethernet = <&gmac1>;
+                                       phy-mode = "rgmii";
+                                       fixed-link {
+                                               speed = <1000>;
+                                               full-duplex;
+                                               pause;
+                                       };
+                               };
+                       };
+               };
+       };
+
+
        soc {
                flash@30000000 {
                        /*
                                /*
                                 * gpio0fgrp cover line 18 used by reset button
                                 * gpio0ggrp cover line 20 used by info LED
+                                * gpio0hgrp cover line 21, 22 used by MDIO for Marvell PHY
                                 * gpio0kgrp cover line 31 used by USB LED
                                 */
                                gpio0_default_pins: pinctrl-gpio0 {
                                                function = "gpio0";
                                                groups = "gpio0fgrp",
                                                "gpio0ggrp",
+                                               "gpio0hgrp",
                                                "gpio0kgrp";
                                        };
                                };
+                               /*
+                                * gpio0dgrp cover lines used by the SPI
+                                * to the Vitesse G5x chip.
+                                */
+                               gpio1_default_pins: pinctrl-gpio1 {
+                                       mux {
+                                               function = "gpio1";
+                                               groups = "gpio1dgrp";
+                                       };
+                               };
+                               pinctrl-gmii {
+                                       mux {
+                                               function = "gmii";
+                                               groups = "gmii_gmac0_grp", "gmii_gmac1_grp";
+                                       };
+                                       /* Settings come from memory dump in PLATO */
+                                       conf0 {
+                                               pins = "V8 GMAC0 RXDV";
+                                               skew-delay = <0>;
+                                       };
+                                       conf1 {
+                                               pins = "Y7 GMAC0 RXC";
+                                               skew-delay = <15>;
+                                       };
+                                       conf2 {
+                                               pins = "T8 GMAC0 TXEN";
+                                               skew-delay = <7>;
+                                       };
+                                       conf3 {
+                                               pins = "U8 GMAC0 TXC";
+                                               skew-delay = <10>;
+                                       };
+                                       conf4 {
+                                               pins = "T10 GMAC1 RXDV";
+                                               skew-delay = <7>;
+                                       };
+                                       conf5 {
+                                               pins = "Y11 GMAC1 RXC";
+                                               skew-delay = <8>;
+                                       };
+                                       conf6 {
+                                               pins = "W11 GMAC1 TXEN";
+                                               skew-delay = <7>;
+                                       };
+                                       conf7 {
+                                               pins = "V11 GMAC1 TXC";
+                                               skew-delay = <5>;
+                                       };
+                                       conf8 {
+                                               /* The data lines all have default skew */
+                                               pins = "W8 GMAC0 RXD0", "V9 GMAC0 RXD1",
+                                                      "Y8 GMAC0 RXD2", "U9 GMAC0 RXD3",
+                                                      "T7 GMAC0 TXD0", "U6 GMAC0 TXD1",
+                                                      "V7 GMAC0 TXD2", "U7 GMAC0 TXD3",
+                                                      "Y12 GMAC1 RXD0", "V12 GMAC1 RXD1",
+                                                      "T11 GMAC1 RXD2", "W12 GMAC1 RXD3",
+                                                      "U10 GMAC1 TXD0", "Y10 GMAC1 TXD1",
+                                                      "W10 GMAC1 TXD2", "T9 GMAC1 TXD3";
+                                               skew-delay = <7>;
+                                       };
+                                       /* Set up drive strength on GMAC0 and GMAC1 to 16 mA */
+                                       conf9 {
+                                               groups = "gmii_gmac0_grp", "gmii_gmac1_grp";
+                                               drive-strength = <16>;
+                                       };
+                               };
                        };
                };
 
                        pinctrl-0 = <&gpio0_default_pins>;
                };
 
+               gpio1: gpio@4e000000 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&gpio1_default_pins>;
+               };
+
                pci@50000000 {
                        status = "okay";
                        interrupt-map-mask = <0xf800 0 0 7>;
                                <0x6000 0 0 4 &pci_intc 2>;
                };
 
+               ethernet@60000000 {
+                       status = "okay";
+
+                       ethernet-port@0 {
+                               phy-mode = "rgmii";
+                               phy-handle = <&phy0>;
+                       };
+                       ethernet-port@1 {
+                               phy-mode = "rgmii";
+                               fixed-link {
+                                       speed = <1000>;
+                                       full-duplex;
+                                       pause;
+                               };
+                       };
+               };
+
                ata@63000000 {
                        status = "okay";
                };
diff --git a/arch/arm/boot/dts/gr-peach-audiocamerashield.dtsi b/arch/arm/boot/dts/gr-peach-audiocamerashield.dtsi
new file mode 100644 (file)
index 0000000..e31a9e3
--- /dev/null
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the GR-Peach audiocamera shield expansion board
+ *
+ * Copyright (C) 2017 Jacopo Mondi <jacopo+renesas@jmondi.org>
+ */
+
+#include "r7s72100.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/r7s72100-pinctrl.h>
+
+/ {
+       /* On-board camera clock. */
+       camera_clk: camera_clk {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <27000000>;
+       };
+};
+
+&pinctrl {
+       i2c1_pins: i2c1 {
+               /* P1_2 as SCL; P1_3 as SDA */
+               pinmux = <RZA1_PINMUX(1, 2, 1)>, <RZA1_PINMUX(1, 3, 1)>;
+       };
+
+       vio_pins: vio {
+               /* CEU pins: VIO_D[0-10], VIO_VD, VIO_HD, VIO_CLK */
+               pinmux = <RZA1_PINMUX(1, 0, 5)>, /* VIO_VD */
+                        <RZA1_PINMUX(1, 1, 5)>, /* VIO_HD */
+                        <RZA1_PINMUX(2, 0, 7)>, /* VIO_D0 */
+                        <RZA1_PINMUX(2, 1, 7)>, /* VIO_D1 */
+                        <RZA1_PINMUX(2, 2, 7)>, /* VIO_D2 */
+                        <RZA1_PINMUX(2, 3, 7)>, /* VIO_D3 */
+                        <RZA1_PINMUX(2, 4, 7)>, /* VIO_D4 */
+                        <RZA1_PINMUX(2, 5, 7)>, /* VIO_D5 */
+                        <RZA1_PINMUX(2, 6, 7)>, /* VIO_D6 */
+                        <RZA1_PINMUX(2, 7, 7)>, /* VIO_D7 */
+                        <RZA1_PINMUX(10, 0, 6)>; /* VIO_CLK */
+       };
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
+
+       status = "okay";
+       clock-frequency = <100000>;
+
+       camera@48 {
+               compatible = "aptina,mt9v111";
+               reg = <0x48>;
+
+               clocks = <&camera_clk>;
+
+               port {
+                       mt9v111_out: endpoint {
+                               remote-endpoint = <&ceu_in>;
+                       };
+               };
+       };
+};
+
+&ceu {
+       pinctrl-names = "default";
+       pinctrl-0 = <&vio_pins>;
+
+       status = "okay";
+
+       port {
+               ceu_in: endpoint {
+                       hsync-active = <1>;
+                       vsync-active = <1>;
+                       bus-width = <8>;
+                       pclk-sample = <1>;
+                       remote-endpoint = <&mt9v111_out>;
+               };
+       };
+};
index ed14aeac056679059d823b8502a122e28ab1ddaa..50278715de762009aa4a01c7f975ac0907a6defa 100644 (file)
                        next-level-cache = <&L2>;
                        clocks = <&a9pll>;
                        clock-names = "cpu";
+                       operating-points = <
+                               /* kHz    ignored */
+                                1300000  1000000
+                                1200000  1000000
+                                1100000  1000000
+                                 800000  1000000
+                                 400000  1000000
+                                 200000  1000000
+                       >;
+                       clock-latency = <100000>;
                };
 
                cpu@902 {
                        next-level-cache = <&L2>;
                        clocks = <&a9pll>;
                        clock-names = "cpu";
+                       operating-points = <
+                               /* kHz    ignored */
+                                1300000  1000000
+                                1200000  1000000
+                                1100000  1000000
+                                 800000  1000000
+                                 400000  1000000
+                                 200000  1000000
+                       >;
+                       clock-latency = <100000>;
                };
 
                cpu@903 {
                        next-level-cache = <&L2>;
                        clocks = <&a9pll>;
                        clock-names = "cpu";
+                       operating-points = <
+                               /* kHz    ignored */
+                                1300000  1000000
+                                1200000  1000000
+                                1100000  1000000
+                                 800000  1000000
+                                 400000  1000000
+                                 200000  1000000
+                       >;
+                       clock-latency = <100000>;
                };
        };
 
index 9fb47724b9c1fa2dee8a6f1695fba9a68d30e80f..ad2ae25b7b4dbeb5fb714dee5af9182166d51457 100644 (file)
                reg = <0x40000000 0x08000000>;
        };
 
+       reg_vddio_sd0: regulator-vddio-sd0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vddio-sd0";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio1 29 0>;
+       };
+
+       reg_lcd_3v3: regulator-lcd-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd-3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio1 18 0>;
+               enable-active-high;
+       };
+
+       reg_lcd_5v: regulator-lcd-5v {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd-5v";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+
+       panel {
+               compatible = "sii,43wvf1g";
+               backlight = <&backlight_display>;
+               dvdd-supply = <&reg_lcd_3v3>;
+               avdd-supply = <&reg_lcd_5v>;
+
+               port {
+                       panel_in: endpoint {
+                               remote-endpoint = <&display_out>;
+                       };
+               };
+       };
+
        apb@80000000 {
                apbh@80000000 {
                        gpmi-nand@8000c000 {
                        lcdif@80030000 {
                                pinctrl-names = "default";
                                pinctrl-0 = <&lcdif_24bit_pins_a>;
-                               lcd-supply = <&reg_lcd_3v3>;
-                               display = <&display0>;
                                status = "okay";
 
-                               display0: display0 {
-                                       bits-per-pixel = <32>;
-                                       bus-width = <24>;
-
-                                       display-timings {
-                                               native-mode = <&timing0>;
-                                               timing0: timing0 {
-                                                       clock-frequency = <9200000>;
-                                                       hactive = <480>;
-                                                       vactive = <272>;
-                                                       hback-porch = <15>;
-                                                       hfront-porch = <8>;
-                                                       vback-porch = <12>;
-                                                       vfront-porch = <4>;
-                                                       hsync-len = <1>;
-                                                       vsync-len = <1>;
-                                                       hsync-active = <0>;
-                                                       vsync-active = <0>;
-                                                       de-active = <1>;
-                                                       pixelclk-active = <0>;
-                                               };
+                               port {
+                                       display_out: endpoint {
+                                               remote-endpoint = <&panel_in>;
                                        };
                                };
                        };
                };
        };
 
-       regulators {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               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: regulator@1 {
-                       compatible = "regulator-fixed";
-                       reg = <1>;
-                       regulator-name = "lcd-3v3";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-                       gpio = <&gpio1 18 0>;
-                       enable-active-high;
-               };
-       };
-
-       backlight {
+       backlight_display: backlight {
                compatible = "pwm-backlight";
                pwms = <&pwm 2 5000000>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
index 6b0ae667640f1c29c61390fccc9f3c3844e4d6e2..93ab5bdfe068a11a75276ebeaa4d31a99e473e67 100644 (file)
                reg = <0x40000000 0x08000000>;
        };
 
+
+       reg_3p3v: regulator-3p3v {
+               compatible = "regulator-fixed";
+               regulator-name = "3P3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       reg_vddio_sd0: regulator-vddio-sd0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vddio-sd0";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio3 28 0>;
+       };
+
+       reg_fec_3v3: regulator-fec-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "fec-3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio2 15 0>;
+       };
+
+       reg_usb0_vbus: regulator-usb0-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usb0_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio3 9 0>;
+               enable-active-high;
+       };
+
+       reg_usb1_vbus: regulator-usb1-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usb1_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio3 8 0>;
+               enable-active-high;
+       };
+
+       reg_lcd_3v3: regulator-lcd-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd-3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio3 30 0>;
+               enable-active-high;
+       };
+
+       reg_can_3v3: regulator-can-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "can-3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio2 13 0>;
+               enable-active-high;
+       };
+
+       reg_lcd_5v: regulator-lcd-5v {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd-5v";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+
+       panel {
+               compatible = "sii,43wvf1g";
+               backlight = <&backlight_display>;
+               dvdd-supply = <&reg_lcd_3v3>;
+               avdd-supply = <&reg_lcd_5v>;
+
+               port {
+                       panel_in: endpoint {
+                               remote-endpoint = <&display_out>;
+                       };
+               };
+       };
+
        apb@80000000 {
                apbh@80000000 {
                        gpmi-nand@8000c000 {
                                pinctrl-names = "default";
                                pinctrl-0 = <&lcdif_24bit_pins_a
                                             &lcdif_pins_evk>;
-                               lcd-supply = <&reg_lcd_3v3>;
-                               display = <&display0>;
                                status = "okay";
 
-                               display0: display0 {
-                                       bits-per-pixel = <32>;
-                                       bus-width = <24>;
-
-                                       display-timings {
-                                               native-mode = <&timing0>;
-                                               timing0: timing0 {
-                                                       clock-frequency = <33500000>;
-                                                       hactive = <800>;
-                                                       vactive = <480>;
-                                                       hback-porch = <89>;
-                                                       hfront-porch = <164>;
-                                                       vback-porch = <23>;
-                                                       vfront-porch = <10>;
-                                                       hsync-len = <10>;
-                                                       vsync-len = <10>;
-                                                       hsync-active = <0>;
-                                                       vsync-active = <0>;
-                                                       de-active = <1>;
-                                                       pixelclk-active = <0>;
-                                               };
+                               port {
+                                       display_out: endpoint {
+                                               remote-endpoint = <&panel_in>;
                                        };
                                };
                        };
                };
        };
 
-       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_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: 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: regulator@3 {
-                       compatible = "regulator-fixed";
-                       reg = <3>;
-                       regulator-name = "usb0_vbus";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-                       gpio = <&gpio3 9 0>;
-                       enable-active-high;
-               };
-
-               reg_usb1_vbus: regulator@4 {
-                       compatible = "regulator-fixed";
-                       reg = <4>;
-                       regulator-name = "usb1_vbus";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-                       gpio = <&gpio3 8 0>;
-                       enable-active-high;
-               };
-
-               reg_lcd_3v3: regulator@5 {
-                       compatible = "regulator-fixed";
-                       reg = <5>;
-                       regulator-name = "lcd-3v3";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-                       gpio = <&gpio3 30 0>;
-                       enable-active-high;
-               };
-
-               reg_can_3v3: regulator@6 {
-                       compatible = "regulator-fixed";
-                       reg = <6>;
-                       regulator-name = "can-3v3";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-                       gpio = <&gpio2 13 0>;
-                       enable-active-high;
-               };
-
-       };
-
        sound {
                compatible = "fsl,imx28-evk-sgtl5000",
                             "fsl,mxs-audio-sgtl5000";
                };
        };
 
-       backlight {
+       backlight_display: backlight {
                compatible = "pwm-backlight";
                pwms = <&pwm 2 5000000>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
diff --git a/arch/arm/boot/dts/imx31-lite.dts b/arch/arm/boot/dts/imx31-lite.dts
new file mode 100644 (file)
index 0000000..db52ddc
--- /dev/null
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (C) 2016-2018 Vladimir Zapolskiy <vz@mleia.com>
+
+/dts-v1/;
+
+#include "imx31.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       model = "LogicPD i.MX31 Lite";
+       compatible = "logicpd,imx31-lite", "fsl,imx31";
+
+       chosen {
+               stdout-path = &uart1;
+       };
+
+       memory@80000000 {
+               reg = <0x80000000 0x8000000>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led0 {
+                       gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
+               };
+
+               led1 {
+                       gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+               };
+       };
+};
+
+&ata {
+       status = "okay";
+};
+
+&nfc {
+       nand-bus-width = <8>;
+       nand-ecc-mode = "hw";
+       nand-on-flash-bbt;
+       status = "okay";
+};
+
+&sdhci1 {
+       bus-width = <4>;
+       cd-gpios = <&gpio2 11 GPIO_ACTIVE_HIGH>;
+       wp-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&spi2 {
+       status = "okay";
+
+       pmic@0 {
+               compatible = "fsl,mc13783";
+               reg = <0>;
+               spi-cs-high;
+               spi-max-frequency = <1000000>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <3 IRQ_TYPE_EDGE_RISING>;
+
+               fsl,mc13xxx-uses-adc;
+               fsl,mc13xxx-uses-rtc;
+
+               regulators {
+                       sw1a {          /* QVCC */
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       sw1b {          /* QVCC */
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       sw2a {          /* 1.8V_DDR, NVCC2, NVCC21 and NVCC22 */
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       sw2b {          /* NVCC10 */
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       violo {         /* NVCC1 and NVCC7 */
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       viohi {         /* VIOHI */
+                               regulator-min-microvolt = <2775000>;
+                               regulator-max-microvolt = <2775000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       vaudio {        /* VAUDIO */
+                               regulator-min-microvolt = <2775000>;
+                               regulator-max-microvolt = <2775000>;
+                       };
+
+                       vcam {          /* NVCC4 */
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                       };
+
+                       vgen {          /* NVCC5 / NVCC8 and NVCC6 / NVCC9 */
+                               regulator-min-microvolt = <2775000>;
+                               regulator-max-microvolt = <2775000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+
+                       vmmc2 {         /* NVCC3 */
+                               regulator-min-microvolt = <1600000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                       };
+               };
+       };
+};
+
+&uart1 {
+       uart-has-rtscts;
+       status = "okay";
+};
+
+/* Routed to the extension board */
+&uart2 {
+       uart-has-rtscts;
+       status = "okay";
+};
+
+/* Routed to the extension board */
+&uart3 {
+       uart-has-rtscts;
+       status = "okay";
+};
+
+&weim {
+       status = "okay";
+
+       nor@0,0 {
+               compatible = "cfi-flash";
+               reg = <0 0x0 0x200000>;
+               bank-width = <2>;
+               linux,mtd-name = "physmap-flash.0";
+               fsl,weim-cs-timing = <0x0000cf03 0xa0330d01 0x00220800>;
+       };
+
+       ethernet@4,0 {
+               compatible = "smsc,lan9117", "smsc,lan9115";
+               reg = <4 0x0 0x100>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
+               phy-mode = "mii";
+               reg-io-width = <2>;
+               smsc,irq-push-pull;
+               fsl,weim-cs-timing = <0x00008701 0x04000541 0x00010000>;
+       };
+};
index 4642c8169a65ba490a68e466b1e6e8a046719a58..ca1419ca303c3d5994a73b5bdddc9e69428dac55 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 //
+// Copyright 2016-2018 Vladimir Zapolskiy <vz@mleia.com>
 // Copyright 2012 Denis 'GNUtoo' Carikli <GNUtoo@no-log.org>
 
 / {
        memory { device_type = "memory"; };
 
        aliases {
+               gpio0 = &gpio1;
+               gpio1 = &gpio2;
+               gpio2 = &gpio3;
+               i2c0 = &i2c1;
+               i2c1 = &i2c2;
+               i2c2 = &i2c3;
                serial0 = &uart1;
                serial1 = &uart2;
                serial2 = &uart3;
                serial3 = &uart4;
                serial4 = &uart5;
+               spi0 = &spi1;
+               spi1 = &spi2;
+               spi2 = &spi3;
        };
 
        cpus {
                interrupt-parent = <&avic>;
                ranges;
 
+               iram: iram@1fffc000 {
+                       compatible = "mmio-sram";
+                       reg = <0x1fffc000 0x4000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x1fffc000 0x4000>;
+               };
+
                aips@43f00000 { /* AIPS1 */
                        compatible = "fsl,aips-bus", "simple-bus";
                        #address-cells = <1>;
                        reg = <0x43f00000 0x100000>;
                        ranges;
 
+                       i2c1: i2c@43f80000 {
+                               compatible = "fsl,imx31-i2c", "fsl,imx21-i2c";
+                               reg = <0x43f80000 0x4000>;
+                               interrupts = <10>;
+                               clocks = <&clks 33>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c3: i2c@43f84000 {
+                               compatible = "fsl,imx31-i2c", "fsl,imx21-i2c";
+                               reg = <0x43f84000 0x4000>;
+                               interrupts = <3>;
+                               clocks = <&clks 35>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       ata: ata@43f8c000 {
+                               compatible = "fsl,imx31-pata", "fsl,imx27-pata";
+                               reg = <0x43f8c000 0x4000>;
+                               interrupts = <15>;
+                               clocks = <&clks 26>;
+                               status = "disabled";
+                       };
+
                        uart1: serial@43f90000 {
                                compatible = "fsl,imx31-uart", "fsl,imx21-uart";
                                reg = <0x43f90000 0x4000>;
                                status = "disabled";
                        };
 
+                       i2c2: i2c@43f98000 {
+                               compatible = "fsl,imx31-i2c", "fsl,imx21-i2c";
+                               reg = <0x43f98000 0x4000>;
+                               interrupts = <4>;
+                               clocks = <&clks 34>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi1: spi@43fa4000 {
+                               compatible = "fsl,imx31-cspi";
+                               reg = <0x43fa4000 0x4000>;
+                               interrupts = <14>;
+                               clocks = <&clks 10>, <&clks 53>;
+                               clock-names = "ipg", "per";
+                               dmas = <&sdma 8 8 0>, <&sdma 9 8 0>;
+                               dma-names = "rx", "tx";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
                        kpp: kpp@43fa8000 {
                                compatible = "fsl,imx31-kpp", "fsl,imx21-kpp";
                                reg = <0x43fa8000 0x4000>;
                        reg = <0x50000000 0x100000>;
                        ranges;
 
+                       sdhci1: sdhci@50004000 {
+                               compatible = "fsl,imx31-mmc";
+                               reg = <0x50004000 0x4000>;
+                               interrupts = <9>;
+                               clocks = <&clks 10>, <&clks 20>;
+                               clock-names = "ipg", "per";
+                               dmas = <&sdma 20 3 0>;
+                               dma-names = "rx-tx";
+                               status = "disabled";
+                       };
+
+                       sdhci2: sdhci@50008000 {
+                               compatible = "fsl,imx31-mmc";
+                               reg = <0x50008000 0x4000>;
+                               interrupts = <8>;
+                               clocks = <&clks 10>, <&clks 21>;
+                               clock-names = "ipg", "per";
+                               dmas = <&sdma 21 3 0>;
+                               dma-names = "rx-tx";
+                               status = "disabled";
+                       };
+
                        uart3: serial@5000c000 {
                                compatible = "fsl,imx31-uart", "fsl,imx21-uart";
                                reg = <0x5000c000 0x4000>;
                                status = "disabled";
                        };
 
+                       spi2: cspi@50010000 {
+                               compatible = "fsl,imx31-cspi";
+                               reg = <0x50010000 0x4000>;
+                               interrupts = <13>;
+                               clocks = <&clks 10>, <&clks 54>;
+                               clock-names = "ipg", "per";
+                               dmas = <&sdma 6 8 0>, <&sdma 7 8 0>;
+                               dma-names = "rx", "tx";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
                        iim: iim@5001c000 {
                                compatible = "fsl,imx31-iim", "fsl,imx27-iim";
                                reg = <0x5001c000 0x1000>;
                                #clock-cells = <1>;
                        };
 
+                       spi3: cspi@53f84000 {
+                               compatible = "fsl,imx31-cspi";
+                               reg = <0x53f84000 0x4000>;
+                               interrupts = <17>;
+                               clocks = <&clks 10>, <&clks 28>;
+                               clock-names = "ipg", "per";
+                               dmas = <&sdma 10 8 0>, <&sdma 11 8 0>;
+                               dma-names = "rx", "tx";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
                        gpt: timer@53f90000 {
                                compatible = "fsl,imx31-gpt";
                                reg = <0x53f90000 0x4000>;
                                clocks = <&clks 10>, <&clks 22>;
                                clock-names = "ipg", "per";
                        };
+
+                       gpio3: gpio@53fa4000 {
+                               compatible = "fsl,imx31-gpio";
+                               reg = <0x53fa4000 0x4000>;
+                               interrupts = <56>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       rng@53fb0000 {
+                               compatible = "fsl,imx31-rnga";
+                               reg = <0x53fb0000 0x4000>;
+                               interrupts = <22>;
+                               clocks = <&clks 29>;
+                       };
+
+                       gpio1: gpio@53fcc000 {
+                               compatible = "fsl,imx31-gpio";
+                               reg = <0x53fcc000 0x4000>;
+                               interrupts = <52>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio2: gpio@53fd0000 {
+                               compatible = "fsl,imx31-gpio";
+                               reg = <0x53fd0000 0x4000>;
+                               interrupts = <51>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       sdma: sdma@53fd4000 {
+                               compatible = "fsl,imx31-sdma";
+                               reg = <0x53fd4000 0x4000>;
+                               interrupts = <34>;
+                               clocks = <&clks 10>, <&clks 27>;
+                               clock-names = "ipg", "ahb";
+                               #dma-cells = <3>;
+                               fsl,sdma-ram-script-name = "imx/sdma/sdma-imx31.bin";
+                       };
+
+                       rtc: rtc@53fd8000 {
+                               compatible = "fsl,imx31-rtc", "fsl,imx21-rtc";
+                               reg = <0x53fd8000 0x4000>;
+                               interrupts = <25>;
+                               clocks = <&clks 2>, <&clks 40>;
+                               clock-names = "ref", "ipg";
+                       };
+
+                       wdog: wdog@53fdc000 {
+                               compatible = "fsl,imx31-wdt", "fsl,imx21-wdt";
+                               reg = <0x53fdc000 0x4000>;
+                               clocks = <&clks 41>;
+                       };
+
+                       pwm: pwm@53fe0000 {
+                               compatible = "fsl,imx31-pwm", "fsl,imx27-pwm";
+                               reg = <0x53fe0000 0x4000>;
+                               interrupts = <26>;
+                               clocks = <&clks 10>, <&clks 42>;
+                               clock-names = "ipg", "per";
+                               #pwm-cells = <2>;
+                               status = "disabled";
+                       };
+               };
+
+               emi@b8000000 { /* External Memory Interface */
+                       compatible = "simple-bus";
+                       reg = <0xb8000000 0x5000>;
+                       ranges;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       nfc: nand@b8000000 {
+                               compatible = "fsl,imx31-nand", "fsl,imx27-nand";
+                               reg = <0xb8000000 0x1000>;
+                               interrupts = <33>;
+                               clocks = <&clks 9>;
+                               dmas = <&sdma 30 17 0>;
+                               dma-names = "rx-tx";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               status = "disabled";
+                       };
+
+                       weim: weim@b8002000 {
+                               compatible = "fsl,imx31-weim", "fsl,imx27-weim";
+                               reg = <0xb8002000 0x1000>;
+                               clocks = <&clks 56>;
+                               #address-cells = <2>;
+                               #size-cells = <1>;
+                               ranges = <0 0 0xa0000000 0x08000000
+                                         1 0 0xa8000000 0x08000000
+                                         2 0 0xb0000000 0x02000000
+                                         3 0 0xb2000000 0x02000000
+                                         4 0 0xb4000000 0x02000000
+                                         5 0 0xb6000000 0x02000000>;
+                               status = "disabled";
+                       };
                };
        };
 };
index f0622ec4ba9c34ae636bac7fbc765a38babc240a..682a99783ee69b24485315576f3852e278ac3081 100644 (file)
        status = "okay";
 };
 
-&usbh2 {
-       status = "okay";
-};
-
-&usbh3 {
-       status = "okay";
-};
-
 &usbotg {
        status = "okay";
 };
index 97e6e7f4ebddf4a0c5cef086d4690138ee849f16..43863347362e83adefbff9ebecc018a3e3ae220c 100644 (file)
@@ -34,7 +34,7 @@
 #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__KPP_COL_2                           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
@@ -44,7 +44,7 @@
 #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__KPP_COL_3                           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
index a9b712db9f6c3131158661f684ad26ae9e23efdf..7fae2ffb76fe2e63ecb4fe8a515b61a65dd99421 100644 (file)
                                status = "disabled";
                        };
 
-                       usbh2: usb@53f80400 {
-                               compatible = "fsl,imx50-usb", "fsl,imx27-usb";
-                               reg = <0x53f80400 0x0200>;
-                               interrupts = <16>;
-                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
-                               dr_mode = "host";
-                               status = "disabled";
-                       };
-
-                       usbh3: usb@53f80600 {
-                               compatible = "fsl,imx50-usb", "fsl,imx27-usb";
-                               reg = <0x53f80600 0x0200>;
-                               interrupts = <17>;
-                               clocks = <&clks IMX5_CLK_USBOH3_GATE>;
-                               dr_mode = "host";
-                               status = "disabled";
-                       };
-
                        gpio1: gpio@53f84000 {
                                compatible = "fsl,imx50-gpio", "fsl,imx35-gpio";
                                reg = <0x53f84000 0x4000>;
index b8ca73d3d379270a6621fa1ae2cf6f353cd8930d..ba60b0cb3cc13ba08c9c414d7b8c317cc936ad7e 100644 (file)
                mux-ext-port = <3>;
        };
 
-       usbphy {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               compatible = "simple-bus";
-
-               usbh1phy: usbh1phy@0 {
-                       compatible = "usb-nop-xceiv";
-                       reg = <0>;
-                       clocks = <&clk_usb>;
-                       clock-names = "main_clk";
-                       reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>;
-                       vcc-supply = <&vusb_reg>;
-                       #phy-cells = <0>;
-               };
+       usbphy1: usbphy1 {
+               compatible = "usb-nop-xceiv";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usbh1reg>;
+               clocks = <&clk_usb>;
+               clock-names = "main_clk";
+               reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>;
+               vcc-supply = <&vusb_reg>;
+               #phy-cells = <0>;
        };
 };
 
        status = "okay";
 };
 
+&pmu {
+       secure-reg-access;
+};
+
 &ssi2 {
        status = "okay";
 };
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usbh1>;
        vbus-supply = <&reg_hub_reset>;
-       fsl,usbphy = <&usbh1phy>;
+       fsl,usbphy = <&usbphy1>;
        phy_type = "ulpi";
        status = "okay";
 };
index b3d952f37cdc9f35c29a9a5039fd5df5f8d9c49b..e9e819f2b0b7d72b87c05f5e6497dc5e669f7a5b 100644 (file)
                fsl,mux-ext-port = <3>;
        };
 
-       usbphy {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               compatible = "simple-bus";
-
-               usbh1phy: usbh1phy@0 {
-                       compatible = "usb-nop-xceiv";
-                       reg = <0>;
-                       clocks = <&clks IMX5_CLK_USB_PHY_GATE>;
-                       clock-names = "main_clk";
-                       clock-frequency = <19200000>;
-                       #phy-cells = <0>;
-               };
+       usbphy1: usbphy1 {
+               compatible = "usb-nop-xceiv";
+               clocks = <&clks IMX5_CLK_USB_PHY_GATE>;
+               clock-names = "main_clk";
+               clock-frequency = <19200000>;
+               #phy-cells = <0>;
        };
 };
 
 &usbh1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usbh1>;
-       fsl,usbphy = <&usbh1phy>;
+       fsl,usbphy = <&usbphy1>;
        dr_mode = "host";
        phy_type = "ulpi";
        status = "okay";
index 8a878687197b35a8e056ba55c4aaec56293123e1..469cce2c03573b5f32d6534ef753b34b4547cd5d 100644 (file)
        status = "okay";
 };
 
+&gpio1 {
+       unused-sd3-wp-gpio {
+               /*
+                * See pinctrl_esdhc1 below for more details on this
+                */
+               gpio-hog;
+               gpios = <1 GPIO_ACTIVE_HIGH>;
+               output-high;
+       };
+};
+
 &i2c2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_i2c2>;
 
                rmi4-f11@11 {
                        reg = <0x11>;
-                       touchscreen-inverted-y;
+                       touchscreen-inverted-x;
                        touchscreen-swapped-x-y;
                        syna,sensor-type = <1>;
                };
        remote-endpoint = <&display_in>;
 };
 
+&pmu {
+       secure-reg-access;
+};
+
 &ssi2 {
        status = "okay";
 };
        rave-sp {
                compatible = "zii,rave-sp-rdu1";
                current-speed = <38400>;
+               #address-cells = <1>;
+               #size-cells = <1>;
 
                watchdog {
                        compatible = "zii,rave-sp-watchdog";
                };
+
+               backlight {
+                       compatible = "zii,rave-sp-backlight";
+               };
+
+               pwrbutton {
+                       compatible = "zii,rave-sp-pwrbutton";
+               };
+
+               eeprom@a3 {
+                       compatible = "zii,rave-sp-eeprom";
+                       reg = <0xa3 0x2000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       zii,eeprom-name = "dds-eeprom";
+               };
+
+               eeprom@a4 {
+                       compatible = "zii,rave-sp-eeprom";
+                       reg = <0xa4 0x4000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       zii,eeprom-name = "main-eeprom";
+               };
+
+               eeprom@ae {
+                       compatible = "zii,rave-sp-eeprom";
+                       reg = <0xae 0x200>;
+                       zii,eeprom-name = "switch-eeprom";
+                       /*
+                        * Not all RDU1s have this functionality, so we
+                        * rely on the bootloader to enable this
+                        */
+                       status = "disabled";
+               };
        };
 };
 
        status = "okay";
 };
 
+&wdog1 {
+       status = "disabled";
+};
+
 &iomuxc {
        pinctrl_ampgpio: ampgpiogrp {
                fsl,pins = <
                        MX51_PAD_SD1_DATA1__SD1_DATA1           0x20d5
                        MX51_PAD_SD1_DATA2__SD1_DATA2           0x20d5
                        MX51_PAD_SD1_DATA3__SD1_DATA3           0x20d5
+                       /*
+                        * GPIO1_1 is not directly used by eSDHC1 in
+                        * any capacity, but earlier versions of RDU1
+                        * used that pin as WP GPIO for eSDHC3 and
+                        * because of that that pad has an external
+                        * pull-up resistor. This is problematic
+                        * because out of reset the pad is configured
+                        * as ALT0 which serves as SD1_WP, which, when
+                        * pulled high by and external pull-up, will
+                        * inhibit execution of any write request to
+                        * attached eMMC device.
+                        *
+                        * To avoid this problem we configure the pad
+                        * to ALT1/GPIO and avoid driving SD1_WP
+                        * signal high.
+                        */
+                       MX51_PAD_GPIO1_1__GPIO1_1               0x0000
                >;
        };
 
diff --git a/arch/arm/boot/dts/imx51-zii-scu2-mezz.dts b/arch/arm/boot/dts/imx51-zii-scu2-mezz.dts
new file mode 100644 (file)
index 0000000..26cf085
--- /dev/null
@@ -0,0 +1,448 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+/*
+ * Copyright (C) 2018 Zodiac Inflight Innovations
+ */
+
+/dts-v1/;
+
+#include "imx51.dtsi"
+
+/ {
+       model = "ZII SCU2 Mezz Board";
+       compatible = "zii,imx51-scu2-mezz", "fsl,imx51";
+
+       chosen {
+               stdout-path = &uart1;
+       };
+
+       /* Will be filled by the bootloader */
+       memory@90000000 {
+               reg = <0x90000000 0>;
+       };
+
+       aliases {
+               mdio-gpio0 = &mdio_gpio;
+       };
+
+       usb_vbus: regulator-usb-vbus {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usb_mmc_reset>;
+               gpio = <&gpio3 13 GPIO_ACTIVE_LOW>;
+               startup-delay-us = <150000>;
+               regulator-name = "usb_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+
+       mdio_gpio: mdio-gpio {
+               compatible = "virtual,mdio-gpio";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_swmdio>;
+               gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>, /* mdc */
+                       <&gpio2 6 GPIO_ACTIVE_HIGH>; /* mdio */
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               switch@0 {
+                       compatible = "marvell,mv88e6085";
+                       reg = <0>;
+                       dsa,member = <0 0>;
+                       eeprom-length = <512>;
+                       interrupt-parent = <&gpio1>;
+                       interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       label = "port4";
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       label = "port5";
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       label = "port6";
+                               };
+
+                               port@3 {
+                                       reg = <3>;
+                                       label = "port7";
+                               };
+
+                               port@4 {
+                                       reg = <4>;
+                                       label = "cpu";
+                                       ethernet = <&fec>;
+
+                                       fixed-link {
+                                               speed = <100>;
+                                               full-duplex;
+                                       };
+                               };
+
+                               port@5 {
+                                       reg = <5>;
+                                       label = "mezz2esb";
+                                       phy-mode = "sgmii";
+
+                                       fixed-link {
+                                               speed = <1000>;
+                                               full-duplex;
+                                       };
+                               };
+                       };
+               };
+       };
+};
+
+&cpu {
+       cpu-supply = <&sw1_reg>;
+};
+
+&ecspi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi1>;
+       cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>,
+                  <&gpio4 25 GPIO_ACTIVE_LOW>;
+       status = "okay";
+
+       pmic@0 {
+               compatible = "fsl,mc13892";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pmic>;
+               spi-max-frequency = <6000000>;
+               spi-cs-high;
+               reg = <0>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+               fsl,mc13xxx-uses-adc;
+
+               regulators {
+                       sw1_reg: sw1 {
+                               regulator-min-microvolt = <600000>;
+                               regulator-max-microvolt = <1375000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1850000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3_reg: sw3 {
+                               regulator-min-microvolt = <1100000>;
+                               regulator-max-microvolt = <1850000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: sw4 {
+                               regulator-min-microvolt = <1100000>;
+                               regulator-max-microvolt = <1850000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vpll_reg: vpll {
+                               regulator-min-microvolt = <1050000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vdig_reg: vdig {
+                               regulator-min-microvolt = <1650000>;
+                               regulator-max-microvolt = <1650000>;
+                               regulator-boot-on;
+                       };
+
+                       vsd_reg: vsd {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3150000>;
+                               regulator-always-on;
+                       };
+
+                       vusb_reg: vusb {
+                               regulator-always-on;
+                       };
+
+                       vusb2_reg: vusb2 {
+                               regulator-min-microvolt = <2400000>;
+                               regulator-max-microvolt = <2775000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vvideo_reg: vvideo {
+                               regulator-min-microvolt = <2775000>;
+                               regulator-max-microvolt = <2775000>;
+                       };
+
+                       vaudio_reg: vaudio {
+                               regulator-min-microvolt = <2300000>;
+                               regulator-max-microvolt = <3000000>;
+                       };
+
+                       vcam_reg: vcam {
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <3000000>;
+                       };
+
+                       vgen1_reg: vgen1 {
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                       };
+
+                       vgen2_reg: vgen2 {
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <3150000>;
+                               regulator-always-on;
+                       };
+
+                       vgen3_reg: vgen3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <2900000>;
+                               regulator-always-on;
+                       };
+               };
+
+               leds {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       led-control = <0x0 0x0 0x3f83f8 0x0>;
+
+                       sysled3: led3@3 {
+                               reg = <3>;
+                               label = "system:red:power";
+                               linux,default-trigger = "default-on";
+                       };
+
+                       sysled4: led4@4 {
+                               reg = <4>;
+                               label = "system:green:act";
+                               linux,default-trigger = "heartbeat";
+                       };
+               };
+       };
+
+       flash@1 {
+               compatible = "atmel,at45", "atmel,dataflash";
+               reg = <1>;
+               spi-max-frequency = <25000000>;
+       };
+};
+
+&esdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc1>;
+       bus-width = <8>;
+       non-removable;
+       no-1-8-v;
+       no-sdio;
+       no-sd;
+       status = "okay";
+};
+
+&esdhc4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc4>;
+       bus-width = <4>;
+       no-1-8-v;
+       no-sdio;
+       cd-gpios = <&gpio4 8 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec>;
+       phy-mode = "mii";
+       status = "okay";
+       phy-reset-gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+       phy-reset-duration = <1>;
+       phy-supply = <&vgen3_reg>;
+       phy-handle = <&ethphy>;
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy: ethernet-phy@0 {
+                       reg = <0>;
+                       max-speed = <100>;
+               };
+       };
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       eeprom@50 {
+               compatible = "atmel,24c04";
+               pagesize = <16>;
+               reg = <0x50>;
+       };
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3>;
+       status = "okay";
+
+       rave-sp {
+               compatible = "zii,rave-sp-mezz";
+               current-speed = <57600>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               watchdog {
+                       compatible = "zii,rave-sp-watchdog-legacy";
+               };
+
+               eeprom@a4 {
+                       compatible = "zii,rave-sp-eeprom";
+                       reg = <0xa4 0x4000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       zii,eeprom-name = "main-eeprom";
+               };
+       };
+};
+
+&usbotg {
+       dr_mode = "host";
+       disable-over-current;
+       phy_type = "utmi_wide";
+       vbus-supply = <&usb_vbus>;
+       status = "okay";
+};
+
+&usbphy0 {
+       vcc-supply = <&vusb2_reg>;
+};
+
+&iomuxc {
+       pinctrl_ecspi1: ecspi1grp {
+               fsl,pins = <
+                       MX51_PAD_CSPI1_MISO__ECSPI1_MISO        0x185
+                       MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI        0x185
+                       MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK        0x185
+                       MX51_PAD_CSPI1_SS0__GPIO4_24            0x85
+                       MX51_PAD_CSPI1_SS1__GPIO4_25            0x85
+               >;
+       };
+
+       pinctrl_esdhc1: esdhc1grp {
+               fsl,pins = <
+                       MX51_PAD_SD1_CMD__SD1_CMD               0x400020d5
+                       MX51_PAD_SD1_CLK__SD1_CLK               0x20d5
+                       MX51_PAD_SD1_DATA0__SD1_DATA0           0x20d5
+                       MX51_PAD_SD1_DATA1__SD1_DATA1           0x20d5
+                       MX51_PAD_SD1_DATA2__SD1_DATA2           0x20d5
+                       MX51_PAD_SD1_DATA3__SD1_DATA3           0x20d5
+                       MX51_PAD_SD2_DATA0__SD1_DAT4            0x20d5
+                       MX51_PAD_SD2_DATA1__SD1_DAT5            0x20d5
+                       MX51_PAD_SD2_DATA2__SD1_DAT6            0x20d5
+                       MX51_PAD_SD2_DATA3__SD1_DAT7            0x20d5
+               >;
+       };
+
+       pinctrl_esdhc4: esdhc4grp {
+               fsl,pins = <
+                       MX51_PAD_NANDF_RB1__SD4_CMD             0x400020d5
+                       MX51_PAD_NANDF_CS2__SD4_CLK             0x20d5
+                       MX51_PAD_NANDF_CS3__SD4_DAT0            0x20d5
+                       MX51_PAD_NANDF_CS4__SD4_DAT1            0x20d5
+                       MX51_PAD_NANDF_CS5__SD4_DAT2            0x20d5
+                       MX51_PAD_NANDF_CS6__SD4_DAT3            0x20d5
+                       MX51_PAD_NANDF_D0__GPIO4_8              0x100
+               >;
+       };
+
+       pinctrl_fec: fecgrp {
+               fsl,pins = <
+                       MX51_PAD_DISP2_DAT15__FEC_TDATA0        0x2004
+                       MX51_PAD_DISP2_DAT6__FEC_TDATA1         0x2004
+                       MX51_PAD_DISP2_DAT7__FEC_TDATA2         0x2004
+                       MX51_PAD_DISP2_DAT8__FEC_TDATA3         0x2004
+                       MX51_PAD_DISP2_DAT9__FEC_TX_EN          0x2004
+                       MX51_PAD_DISP2_DAT10__FEC_COL           0x0180
+                       MX51_PAD_DISP2_DAT11__FEC_RX_CLK        0x0180
+                       MX51_PAD_DISP2_DAT12__FEC_RX_DV         0x20a4
+                       MX51_PAD_DISP2_DAT1__FEC_RX_ER          0x20a4
+                       MX51_PAD_DISP2_DAT13__FEC_TX_CLK        0x2180
+                       MX51_PAD_DI_GP3__FEC_TX_ER              0x2004
+                       MX51_PAD_DISP2_DAT14__FEC_RDATA0        0x2180
+                       MX51_PAD_DI2_DISP_CLK__FEC_RDATA1       0x0085
+                       MX51_PAD_DI_GP4__FEC_RDATA2             0x0085
+                       MX51_PAD_DISP2_DAT0__FEC_RDATA3         0x0085
+                       MX51_PAD_DI2_PIN2__FEC_MDC              0x2004
+                       MX51_PAD_DI2_PIN3__FEC_MDIO             0x01f5
+                       MX51_PAD_DI2_PIN4__FEC_CRS              0x0180
+                       MX51_PAD_EIM_A20__GPIO2_14              0x0085
+                       MX51_PAD_EIM_A21__GPIO2_15              0x00e5
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX51_PAD_KEY_COL4__I2C2_SCL             0x400001ed
+                       MX51_PAD_KEY_COL5__I2C2_SDA             0x400001ed
+               >;
+       };
+
+       pinctrl_pmic: pmicgrp {
+               fsl,pins = <
+                       MX51_PAD_GPIO1_4__GPIO1_4               0x85
+                       MX51_PAD_GPIO1_8__GPIO1_8               0xe5
+               >;
+       };
+
+       pinctrl_swmdio: swmdiogrp {
+               fsl,pins = <
+                       MX51_PAD_EIM_D22__GPIO2_6               0x100
+                       MX51_PAD_EIM_D23__GPIO2_7               0x100
+               >;
+       };
+
+       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_usb_mmc_reset: usbmmcgrp {
+               fsl,pins = <
+                       MX51_PAD_CSI1_D9__GPIO3_13              0x85
+               >;
+       };
+};
diff --git a/arch/arm/boot/dts/imx51-zii-scu3-esb.dts b/arch/arm/boot/dts/imx51-zii-scu3-esb.dts
new file mode 100644 (file)
index 0000000..e6ebac8
--- /dev/null
@@ -0,0 +1,467 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+/*
+ * Copyright (C) 2018 Zodiac Inflight Innovations
+ */
+
+/dts-v1/;
+
+#include "imx51.dtsi"
+
+/ {
+       model = "ZII SCU3 ESB board";
+       compatible = "zii,imx51-scu3-esb", "fsl,imx51";
+
+       chosen {
+               stdout-path = &uart1;
+       };
+
+       /* Will be filled by the bootloader */
+       memory@90000000 {
+               reg = <0x90000000 0>;
+       };
+
+       usb_vbus: regulator-usb-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usb_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usb_mmc_reset>;
+               gpio = <&gpio4 19 GPIO_ACTIVE_LOW>;
+               startup-delay-us = <150000>;
+       };
+};
+
+&cpu {
+       cpu-supply = <&sw1_reg>;
+};
+
+&ecspi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi1>;
+       cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>,
+                  <&gpio4 25 GPIO_ACTIVE_LOW>;
+       status = "okay";
+
+       pmic@0 {
+               compatible = "fsl,mc13892";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pmic>;
+               spi-max-frequency = <6000000>;
+               spi-cs-high;
+               reg = <0>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+               fsl,mc13xxx-uses-adc;
+
+               regulators {
+                       sw1_reg: sw1 {
+                               regulator-min-microvolt = <600000>;
+                               regulator-max-microvolt = <1375000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1850000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw3_reg: sw3 {
+                               regulator-min-microvolt = <1100000>;
+                               regulator-max-microvolt = <1850000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: sw4 {
+                               regulator-min-microvolt = <1100000>;
+                               regulator-max-microvolt = <1850000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vpll_reg: vpll {
+                               regulator-min-microvolt = <1050000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vdig_reg: vdig {
+                               regulator-min-microvolt = <1650000>;
+                               regulator-max-microvolt = <1650000>;
+                               regulator-boot-on;
+                       };
+
+                       vsd_reg: vsd {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3150000>;
+                       };
+
+                       vusb_reg: vusb {
+                               regulator-always-on;
+                       };
+
+                       vusb2_reg: vusb2 {
+                               regulator-min-microvolt = <2400000>;
+                               regulator-max-microvolt = <2775000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vvideo_reg: vvideo {
+                               regulator-min-microvolt = <2775000>;
+                               regulator-max-microvolt = <2775000>;
+                       };
+
+                       vaudio_reg: vaudio {
+                               regulator-min-microvolt = <2300000>;
+                               regulator-max-microvolt = <3000000>;
+                       };
+
+                       vcam_reg: vcam {
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <3000000>;
+                       };
+
+                       vgen1_reg: vgen1 {
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                       };
+
+                       vgen2_reg: vgen2 {
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <3150000>;
+                               regulator-always-on;
+                       };
+
+                       vgen3_reg: vgen3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <2900000>;
+                               regulator-always-on;
+                       };
+               };
+
+               leds {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       led-control = <0x0 0x0 0x3f83f8 0x0>;
+
+                       sysled3: led3@3 {
+                               reg = <3>;
+                               label = "system:red:power";
+                               linux,default-trigger = "default-on";
+                       };
+
+                       sysled4: led4@4 {
+                               reg = <4>;
+                               label = "system:green:act";
+                               linux,default-trigger = "heartbeat";
+                       };
+               };
+       };
+
+       flash@1 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "atmel,at45", "atmel,dataflash";
+               spi-max-frequency = <25000000>;
+               reg = <1>;
+       };
+};
+
+&esdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc1>;
+       bus-width = <8>;
+       non-removable;
+       no-1-8-v;
+       no-sdio;
+       no-sd;
+       status = "okay";
+};
+
+&esdhc4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc4>;
+       bus-width = <4>;
+       no-1-8-v;
+       no-sdio;
+       cd-gpios = <&gpio4 8 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec>;
+       phy-mode = "mii";
+       status = "okay";
+
+       fixed-link {
+               speed = <100>;
+               full-duplex;
+       };
+
+       fec_mdio: mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "okay";
+
+               switch@0 {
+                       compatible = "marvell,mv88e6085";
+                       reg = <0>;
+                       dsa,member = <0 0>;
+                       eeprom-length = <512>;
+                       interrupt-parent = <&gpio4>;
+                       interrupts = <20 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_switch>;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       label = "port1";
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       label = "port2";
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       label = "port3";
+                               };
+
+                               port@3 {
+                                       reg = <3>;
+                                       label = "scu2scu";
+                               };
+
+                               port@4 {
+                                       reg = <4>;
+                                       label = "esb2host";
+                               };
+
+                               port@5 {
+                                       reg = <5>;
+                                       label = "esb2mezz";
+                                       phy-mode = "sgmii";
+
+                                       fixed-link {
+                                               speed = <1000>;
+                                               full-duplex;
+                                       };
+                               };
+
+                               port@6 {
+                                       reg = <6>;
+                                       label = "cpu";
+                                       phy-mode = "mii";
+                                       ethernet = <&fec>;
+
+                                       fixed-link {
+                                               speed = <100>;
+                                               full-duplex;
+                                       };
+                               };
+                       };
+               };
+       };
+};
+
+&ipu {
+       status = "disabled";
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       eeprom@50 {
+               compatible = "atmel,24c04";
+               pagesize = <16>;
+               reg = <0x50>;
+       };
+
+       lm75@48 {
+               compatible = "national,lm75";
+               reg = <0x48>;
+       };
+};
+
+&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";
+
+       rave-sp {
+               compatible = "zii,rave-sp-esb";
+               current-speed = <57600>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               watchdog {
+                       compatible = "zii,rave-sp-watchdog-legacy";
+               };
+
+               eeprom@a4 {
+                       compatible = "zii,rave-sp-eeprom";
+                       reg = <0xa4 0x4000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       zii,eeprom-name = "main-eeprom";
+               };
+       };
+};
+
+&usbotg {
+       dr_mode = "host";
+       disable-over-current;
+       phy_type = "utmi_wide";
+       vbus-supply = <&usb_vbus>;
+       status = "okay";
+};
+
+&usbphy0 {
+       vcc-supply = <&vusb2_reg>;
+};
+
+&wdog1 {
+       status = "disabled";
+};
+
+&iomuxc {
+       pinctrl_ecspi1: ecspi1grp {
+               fsl,pins = <
+                       MX51_PAD_CSPI1_MISO__ECSPI1_MISO        0x185
+                       MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI        0x185
+                       MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK        0x185
+                       MX51_PAD_CSPI1_SS0__GPIO4_24            0x85
+                       MX51_PAD_CSPI1_SS1__GPIO4_25            0x85
+               >;
+       };
+
+       pinctrl_esdhc1: esdhc1grp {
+               fsl,pins = <
+                       MX51_PAD_SD1_CMD__SD1_CMD               0x400020d5
+                       MX51_PAD_SD1_CLK__SD1_CLK               0x20d5
+                       MX51_PAD_SD1_DATA0__SD1_DATA0           0x20d5
+                       MX51_PAD_SD1_DATA1__SD1_DATA1           0x20d5
+                       MX51_PAD_SD1_DATA2__SD1_DATA2           0x20d5
+                       MX51_PAD_SD1_DATA3__SD1_DATA3           0x20d5
+                       MX51_PAD_SD2_DATA0__SD1_DAT4            0x20d5
+                       MX51_PAD_SD2_DATA1__SD1_DAT5            0x20d5
+                       MX51_PAD_SD2_DATA2__SD1_DAT6            0x20d5
+                       MX51_PAD_SD2_DATA3__SD1_DAT7            0x20d5
+               >;
+       };
+
+       pinctrl_esdhc4: esdhc4grp {
+               fsl,pins = <
+                       MX51_PAD_NANDF_RB1__SD4_CMD             0x400020d5
+                       MX51_PAD_NANDF_CS2__SD4_CLK             0x20d5
+                       MX51_PAD_NANDF_CS3__SD4_DAT0            0x20d5
+                       MX51_PAD_NANDF_CS4__SD4_DAT1            0x20d5
+                       MX51_PAD_NANDF_CS5__SD4_DAT2            0x20d5
+                       MX51_PAD_NANDF_CS6__SD4_DAT3            0x20d5
+                       MX51_PAD_NANDF_D0__GPIO4_8              0x100
+               >;
+       };
+
+       pinctrl_fec: fecgrp {
+               fsl,pins = <
+                       MX51_PAD_DISP2_DAT15__FEC_TDATA0        0x2004
+                       MX51_PAD_DISP2_DAT6__FEC_TDATA1         0x2004
+                       MX51_PAD_DISP2_DAT7__FEC_TDATA2         0x2004
+                       MX51_PAD_DISP2_DAT8__FEC_TDATA3         0x2004
+                       MX51_PAD_DISP2_DAT9__FEC_TX_EN          0x2004
+                       MX51_PAD_DISP2_DAT10__FEC_COL           0x0180
+                       MX51_PAD_DISP2_DAT11__FEC_RX_CLK        0x0180
+                       MX51_PAD_DISP2_DAT12__FEC_RX_DV         0x20a4
+
+                       MX51_PAD_DISP2_DAT13__FEC_TX_CLK        0x2180
+                       MX51_PAD_DISP2_DAT14__FEC_RDATA0        0x2180
+                       MX51_PAD_DI2_DISP_CLK__FEC_RDATA1       0x0085
+                       MX51_PAD_DI_GP4__FEC_RDATA2             0x0085
+                       MX51_PAD_DISP2_DAT0__FEC_RDATA3         0x0085
+                       MX51_PAD_DI2_PIN2__FEC_MDC              0x2004
+                       MX51_PAD_DI2_PIN3__FEC_MDIO             0x01f5
+                       MX51_PAD_DI2_PIN4__FEC_CRS              0x0180
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX51_PAD_KEY_COL4__I2C2_SCL             0x400001ed
+                       MX51_PAD_KEY_COL5__I2C2_SDA             0x400001ed
+               >;
+       };
+
+       pinctrl_pmic: pmicgrp {
+               fsl,pins = <
+                       MX51_PAD_GPIO1_4__GPIO1_4               0x85
+                       MX51_PAD_GPIO1_8__GPIO1_8               0xe5
+               >;
+       };
+
+       pinctrl_switch: switchgrp {
+               fsl,pins = <
+                       MX51_PAD_AUD3_BB_CK__GPIO4_20           0xc5
+               >;
+       };
+
+       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
+                       MX51_PAD_USBH1_DATA0__UART2_CTS         0x1c5
+                       MX51_PAD_USBH1_DATA3__UART2_RTS         0x1c5
+               >;
+       };
+
+       pinctrl_uart3: uart3grp {
+               fsl,pins = <
+                       MX51_PAD_UART3_RXD__UART3_RXD           0x1c5
+                       MX51_PAD_UART3_TXD__UART3_TXD           0x1c5
+               >;
+       };
+
+       pinctrl_usb_mmc_reset: usbmmcgrp {
+               fsl,pins = <
+                       MX51_PAD_AUD3_BB_RXD__GPIO4_19          0x100
+               >;
+       };
+};
index fe01b890c715d19c7af3cd5ade82667fb3f72549..5c4ba91e43ba4b2e797d3d34dea32093f9a1f0e6 100644 (file)
                };
        };
 
-       usbphy {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               compatible = "simple-bus";
+       pmu: pmu {
+               compatible = "arm,cortex-a8-pmu";
+               interrupt-parent = <&tzic>;
+               interrupts = <77>;
+       };
 
-               usbphy0: usbphy@0 {
-                       compatible = "usb-nop-xceiv";
-                       reg = <0>;
-                       clocks = <&clks IMX5_CLK_USB_PHY_GATE>;
-                       clock-names = "main_clk";
-                       #phy-cells = <0>;
-               };
+       usbphy0: usbphy0 {
+               compatible = "usb-nop-xceiv";
+               clocks = <&clks IMX5_CLK_USB_PHY_GATE>;
+               clock-names = "main_clk";
+               #phy-cells = <0>;
        };
 
        display-subsystem {
                                };
                        };
 
+                       aipstz1: bridge@73f00000 {
+                               compatible = "fsl,imx51-aipstz";
+                               reg = <0x73f00000 0x60>;
+                       };
+
                        usbotg: usb@73f80000 {
                                compatible = "fsl,imx51-usb", "fsl,imx27-usb";
                                reg = <0x73f80000 0x0200>;
                        reg = <0x80000000 0x10000000>;
                        ranges;
 
+                       aipstz2: bridge@83f00000 {
+                               compatible = "fsl,imx51-aipstz";
+                               reg = <0x83f00000 0x60>;
+                       };
+
                        iim: iim@83f98000 {
                                compatible = "fsl,imx51-iim", "fsl,imx27-iim";
                                reg = <0x83f98000 0x4000>;
                                clocks = <&clks IMX5_CLK_IIM_GATE>;
                        };
 
+                       tigerp: tigerp@83fa0000 {
+                               compatible = "fsl,imx51-tigerp";
+                               reg = <0x83fa0000 0x28>;
+                       };
+
                        owire: owire@83fa4000 {
                                compatible = "fsl,imx51-owire", "fsl,imx21-owire";
                                reg = <0x83fa4000 0x4000>;
                                status = "disabled";
                        };
 
+                       m4if: m4if@83fd8000 {
+                               compatible = "fsl,imx51-m4if";
+                               reg = <0x83fd8000 0x1000>;
+                       };
+
                        weim: weim@83fda000 {
                                #address-cells = <2>;
                                #size-cells = <1>;
                                clock-names = "ipg", "ahb", "ptp";
                                status = "disabled";
                        };
+
+                       vpu@83ff4000 {
+                               compatible = "fsl,imx51-vpu", "cnm,codahx4";
+                               reg = <0x83ff4000 0x1000>;
+                               interrupts = <9>;
+                               clocks = <&clks IMX5_CLK_VPU_REFERENCE_GATE>,
+                                        <&clks IMX5_CLK_VPU_GATE>;
+                               clock-names = "per", "ahb";
+                               resets = <&src 1>;
+                               iram = <&iram>;
+                       };
+
+                       sahara: crypto@83ff8000 {
+                               compatible = "fsl,imx53-sahara", "fsl,imx51-sahara";
+                               reg = <0x83ff8000 0x4000>;
+                               interrupts = <19 20>;
+                               clocks = <&clks IMX5_CLK_SAHARA_IPG_GATE>,
+                                        <&clks IMX5_CLK_SAHARA_IPG_GATE>;
+                               clock-names = "ipg", "ahb";
+                       };
                };
        };
 };
diff --git a/arch/arm/boot/dts/imx53-kp-ddc.dts b/arch/arm/boot/dts/imx53-kp-ddc.dts
new file mode 100644 (file)
index 0000000..0e7f071
--- /dev/null
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2018
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ */
+
+/dts-v1/;
+#include "imx53-kp.dtsi"
+
+/ {
+       model = "K+P imx53 DDC";
+       compatible = "kiebackpeter,imx53-ddc", "fsl,imx53";
+
+       backlight_lcd: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm2 0 50000>;
+               power-supply = <&reg_backlight>;
+               brightness-levels = <0 24 28 32 36
+                                    40 44 48 52 56
+                                    60 64 68 72 76
+                                    80 84 88 92 96 100>;
+               default-brightness-level = <20>;
+       };
+
+       lcd_display: display {
+               compatible = "fsl,imx-parallel-display";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interface-pix-fmt = "rgb24";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_disp>;
+
+               port@0 {
+                       reg = <0>;
+
+                       display1_in: endpoint {
+                               remote-endpoint = <&ipu_di1_disp1>;
+                       };
+               };
+
+               port@1 {
+                       reg = <1>;
+
+                       lcd_display_out: endpoint {
+                               remote-endpoint = <&lcd_panel_in>;
+                       };
+               };
+       };
+
+       lcd_panel: lcd-panel {
+               compatible = "koe,tx14d24vm1bpa";
+               backlight = <&backlight_lcd>;
+               power-supply = <&reg_3v3>;
+
+               port {
+                       lcd_panel_in: endpoint {
+                               remote-endpoint = <&lcd_display_out>;
+                       };
+               };
+       };
+
+       reg_backlight: regulator-backlight {
+               compatible = "regulator-fixed";
+               regulator-name = "backlight-supply";
+               regulator-min-microvolt = <15000000>;
+               regulator-max-microvolt = <15000000>;
+               regulator-always-on;
+       };
+};
+
+&fec {
+       status = "okay";
+};
+
+&i2c3 {
+       adc@48 {
+               compatible = "ti,ads1015";
+               reg = <0x48>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               channel@4 {
+                       reg = <4>;
+                       ti,gain = <2>;
+                       ti,datarate = <4>;
+               };
+
+               channel@6 {
+                       reg = <6>;
+                       ti,gain = <2>;
+                       ti,datarate = <4>;
+               };
+       };
+
+       gpio-expander2@21 {
+               compatible = "nxp,pcf8574";
+               reg = <0x21>;
+               interrupts = <109>;
+               #gpio-cells = <2>;
+               gpio-controller;
+       };
+};
+
+&iomuxc {
+       imx53-kp-ddc {
+               pinctrl_disp: dispgrp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_A16__IPU_DI1_DISP_CLK      0x4
+                               MX53_PAD_EIM_DA10__IPU_DI1_PIN15        0x4
+                               MX53_PAD_EIM_DA9__IPU_DISP1_DAT_0       0x4
+                               MX53_PAD_EIM_DA8__IPU_DISP1_DAT_1       0x4
+                               MX53_PAD_EIM_DA7__IPU_DISP1_DAT_2       0x4
+                               MX53_PAD_EIM_DA6__IPU_DISP1_DAT_3       0x4
+                               MX53_PAD_EIM_DA5__IPU_DISP1_DAT_4       0x4
+                               MX53_PAD_EIM_DA4__IPU_DISP1_DAT_5       0x4
+                               MX53_PAD_EIM_DA3__IPU_DISP1_DAT_6       0x4
+                               MX53_PAD_EIM_DA2__IPU_DISP1_DAT_7       0x4
+                               MX53_PAD_EIM_DA1__IPU_DISP1_DAT_8       0x4
+                               MX53_PAD_EIM_DA0__IPU_DISP1_DAT_9       0x4
+                               MX53_PAD_EIM_EB1__IPU_DISP1_DAT_10      0x4
+                               MX53_PAD_EIM_EB0__IPU_DISP1_DAT_11      0x4
+                               MX53_PAD_EIM_A17__IPU_DISP1_DAT_12      0x4
+                               MX53_PAD_EIM_A18__IPU_DISP1_DAT_13      0x4
+                               MX53_PAD_EIM_A19__IPU_DISP1_DAT_14      0x4
+                               MX53_PAD_EIM_A20__IPU_DISP1_DAT_15      0x4
+                               MX53_PAD_EIM_A21__IPU_DISP1_DAT_16      0x4
+                               MX53_PAD_EIM_A22__IPU_DISP1_DAT_17      0x4
+                               MX53_PAD_EIM_A23__IPU_DISP1_DAT_18      0x4
+                               MX53_PAD_EIM_A24__IPU_DISP1_DAT_19      0x4
+                               MX53_PAD_EIM_D31__IPU_DISP1_DAT_20      0x4
+                               MX53_PAD_EIM_D30__IPU_DISP1_DAT_21      0x4
+                               MX53_PAD_EIM_D26__IPU_DISP1_DAT_22      0x4
+                               MX53_PAD_EIM_D27__IPU_DISP1_DAT_23      0x4
+                               MX53_PAD_GPIO_1__PWM2_PWMO 0x4
+                       >;
+               };
+       };
+};
+
+&ipu_di1_disp1 {
+       remote-endpoint = <&display1_in>;
+};
+
+&pmic {
+       fsl,mc13xxx-uses-touch;
+};
diff --git a/arch/arm/boot/dts/imx53-kp-hsc.dts b/arch/arm/boot/dts/imx53-kp-hsc.dts
new file mode 100644 (file)
index 0000000..6e3d71b
--- /dev/null
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2018
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ */
+
+/dts-v1/;
+#include "imx53-kp.dtsi"
+
+/ {
+       model = "K+P imx53 HSC";
+       compatible = "kiebackpeter,imx53-hsc", "fsl,imx53";
+};
+
+&fec {
+       status = "okay";
+
+       fixed-link { /* RMII fixed link to LAN9303 */
+               speed = <100>;
+               full-duplex;
+       };
+};
+
+&i2c3 {
+       switch: switch@a {
+               compatible = "smsc,lan9303-i2c";
+               reg = <0xa>;
+               reset-gpios = <&gpio7 6 GPIO_ACTIVE_LOW>;
+               reset-duration = <400>;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 { /* RMII fixed link to master */
+                               reg = <0>;
+                               label = "cpu";
+                               ethernet = <&fec>;
+                       };
+
+                       port@1 { /* external port 1 */
+                               reg = <1>;
+                               label = "lan1";
+                       };
+
+                       port@2 { /* external port 2 */
+                               reg = <2>;
+                               label = "lan2";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/imx53-kp.dtsi b/arch/arm/boot/dts/imx53-kp.dtsi
new file mode 100644 (file)
index 0000000..8b25416
--- /dev/null
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2018
+ * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
+ */
+
+/dts-v1/;
+#include "imx53-tqma53.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+       buzzer {
+               compatible = "pwm-beeper";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_buzzer>;
+               pwms = <&pwm1 0 500000>;
+       };
+
+       gpio-buttons {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpiobuttons>;
+
+               button-kalt {
+                       label = "Kaltstart";
+                       linux,code = <KEY_F6>;
+                       gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>;
+               };
+
+               button-pwr {
+                       label = "PowerFailInterrupt";
+                       linux,code = <KEY_F7>;
+                       gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_leds>;
+
+               led-bus {
+                       label = "bus";
+                       gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "gpio";
+                       default-state = "off";
+               };
+
+               led-error {
+                       label = "error";
+                       gpios = <&gpio3 28 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "gpio";
+                       default-state = "off";
+               };
+
+               led-flash {
+                       label = "flash";
+                       gpios = <&gpio5 0 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       reg_3v3: regulator-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+};
+
+&can1 {
+       status = "okay";
+};
+
+&can2 {
+       status = "okay";
+};
+
+&i2c3 {
+       status = "okay";
+
+       gpio-expander1@22 {
+               compatible = "nxp,pcf8574";
+               reg = <0x22>;
+               interrupts = <109>;
+               #gpio-cells = <2>;
+               gpio-controller;
+       };
+
+       rtc@51 {
+               compatible = "nxp,pcf8563";
+               reg = <0x51>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_kp_common>;
+
+       imx53-kp-common {
+               pinctrl_buzzer: buzzergrp {
+                       fsl,pins = <
+                               MX53_PAD_SD1_DATA3__PWM1_PWMO 0x1e4
+                       >;
+               };
+
+               pinctrl_gpiobuttons: gpiobuttonsgrp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_RW__GPIO2_26 0x1e4
+                               MX53_PAD_EIM_D22__GPIO3_22 0x1e4
+                       >;
+               };
+
+               pinctrl_kp_common: kpcommongrp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_CS0__GPIO2_23 0x1e4
+                               MX53_PAD_GPIO_19__GPIO4_5  0x1e4
+                               MX53_PAD_PATA_DATA6__GPIO2_6 0x1e4
+                               MX53_PAD_PATA_DATA7__GPIO2_7 0xe0
+                               MX53_PAD_CSI0_DAT14__GPIO6_0 0x1e4
+                               MX53_PAD_CSI0_DAT16__GPIO6_2 0x1e4
+                               MX53_PAD_CSI0_DAT18__GPIO6_4 0x1e4
+                               MX53_PAD_EIM_D17__GPIO3_17 0x1e4
+                               MX53_PAD_EIM_D18__GPIO3_18 0x1e4
+                               MX53_PAD_EIM_D21__GPIO3_21 0x1e4
+                               MX53_PAD_EIM_D29__GPIO3_29 0x1e4
+                               MX53_PAD_EIM_DA11__GPIO3_11 0x1e4
+                               MX53_PAD_EIM_DA13__GPIO3_13 0x1e4
+                               MX53_PAD_EIM_DA14__GPIO3_14 0x1e4
+                               MX53_PAD_SD1_DATA0__GPIO1_16 0x1e4
+                               MX53_PAD_SD1_CMD__GPIO1_18 0x1e4
+                               MX53_PAD_SD1_CLK__GPIO1_20 0x1e4
+                       >;
+               };
+
+               pinctrl_leds: ledgrp {
+                       fsl,pins = <
+                               MX53_PAD_EIM_EB2__GPIO2_30 0x1d4
+                               MX53_PAD_EIM_D28__GPIO3_28 0x1d4
+                               MX53_PAD_EIM_WAIT__GPIO5_0 0x1d4
+                       >;
+               };
+
+               pinctrl_uart4: uart4grp {
+                       fsl,pins = <
+                               MX53_PAD_CSI0_DAT12__UART4_TXD_MUX 0x1e4
+                               MX53_PAD_CSI0_DAT13__UART4_RXD_MUX 0x1e4
+                       >;
+               };
+       };
+};
+
+&pinctrl_uart1 {
+       fsl,pins = <
+               MX53_PAD_EIM_D23__GPIO3_23 0x1e4
+               MX53_PAD_EIM_EB3__GPIO2_31 0x1e4
+               MX53_PAD_EIM_D24__GPIO3_24 0x1e4
+               MX53_PAD_EIM_D25__GPIO3_25 0x1e4
+               MX53_PAD_EIM_D19__GPIO3_19 0x1e4
+               MX53_PAD_EIM_D20__GPIO3_20 0x1e4
+       >;
+};
+
+&uart1 {
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&uart3 {
+       status = "okay";
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart4>;
+       status = "okay";
+};
+
+&usbh1 {
+       status = "okay";
+};
+
+&usbphy0 {
+       status = "disabled";
+};
index 3aa6f693fa9fb51a02c2c1300849f979bf2b56c3..cdb90bee7b4a2b3d4d68681cc68c0c0efea7efae 100644 (file)
                regulator-always-on;
        };
 
+       reg_3v3: regulator-3v3 {
+               /* TPS54320 */
+               compatible = "regulator-fixed";
+               regulator-name = "3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       reg_3v3_lcd: regulator-3v3-lcd {
+               /* MIC2009 */
+               compatible = "regulator-fixed";
+               regulator-name = "LCD_3V3";
+               vin-supply = <&reg_3v3>;
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
        pwm_bl: backlight {
                compatible = "pwm-backlight";
                pwms = <&pwm2 0 50000>;
                                     234 237 239 242 244 247 249 252 255>;
                default-brightness-level = <0>;
                enable-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
+               power-supply = <&reg_3v3_lcd>;
        };
 
        leds {
                };
        };
 
-       usbphy2: usbphy2 {
+       usbphy2: usbphy-2 {
                compatible = "usb-nop-xceiv";
+               vcc-supply = <&reg_3v3>;
                reset-gpios = <&gpio4 4 GPIO_ACTIVE_LOW>;
                clock-names = "main_clk";
                clock-frequency = <24000000>;
                assigned-clock-parents = <&clks IMX5_CLK_OSC>;
        };
 
-       usbphy3: usbphy3 {
+       usbphy3: usbphy-3 {
                compatible = "usb-nop-xceiv";
+               vcc-supply = <&reg_3v3>;
                reset-gpios = <&gpio2 19 GPIO_ACTIVE_LOW>;
                clock-names = "main_clk";
 
 
        panel-lvds0 {
                compatible = "nvd,9128";
+               power-supply = <&reg_3v3_lcd>;
 
                port {
                        panel_in_lvds0: endpoint {
        };
 };
 
+&usbphy0 {
+       vcc-supply = <&reg_3v3>;
+};
+
+&usbphy1 {
+       vcc-supply = <&reg_3v3>;
+};
+
 &audmux {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_audmux>;
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_fec>;
+       phy-supply = <&reg_3v3>;
        phy-mode = "rmii";
        phy-reset-gpios = <&gpio2 16 GPIO_ACTIVE_LOW>;
        status = "okay";
        };
 };
 
+&pmu {
+       secure-reg-access;
+};
+
 &pwm1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
index ef7658a788364dfff3d3f2a36cf3f0c4582218ef..7423d462d1e4229699f755a75e8237a06a51465c 100644 (file)
        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
                        >;
                };
 
+               pinctrl_codec: codecgrp {
+                       fsl,pins = <
+                               MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK       0x1c4
+                       >;
+               };
+
                pinctrl_esdhc1: esdhc1grp {
                        fsl,pins = <
                                MX53_PAD_SD1_DATA0__ESDHC1_DAT0         0x1d5
        sgtl5000: codec@a {
                compatible = "fsl,sgtl5000";
                reg = <0x0a>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_codec>;
                #sound-dai-cells = <0>;
                VDDA-supply = <&reg_3p2v>;
                VDDIO-supply = <&reg_3p2v>;
index 1a7a7bb3df45f3d7854e41b5a654688fe9159fcc..6386185ae23403089e4cb9a5a7e6c559d5637750 100644 (file)
                };
        };
 
-       pmu {
+       pmu: pmu {
                compatible = "arm,cortex-a8-pmu";
                interrupt-parent = <&tzic>;
                interrupts = <77>;
                                status = "disabled";
                        };
 
+                       tigerp: tigerp@63fa0000 {
+                               compatible = "fsl,imx53-tigerp", "fsl,imx51-tigerp";
+                               reg = <0x63fa0000 0x28>;
+                       };
+
                        owire: owire@63fa4000 {
                                compatible = "fsl,imx53-owire", "fsl,imx21-owire";
                                reg = <0x63fa4000 0x4000>;
index 3dee3af1a4c1628fdad7613fdb75b3a38d427b16..9de45a7173561949a095a22a1cfcff7c9c459c25 100644 (file)
 
 /* Colibri MMC */
 &usdhc1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_mmc_cd>;
-       cd-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; /* MMCD */
        status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/imx6dl-icore-mipi.dts b/arch/arm/boot/dts/imx6dl-icore-mipi.dts
new file mode 100644 (file)
index 0000000..bf53f05
--- /dev/null
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 Engicam S.r.l.
+ * Copyright (C) 2018 Amarula Solutions B.V.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-icore.dtsi"
+
+/ {
+       model = "Engicam i.CoreM6 DualLite/Solo MIPI Starter Kit";
+       compatible = "engicam,imx6-icore", "fsl,imx6dl";
+};
+
+&hdmi {
+       ddc-i2c-bus = <&i2c2>;
+       status = "okay";
+};
+
+&usdhc3 {
+       status = "okay";
+};
index 6b2d29138bedee1482198c9b3ff88b03910428fc..df8607fe414238cb0b1ca5562cba3e686d64fe51 100644 (file)
 
 /dts-v1/;
 
+#include <dt-bindings/gpio/gpio.h>
 #include "imx6dl.dtsi"
 
 / {
        model = "BTicino i.MX6DL Mamoj board";
        compatible = "bticino,imx6dl-mamoj", "fsl,imx6dl";
+
+       backlight_lcd: backlight-lcd {
+               compatible = "pwm-backlight";
+               pwms = <&pwm3 0 25000>; /* 25000ns -> 40kHz */
+               brightness-levels = <0 4 8 16 32 64 128 160 192 224 255>;
+               default-brightness-level = <7>;
+       };
+
+       display: disp0 {
+               compatible = "fsl,imx-parallel-display";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interface-pix-fmt = "rgb24";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_ipu1_lcdif>;
+               status = "okay";
+
+               port@0 {
+                       reg = <0>;
+
+                       lcd_display_in: endpoint {
+                               remote-endpoint = <&ipu1_di0_disp0>;
+                       };
+               };
+
+               port@1 {
+                       reg = <1>;
+
+                       lcd_display_out: endpoint {
+                               remote-endpoint = <&lcd_panel_in>;
+                       };
+               };
+       };
+
+       panel-lcd {
+               compatible = "rocktech,rk070er9427";
+               backlight = <&backlight_lcd>;
+               power-supply = <&reg_lcd_lr>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_ipu1_lcdif_pwr>;
+
+               port {
+                       lcd_panel_in: endpoint {
+                               remote-endpoint = <&lcd_display_out>;
+                       };
+               };
+       };
+
+       reg_lcd_3v3: regulator-lcd-dvdd {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd-dvdd";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio3 1 0>;
+               enable-active-high;
+               startup-delay-us = <21000>;
+       };
+
+       reg_lcd_power: regulator-lcd-power {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd-enable";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio3 6 0>;
+               enable-active-high;
+               vin-supply = <&reg_lcd_3v3>;
+       };
+
+       reg_lcd_vgl: regulator-lcd-vgl {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd-vgl";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>;
+               startup-delay-us = <6000>;
+               enable-active-high;
+               vin-supply = <&reg_lcd_power>;
+       };
+
+       reg_lcd_vgh: regulator-lcd-vgh {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd-vgh";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio3 31 GPIO_ACTIVE_HIGH>;
+               startup-delay-us = <6000>;
+               enable-active-high;
+               vin-supply = <&reg_lcd_avdd>;
+       };
+
+       reg_lcd_vcom: regulator-lcd-vcom {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd-vcom";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio4 14 GPIO_ACTIVE_HIGH>;
+               startup-delay-us = <11000>;
+               enable-active-high;
+               vin-supply = <&reg_lcd_vgh>;
+       };
+
+       reg_lcd_lr: regulator-lcd-lr {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd-lr";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio4 15 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+               vin-supply = <&reg_lcd_vcom>;
+       };
+
+       reg_lcd_avdd: regulator-lcd-avdd {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd-avdd";
+               regulator-min-microvolt = <10280000>;
+               regulator-max-microvolt = <10280000>;
+               gpio = <&gpio2 13 GPIO_ACTIVE_HIGH>;
+               startup-delay-us = <6000>;
+               enable-active-high;
+               vin-supply = <&reg_lcd_vgl>;
+       };
+
+       reg_usb_host: regulator-usb-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usbhost-vbus";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usbhost>;
+               regulator-min-microvolt = <50000000>;
+               regulator-max-microvolt = <50000000>;
+               gpio = <&gpio6 6 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       reg_wl18xx_vmmc:  regulator-wl18xx-vmcc {
+               compatible = "regulator-fixed";
+               regulator-name = "vwl1807";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_wlan>;
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               gpio = <&gpio6 21 GPIO_ACTIVE_HIGH>;
+               startup-delay-us = <70000>;
+               enable-active-high;
+       };
 };
 
 &fec {
        };
 };
 
+&ipu1_di0_disp0 {
+       remote-endpoint = <&lcd_display_in>;
+};
+
+&pwm3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm3>;
+       status = "okay";
+};
+
 &uart3 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart3>;
        status = "okay";
 };
 
+&usbh1 {
+       vbus-supply = <&reg_usb_host>;
+       status = "okay";
+};
+
+&usbotg {
+       dr_mode = "peripheral";
+       status = "okay";
+};
+
+&usdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       bus-width = <4>;
+       vmmc-supply = <&reg_wl18xx_vmmc>;
+       no-1-8-v;
+       non-removable;
+       wakeup-source;
+       keep-power-in-suspend;
+       cap-power-off-card;
+       max-frequency = <25000000>;
+       #address-cells = <1>;
+       #size-cells = <0>;
+       status = "okay";
+
+       wlcore: wlcore@2 {
+               compatible = "ti,wl1837";
+               reg = <2>;
+               interrupt-parent = <&gpio6>;
+               interrupts = <23 IRQ_TYPE_LEVEL_HIGH>;
+               tcxo-clock-frequency = <26000000>;
+       };
+};
+
 &usdhc3 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc3>;
                >;
        };
 
+       pinctrl_ipu1_lcdif: pinctrlipu1lcdif { /* parallel port 24-bit */
+               fsl,pins = <
+                       MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10 /* VDOUT_PCLK */
+                       MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15       0x10
+                       MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02        0x10 /* VDOUT_HSYNC */
+                       MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03        0x10 /* VDOUT_VSYNC */
+                       MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04        0x10 /* VDOUT_RESET */
+                       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_lcdif_pwr: ipu1lcdifpwrgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_DA1__GPIO3_IO01          0x40013058 /* EN_LCD33V */
+                       MX6QDL_PAD_SD4_DAT5__GPIO2_IO13         0x4001b0b0 /* EN_AVDD */
+                       MX6QDL_PAD_EIM_D31__GPIO3_IO31          0x40013058 /* ENVGH */
+                       MX6QDL_PAD_EIM_A18__GPIO2_IO20          0x40013058 /* ENVGL */
+                       MX6QDL_PAD_EIM_DA6__GPIO3_IO06          0x40013058 /* LCD_POWER */
+                       MX6QDL_PAD_KEY_COL4__GPIO4_IO14         0x40013058 /* EN_VCOM_LCD */
+                       MX6QDL_PAD_KEY_ROW4__GPIO4_IO15         0x40013058 /* LCD_L_R */
+                       MX6QDL_PAD_EIM_DA2__GPIO3_IO02          0x40013058 /* LCD_U_D */
+               >;
+       };
+
+       pinctrl_pwm3: pwm3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
+               >;
+       };
+
        pinctrl_uart3: uart3grp {
                fsl,pins = <
                        MX6QDL_PAD_EIM_D24__UART3_TX_DATA       0x1b0b1
                >;
        };
 
+       pinctrl_usbhost: usbhostgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_A23__GPIO6_IO06          0x4001b0b0
+               >;
+       };
+
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD1_CMD__SD1_CMD    0x17069
+                       MX6QDL_PAD_SD1_CLK__SD1_CLK    0x10079
+                       MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17069
+                       MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17069
+                       MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17069
+                       MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17069
+               >;
+       };
+
        pinctrl_usdhc3: usdhc3grp {
                fsl,pins = <
                        MX6QDL_PAD_SD3_CMD__SD3_CMD     0x17059
                        MX6QDL_PAD_SD3_DAT7__SD3_DATA7  0x17059
                >;
        };
+
+       pinctrl_wlan: wlangrp {
+               fsl,pins = <
+                       MX6QDL_PAD_RGMII_TD1__GPIO6_IO21        0x4001b0b0
+               >;
+       };
 };
index 30ce2c0cec2b4ff524a5a75ed67949a98e42270a..61fa30991d675b7c42f0e2c2e4c038fc800192cf 100644 (file)
@@ -1,42 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright 2015 Boundary Devices, Inc.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 /dts-v1/;
 
index ec53d7a09572f79f77b2cebdf353d966bdceea6b..ef58d3b0ea0d4063002429be6847d146b64f532b 100644 (file)
@@ -1,44 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright 2013 Boundary Devices, Inc.
  * Copyright 2012 Freescale Semiconductor, Inc.
  * Copyright 2011 Linaro Ltd.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 2e98c92adff748c2724001c0fabb37e66586ebe2..dd3226fe5ecd57e606b6b1eca6090c9634b43837 100644 (file)
                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>;
-               };
-
-               reg_3p3v: regulator@1 {
-                       compatible = "regulator-fixed";
-                       reg = <1>;
-                       regulator-name = "3P3V";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-               };
-
-               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;
-               };
+       chosen {
+               stdout-path = "serial1:115200n8";
        };
 
        leds {
                        mux-int-port = <1>;
                        mux-ext-port = <3>;
        };
+
+       reg_2p5v: regulator-2p5v {
+               compatible = "regulator-fixed";
+               regulator-name = "2P5V";
+               regulator-min-microvolt = <2500000>;
+               regulator-max-microvolt = <2500000>;
+       };
+
+       reg_3p3v: regulator-3p3v {
+               compatible = "regulator-fixed";
+               regulator-name = "3P3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       reg_usb_otg_vbus: regulator-usbotgvbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usb_otg_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio3 22 GPIO_ACTIVE_LOW>;
+       };
 };
 
 &audmux {
index b384913c34ddaf4ed6df751b083abd35d15b454d..f0607eb41df42ae00cb517878c347f50f37b9640 100644 (file)
@@ -33,6 +33,7 @@
                                396000  1175000
                        >;
                        clock-latency = <61036>; /* two CLK32 periods */
+                       #cooling-cells = <2>;
                        clocks = <&clks IMX6QDL_CLK_ARM>,
                                 <&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
                                 <&clks IMX6QDL_CLK_STEP>,
                        device_type = "cpu";
                        reg = <1>;
                        next-level-cache = <&L2>;
+                       operating-points = <
+                               /* kHz    uV */
+                               996000  1250000
+                               792000  1175000
+                               396000  1150000
+                       >;
+                       fsl,soc-operating-points = <
+                               /* ARM kHz  SOC-PU uV */
+                               996000  1175000
+                               792000  1175000
+                               396000  1175000
+                       >;
+                       clock-latency = <61036>; /* two CLK32 periods */
+                       clocks = <&clks IMX6QDL_CLK_ARM>,
+                                <&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
+                                <&clks IMX6QDL_CLK_STEP>,
+                                <&clks IMX6QDL_CLK_PLL1_SW>,
+                                <&clks IMX6QDL_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>;
                };
        };
 
index aa0e631f3c0aa07ca1bf7b490a09b2efdf2878a2..707ac9a46115f02bd6307413a1bbd7935a7d7799 100644 (file)
                rtc1 = &snvs_rtc;
        };
 
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
        gpio-keys {
                compatible = "gpio-keys";
                pinctrl-names = "default";
                 */
                compatible = "edt,et057090dhu";
                backlight = <&backlight>;
+               power-supply = <&reg_3v3_sw>;
 
                port {
                        lcd_panel_in: endpoint {
                enable-active-high;
                status = "okay";
        };
+
+       reg_3v3_sw: regulator-3v3-sw {
+               compatible = "regulator-fixed";
+               regulator-name = "3.3V_SW";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
 };
 
 &backlight {
        brightness-levels = <0 127 191 223 239 247 251 255>;
        default-brightness-level = <1>;
+       power-supply = <&reg_3v3_sw>;
        status = "okay";
 };
 
 &can1 {
+       xceiver-supply = <&reg_3v3_sw>;
        status = "okay";
 };
 
 &can2 {
+       xceiver-supply = <&reg_3v3_sw>;
        status = "okay";
 };
 
index e8dccf5521224629bc8451557cd5be111d0d464c..4e1c8feaef82207805d102d0aa724db06ae4e39e 100644 (file)
                rtc1 = &snvs_rtc;
        };
 
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
        gpio-keys {
                compatible = "gpio-keys";
                pinctrl-names = "default";
index 6831dfd24cc1db89f873f63e4f99c196f6e60334..469e3d0e28276e78c26a000ae3f9cda004706bd1 100644 (file)
                rtc1 = &snvs_rtc;
        };
 
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
        gpio-keys {
                compatible = "gpio-keys";
                pinctrl-names = "default";
index 65ef4cacbc7152497cf5a04c07609ce4ff39e1e2..18ae4f3be6e38f93a9421ca4152e7a11bf43ad23 100644 (file)
        >;
 };
 
+&cpu1 {
+       /*
+        * Although the imx6q fuse indicates that 1.2GHz operation is possible,
+        * the module behaves unstable at this frequency. Hence, remove the
+        * 1.2GHz operation point here.
+        */
+       operating-points = <
+               /* kHz  uV */
+               996000  1250000
+               852000  1250000
+               792000  1175000
+               396000  975000
+       >;
+       fsl,soc-operating-points = <
+               /* ARM kHz      SOC-PU uV */
+               996000          1250000
+               852000          1250000
+               792000          1175000
+               396000          1175000
+       >;
+};
+
+&cpu2 {
+       /*
+        * Although the imx6q fuse indicates that 1.2GHz operation is possible,
+        * the module behaves unstable at this frequency. Hence, remove the
+        * 1.2GHz operation point here.
+        */
+       operating-points = <
+               /* kHz  uV */
+               996000  1250000
+               852000  1250000
+               792000  1175000
+               396000  975000
+       >;
+       fsl,soc-operating-points = <
+               /* ARM kHz      SOC-PU uV */
+               996000          1250000
+               852000          1250000
+               792000          1175000
+               396000          1175000
+       >;
+};
+
+&cpu3 {
+       /*
+        * Although the imx6q fuse indicates that 1.2GHz operation is possible,
+        * the module behaves unstable at this frequency. Hence, remove the
+        * 1.2GHz operation point here.
+        */
+       operating-points = <
+               /* kHz  uV */
+               996000  1250000
+               852000  1250000
+               792000  1175000
+               396000  975000
+       >;
+       fsl,soc-operating-points = <
+               /* ARM kHz      SOC-PU uV */
+               996000          1250000
+               852000          1250000
+               792000          1175000
+               396000          1175000
+       >;
+};
+
 &ecspi1 {
        cs-gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>, <&gpio3 19 GPIO_ACTIVE_HIGH>;
        pinctrl-names = "default";
index acd3d33476d42e4e332ec7d6a5c21ab9d6ee867f..95b2efda17b42ebb6cb0203a941c8ebd3b4be8b7 100644 (file)
        status = "okay";
 };
 
+&mipi_csi {
+       status = "okay";
+};
+
+&ov5640 {
+       status = "okay";
+};
+
 &usdhc3 {
        status = "okay";
 };
index 2a3c44f98eed8fc415290be719a616c6e12450d5..03bec0c53063733b4313e7b19498f8c340ea5aa1 100644 (file)
@@ -1,42 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright 2015 Boundary Devices, Inc.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 /dts-v1/;
 
index c5d59baa1a07e17ba22bdc884de8391a11289807..eb4eecb6ed22167daa4075af326d38cbe68e8638 100644 (file)
@@ -1,42 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright 2016 Boundary Devices, Inc.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 /dts-v1/;
 
index df8ff397a91421374a51eb5a479b3540f5ca8330..435445a34ad026c0ae623b32d14b29348c352f63 100644 (file)
@@ -1,44 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright 2013 Boundary Devices, Inc.
  * Copyright 2012 Freescale Semiconductor, Inc.
  * Copyright 2011 Linaro Ltd.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index f2368a073d07ecd73430dd3870d75291dfe73c3b..c54362fcc508118421c505ea67ccad8449f40e7d 100644 (file)
                touchscreen-size-y = <480>;
                touchscreen-inverted-x;
                touchscreen-inverted-y;
+               wakeup-source;
        };
 
        rtc@68 {
index 77f8f030dd0772aba631f57b704a7e60a9bd0532..0193ee6fe964a4be2a12e1b56374272293f16d2c 100644 (file)
@@ -38,6 +38,7 @@
                                396000  1175000
                        >;
                        clock-latency = <61036>; /* two CLK32 periods */
+                       #cooling-cells = <2>;
                        clocks = <&clks IMX6QDL_CLK_ARM>,
                                 <&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
                                 <&clks IMX6QDL_CLK_STEP>,
                        soc-supply = <&reg_soc>;
                };
 
-               cpu@1 {
+               cpu1: cpu@1 {
                        compatible = "arm,cortex-a9";
                        device_type = "cpu";
                        reg = <1>;
                        next-level-cache = <&L2>;
+                       operating-points = <
+                               /* kHz    uV */
+                               1200000 1275000
+                               996000  1250000
+                               852000  1250000
+                               792000  1175000
+                               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 IMX6QDL_CLK_ARM>,
+                                <&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
+                                <&clks IMX6QDL_CLK_STEP>,
+                                <&clks IMX6QDL_CLK_PLL1_SW>,
+                                <&clks IMX6QDL_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>;
                };
 
-               cpu@2 {
+               cpu2: cpu@2 {
                        compatible = "arm,cortex-a9";
                        device_type = "cpu";
                        reg = <2>;
                        next-level-cache = <&L2>;
+                       operating-points = <
+                               /* kHz    uV */
+                               1200000 1275000
+                               996000  1250000
+                               852000  1250000
+                               792000  1175000
+                               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 IMX6QDL_CLK_ARM>,
+                                <&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
+                                <&clks IMX6QDL_CLK_STEP>,
+                                <&clks IMX6QDL_CLK_PLL1_SW>,
+                                <&clks IMX6QDL_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>;
                };
 
-               cpu@3 {
+               cpu3: cpu@3 {
                        compatible = "arm,cortex-a9";
                        device_type = "cpu";
                        reg = <3>;
                        next-level-cache = <&L2>;
+                       operating-points = <
+                               /* kHz    uV */
+                               1200000 1275000
+                               996000  1250000
+                               852000  1250000
+                               792000  1175000
+                               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 IMX6QDL_CLK_ARM>,
+                                <&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
+                                <&clks IMX6QDL_CLK_STEP>,
+                                <&clks IMX6QDL_CLK_PLL1_SW>,
+                                <&clks IMX6QDL_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>;
                };
        };
 
index 64fbee61de4492d733d236e0cc6cf667e6a1cee1..05f07ea3e8c8051338dfec9db3977e095ae19431 100644 (file)
                status = "disabled";
        };
 
-       reg_1p8v: regulator-1p8v {
+       reg_module_3v3: regulator-module-3v3 {
                compatible = "regulator-fixed";
-               regulator-name = "1P8V";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <1800000>;
-               regulator-always-on;
-       };
-
-       reg_2p5v: regulator-2p5v {
-               compatible = "regulator-fixed";
-               regulator-name = "2P5V";
-               regulator-min-microvolt = <2500000>;
-               regulator-max-microvolt = <2500000>;
+               regulator-name = "+V3.3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
                regulator-always-on;
        };
 
-       reg_3p3v: regulator-3p3v {
+       reg_module_3v3_audio: regulator-module-3v3-audio {
                compatible = "regulator-fixed";
-               regulator-name = "3P3V";
+               regulator-name = "+V3.3_AUDIO";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
                regulator-always-on;
 
                        vgen4_reg: vgen4 {
                                regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <3300000>;
+                               regulator-max-microvolt = <1800000>;
                                regulator-boot-on;
                                regulator-always-on;
                        };
                compatible = "fsl,sgtl5000";
                reg = <0x0a>;
                clocks = <&clks IMX6QDL_CLK_CKO>;
-               VDDA-supply = <&reg_2p5v>;
-               VDDIO-supply = <&reg_3p3v>;
+               VDDA-supply = <&reg_module_3v3_audio>;
+               VDDIO-supply = <&reg_module_3v3>;
+               VDDD-supply = <&vgen4_reg>;
        };
 
        /* STMPE811 touch screen controller */
 &usdhc1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc1_4bit &pinctrl_usdhc1_8bit>;
-       vqmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&reg_module_3v3>;
        bus-width = <8>;
-       voltage-ranges = <3300 3300>;
+       disable-wp;
+       no-1-8-v;
        status = "disabled";
 };
 
 &usdhc2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc2>;
-       vqmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&reg_module_3v3>;
        bus-width = <4>;
-       voltage-ranges = <3300 3300>;
+       disable-wp;
+       no-1-8-v;
        status = "disabled";
 };
 
 &usdhc3 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc3>;
-       vqmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&reg_module_3v3>;
        bus-width = <8>;
-       voltage-ranges = <3300 3300>;
+       no-1-8-v;
        non-removable;
        status = "okay";
 };
                        MX6QDL_PAD_SD3_RST__SD3_RESET  0x17059
                >;
        };
-
-       pinctrl_usdhc3_100mhz: usdhc3100mhzgrp {
-               fsl,pins = <
-                       MX6QDL_PAD_SD3_CMD__SD3_CMD    0x170b9
-                       MX6QDL_PAD_SD3_CLK__SD3_CLK    0x100b9
-                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9
-                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9
-                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9
-                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9
-                       MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170b9
-                       MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170b9
-                       MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170b9
-                       MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170b9
-                       /* eMMC reset */
-                       MX6QDL_PAD_SD3_RST__SD3_RESET  0x170b9
-               >;
-       };
-
-       pinctrl_usdhc3_200mhz: usdhc3200mhzgrp {
-               fsl,pins = <
-                       MX6QDL_PAD_SD3_CMD__SD3_CMD    0x170f9
-                       MX6QDL_PAD_SD3_CLK__SD3_CLK    0x100f9
-                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9
-                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9
-                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9
-                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9
-                       MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9
-                       MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9
-                       MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9
-                       MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9
-                       /* eMMC reset */
-                       MX6QDL_PAD_SD3_RST__SD3_RESET  0x170f9
-               >;
-       };
 };
index 76035db96f67831bc576cbea7f50f4b6ffe6d5b4..87e15e7cb32b1e7ea3305faf0d233f129d8eb0b0 100644 (file)
                status = "disabled";
        };
 
-       reg_1p8v: regulator-1p8v {
+       reg_module_3v3: regulator-module-3v3 {
                compatible = "regulator-fixed";
-               regulator-name = "1P8V";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <1800000>;
-               regulator-always-on;
-       };
-
-       reg_2p5v: regulator-2p5v {
-               compatible = "regulator-fixed";
-               regulator-name = "2P5V";
-               regulator-min-microvolt = <2500000>;
-               regulator-max-microvolt = <2500000>;
+               regulator-name = "+V3.3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
                regulator-always-on;
        };
 
-       reg_3p3v: regulator-3p3v {
+       reg_module_3v3_audio: regulator-module-3v3-audio {
                compatible = "regulator-fixed";
-               regulator-name = "3P3V";
+               regulator-name = "+V3.3_AUDIO";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
                regulator-always-on;
 
                        vgen4_reg: vgen4 {
                                regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <3300000>;
+                               regulator-max-microvolt = <1800000>;
                                regulator-boot-on;
                                regulator-always-on;
                        };
                compatible = "fsl,sgtl5000";
                reg = <0x0a>;
                clocks = <&clks IMX6QDL_CLK_CKO>;
-               VDDA-supply = <&reg_2p5v>;
-               VDDIO-supply = <&reg_3p3v>;
+               VDDA-supply = <&reg_module_3v3_audio>;
+               VDDIO-supply = <&reg_module_3v3>;
+               VDDD-supply = <&vgen4_reg>;
                lrclk-strength = <3>;
        };
 
 /* Colibri MMC */
 &usdhc1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_usdhc1>;
-       vqmmc-supply = <&reg_3p3v>;
+       pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_mmc_cd>;
+       cd-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; /* MMCD */
+       disable-wp;
+       vqmmc-supply = <&reg_module_3v3>;
        bus-width = <4>;
-       voltage-ranges = <3300 3300>;
+       no-1-8-v;
        status = "disabled";
 };
 
 &usdhc3 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc3>;
-       vqmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&reg_module_3v3>;
        bus-width = <8>;
-       voltage-ranges = <3300 3300>;
+       no-1-8-v;
        non-removable;
        status = "okay";
 };
 
        pinctrl_gpio_keys: gpiokeys {
                fsl,pins = <
-                       /* Power button */
-                       MX6QDL_PAD_EIM_A16__GPIO2_IO22          0x1b0b0
+                       MX6QDL_PAD_EIM_A16__GPIO2_IO22          0x130b0
                >;
        };
 
 
        pinctrl_mmc_cd: gpiommccd {
                fsl,pins = <
-                       MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x80000000
+                       MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x1b0b1
                >;
        };
 
                >;
        };
 
-       pinctrl_usdhc3_100mhz: usdhc3100mhzgrp {
-               fsl,pins = <
-                       MX6QDL_PAD_SD3_CMD__SD3_CMD     0x170b9
-                       MX6QDL_PAD_SD3_CLK__SD3_CLK     0x100b9
-                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0  0x170b9
-                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1  0x170b9
-                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2  0x170b9
-                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3  0x170b9
-                       MX6QDL_PAD_SD3_DAT4__SD3_DATA4  0x170b9
-                       MX6QDL_PAD_SD3_DAT5__SD3_DATA5  0x170b9
-                       MX6QDL_PAD_SD3_DAT6__SD3_DATA6  0x170b9
-                       MX6QDL_PAD_SD3_DAT7__SD3_DATA7  0x170b9
-                       /* eMMC reset */
-                       MX6QDL_PAD_SD3_RST__SD3_RESET   0x170b9
-               >;
-       };
-
-       pinctrl_usdhc3_200mhz: usdhc3200mhzgrp {
-               fsl,pins = <
-                       MX6QDL_PAD_SD3_CMD__SD3_CMD     0x170f9
-                       MX6QDL_PAD_SD3_CLK__SD3_CLK     0x100f9
-                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0  0x170f9
-                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1  0x170f9
-                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2  0x170f9
-                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3  0x170f9
-                       MX6QDL_PAD_SD3_DAT4__SD3_DATA4  0x170f9
-                       MX6QDL_PAD_SD3_DAT5__SD3_DATA5  0x170f9
-                       MX6QDL_PAD_SD3_DAT6__SD3_DATA6  0x170f9
-                       MX6QDL_PAD_SD3_DAT7__SD3_DATA7  0x170f9
-                       /* eMMC reset */
-                       MX6QDL_PAD_SD3_RST__SD3_RESET   0x170f9
-               >;
-       };
-
        pinctrl_weim_cs0: weimcs0grp {
                fsl,pins = <
                        /* nEXT_CS0 */
index 0a1574998fc6a89a423b706f143c4376e75c337c..9ce993776160df74623b6e20e568b4945bc85eaf 100644 (file)
@@ -65,8 +65,7 @@
                regulator-always-on;
        };
 
-
-       reg_2p5v: regulator-3p3v {
+       reg_2p5v: regulator-2p5v {
                compatible = "regulator-fixed";
                regulator-name = "2P5V";
                regulator-min-microvolt = <2500000>;
        pinctrl-0 = <&pinctrl_i2c3>;
        status = "okay";
 
+       ov5640: camera@3c {
+               compatible = "ovti,ov5640";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_ov5640>;
+               reg = <0x3c>;
+               clocks = <&clks IMX6QDL_CLK_CKO>;
+               clock-names = "xclk";
+               DOVDD-supply = <&reg_1p8v>;
+               AVDD-supply = <&reg_3p3v>;
+               DVDD-supply = <&reg_3p3v>;
+               powerdown-gpios = <&gpio5 30 GPIO_ACTIVE_HIGH>;
+               reset-gpios = <&gpio5 31 GPIO_ACTIVE_LOW>;
+               status = "disabled";
+
+               port {
+                       ov5640_to_mipi_csi2: endpoint {
+                               remote-endpoint = <&mipi_csi2_in>;
+                               clock-lanes = <0>;
+                               data-lanes = <1 2>;
+                       };
+               };
+       };
+
        sgtl5000: codec@a {
                #sound-dai-cells = <0>;
                compatible = "fsl,sgtl5000";
        };
 };
 
+&mipi_csi {
+       status = "disabled";
+
+       port@0 {
+               reg = <0>;
+
+               mipi_csi2_in: endpoint {
+                       remote-endpoint = <&ov5640_to_mipi_csi2>;
+                       clock-lanes = <0>;
+                       data-lanes = <1 2>;
+               };
+       };
+};
+
 &pwm3 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm3>;
                fsl,pins = <
                        MX6QDL_PAD_GPIO_5__I2C3_SCL  0x4001b8b1
                        MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
-                       MX6QDL_PAD_GPIO_0__CCM_CLKO1    0x130b0
+               >;
+       };
+
+       pinctrl_ov5640: ov5640grp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT12__GPIO5_IO30 0x1b0b0
+                       MX6QDL_PAD_CSI0_DAT13__GPIO5_IO31 0x1b0b0
+                       MX6QDL_PAD_GPIO_0__CCM_CLKO1      0x130b0
                >;
        };
 
index aab088f318e8d202537b6ee566dcb6cf46b4b88f..29baf25ae5d04cab3fb123529a3389ea05b5099d 100644 (file)
@@ -1,42 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright 2015 Boundary Devices, Inc.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
                reg = <0x38>;
                interrupt-parent = <&gpio1>;
                interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+               wakeup-source;
        };
 
        rtc@6f {
index 87ca6ead4098052ae1044c223e23284c25dc3677..39200e5dc896568978172c8d3075139b375546a2 100644 (file)
@@ -1,42 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright 2015 Boundary Devices, Inc.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
                reg = <0x38>;
                interrupt-parent = <&gpio1>;
                interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+               wakeup-source;
        };
 };
 
index f5b763d392853dc0d59b09b940012032754ab918..572abd7499b174ae431b7f788b85c7c35eeb536b 100644 (file)
@@ -1,42 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright 2016 Boundary Devices, Inc.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
                reg = <0x38>;
                interrupt-parent = <&gpio1>;
                interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+               wakeup-source;
        };
 };
 
index 596866b0a0d2ceebc010beb4d1104e2832f5f63f..98384a6c5d1295eadd103eabd0ca8f9ce7c4da26 100644 (file)
@@ -1,44 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright 2013 Boundary Devices, Inc.
  * Copyright 2011 Freescale Semiconductor, Inc.
  * Copyright 2011 Linaro Ltd.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
                reg = <0x38>;
                interrupt-parent = <&gpio1>;
                interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+               wakeup-source;
        };
 };
 
index 0e28e36ddbb2d2431c8c815a0bdd6c4ac116481f..9f11f1fcc3e6caac35c38c5b81038b3a1a152078 100644 (file)
@@ -6,6 +6,10 @@
 #include <dt-bindings/gpio/gpio.h>
 
 / {
+       chosen {
+               stdout-path = &uart4;
+       };
+
        memory@10000000 {
                reg = <0x10000000 0x80000000>;
        };
                                gpio-controller;
                                #gpio-cells = <2>;
                        };
+
+                       light-sensor@44 {
+                               compatible = "isil,isl29023";
+                               reg = <0x44>;
+                               interrupt-parent = <&gpio5>;
+                               interrupts = <17 IRQ_TYPE_EDGE_FALLING>;
+                       };
+
+                       magnetometer@e {
+                               compatible = "fsl,mag3110";
+                               reg = <0x0e>;
+                               interrupt-parent = <&gpio2>;
+                               interrupts = <29 IRQ_TYPE_EDGE_RISING>;
+                       };
+
+                       accelerometer@1c {
+                               compatible = "fsl,mma8451";
+                               reg = <0x1c>;
+                               interrupt-parent = <&gpio6>;
+                               interrupts = <31 IRQ_TYPE_LEVEL_LOW>;
+                       };
                };
        };
 };
index 15744ad52535cae0ebec5fba5f14bdab52e87136..6e46a195b3997f86800462746299f7c7d9924a25 100644 (file)
                        sw4_reg: sw4 {
                                regulator-min-microvolt = <800000>;
                                regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
                        };
 
                        swbst_reg: swbst {
index e1afa54404d0f2afa473045acc9b0b3898501bd3..381bf61fcd284ad3c7052e799f9051901af0c6d8 100644 (file)
@@ -8,30 +8,6 @@
 #include <dt-bindings/gpio/gpio.h>
 
 / {
-       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;
-               };
-       };
-
        sound {
                compatible = "fsl,imx6-wandboard-sgtl5000",
                             "fsl,imx-audio-sgtl5000";
                spdif-controller = <&spdif>;
                spdif-out;
        };
+
+       reg_2p5v: regulator-2p5v {
+               compatible = "regulator-fixed";
+               regulator-name = "2P5V";
+               regulator-min-microvolt = <2500000>;
+               regulator-max-microvolt = <2500000>;
+               regulator-always-on;
+       };
+
+       reg_3p3v: regulator-3p3v {
+               compatible = "regulator-fixed";
+               regulator-name = "3P3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       reg_usb_otg_vbus: regulator-usbotgvbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usb_otg_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usbotgvbus>;
+               gpio = <&gpio3 22 GPIO_ACTIVE_LOW>;
+       };
 };
 
 &audmux {
                        >;
                };
 
+               pinctrl_usbotgvbus: usbotgvbusgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D22__GPIO3_IO22          0x130b0
+                       >;
+               };
+
                pinctrl_usdhc1: usdhc1grp {
                        fsl,pins = <
                                MX6QDL_PAD_SD1_CMD__SD1_CMD             0x17059
 };
 
 &usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usbotg>;
        disable-over-current;
-       dr_mode = "peripheral";
+       dr_mode = "otg";
        status = "okay";
 };
 
index f14df0baf2ab42867e30f3b93520b75652561afa..7fff3717cf7c09ae29d130756b3f33856d7ef819 100644 (file)
        rave-sp {
                compatible = "zii,rave-sp-rdu2";
                current-speed = <1000000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
 
                watchdog {
                        compatible = "zii,rave-sp-watchdog";
                };
+
+               backlight {
+                       compatible = "zii,rave-sp-backlight";
+               };
+
+               pwrbutton {
+                       compatible = "zii,rave-sp-pwrbutton";
+               };
+
+               eeprom@a3 {
+                       compatible = "zii,rave-sp-eeprom";
+                       reg = <0xa3 0x4000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       zii,eeprom-name = "dds-eeprom";
+               };
+
+               eeprom@a4 {
+                       compatible = "zii,rave-sp-eeprom";
+                       reg = <0xa4 0x4000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       zii,eeprom-name = "main-eeprom";
+               };
        };
 };
 
 
                rmi4-f11@11 {
                        reg = <0x11>;
-                       touchscreen-inverted-y;
+                       touchscreen-inverted-x;
                        touchscreen-swapped-x-y;
                        syna,sensor-type = <1>;
                };
 
                rmi4-f12@12 {
                        reg = <0x12>;
-                       touchscreen-inverted-y;
+                       touchscreen-inverted-x;
                        touchscreen-swapped-x-y;
                        syna,sensor-type = <1>;
                };
index 911141e246810fe654db3d44dd147afca7122569..61d2d26afbf4d90474dcae54930bb036ba13412b 100644 (file)
 
                        crypto: caam@2100000 {
                                compatible = "fsl,sec-v4.0";
-                               fsl,sec-era = <4>;
                                #address-cells = <1>;
                                #size-cells = <1>;
                                reg = <0x2100000 0x10000>;
index a39b8603658189bf2369066427bfd11ca0bea7cc..741d1ed338ca24b0e3c95e6882cb7482903ce8b3 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright 2016 Boundary Devices, Inc.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 011726c836cdae683bc94ebd27c724873e73cf64..1593ac86b2a4c52f48c480b9984a3543810c9194 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright 2017 Boundary Devices, Inc.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 92ad01f676e345f4f7e97f602026c50135c97039..679b4482ab13aca4bcaa0506f73b3c3a04233134 100644 (file)
        model = "Freescale i.MX6 SoloLite EVK Board";
        compatible = "fsl,imx6sl-evk", "fsl,imx6sl";
 
+       chosen {
+               stdout-path = &uart1;
+       };
+
        memory@80000000 {
                reg = <0x80000000 0x40000000>;
        };
@@ -73,6 +77,8 @@
 
        reg_lcd_3v3: regulator-lcd-3v3 {
                compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_reg_lcd_3v3>;
                regulator-name = "lcd-3v3";
                gpio = <&gpio4 3 GPIO_ACTIVE_HIGH>;
                enable-active-high;
                        sw4_reg: sw4 {
                                regulator-min-microvolt = <800000>;
                                regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
                        };
 
                        swbst_reg: swbst {
                        >;
                };
 
+               pinctrl_reg_lcd_3v3: reglcd3v3grp {
+                       fsl,pins = <
+                               MX6SL_PAD_KEY_ROW5__GPIO4_IO03    0x17059
+                       >;
+               };
+
                pinctrl_uart1: uart1grp {
                        fsl,pins = <
                                MX6SL_PAD_UART1_RXD__UART1_RX_DATA      0x1b0b1
index 994e48dc1df0a01e1be33c2bc8750e453b83ddb4..7a4f5dace9026b0075507f46107c95bba1ab6397 100644 (file)
@@ -60,6 +60,7 @@
                                396000          1175000
                        >;
                        clock-latency = <61036>; /* two CLK32 periods */
+                       #cooling-cells = <2>;
                        clocks = <&clks IMX6SL_CLK_ARM>, <&clks IMX6SL_CLK_PLL2_PFD2>,
                                        <&clks IMX6SL_CLK_STEP>, <&clks IMX6SL_CLK_PLL1_SW>,
                                        <&clks IMX6SL_CLK_PLL1_SYS>;
                                regulator-1p1 {
                                        compatible = "fsl,anatop-regulator";
                                        regulator-name = "vdd1p1";
-                                       regulator-min-microvolt = <800000>;
-                                       regulator-max-microvolt = <1375000>;
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1200000>;
                                        regulator-always-on;
                                        anatop-reg-offset = <0x110>;
                                        anatop-vol-bit-shift = <8>;
                                regulator-2p5 {
                                        compatible = "fsl,anatop-regulator";
                                        regulator-name = "vdd2p5";
-                                       regulator-min-microvolt = <2100000>;
-                                       regulator-max-microvolt = <2850000>;
+                                       regulator-min-microvolt = <2250000>;
+                                       regulator-max-microvolt = <2750000>;
                                        regulator-always-on;
                                        anatop-reg-offset = <0x130>;
                                        anatop-vol-bit-shift = <8>;
                                #interrupt-cells = <3>;
                                interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>;
                                interrupt-parent = <&intc>;
-                               pu-supply = <&reg_pu>;
-                               clocks = <&clks IMX6SL_CLK_GPU2D_OVG>,
-                                        <&clks IMX6SL_CLK_GPU2D_PODF>;
-                               #power-domain-cells = <1>;
+                               clocks = <&clks IMX6SL_CLK_IPG>;
+                               clock-names = "ipg";
+
+                               pgc {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       power-domain@0 {
+                                               reg = <0>;
+                                               #power-domain-cells = <0>;
+                                       };
+
+                                       pd_pu: power-domain@1 {
+                                               reg = <1>;
+                                               #power-domain-cells = <0>;
+                                               power-supply = <&reg_pu>;
+                                               clocks = <&clks IMX6SL_CLK_GPU2D_OVG>,
+                                                        <&clks IMX6SL_CLK_GPU2D_PODF>;
+                                       };
+
+                                       pd_disp: power-domain@2 {
+                                               reg = <2>;
+                                               #power-domain-cells = <0>;
+                                               clocks = <&clks IMX6SL_CLK_LCDIF_AXI>,
+                                                        <&clks IMX6SL_CLK_LCDIF_PIX>,
+                                                        <&clks IMX6SL_CLK_EPDC_AXI>,
+                                                        <&clks IMX6SL_CLK_EPDC_PIX>,
+                                                        <&clks IMX6SL_CLK_PXP_AXI>;
+                                       };
+                               };
                        };
 
                        gpr: iomuxc-gpr@20e0000 {
                                         <&clks IMX6SL_CLK_DUMMY>;
                                clock-names = "pix", "axi", "disp_axi";
                                status = "disabled";
+                               power-domains = <&pd_disp>;
                        };
 
                        dcp: dcp@20fc000 {
                                status = "disabled";
                        };
                };
+
+               gpu_2d: gpu@2200000 {
+                       compatible = "vivante,gc";
+                       reg = <0x02200000 0x4000>;
+                       interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clks IMX6SL_CLK_MMDC_ROOT>,
+                                <&clks IMX6SL_CLK_GPU2D_OVG>;
+                       clock-names = "bus", "core";
+                       power-domains = <&pd_pu>;
+               };
+
+               gpu_vg: gpu@2204000 {
+                       compatible = "vivante,gc";
+                       reg = <0x02204000 0x4000>;
+                       interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clks IMX6SL_CLK_MMDC_ROOT>,
+                                <&clks IMX6SL_CLK_GPU2D_OVG>;
+                       clock-names = "bus", "core";
+                       power-domains = <&pd_pu>;
+               };
        };
 };
diff --git a/arch/arm/boot/dts/imx6sll-evk.dts b/arch/arm/boot/dts/imx6sll-evk.dts
new file mode 100644 (file)
index 0000000..c8e1155
--- /dev/null
@@ -0,0 +1,463 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "imx6sll.dtsi"
+
+/ {
+       model = "Freescale i.MX6SLL EVK Board";
+       compatible = "fsl,imx6sll-evk", "fsl,imx6sll";
+
+       chosen {
+               stdout-path = &uart1;
+       };
+
+       memory@80000000 {
+               reg = <0x80000000 0x80000000>;
+       };
+
+       backlight_display: backlight-display {
+               compatible = "pwm-backlight";
+               pwms = <&pwm1 0 5000000>;
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <6>;
+               status = "okay";
+       };
+
+       reg_usb_otg1_vbus: regulator-otg1-vbus {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usb_otg1_vbus>;
+               regulator-name = "usb_otg1_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio4 0 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       reg_usb_otg2_vbus: regulator-otg2-vbus {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usb_otg2_vbus>;
+               regulator-name = "usb_otg2_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio4 2 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       reg_aud3v: regulator-aud3v {
+               compatible = "regulator-fixed";
+               regulator-name = "wm8962-supply-3v15";
+               regulator-min-microvolt = <3150000>;
+               regulator-max-microvolt = <3150000>;
+               regulator-boot-on;
+       };
+
+       reg_aud4v: regulator-aud4v {
+               compatible = "regulator-fixed";
+               regulator-name = "wm8962-supply-4v2";
+               regulator-min-microvolt = <4325000>;
+               regulator-max-microvolt = <4325000>;
+               regulator-boot-on;
+       };
+
+       reg_lcd_3v3: regulator-lcd-3v3 {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_reg_lcd_3v3>;
+               regulator-name = "lcd-3v3";
+               gpio = <&gpio4 3 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       reg_lcd_5v: regulator-lcd-5v {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd-5v0";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+
+       reg_sd1_vmmc: regulator-sd1-vmmc {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_reg_sd1_vmmc>;
+               regulator-name = "SD1_SPWR";
+               regulator-min-microvolt = <3000000>;
+               regulator-max-microvolt = <3000000>;
+               gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       reg_sd3_vmmc: regulator-sd3-vmmc {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_reg_sd3_vmmc>;
+               regulator-name = "SD3_WIFI";
+               regulator-min-microvolt = <3000000>;
+               regulator-max-microvolt = <3000000>;
+               gpio = <&gpio4 4 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       panel {
+               compatible = "sii,43wvf1g";
+               backlight = <&backlight_display>;
+               dvdd-supply = <&reg_lcd_3v3>;
+               avdd-supply = <&reg_lcd_5v>;
+
+               port {
+                       panel_in: endpoint {
+                               remote-endpoint = <&display_out>;
+                       };
+               };
+       };
+};
+
+&cpu0 {
+       arm-supply = <&sw1a_reg>;
+       soc-supply = <&sw1c_reg>;
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       pfuze100: pmic@8 {
+               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>;
+                               regulator-always-on;
+                       };
+
+                       swbst_reg: swbst {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5150000>;
+                       };
+
+                       snvs_reg: vsnvs {
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vref_reg: vrefddr {
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vgen1_reg: 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;
+                       };
+               };
+       };
+};
+
+&lcdif {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lcd>;
+       status = "okay";
+
+       port {
+               display_out: endpoint {
+                       remote-endpoint = <&panel_in>;
+               };
+       };
+};
+
+&pwm1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm1>;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&usdhc1 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+       cd-gpios = <&gpio4 7 GPIO_ACTIVE_LOW>;
+       wp-gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>;
+       keep-power-in-suspend;
+       wakeup-source;
+       vmmc-supply = <&reg_sd1_vmmc>;
+       status = "okay";
+};
+
+&usbotg1 {
+       vbus-supply = <&reg_usb_otg1_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg1>;
+       disable-over-current;
+       srp-disable;
+       hnp-disable;
+       adp-disable;
+       status = "okay";
+};
+
+&usbotg2 {
+       vbus-supply = <&reg_usb_otg2_vbus>;
+       dr_mode = "host";
+       disable-over-current;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+       cd-gpios = <&gpio3 22 GPIO_ACTIVE_LOW>;
+       keep-power-in-suspend;
+       enable-sdio-wakeup;
+       vmmc-supply = <&reg_sd3_vmmc>;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_reg_sd3_vmmc: sd3vmmcgrp {
+               fsl,pins = <
+                       MX6SLL_PAD_KEY_COL6__GPIO4_IO04 0x17059
+               >;
+       };
+
+       pinctrl_usb_otg1_vbus: vbus1grp {
+               fsl,pins = <
+                       MX6SLL_PAD_KEY_COL4__GPIO4_IO00 0x17059
+               >;
+       };
+
+       pinctrl_usb_otg2_vbus: vbus2grp {
+               fsl,pins = <
+                       MX6SLL_PAD_KEY_COL5__GPIO4_IO02 0x17059
+               >;
+       };
+
+       pinctrl_reg_lcd_3v3: reglcd3v3grp {
+               fsl,pins = <
+                       MX6SLL_PAD_KEY_ROW5__GPIO4_IO03 0x17059
+               >;
+       };
+
+       pinctrl_reg_sd1_vmmc: sd1vmmcgrp {
+               fsl,pins = <
+                       MX6SLL_PAD_KEY_COL3__GPIO3_IO30 0x17059
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX6SLL_PAD_UART1_TXD__UART1_DCE_TX 0x1b0b1
+                       MX6SLL_PAD_UART1_RXD__UART1_DCE_RX 0x1b0b1
+               >;
+       };
+
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       MX6SLL_PAD_SD1_CMD__SD1_CMD     0x17059
+                       MX6SLL_PAD_SD1_CLK__SD1_CLK     0x13059
+                       MX6SLL_PAD_SD1_DATA0__SD1_DATA0 0x17059
+                       MX6SLL_PAD_SD1_DATA1__SD1_DATA1 0x17059
+                       MX6SLL_PAD_SD1_DATA2__SD1_DATA2 0x17059
+                       MX6SLL_PAD_SD1_DATA3__SD1_DATA3 0x17059
+               >;
+       };
+
+       pinctrl_usdhc1_100mhz: usdhc1grp_100mhz {
+               fsl,pins = <
+                       MX6SLL_PAD_SD1_CMD__SD1_CMD     0x170b9
+                       MX6SLL_PAD_SD1_CLK__SD1_CLK     0x130b9
+                       MX6SLL_PAD_SD1_DATA0__SD1_DATA0 0x170b9
+                       MX6SLL_PAD_SD1_DATA1__SD1_DATA1 0x170b9
+                       MX6SLL_PAD_SD1_DATA2__SD1_DATA2 0x170b9
+                       MX6SLL_PAD_SD1_DATA3__SD1_DATA3 0x170b9
+               >;
+       };
+
+       pinctrl_usdhc1_200mhz: usdhc1grp_200mhz {
+               fsl,pins = <
+                       MX6SLL_PAD_SD1_CMD__SD1_CMD     0x170f9
+                       MX6SLL_PAD_SD1_CLK__SD1_CLK     0x130f9
+                       MX6SLL_PAD_SD1_DATA0__SD1_DATA0 0x170f9
+                       MX6SLL_PAD_SD1_DATA1__SD1_DATA1 0x170f9
+                       MX6SLL_PAD_SD1_DATA2__SD1_DATA2 0x170f9
+                       MX6SLL_PAD_SD1_DATA3__SD1_DATA3 0x170f9
+               >;
+       };
+
+       pinctrl_usbotg1: usbotg1grp {
+               fsl,pins = <
+                       MX6SLL_PAD_EPDC_PWR_COM__USB_OTG1_ID 0x17059
+               >;
+       };
+
+       pinctrl_usdhc3: usdhc3grp {
+               fsl,pins = <
+                       MX6SLL_PAD_SD3_CMD__SD3_CMD             0x17061
+                       MX6SLL_PAD_SD3_CLK__SD3_CLK             0x13061
+                       MX6SLL_PAD_SD3_DATA0__SD3_DATA0         0x17061
+                       MX6SLL_PAD_SD3_DATA1__SD3_DATA1         0x17061
+                       MX6SLL_PAD_SD3_DATA2__SD3_DATA2         0x17061
+                       MX6SLL_PAD_SD3_DATA3__SD3_DATA3         0x17061
+                       MX6SLL_PAD_REF_CLK_32K__GPIO3_IO22      0x17059
+               >;
+       };
+
+       pinctrl_usdhc3_100mhz: usdhc3grp_100mhz {
+               fsl,pins = <
+                       MX6SLL_PAD_SD3_CMD__SD3_CMD             0x170a1
+                       MX6SLL_PAD_SD3_CLK__SD3_CLK             0x130a1
+                       MX6SLL_PAD_SD3_DATA0__SD3_DATA0         0x170a1
+                       MX6SLL_PAD_SD3_DATA1__SD3_DATA1         0x170a1
+                       MX6SLL_PAD_SD3_DATA2__SD3_DATA2         0x170a1
+                       MX6SLL_PAD_SD3_DATA3__SD3_DATA3         0x170a1
+                       MX6SLL_PAD_REF_CLK_32K__GPIO3_IO22      0x17059
+               >;
+       };
+
+       pinctrl_usdhc3_200mhz: usdhc3grp_200mhz {
+               fsl,pins = <
+                       MX6SLL_PAD_SD3_CMD__SD3_CMD             0x170e9
+                       MX6SLL_PAD_SD3_CLK__SD3_CLK             0x130f9
+                       MX6SLL_PAD_SD3_DATA0__SD3_DATA0         0x170e9
+                       MX6SLL_PAD_SD3_DATA1__SD3_DATA1         0x170e9
+                       MX6SLL_PAD_SD3_DATA2__SD3_DATA2         0x170e9
+                       MX6SLL_PAD_SD3_DATA3__SD3_DATA3         0x170e9
+                       MX6SLL_PAD_REF_CLK_32K__GPIO3_IO22      0x17059
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX6SLL_PAD_I2C1_SCL__I2C1_SCL    0x4001b8b1
+                       MX6SLL_PAD_I2C1_SDA__I2C1_SDA    0x4001b8b1
+               >;
+       };
+
+       pinctrl_lcd: lcdgrp {
+               fsl,pins = <
+                       MX6SLL_PAD_LCD_DATA00__LCD_DATA00       0x79
+                       MX6SLL_PAD_LCD_DATA01__LCD_DATA01       0x79
+                       MX6SLL_PAD_LCD_DATA02__LCD_DATA02       0x79
+                       MX6SLL_PAD_LCD_DATA03__LCD_DATA03       0x79
+                       MX6SLL_PAD_LCD_DATA04__LCD_DATA04       0x79
+                       MX6SLL_PAD_LCD_DATA05__LCD_DATA05       0x79
+                       MX6SLL_PAD_LCD_DATA06__LCD_DATA06       0x79
+                       MX6SLL_PAD_LCD_DATA07__LCD_DATA07       0x79
+                       MX6SLL_PAD_LCD_DATA08__LCD_DATA08       0x79
+                       MX6SLL_PAD_LCD_DATA09__LCD_DATA09       0x79
+                       MX6SLL_PAD_LCD_DATA10__LCD_DATA10       0x79
+                       MX6SLL_PAD_LCD_DATA11__LCD_DATA11       0x79
+                       MX6SLL_PAD_LCD_DATA12__LCD_DATA12       0x79
+                       MX6SLL_PAD_LCD_DATA13__LCD_DATA13       0x79
+                       MX6SLL_PAD_LCD_DATA14__LCD_DATA14       0x79
+                       MX6SLL_PAD_LCD_DATA15__LCD_DATA15       0x79
+                       MX6SLL_PAD_LCD_DATA16__LCD_DATA16       0x79
+                       MX6SLL_PAD_LCD_DATA17__LCD_DATA17       0x79
+                       MX6SLL_PAD_LCD_DATA18__LCD_DATA18       0x79
+                       MX6SLL_PAD_LCD_DATA19__LCD_DATA19       0x79
+                       MX6SLL_PAD_LCD_DATA20__LCD_DATA20       0x79
+                       MX6SLL_PAD_LCD_DATA21__LCD_DATA21       0x79
+                       MX6SLL_PAD_LCD_DATA22__LCD_DATA22       0x79
+                       MX6SLL_PAD_LCD_DATA23__LCD_DATA23       0x79
+                       MX6SLL_PAD_LCD_CLK__LCD_CLK             0x79
+                       MX6SLL_PAD_LCD_ENABLE__LCD_ENABLE       0x79
+                       MX6SLL_PAD_LCD_HSYNC__LCD_HSYNC         0x79
+                       MX6SLL_PAD_LCD_VSYNC__LCD_VSYNC         0x79
+                       MX6SLL_PAD_LCD_RESET__LCD_RESET         0x79
+               >;
+       };
+
+       pinctrl_pwm1: pmw1grp {
+               fsl,pins = <
+                       MX6SLL_PAD_PWM1__PWM1_OUT   0x110b0
+               >;
+       };
+};
diff --git a/arch/arm/boot/dts/imx6sll-pinfunc.h b/arch/arm/boot/dts/imx6sll-pinfunc.h
new file mode 100644 (file)
index 0000000..713a346
--- /dev/null
@@ -0,0 +1,880 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP.
+ *
+ */
+
+#ifndef __DTS_IMX6SLL_PINFUNC_H
+#define __DTS_IMX6SLL_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX6SLL_PAD_WDOG_B__WDOG1_B                                0x0014 0x02DC 0x0000 0x0 0x0
+#define MX6SLL_PAD_WDOG_B__WDOG1_RESET_B_DEB                      0x0014 0x02DC 0x0000 0x1 0x0
+#define MX6SLL_PAD_WDOG_B__UART5_RI_B                             0x0014 0x02DC 0x0000 0x2 0x0
+#define MX6SLL_PAD_WDOG_B__GPIO3_IO18                             0x0014 0x02DC 0x0000 0x5 0x0
+#define MX6SLL_PAD_REF_CLK_24M__XTALOSC_REF_CLK_24M               0x0018 0x02E0 0x0000 0x0 0x0
+#define MX6SLL_PAD_REF_CLK_24M__I2C3_SCL                          0x0018 0x02E0 0x068C 0x1 0x0
+#define MX6SLL_PAD_REF_CLK_24M__PWM3_OUT                          0x0018 0x02E0 0x0000 0x2 0x0
+#define MX6SLL_PAD_REF_CLK_24M__USB_OTG2_ID                       0x0018 0x02E0 0x0560 0x3 0x0
+#define MX6SLL_PAD_REF_CLK_24M__CCM_PMIC_READY                    0x0018 0x02E0 0x05AC 0x4 0x0
+#define MX6SLL_PAD_REF_CLK_24M__GPIO3_IO21                        0x0018 0x02E0 0x0000 0x5 0x0
+#define MX6SLL_PAD_REF_CLK_24M__SD3_WP                            0x0018 0x02E0 0x0794 0x6 0x0
+#define MX6SLL_PAD_REF_CLK_32K__XTALOSC_REF_CLK_32K               0x001C 0x02E4 0x0000 0x0 0x0
+#define MX6SLL_PAD_REF_CLK_32K__I2C3_SDA                          0x001C 0x02E4 0x0690 0x1 0x0
+#define MX6SLL_PAD_REF_CLK_32K__PWM4_OUT                          0x001C 0x02E4 0x0000 0x2 0x0
+#define MX6SLL_PAD_REF_CLK_32K__USB_OTG1_ID                       0x001C 0x02E4 0x055C 0x3 0x0
+#define MX6SLL_PAD_REF_CLK_32K__SD1_LCTL                          0x001C 0x02E4 0x0000 0x4 0x0
+#define MX6SLL_PAD_REF_CLK_32K__GPIO3_IO22                        0x001C 0x02E4 0x0000 0x5 0x0
+#define MX6SLL_PAD_REF_CLK_32K__SD3_CD_B                          0x001C 0x02E4 0x0780 0x6 0x0
+#define MX6SLL_PAD_PWM1__PWM1_OUT                                 0x0020 0x02E8 0x0000 0x0 0x0
+#define MX6SLL_PAD_PWM1__CCM_CLKO                                 0x0020 0x02E8 0x0000 0x1 0x0
+#define MX6SLL_PAD_PWM1__AUDIO_CLK_OUT                            0x0020 0x02E8 0x0000 0x2 0x0
+#define MX6SLL_PAD_PWM1__CSI_MCLK                                 0x0020 0x02E8 0x0000 0x4 0x0
+#define MX6SLL_PAD_PWM1__GPIO3_IO23                               0x0020 0x02E8 0x0000 0x5 0x0
+#define MX6SLL_PAD_PWM1__EPIT1_OUT                                0x0020 0x02E8 0x0000 0x6 0x0
+#define MX6SLL_PAD_KEY_COL0__KEY_COL0                             0x0024 0x02EC 0x06A0 0x0 0x0
+#define MX6SLL_PAD_KEY_COL0__I2C2_SCL                             0x0024 0x02EC 0x0684 0x1 0x0
+#define MX6SLL_PAD_KEY_COL0__LCD_DATA00                           0x0024 0x02EC 0x06D8 0x2 0x0
+#define MX6SLL_PAD_KEY_COL0__SD1_CD_B                             0x0024 0x02EC 0x0770 0x4 0x1
+#define MX6SLL_PAD_KEY_COL0__GPIO3_IO24                           0x0024 0x02EC 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_ROW0__KEY_ROW0                             0x0028 0x02F0 0x06C0 0x0 0x0
+#define MX6SLL_PAD_KEY_ROW0__I2C2_SDA                             0x0028 0x02F0 0x0688 0x1 0x0
+#define MX6SLL_PAD_KEY_ROW0__LCD_DATA01                           0x0028 0x02F0 0x06DC 0x2 0x0
+#define MX6SLL_PAD_KEY_ROW0__SD1_WP                               0x0028 0x02F0 0x0774 0x4 0x1
+#define MX6SLL_PAD_KEY_ROW0__GPIO3_IO25                           0x0028 0x02F0 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_COL1__KEY_COL1                             0x002C 0x02F4 0x06A4 0x0 0x0
+#define MX6SLL_PAD_KEY_COL1__ECSPI4_MOSI                          0x002C 0x02F4 0x0658 0x1 0x1
+#define MX6SLL_PAD_KEY_COL1__LCD_DATA02                           0x002C 0x02F4 0x06E0 0x2 0x0
+#define MX6SLL_PAD_KEY_COL1__SD3_DATA4                            0x002C 0x02F4 0x0784 0x4 0x0
+#define MX6SLL_PAD_KEY_COL1__GPIO3_IO26                           0x002C 0x02F4 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_ROW1__KEY_ROW1                             0x0030 0x02F8 0x06C4 0x0 0x0
+#define MX6SLL_PAD_KEY_ROW1__ECSPI4_MISO                          0x0030 0x02F8 0x0654 0x1 0x1
+#define MX6SLL_PAD_KEY_ROW1__LCD_DATA03                           0x0030 0x02F8 0x06E4 0x2 0x0
+#define MX6SLL_PAD_KEY_ROW1__CSI_FIELD                            0x0030 0x02F8 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_ROW1__SD3_DATA5                            0x0030 0x02F8 0x0788 0x4 0x0
+#define MX6SLL_PAD_KEY_ROW1__GPIO3_IO27                           0x0030 0x02F8 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_COL2__KEY_COL2                             0x0034 0x02FC 0x06A8 0x0 0x0
+#define MX6SLL_PAD_KEY_COL2__ECSPI4_SS0                           0x0034 0x02FC 0x065C 0x1 0x1
+#define MX6SLL_PAD_KEY_COL2__LCD_DATA04                           0x0034 0x02FC 0x06E8 0x2 0x0
+#define MX6SLL_PAD_KEY_COL2__CSI_DATA12                           0x0034 0x02FC 0x05B8 0x3 0x1
+#define MX6SLL_PAD_KEY_COL2__SD3_DATA6                            0x0034 0x02FC 0x078C 0x4 0x0
+#define MX6SLL_PAD_KEY_COL2__GPIO3_IO28                           0x0034 0x02FC 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_ROW2__KEY_ROW2                             0x0038 0x0300 0x06C8 0x0 0x0
+#define MX6SLL_PAD_KEY_ROW2__ECSPI4_SCLK                          0x0038 0x0300 0x0650 0x1 0x1
+#define MX6SLL_PAD_KEY_ROW2__LCD_DATA05                           0x0038 0x0300 0x06EC 0x2 0x0
+#define MX6SLL_PAD_KEY_ROW2__CSI_DATA13                           0x0038 0x0300 0x05BC 0x3 0x1
+#define MX6SLL_PAD_KEY_ROW2__SD3_DATA7                            0x0038 0x0300 0x0790 0x4 0x0
+#define MX6SLL_PAD_KEY_ROW2__GPIO3_IO29                           0x0038 0x0300 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_COL3__KEY_COL3                             0x003C 0x0304 0x06AC 0x0 0x0
+#define MX6SLL_PAD_KEY_COL3__AUD6_RXFS                            0x003C 0x0304 0x05A0 0x1 0x1
+#define MX6SLL_PAD_KEY_COL3__LCD_DATA06                           0x003C 0x0304 0x06F0 0x2 0x0
+#define MX6SLL_PAD_KEY_COL3__CSI_DATA14                           0x003C 0x0304 0x05C0 0x3 0x1
+#define MX6SLL_PAD_KEY_COL3__GPIO3_IO30                           0x003C 0x0304 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_COL3__SD1_RESET                            0x003C 0x0304 0x0000 0x6 0x0
+#define MX6SLL_PAD_KEY_ROW3__KEY_ROW3                             0x0040 0x0308 0x06CC 0x0 0x1
+#define MX6SLL_PAD_KEY_ROW3__AUD6_RXC                             0x0040 0x0308 0x059C 0x1 0x1
+#define MX6SLL_PAD_KEY_ROW3__LCD_DATA07                           0x0040 0x0308 0x06F4 0x2 0x1
+#define MX6SLL_PAD_KEY_ROW3__CSI_DATA15                           0x0040 0x0308 0x05C4 0x3 0x2
+#define MX6SLL_PAD_KEY_ROW3__GPIO3_IO31                           0x0040 0x0308 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_ROW3__SD1_VSELECT                          0x0040 0x0308 0x0000 0x6 0x0
+#define MX6SLL_PAD_KEY_COL4__KEY_COL4                             0x0044 0x030C 0x06B0 0x0 0x1
+#define MX6SLL_PAD_KEY_COL4__AUD6_RXD                             0x0044 0x030C 0x0594 0x1 0x1
+#define MX6SLL_PAD_KEY_COL4__LCD_DATA08                           0x0044 0x030C 0x06F8 0x2 0x1
+#define MX6SLL_PAD_KEY_COL4__CSI_DATA16                           0x0044 0x030C 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_COL4__GPIO4_IO00                           0x0044 0x030C 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_COL4__USB_OTG1_PWR                         0x0044 0x030C 0x0000 0x6 0x0
+#define MX6SLL_PAD_KEY_ROW4__KEY_ROW4                             0x0048 0x0310 0x06D0 0x0 0x1
+#define MX6SLL_PAD_KEY_ROW4__AUD6_TXC                             0x0048 0x0310 0x05A4 0x1 0x1
+#define MX6SLL_PAD_KEY_ROW4__LCD_DATA09                           0x0048 0x0310 0x06FC 0x2 0x1
+#define MX6SLL_PAD_KEY_ROW4__CSI_DATA17                           0x0048 0x0310 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_ROW4__GPIO4_IO01                           0x0048 0x0310 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_ROW4__USB_OTG1_OC                          0x0048 0x0310 0x076C 0x6 0x2
+#define MX6SLL_PAD_KEY_COL5__KEY_COL5                             0x004C 0x0314 0x0694 0x0 0x1
+#define MX6SLL_PAD_KEY_COL5__AUD6_TXFS                            0x004C 0x0314 0x05A8 0x1 0x1
+#define MX6SLL_PAD_KEY_COL5__LCD_DATA10                           0x004C 0x0314 0x0700 0x2 0x0
+#define MX6SLL_PAD_KEY_COL5__CSI_DATA18                           0x004C 0x0314 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_COL5__GPIO4_IO02                           0x004C 0x0314 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_COL5__USB_OTG2_PWR                         0x004C 0x0314 0x0000 0x6 0x0
+#define MX6SLL_PAD_KEY_ROW5__KEY_ROW5                             0x0050 0x0318 0x06B4 0x0 0x2
+#define MX6SLL_PAD_KEY_ROW5__AUD6_TXD                             0x0050 0x0318 0x0598 0x1 0x1
+#define MX6SLL_PAD_KEY_ROW5__LCD_DATA11                           0x0050 0x0318 0x0704 0x2 0x1
+#define MX6SLL_PAD_KEY_ROW5__CSI_DATA19                           0x0050 0x0318 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_ROW5__GPIO4_IO03                           0x0050 0x0318 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_ROW5__USB_OTG2_OC                          0x0050 0x0318 0x0768 0x6 0x3
+#define MX6SLL_PAD_KEY_COL6__KEY_COL6                             0x0054 0x031C 0x0698 0x0 0x2
+#define MX6SLL_PAD_KEY_COL6__UART4_DCE_RX                         0x0054 0x031C 0x075C 0x1 0x2
+#define MX6SLL_PAD_KEY_COL6__UART4_DTE_TX                         0x0054 0x031C 0x0000 0x1 0x0
+#define MX6SLL_PAD_KEY_COL6__LCD_DATA12                           0x0054 0x031C 0x0708 0x2 0x1
+#define MX6SLL_PAD_KEY_COL6__CSI_DATA20                           0x0054 0x031C 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_COL6__GPIO4_IO04                           0x0054 0x031C 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_COL6__SD3_RESET                            0x0054 0x031C 0x0000 0x6 0x0
+#define MX6SLL_PAD_KEY_ROW6__KEY_ROW6                             0x0058 0x0320 0x06B8 0x0 0x2
+#define MX6SLL_PAD_KEY_ROW6__UART4_DCE_TX                         0x0058 0x0320 0x0000 0x1 0x0
+#define MX6SLL_PAD_KEY_ROW6__UART4_DTE_RX                         0x0058 0x0320 0x075C 0x1 0x3
+#define MX6SLL_PAD_KEY_ROW6__LCD_DATA13                           0x0058 0x0320 0x070C 0x2 0x1
+#define MX6SLL_PAD_KEY_ROW6__CSI_DATA21                           0x0058 0x0320 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_ROW6__GPIO4_IO05                           0x0058 0x0320 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_ROW6__SD3_VSELECT                          0x0058 0x0320 0x0000 0x6 0x0
+#define MX6SLL_PAD_KEY_COL7__KEY_COL7                             0x005C 0x0324 0x069C 0x0 0x2
+#define MX6SLL_PAD_KEY_COL7__UART4_DCE_RTS                        0x005C 0x0324 0x0758 0x1 0x2
+#define MX6SLL_PAD_KEY_COL7__UART4_DTE_CTS                        0x005C 0x0324 0x0000 0x1 0x0
+#define MX6SLL_PAD_KEY_COL7__LCD_DATA14                           0x005C 0x0324 0x0710 0x2 0x1
+#define MX6SLL_PAD_KEY_COL7__CSI_DATA22                           0x005C 0x0324 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_COL7__GPIO4_IO06                           0x005C 0x0324 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_COL7__SD1_WP                               0x005C 0x0324 0x0774 0x6 0x3
+#define MX6SLL_PAD_KEY_ROW7__KEY_ROW7                             0x0060 0x0328 0x06BC 0x0 0x2
+#define MX6SLL_PAD_KEY_ROW7__UART4_DCE_CTS                        0x0060 0x0328 0x0000 0x1 0x0
+#define MX6SLL_PAD_KEY_ROW7__UART4_DTE_RTS                        0x0060 0x0328 0x0758 0x1 0x3
+#define MX6SLL_PAD_KEY_ROW7__LCD_DATA15                           0x0060 0x0328 0x0714 0x2 0x1
+#define MX6SLL_PAD_KEY_ROW7__CSI_DATA23                           0x0060 0x0328 0x0000 0x3 0x0
+#define MX6SLL_PAD_KEY_ROW7__GPIO4_IO07                           0x0060 0x0328 0x0000 0x5 0x0
+#define MX6SLL_PAD_KEY_ROW7__SD1_CD_B                             0x0060 0x0328 0x0770 0x6 0x3
+#define MX6SLL_PAD_EPDC_DATA00__EPDC_DATA00                       0x0064 0x032C 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA00__ECSPI4_MOSI                       0x0064 0x032C 0x0658 0x1 0x2
+#define MX6SLL_PAD_EPDC_DATA00__LCD_DATA24                        0x0064 0x032C 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA00__CSI_DATA00                        0x0064 0x032C 0x05C8 0x3 0x2
+#define MX6SLL_PAD_EPDC_DATA00__GPIO1_IO07                        0x0064 0x032C 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA01__EPDC_DATA01                       0x0068 0x0330 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA01__ECSPI4_MISO                       0x0068 0x0330 0x0654 0x1 0x2
+#define MX6SLL_PAD_EPDC_DATA01__LCD_DATA25                        0x0068 0x0330 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA01__CSI_DATA01                        0x0068 0x0330 0x05CC 0x3 0x2
+#define MX6SLL_PAD_EPDC_DATA01__GPIO1_IO08                        0x0068 0x0330 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA02__EPDC_DATA02                       0x006C 0x0334 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA02__ECSPI4_SS0                        0x006C 0x0334 0x065C 0x1 0x2
+#define MX6SLL_PAD_EPDC_DATA02__LCD_DATA26                        0x006C 0x0334 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA02__CSI_DATA02                        0x006C 0x0334 0x05D0 0x3 0x2
+#define MX6SLL_PAD_EPDC_DATA02__GPIO1_IO09                        0x006C 0x0334 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA03__EPDC_DATA03                       0x0070 0x0338 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA03__ECSPI4_SCLK                       0x0070 0x0338 0x0650 0x1 0x2
+#define MX6SLL_PAD_EPDC_DATA03__LCD_DATA27                        0x0070 0x0338 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA03__CSI_DATA03                        0x0070 0x0338 0x05D4 0x3 0x2
+#define MX6SLL_PAD_EPDC_DATA03__GPIO1_IO10                        0x0070 0x0338 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA04__EPDC_DATA04                       0x0074 0x033C 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA04__ECSPI4_SS1                        0x0074 0x033C 0x0660 0x1 0x1
+#define MX6SLL_PAD_EPDC_DATA04__LCD_DATA28                        0x0074 0x033C 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA04__CSI_DATA04                        0x0074 0x033C 0x05D8 0x3 0x2
+#define MX6SLL_PAD_EPDC_DATA04__GPIO1_IO11                        0x0074 0x033C 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA05__EPDC_DATA05                       0x0078 0x0340 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA05__ECSPI4_SS2                        0x0078 0x0340 0x0664 0x1 0x1
+#define MX6SLL_PAD_EPDC_DATA05__LCD_DATA29                        0x0078 0x0340 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA05__CSI_DATA05                        0x0078 0x0340 0x05DC 0x3 0x2
+#define MX6SLL_PAD_EPDC_DATA05__GPIO1_IO12                        0x0078 0x0340 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA06__EPDC_DATA06                       0x007C 0x0344 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA06__ECSPI4_SS3                        0x007C 0x0344 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_DATA06__LCD_DATA30                        0x007C 0x0344 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA06__CSI_DATA06                        0x007C 0x0344 0x05E0 0x3 0x2
+#define MX6SLL_PAD_EPDC_DATA06__GPIO1_IO13                        0x007C 0x0344 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA07__EPDC_DATA07                       0x0080 0x0348 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA07__ECSPI4_RDY                        0x0080 0x0348 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_DATA07__LCD_DATA31                        0x0080 0x0348 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA07__CSI_DATA07                        0x0080 0x0348 0x05E4 0x3 0x2
+#define MX6SLL_PAD_EPDC_DATA07__GPIO1_IO14                        0x0080 0x0348 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA08__EPDC_DATA08                       0x0084 0x034C 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA08__ECSPI3_MOSI                       0x0084 0x034C 0x063C 0x1 0x2
+#define MX6SLL_PAD_EPDC_DATA08__EPDC_PWR_CTRL0                    0x0084 0x034C 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA08__GPIO1_IO15                        0x0084 0x034C 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA09__EPDC_DATA09                       0x0088 0x0350 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA09__ECSPI3_MISO                       0x0088 0x0350 0x0638 0x1 0x2
+#define MX6SLL_PAD_EPDC_DATA09__EPDC_PWR_CTRL1                    0x0088 0x0350 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA09__GPIO1_IO16                        0x0088 0x0350 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA10__EPDC_DATA10                       0x008C 0x0354 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA10__ECSPI3_SS0                        0x008C 0x0354 0x0648 0x1 0x2
+#define MX6SLL_PAD_EPDC_DATA10__EPDC_PWR_CTRL2                    0x008C 0x0354 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA10__GPIO1_IO17                        0x008C 0x0354 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA11__EPDC_DATA11                       0x0090 0x0358 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA11__ECSPI3_SCLK                       0x0090 0x0358 0x0630 0x1 0x2
+#define MX6SLL_PAD_EPDC_DATA11__EPDC_PWR_CTRL3                    0x0090 0x0358 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA11__GPIO1_IO18                        0x0090 0x0358 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA12__EPDC_DATA12                       0x0094 0x035C 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA12__UART2_DCE_RX                      0x0094 0x035C 0x074C 0x1 0x4
+#define MX6SLL_PAD_EPDC_DATA12__UART2_DTE_TX                      0x0094 0x035C 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_DATA12__EPDC_PWR_COM                      0x0094 0x035C 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA12__GPIO1_IO19                        0x0094 0x035C 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA12__ECSPI3_SS1                        0x0094 0x035C 0x064C 0x6 0x1
+#define MX6SLL_PAD_EPDC_DATA13__EPDC_DATA13                       0x0098 0x0360 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA13__UART2_DCE_TX                      0x0098 0x0360 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_DATA13__UART2_DTE_RX                      0x0098 0x0360 0x074C 0x1 0x5
+#define MX6SLL_PAD_EPDC_DATA13__EPDC_PWR_IRQ                      0x0098 0x0360 0x0668 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA13__GPIO1_IO20                        0x0098 0x0360 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA13__ECSPI3_SS2                        0x0098 0x0360 0x0640 0x6 0x1
+#define MX6SLL_PAD_EPDC_DATA14__EPDC_DATA14                       0x009C 0x0364 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA14__UART2_DCE_RTS                     0x009C 0x0364 0x0748 0x1 0x4
+#define MX6SLL_PAD_EPDC_DATA14__UART2_DTE_CTS                     0x009C 0x0364 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_DATA14__EPDC_PWR_STAT                     0x009C 0x0364 0x066C 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA14__GPIO1_IO21                        0x009C 0x0364 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA14__ECSPI3_SS3                        0x009C 0x0364 0x0644 0x6 0x1
+#define MX6SLL_PAD_EPDC_DATA15__EPDC_DATA15                       0x00A0 0x0368 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_DATA15__UART2_DCE_CTS                     0x00A0 0x0368 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_DATA15__UART2_DTE_RTS                     0x00A0 0x0368 0x0748 0x1 0x5
+#define MX6SLL_PAD_EPDC_DATA15__EPDC_PWR_WAKE                     0x00A0 0x0368 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_DATA15__GPIO1_IO22                        0x00A0 0x0368 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_DATA15__ECSPI3_RDY                        0x00A0 0x0368 0x0634 0x6 0x1
+#define MX6SLL_PAD_EPDC_SDCLK__EPDC_SDCLK_P                       0x00A4 0x036C 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_SDCLK__ECSPI2_MOSI                        0x00A4 0x036C 0x0624 0x1 0x2
+#define MX6SLL_PAD_EPDC_SDCLK__I2C2_SCL                           0x00A4 0x036C 0x0684 0x2 0x2
+#define MX6SLL_PAD_EPDC_SDCLK__CSI_DATA08                         0x00A4 0x036C 0x05E8 0x3 0x2
+#define MX6SLL_PAD_EPDC_SDCLK__GPIO1_IO23                         0x00A4 0x036C 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_SDLE__EPDC_SDLE                           0x00A8 0x0370 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_SDLE__ECSPI2_MISO                         0x00A8 0x0370 0x0620 0x1 0x2
+#define MX6SLL_PAD_EPDC_SDLE__I2C2_SDA                            0x00A8 0x0370 0x0688 0x2 0x2
+#define MX6SLL_PAD_EPDC_SDLE__CSI_DATA09                          0x00A8 0x0370 0x05EC 0x3 0x2
+#define MX6SLL_PAD_EPDC_SDLE__GPIO1_IO24                          0x00A8 0x0370 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_SDOE__EPDC_SDOE                           0x00AC 0x0374 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_SDOE__ECSPI2_SS0                          0x00AC 0x0374 0x0628 0x1 0x1
+#define MX6SLL_PAD_EPDC_SDOE__CSI_DATA10                          0x00AC 0x0374 0x05B0 0x3 0x2
+#define MX6SLL_PAD_EPDC_SDOE__GPIO1_IO25                          0x00AC 0x0374 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_SDSHR__EPDC_SDSHR                         0x00B0 0x0378 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_SDSHR__ECSPI2_SCLK                        0x00B0 0x0378 0x061C 0x1 0x2
+#define MX6SLL_PAD_EPDC_SDSHR__EPDC_SDCE4                         0x00B0 0x0378 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_SDSHR__CSI_DATA11                         0x00B0 0x0378 0x05B4 0x3 0x2
+#define MX6SLL_PAD_EPDC_SDSHR__GPIO1_IO26                         0x00B0 0x0378 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_SDCE0__EPDC_SDCE0                         0x00B4 0x037C 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_SDCE0__ECSPI2_SS1                         0x00B4 0x037C 0x062C 0x1 0x1
+#define MX6SLL_PAD_EPDC_SDCE0__PWM3_OUT                           0x00B4 0x037C 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_SDCE0__GPIO1_IO27                         0x00B4 0x037C 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_SDCE1__EPDC_SDCE1                         0x00B8 0x0380 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_SDCE1__WDOG2_B                            0x00B8 0x0380 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_SDCE1__PWM4_OUT                           0x00B8 0x0380 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_SDCE1__GPIO1_IO28                         0x00B8 0x0380 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_SDCE2__EPDC_SDCE2                         0x00BC 0x0384 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_SDCE2__I2C3_SCL                           0x00BC 0x0384 0x068C 0x1 0x2
+#define MX6SLL_PAD_EPDC_SDCE2__PWM1_OUT                           0x00BC 0x0384 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_SDCE2__GPIO1_IO29                         0x00BC 0x0384 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_SDCE3__EPDC_SDCE3                         0x00C0 0x0388 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_SDCE3__I2C3_SDA                           0x00C0 0x0388 0x0690 0x1 0x2
+#define MX6SLL_PAD_EPDC_SDCE3__PWM2_OUT                           0x00C0 0x0388 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_SDCE3__GPIO1_IO30                         0x00C0 0x0388 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_GDCLK__EPDC_GDCLK                         0x00C4 0x038C 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_GDCLK__ECSPI2_SS2                         0x00C4 0x038C 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_GDCLK__CSI_PIXCLK                         0x00C4 0x038C 0x05F4 0x3 0x2
+#define MX6SLL_PAD_EPDC_GDCLK__GPIO1_IO31                         0x00C4 0x038C 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_GDCLK__SD2_RESET                          0x00C4 0x038C 0x0000 0x6 0x0
+#define MX6SLL_PAD_EPDC_GDOE__EPDC_GDOE                           0x00C8 0x0390 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_GDOE__ECSPI2_SS3                          0x00C8 0x0390 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_GDOE__CSI_HSYNC                           0x00C8 0x0390 0x05F0 0x3 0x2
+#define MX6SLL_PAD_EPDC_GDOE__GPIO2_IO00                          0x00C8 0x0390 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_GDOE__SD2_VSELECT                         0x00C8 0x0390 0x0000 0x6 0x0
+#define MX6SLL_PAD_EPDC_GDRL__EPDC_GDRL                           0x00CC 0x0394 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_GDRL__ECSPI2_RDY                          0x00CC 0x0394 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_GDRL__CSI_MCLK                            0x00CC 0x0394 0x0000 0x3 0x0
+#define MX6SLL_PAD_EPDC_GDRL__GPIO2_IO01                          0x00CC 0x0394 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_GDRL__SD2_WP                              0x00CC 0x0394 0x077C 0x6 0x2
+#define MX6SLL_PAD_EPDC_GDSP__EPDC_GDSP                           0x00D0 0x0398 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_GDSP__PWM4_OUT                            0x00D0 0x0398 0x0000 0x1 0x0
+#define MX6SLL_PAD_EPDC_GDSP__CSI_VSYNC                           0x00D0 0x0398 0x05F8 0x3 0x2
+#define MX6SLL_PAD_EPDC_GDSP__GPIO2_IO02                          0x00D0 0x0398 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_GDSP__SD2_CD_B                            0x00D0 0x0398 0x0778 0x6 0x2
+#define MX6SLL_PAD_EPDC_VCOM0__EPDC_VCOM0                         0x00D4 0x039C 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_VCOM0__AUD5_RXFS                          0x00D4 0x039C 0x0588 0x1 0x1
+#define MX6SLL_PAD_EPDC_VCOM0__UART3_DCE_RX                       0x00D4 0x039C 0x0754 0x2 0x4
+#define MX6SLL_PAD_EPDC_VCOM0__UART3_DTE_TX                       0x00D4 0x039C 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_VCOM0__GPIO2_IO03                         0x00D4 0x039C 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_VCOM0__EPDC_SDCE5                         0x00D4 0x039C 0x0000 0x6 0x0
+#define MX6SLL_PAD_EPDC_VCOM1__EPDC_VCOM1                         0x00D8 0x03A0 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_VCOM1__AUD5_RXD                           0x00D8 0x03A0 0x057C 0x1 0x1
+#define MX6SLL_PAD_EPDC_VCOM1__UART3_DCE_TX                       0x00D8 0x03A0 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_VCOM1__UART3_DTE_RX                       0x00D8 0x03A0 0x0754 0x2 0x5
+#define MX6SLL_PAD_EPDC_VCOM1__GPIO2_IO04                         0x00D8 0x03A0 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_VCOM1__EPDC_SDCE6                         0x00D8 0x03A0 0x0000 0x6 0x0
+#define MX6SLL_PAD_EPDC_BDR0__EPDC_BDR0                           0x00DC 0x03A4 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_BDR0__UART3_DCE_RTS                       0x00DC 0x03A4 0x0750 0x2 0x2
+#define MX6SLL_PAD_EPDC_BDR0__UART3_DTE_CTS                       0x00DC 0x03A4 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_BDR0__GPIO2_IO05                          0x00DC 0x03A4 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_BDR0__EPDC_SDCE7                          0x00DC 0x03A4 0x0000 0x6 0x0
+#define MX6SLL_PAD_EPDC_BDR1__EPDC_BDR1                           0x00E0 0x03A8 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_BDR1__UART3_DCE_CTS                       0x00E0 0x03A8 0x0000 0x2 0x0
+#define MX6SLL_PAD_EPDC_BDR1__UART3_DTE_RTS                       0x00E0 0x03A8 0x0750 0x2 0x3
+#define MX6SLL_PAD_EPDC_BDR1__GPIO2_IO06                          0x00E0 0x03A8 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_BDR1__EPDC_SDCE8                          0x00E0 0x03A8 0x0000 0x6 0x0
+#define MX6SLL_PAD_EPDC_PWR_CTRL0__EPDC_PWR_CTRL0                 0x00E4 0x03AC 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_PWR_CTRL0__AUD5_RXC                       0x00E4 0x03AC 0x0584 0x1 0x1
+#define MX6SLL_PAD_EPDC_PWR_CTRL0__LCD_DATA16                     0x00E4 0x03AC 0x0718 0x2 0x1
+#define MX6SLL_PAD_EPDC_PWR_CTRL0__GPIO2_IO07                     0x00E4 0x03AC 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_PWR_CTRL1__EPDC_PWR_CTRL1                 0x00E8 0x03B0 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_PWR_CTRL1__AUD5_TXFS                      0x00E8 0x03B0 0x0590 0x1 0x1
+#define MX6SLL_PAD_EPDC_PWR_CTRL1__LCD_DATA17                     0x00E8 0x03B0 0x071C 0x2 0x1
+#define MX6SLL_PAD_EPDC_PWR_CTRL1__GPIO2_IO08                     0x00E8 0x03B0 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_PWR_CTRL2__EPDC_PWR_CTRL2                 0x00EC 0x03B4 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_PWR_CTRL2__AUD5_TXD                       0x00EC 0x03B4 0x0580 0x1 0x1
+#define MX6SLL_PAD_EPDC_PWR_CTRL2__LCD_DATA18                     0x00EC 0x03B4 0x0720 0x2 0x1
+#define MX6SLL_PAD_EPDC_PWR_CTRL2__GPIO2_IO09                     0x00EC 0x03B4 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_PWR_CTRL3__EPDC_PWR_CTRL3                 0x00F0 0x03B8 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_PWR_CTRL3__AUD5_TXC                       0x00F0 0x03B8 0x058C 0x1 0x1
+#define MX6SLL_PAD_EPDC_PWR_CTRL3__LCD_DATA19                     0x00F0 0x03B8 0x0724 0x2 0x1
+#define MX6SLL_PAD_EPDC_PWR_CTRL3__GPIO2_IO10                     0x00F0 0x03B8 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_PWR_COM__EPDC_PWR_COM                     0x00F4 0x03BC 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_PWR_COM__LCD_DATA20                       0x00F4 0x03BC 0x0728 0x2 0x1
+#define MX6SLL_PAD_EPDC_PWR_COM__USB_OTG1_ID                      0x00F4 0x03BC 0x055C 0x4 0x4
+#define MX6SLL_PAD_EPDC_PWR_COM__GPIO2_IO11                       0x00F4 0x03BC 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_PWR_COM__SD3_RESET                        0x00F4 0x03BC 0x0000 0x6 0x0
+#define MX6SLL_PAD_EPDC_PWR_IRQ__EPDC_PWR_IRQ                     0x00F8 0x03C0 0x0668 0x0 0x1
+#define MX6SLL_PAD_EPDC_PWR_IRQ__LCD_DATA21                       0x00F8 0x03C0 0x072C 0x2 0x1
+#define MX6SLL_PAD_EPDC_PWR_IRQ__USB_OTG2_ID                      0x00F8 0x03C0 0x0560 0x4 0x3
+#define MX6SLL_PAD_EPDC_PWR_IRQ__GPIO2_IO12                       0x00F8 0x03C0 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_PWR_IRQ__SD3_VSELECT                      0x00F8 0x03C0 0x0000 0x6 0x0
+#define MX6SLL_PAD_EPDC_PWR_STAT__EPDC_PWR_STAT                   0x00FC 0x03C4 0x066C 0x0 0x1
+#define MX6SLL_PAD_EPDC_PWR_STAT__LCD_DATA22                      0x00FC 0x03C4 0x0730 0x2 0x1
+#define MX6SLL_PAD_EPDC_PWR_STAT__ARM_EVENTI                      0x00FC 0x03C4 0x0000 0x4 0x0
+#define MX6SLL_PAD_EPDC_PWR_STAT__GPIO2_IO13                      0x00FC 0x03C4 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_PWR_STAT__SD3_WP                          0x00FC 0x03C4 0x0794 0x6 0x2
+#define MX6SLL_PAD_EPDC_PWR_WAKE__EPDC_PWR_WAKE                   0x0100 0x03C8 0x0000 0x0 0x0
+#define MX6SLL_PAD_EPDC_PWR_WAKE__LCD_DATA23                      0x0100 0x03C8 0x0734 0x2 0x1
+#define MX6SLL_PAD_EPDC_PWR_WAKE__ARM_EVENTO                      0x0100 0x03C8 0x0000 0x4 0x0
+#define MX6SLL_PAD_EPDC_PWR_WAKE__GPIO2_IO14                      0x0100 0x03C8 0x0000 0x5 0x0
+#define MX6SLL_PAD_EPDC_PWR_WAKE__SD3_CD_B                        0x0100 0x03C8 0x0780 0x6 0x2
+#define MX6SLL_PAD_LCD_CLK__LCD_CLK                               0x0104 0x03CC 0x0000 0x0 0x0
+#define MX6SLL_PAD_LCD_CLK__LCD_WR_RWN                            0x0104 0x03CC 0x0000 0x2 0x0
+#define MX6SLL_PAD_LCD_CLK__PWM4_OUT                              0x0104 0x03CC 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_CLK__GPIO2_IO15                            0x0104 0x03CC 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_ENABLE__LCD_ENABLE                         0x0108 0x03D0 0x0000 0x0 0x0
+#define MX6SLL_PAD_LCD_ENABLE__LCD_RD_E                           0x0108 0x03D0 0x0000 0x2 0x0
+#define MX6SLL_PAD_LCD_ENABLE__UART2_DCE_RX                       0x0108 0x03D0 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_ENABLE__UART2_DTE_TX                       0x0108 0x03D0 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_ENABLE__GPIO2_IO16                         0x0108 0x03D0 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_HSYNC__LCD_HSYNC                           0x010C 0x03D4 0x06D4 0x0 0x0
+#define MX6SLL_PAD_LCD_HSYNC__LCD_CS                              0x010C 0x03D4 0x0000 0x2 0x0
+#define MX6SLL_PAD_LCD_HSYNC__UART2_DCE_TX                        0x010C 0x03D4 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_HSYNC__UART2_DTE_RX                        0x010C 0x03D4 0x074C 0x4 0x1
+#define MX6SLL_PAD_LCD_HSYNC__GPIO2_IO17                          0x010C 0x03D4 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_HSYNC__ARM_TRACE_CLK                       0x010C 0x03D4 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_VSYNC__LCD_VSYNC                           0x0110 0x03D8 0x0000 0x0 0x0
+#define MX6SLL_PAD_LCD_VSYNC__LCD_RS                              0x0110 0x03D8 0x0000 0x2 0x0
+#define MX6SLL_PAD_LCD_VSYNC__UART2_DCE_RTS                       0x0110 0x03D8 0x0748 0x4 0x0
+#define MX6SLL_PAD_LCD_VSYNC__UART2_DTE_CTS                       0x0110 0x03D8 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_VSYNC__GPIO2_IO18                          0x0110 0x03D8 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_VSYNC__ARM_TRACE_CTL                       0x0110 0x03D8 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_RESET__LCD_RESET                           0x0114 0x03DC 0x0000 0x0 0x0
+#define MX6SLL_PAD_LCD_RESET__LCD_BUSY                            0x0114 0x03DC 0x06D4 0x2 0x1
+#define MX6SLL_PAD_LCD_RESET__UART2_DCE_CTS                       0x0114 0x03DC 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_RESET__UART2_DTE_RTS                       0x0114 0x03DC 0x0748 0x4 0x1
+#define MX6SLL_PAD_LCD_RESET__GPIO2_IO19                          0x0114 0x03DC 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_RESET__CCM_PMIC_READY                      0x0114 0x03DC 0x05AC 0x6 0x2
+#define MX6SLL_PAD_LCD_DATA00__LCD_DATA00                         0x0118 0x03E0 0x06D8 0x0 0x1
+#define MX6SLL_PAD_LCD_DATA00__ECSPI1_MOSI                        0x0118 0x03E0 0x0608 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA00__USB_OTG2_ID                        0x0118 0x03E0 0x0560 0x2 0x2
+#define MX6SLL_PAD_LCD_DATA00__PWM1_OUT                           0x0118 0x03E0 0x0000 0x3 0x0
+#define MX6SLL_PAD_LCD_DATA00__UART5_DTR_B                        0x0118 0x03E0 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA00__GPIO2_IO20                         0x0118 0x03E0 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA00__ARM_TRACE00                        0x0118 0x03E0 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA00__SRC_BOOT_CFG00                     0x0118 0x03E0 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA01__LCD_DATA01                         0x011C 0x03E4 0x06DC 0x0 0x1
+#define MX6SLL_PAD_LCD_DATA01__ECSPI1_MISO                        0x011C 0x03E4 0x0604 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA01__USB_OTG1_ID                        0x011C 0x03E4 0x055C 0x2 0x3
+#define MX6SLL_PAD_LCD_DATA01__PWM2_OUT                           0x011C 0x03E4 0x0000 0x3 0x0
+#define MX6SLL_PAD_LCD_DATA01__AUD4_RXFS                          0x011C 0x03E4 0x0570 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA01__GPIO2_IO21                         0x011C 0x03E4 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA01__ARM_TRACE01                        0x011C 0x03E4 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA01__SRC_BOOT_CFG01                     0x011C 0x03E4 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA02__LCD_DATA02                         0x0120 0x03E8 0x06E0 0x0 0x1
+#define MX6SLL_PAD_LCD_DATA02__ECSPI1_SS0                         0x0120 0x03E8 0x0614 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA02__EPIT2_OUT                          0x0120 0x03E8 0x0000 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA02__PWM3_OUT                           0x0120 0x03E8 0x0000 0x3 0x0
+#define MX6SLL_PAD_LCD_DATA02__AUD4_RXC                           0x0120 0x03E8 0x056C 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA02__GPIO2_IO22                         0x0120 0x03E8 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA02__ARM_TRACE02                        0x0120 0x03E8 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA02__SRC_BOOT_CFG02                     0x0120 0x03E8 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA03__LCD_DATA03                         0x0124 0x03EC 0x06E4 0x0 0x1
+#define MX6SLL_PAD_LCD_DATA03__ECSPI1_SCLK                        0x0124 0x03EC 0x05FC 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA03__UART5_DSR_B                        0x0124 0x03EC 0x0000 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA03__PWM4_OUT                           0x0124 0x03EC 0x0000 0x3 0x0
+#define MX6SLL_PAD_LCD_DATA03__AUD4_RXD                           0x0124 0x03EC 0x0564 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA03__GPIO2_IO23                         0x0124 0x03EC 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA03__ARM_TRACE03                        0x0124 0x03EC 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA03__SRC_BOOT_CFG03                     0x0124 0x03EC 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA04__LCD_DATA04                         0x0128 0x03F0 0x06E8 0x0 0x1
+#define MX6SLL_PAD_LCD_DATA04__ECSPI1_SS1                         0x0128 0x03F0 0x060C 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA04__CSI_VSYNC                          0x0128 0x03F0 0x05F8 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA04__WDOG2_RESET_B_DEB                  0x0128 0x03F0 0x0000 0x3 0x0
+#define MX6SLL_PAD_LCD_DATA04__AUD4_TXC                           0x0128 0x03F0 0x0574 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA04__GPIO2_IO24                         0x0128 0x03F0 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA04__ARM_TRACE04                        0x0128 0x03F0 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA04__SRC_BOOT_CFG04                     0x0128 0x03F0 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA05__LCD_DATA05                         0x012C 0x03F4 0x06EC 0x0 0x1
+#define MX6SLL_PAD_LCD_DATA05__ECSPI1_SS2                         0x012C 0x03F4 0x0610 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA05__CSI_HSYNC                          0x012C 0x03F4 0x05F0 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA05__AUD4_TXFS                          0x012C 0x03F4 0x0578 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA05__GPIO2_IO25                         0x012C 0x03F4 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA05__ARM_TRACE05                        0x012C 0x03F4 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA05__SRC_BOOT_CFG05                     0x012C 0x03F4 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA06__LCD_DATA06                         0x0130 0x03F8 0x06F0 0x0 0x1
+#define MX6SLL_PAD_LCD_DATA06__ECSPI1_SS3                         0x0130 0x03F8 0x0618 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA06__CSI_PIXCLK                         0x0130 0x03F8 0x05F4 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA06__AUD4_TXD                           0x0130 0x03F8 0x0568 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA06__GPIO2_IO26                         0x0130 0x03F8 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA06__ARM_TRACE06                        0x0130 0x03F8 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA06__SRC_BOOT_CFG06                     0x0130 0x03F8 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA07__LCD_DATA07                         0x0134 0x03FC 0x06F4 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA07__ECSPI1_RDY                         0x0134 0x03FC 0x0600 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA07__CSI_MCLK                           0x0134 0x03FC 0x0000 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA07__AUDIO_CLK_OUT                      0x0134 0x03FC 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA07__GPIO2_IO27                         0x0134 0x03FC 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA07__ARM_TRACE07                        0x0134 0x03FC 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA07__SRC_BOOT_CFG07                     0x0134 0x03FC 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA08__LCD_DATA08                         0x0138 0x0400 0x06F8 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA08__KEY_COL0                           0x0138 0x0400 0x06A0 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA08__CSI_DATA09                         0x0138 0x0400 0x05EC 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA08__ECSPI2_SCLK                        0x0138 0x0400 0x061C 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA08__GPIO2_IO28                         0x0138 0x0400 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA08__ARM_TRACE08                        0x0138 0x0400 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA08__SRC_BOOT_CFG08                     0x0138 0x0400 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA09__LCD_DATA09                         0x013C 0x0404 0x06FC 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA09__KEY_ROW0                           0x013C 0x0404 0x06C0 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA09__CSI_DATA08                         0x013C 0x0404 0x05E8 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA09__ECSPI2_MOSI                        0x013C 0x0404 0x0624 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA09__GPIO2_IO29                         0x013C 0x0404 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA09__ARM_TRACE09                        0x013C 0x0404 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA09__SRC_BOOT_CFG09                     0x013C 0x0404 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA10__LCD_DATA10                         0x0140 0x0408 0x0700 0x0 0x1
+#define MX6SLL_PAD_LCD_DATA10__KEY_COL1                           0x0140 0x0408 0x06A4 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA10__CSI_DATA07                         0x0140 0x0408 0x05E4 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA10__ECSPI2_MISO                        0x0140 0x0408 0x0620 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA10__GPIO2_IO30                         0x0140 0x0408 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA10__ARM_TRACE10                        0x0140 0x0408 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA10__SRC_BOOT_CFG10                     0x0140 0x0408 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA11__LCD_DATA11                         0x0144 0x040C 0x0704 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA11__KEY_ROW1                           0x0144 0x040C 0x06C4 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA11__CSI_DATA06                         0x0144 0x040C 0x05E0 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA11__ECSPI2_SS1                         0x0144 0x040C 0x062C 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA11__GPIO2_IO31                         0x0144 0x040C 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA11__ARM_TRACE11                        0x0144 0x040C 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA11__SRC_BOOT_CFG11                     0x0144 0x040C 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA12__LCD_DATA12                         0x0148 0x0410 0x0708 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA12__KEY_COL2                           0x0148 0x0410 0x06A8 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA12__CSI_DATA05                         0x0148 0x0410 0x05DC 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA12__UART5_DCE_RTS                      0x0148 0x0410 0x0760 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA12__UART5_DTE_CTS                      0x0148 0x0410 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA12__GPIO3_IO00                         0x0148 0x0410 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA12__ARM_TRACE12                        0x0148 0x0410 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA12__SRC_BOOT_CFG12                     0x0148 0x0410 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA13__LCD_DATA13                         0x014C 0x0414 0x070C 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA13__KEY_ROW2                           0x014C 0x0414 0x06C8 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA13__CSI_DATA04                         0x014C 0x0414 0x05D8 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA13__UART5_DCE_CTS                      0x014C 0x0414 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA13__UART5_DTE_RTS                      0x014C 0x0414 0x0760 0x4 0x1
+#define MX6SLL_PAD_LCD_DATA13__GPIO3_IO01                         0x014C 0x0414 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA13__ARM_TRACE13                        0x014C 0x0414 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA13__SRC_BOOT_CFG13                     0x014C 0x0414 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA14__LCD_DATA14                         0x0150 0x0418 0x0710 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA14__KEY_COL3                           0x0150 0x0418 0x06AC 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA14__CSI_DATA03                         0x0150 0x0418 0x05D4 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA14__UART5_DCE_RX                       0x0150 0x0418 0x0764 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA14__UART5_DTE_TX                       0x0150 0x0418 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA14__GPIO3_IO02                         0x0150 0x0418 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA14__ARM_TRACE14                        0x0150 0x0418 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA14__SRC_BOOT_CFG14                     0x0150 0x0418 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA15__LCD_DATA15                         0x0154 0x041C 0x0714 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA15__KEY_ROW3                           0x0154 0x041C 0x06CC 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA15__CSI_DATA02                         0x0154 0x041C 0x05D0 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA15__UART5_DCE_TX                       0x0154 0x041C 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA15__UART5_DTE_RX                       0x0154 0x041C 0x0764 0x4 0x1
+#define MX6SLL_PAD_LCD_DATA15__GPIO3_IO03                         0x0154 0x041C 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA15__ARM_TRACE15                        0x0154 0x041C 0x0000 0x6 0x0
+#define MX6SLL_PAD_LCD_DATA15__SRC_BOOT_CFG15                     0x0154 0x041C 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA16__LCD_DATA16                         0x0158 0x0420 0x0718 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA16__KEY_COL4                           0x0158 0x0420 0x06B0 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA16__CSI_DATA01                         0x0158 0x0420 0x05CC 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA16__I2C2_SCL                           0x0158 0x0420 0x0684 0x4 0x1
+#define MX6SLL_PAD_LCD_DATA16__GPIO3_IO04                         0x0158 0x0420 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA16__SRC_BOOT_CFG24                     0x0158 0x0420 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA17__LCD_DATA17                         0x015C 0x0424 0x071C 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA17__KEY_ROW4                           0x015C 0x0424 0x06D0 0x1 0x0
+#define MX6SLL_PAD_LCD_DATA17__CSI_DATA00                         0x015C 0x0424 0x05C8 0x2 0x0
+#define MX6SLL_PAD_LCD_DATA17__I2C2_SDA                           0x015C 0x0424 0x0688 0x4 0x1
+#define MX6SLL_PAD_LCD_DATA17__GPIO3_IO05                         0x015C 0x0424 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA17__SRC_BOOT_CFG25                     0x015C 0x0424 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA18__LCD_DATA18                         0x0160 0x0428 0x0720 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA18__KEY_COL5                           0x0160 0x0428 0x0694 0x1 0x2
+#define MX6SLL_PAD_LCD_DATA18__CSI_DATA15                         0x0160 0x0428 0x05C4 0x2 0x1
+#define MX6SLL_PAD_LCD_DATA18__GPT_CAPTURE1                       0x0160 0x0428 0x0670 0x4 0x1
+#define MX6SLL_PAD_LCD_DATA18__GPIO3_IO06                         0x0160 0x0428 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA18__SRC_BOOT_CFG26                     0x0160 0x0428 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA19__LCD_DATA19                         0x0164 0x042C 0x0724 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA19__KEY_ROW5                           0x0164 0x042C 0x06B4 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA19__CSI_DATA14                         0x0164 0x042C 0x05C0 0x2 0x2
+#define MX6SLL_PAD_LCD_DATA19__GPT_CAPTURE2                       0x0164 0x042C 0x0674 0x4 0x1
+#define MX6SLL_PAD_LCD_DATA19__GPIO3_IO07                         0x0164 0x042C 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA19__SRC_BOOT_CFG27                     0x0164 0x042C 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA20__LCD_DATA20                         0x0168 0x0430 0x0728 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA20__KEY_COL6                           0x0168 0x0430 0x0698 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA20__CSI_DATA13                         0x0168 0x0430 0x05BC 0x2 0x2
+#define MX6SLL_PAD_LCD_DATA20__GPT_COMPARE1                       0x0168 0x0430 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA20__GPIO3_IO08                         0x0168 0x0430 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA20__SRC_BOOT_CFG28                     0x0168 0x0430 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA21__LCD_DATA21                         0x016C 0x0434 0x072C 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA21__KEY_ROW6                           0x016C 0x0434 0x06B8 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA21__CSI_DATA12                         0x016C 0x0434 0x05B8 0x2 0x2
+#define MX6SLL_PAD_LCD_DATA21__GPT_COMPARE2                       0x016C 0x0434 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA21__GPIO3_IO09                         0x016C 0x0434 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA21__SRC_BOOT_CFG29                     0x016C 0x0434 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA22__LCD_DATA22                         0x0170 0x0438 0x0730 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA22__KEY_COL7                           0x0170 0x0438 0x069C 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA22__CSI_DATA11                         0x0170 0x0438 0x05B4 0x2 0x1
+#define MX6SLL_PAD_LCD_DATA22__GPT_COMPARE3                       0x0170 0x0438 0x0000 0x4 0x0
+#define MX6SLL_PAD_LCD_DATA22__GPIO3_IO10                         0x0170 0x0438 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA22__SRC_BOOT_CFG30                     0x0170 0x0438 0x0000 0x7 0x0
+#define MX6SLL_PAD_LCD_DATA23__LCD_DATA23                         0x0174 0x043C 0x0734 0x0 0x0
+#define MX6SLL_PAD_LCD_DATA23__KEY_ROW7                           0x0174 0x043C 0x06BC 0x1 0x1
+#define MX6SLL_PAD_LCD_DATA23__CSI_DATA10                         0x0174 0x043C 0x05B0 0x2 0x1
+#define MX6SLL_PAD_LCD_DATA23__GPT_CLKIN                          0x0174 0x043C 0x0678 0x4 0x1
+#define MX6SLL_PAD_LCD_DATA23__GPIO3_IO11                         0x0174 0x043C 0x0000 0x5 0x0
+#define MX6SLL_PAD_LCD_DATA23__SRC_BOOT_CFG31                     0x0174 0x043C 0x0000 0x7 0x0
+#define MX6SLL_PAD_AUD_RXFS__AUD3_RXFS                            0x0178 0x0440 0x0000 0x0 0x0
+#define MX6SLL_PAD_AUD_RXFS__I2C1_SCL                             0x0178 0x0440 0x067C 0x1 0x1
+#define MX6SLL_PAD_AUD_RXFS__UART3_DCE_RX                         0x0178 0x0440 0x0754 0x2 0x0
+#define MX6SLL_PAD_AUD_RXFS__UART3_DTE_TX                         0x0178 0x0440 0x0000 0x2 0x0
+#define MX6SLL_PAD_AUD_RXFS__I2C3_SCL                             0x0178 0x0440 0x068C 0x4 0x1
+#define MX6SLL_PAD_AUD_RXFS__GPIO1_IO00                           0x0178 0x0440 0x0000 0x5 0x0
+#define MX6SLL_PAD_AUD_RXFS__ECSPI3_SS0                           0x0178 0x0440 0x0648 0x6 0x0
+#define MX6SLL_PAD_AUD_RXFS__MBIST_BEND                           0x0178 0x0440 0x0000 0x7 0x0
+#define MX6SLL_PAD_AUD_RXC__AUD3_RXC                              0x017C 0x0444 0x0000 0x0 0x0
+#define MX6SLL_PAD_AUD_RXC__I2C1_SDA                              0x017C 0x0444 0x0680 0x1 0x1
+#define MX6SLL_PAD_AUD_RXC__UART3_DCE_TX                          0x017C 0x0444 0x0000 0x2 0x0
+#define MX6SLL_PAD_AUD_RXC__UART3_DTE_RX                          0x017C 0x0444 0x0754 0x2 0x1
+#define MX6SLL_PAD_AUD_RXC__I2C3_SDA                              0x017C 0x0444 0x0690 0x4 0x1
+#define MX6SLL_PAD_AUD_RXC__GPIO1_IO01                            0x017C 0x0444 0x0000 0x5 0x0
+#define MX6SLL_PAD_AUD_RXC__ECSPI3_SS1                            0x017C 0x0444 0x064C 0x6 0x0
+#define MX6SLL_PAD_AUD_RXD__AUD3_RXD                              0x0180 0x0448 0x0000 0x0 0x0
+#define MX6SLL_PAD_AUD_RXD__ECSPI3_MOSI                           0x0180 0x0448 0x063C 0x1 0x0
+#define MX6SLL_PAD_AUD_RXD__UART4_DCE_RX                          0x0180 0x0448 0x075C 0x2 0x0
+#define MX6SLL_PAD_AUD_RXD__UART4_DTE_TX                          0x0180 0x0448 0x0000 0x2 0x0
+#define MX6SLL_PAD_AUD_RXD__SD1_LCTL                              0x0180 0x0448 0x0000 0x4 0x0
+#define MX6SLL_PAD_AUD_RXD__GPIO1_IO02                            0x0180 0x0448 0x0000 0x5 0x0
+#define MX6SLL_PAD_AUD_TXC__AUD3_TXC                              0x0184 0x044C 0x0000 0x0 0x0
+#define MX6SLL_PAD_AUD_TXC__ECSPI3_MISO                           0x0184 0x044C 0x0638 0x1 0x0
+#define MX6SLL_PAD_AUD_TXC__UART4_DCE_TX                          0x0184 0x044C 0x0000 0x2 0x0
+#define MX6SLL_PAD_AUD_TXC__UART4_DTE_RX                          0x0184 0x044C 0x075C 0x2 0x1
+#define MX6SLL_PAD_AUD_TXC__SD2_LCTL                              0x0184 0x044C 0x0000 0x4 0x0
+#define MX6SLL_PAD_AUD_TXC__GPIO1_IO03                            0x0184 0x044C 0x0000 0x5 0x0
+#define MX6SLL_PAD_AUD_TXFS__AUD3_TXFS                            0x0188 0x0450 0x0000 0x0 0x0
+#define MX6SLL_PAD_AUD_TXFS__PWM3_OUT                             0x0188 0x0450 0x0000 0x1 0x0
+#define MX6SLL_PAD_AUD_TXFS__UART4_DCE_RTS                        0x0188 0x0450 0x0758 0x2 0x0
+#define MX6SLL_PAD_AUD_TXFS__UART4_DTE_CTS                        0x0188 0x0450 0x0000 0x2 0x0
+#define MX6SLL_PAD_AUD_TXFS__SD3_LCTL                             0x0188 0x0450 0x0000 0x4 0x0
+#define MX6SLL_PAD_AUD_TXFS__GPIO1_IO04                           0x0188 0x0450 0x0000 0x5 0x0
+#define MX6SLL_PAD_AUD_TXD__AUD3_TXD                              0x018C 0x0454 0x0000 0x0 0x0
+#define MX6SLL_PAD_AUD_TXD__ECSPI3_SCLK                           0x018C 0x0454 0x0630 0x1 0x0
+#define MX6SLL_PAD_AUD_TXD__UART4_DCE_CTS                         0x018C 0x0454 0x0000 0x2 0x0
+#define MX6SLL_PAD_AUD_TXD__UART4_DTE_RTS                         0x018C 0x0454 0x0758 0x2 0x1
+#define MX6SLL_PAD_AUD_TXD__GPIO1_IO05                            0x018C 0x0454 0x0000 0x5 0x0
+#define MX6SLL_PAD_AUD_MCLK__AUDIO_CLK_OUT                        0x0190 0x0458 0x0000 0x0 0x0
+#define MX6SLL_PAD_AUD_MCLK__PWM4_OUT                             0x0190 0x0458 0x0000 0x1 0x0
+#define MX6SLL_PAD_AUD_MCLK__ECSPI3_RDY                           0x0190 0x0458 0x0634 0x2 0x0
+#define MX6SLL_PAD_AUD_MCLK__WDOG2_RESET_B_DEB                    0x0190 0x0458 0x0000 0x4 0x0
+#define MX6SLL_PAD_AUD_MCLK__GPIO1_IO06                           0x0190 0x0458 0x0000 0x5 0x0
+#define MX6SLL_PAD_AUD_MCLK__SPDIF_EXT_CLK                        0x0190 0x0458 0x073C 0x6 0x1
+#define MX6SLL_PAD_UART1_RXD__UART1_DCE_RX                        0x0194 0x045C 0x0744 0x0 0x0
+#define MX6SLL_PAD_UART1_RXD__UART1_DTE_TX                        0x0194 0x045C 0x0000 0x0 0x0
+#define MX6SLL_PAD_UART1_RXD__PWM1_OUT                            0x0194 0x045C 0x0000 0x1 0x0
+#define MX6SLL_PAD_UART1_RXD__UART4_DCE_RX                        0x0194 0x045C 0x075C 0x2 0x4
+#define MX6SLL_PAD_UART1_RXD__UART4_DTE_TX                        0x0194 0x045C 0x0000 0x2 0x0
+#define MX6SLL_PAD_UART1_RXD__UART5_DCE_RX                        0x0194 0x045C 0x0764 0x4 0x6
+#define MX6SLL_PAD_UART1_RXD__UART5_DTE_TX                        0x0194 0x045C 0x0000 0x4 0x0
+#define MX6SLL_PAD_UART1_RXD__GPIO3_IO16                          0x0194 0x045C 0x0000 0x5 0x0
+#define MX6SLL_PAD_UART1_TXD__UART1_DCE_TX                        0x0198 0x0460 0x0000 0x0 0x0
+#define MX6SLL_PAD_UART1_TXD__UART1_DTE_RX                        0x0198 0x0460 0x0744 0x0 0x1
+#define MX6SLL_PAD_UART1_TXD__PWM2_OUT                            0x0198 0x0460 0x0000 0x1 0x0
+#define MX6SLL_PAD_UART1_TXD__UART4_DCE_TX                        0x0198 0x0460 0x0000 0x2 0x0
+#define MX6SLL_PAD_UART1_TXD__UART4_DTE_RX                        0x0198 0x0460 0x075C 0x2 0x5
+#define MX6SLL_PAD_UART1_TXD__UART5_DCE_TX                        0x0198 0x0460 0x0000 0x4 0x0
+#define MX6SLL_PAD_UART1_TXD__UART5_DTE_RX                        0x0198 0x0460 0x0764 0x4 0x7
+#define MX6SLL_PAD_UART1_TXD__GPIO3_IO17                          0x0198 0x0460 0x0000 0x5 0x0
+#define MX6SLL_PAD_UART1_TXD__UART5_DCD_B                         0x0198 0x0460 0x0000 0x7 0x0
+#define MX6SLL_PAD_I2C1_SCL__I2C1_SCL                             0x019C 0x0464 0x067C 0x0 0x0
+#define MX6SLL_PAD_I2C1_SCL__UART1_DCE_RTS                        0x019C 0x0464 0x0740 0x1 0x0
+#define MX6SLL_PAD_I2C1_SCL__UART1_DTE_CTS                        0x019C 0x0464 0x0000 0x1 0x0
+#define MX6SLL_PAD_I2C1_SCL__ECSPI3_SS2                           0x019C 0x0464 0x0640 0x2 0x0
+#define MX6SLL_PAD_I2C1_SCL__SD3_RESET                            0x019C 0x0464 0x0000 0x4 0x0
+#define MX6SLL_PAD_I2C1_SCL__GPIO3_IO12                           0x019C 0x0464 0x0000 0x5 0x0
+#define MX6SLL_PAD_I2C1_SCL__ECSPI1_SS1                           0x019C 0x0464 0x060C 0x6 0x0
+#define MX6SLL_PAD_I2C1_SDA__I2C1_SDA                             0x01A0 0x0468 0x0680 0x0 0x0
+#define MX6SLL_PAD_I2C1_SDA__UART1_DCE_CTS                        0x01A0 0x0468 0x0000 0x1 0x0
+#define MX6SLL_PAD_I2C1_SDA__UART1_DTE_RTS                        0x01A0 0x0468 0x0740 0x1 0x1
+#define MX6SLL_PAD_I2C1_SDA__ECSPI3_SS3                           0x01A0 0x0468 0x0644 0x2 0x0
+#define MX6SLL_PAD_I2C1_SDA__SD3_VSELECT                          0x01A0 0x0468 0x0000 0x4 0x0
+#define MX6SLL_PAD_I2C1_SDA__GPIO3_IO13                           0x01A0 0x0468 0x0000 0x5 0x0
+#define MX6SLL_PAD_I2C1_SDA__ECSPI1_SS2                           0x01A0 0x0468 0x0610 0x6 0x0
+#define MX6SLL_PAD_I2C2_SCL__I2C2_SCL                             0x01A4 0x046C 0x0684 0x0 0x3
+#define MX6SLL_PAD_I2C2_SCL__AUD4_RXFS                            0x01A4 0x046C 0x0570 0x1 0x2
+#define MX6SLL_PAD_I2C2_SCL__SPDIF_IN                             0x01A4 0x046C 0x0738 0x2 0x2
+#define MX6SLL_PAD_I2C2_SCL__SD3_WP                               0x01A4 0x046C 0x0794 0x4 0x3
+#define MX6SLL_PAD_I2C2_SCL__GPIO3_IO14                           0x01A4 0x046C 0x0000 0x5 0x0
+#define MX6SLL_PAD_I2C2_SCL__ECSPI1_RDY                           0x01A4 0x046C 0x0600 0x6 0x1
+#define MX6SLL_PAD_I2C2_SDA__I2C2_SDA                             0x01A8 0x0470 0x0688 0x0 0x3
+#define MX6SLL_PAD_I2C2_SDA__AUD4_RXC                             0x01A8 0x0470 0x056C 0x1 0x2
+#define MX6SLL_PAD_I2C2_SDA__SPDIF_OUT                            0x01A8 0x0470 0x0000 0x2 0x0
+#define MX6SLL_PAD_I2C2_SDA__SD3_CD_B                             0x01A8 0x0470 0x0780 0x4 0x3
+#define MX6SLL_PAD_I2C2_SDA__GPIO3_IO15                           0x01A8 0x0470 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI1_SCLK__ECSPI1_SCLK                       0x01AC 0x0474 0x05FC 0x0 0x1
+#define MX6SLL_PAD_ECSPI1_SCLK__AUD4_TXD                          0x01AC 0x0474 0x0568 0x1 0x1
+#define MX6SLL_PAD_ECSPI1_SCLK__UART5_DCE_RX                      0x01AC 0x0474 0x0764 0x2 0x2
+#define MX6SLL_PAD_ECSPI1_SCLK__UART5_DTE_TX                      0x01AC 0x0474 0x0000 0x2 0x0
+#define MX6SLL_PAD_ECSPI1_SCLK__EPDC_VCOM0                        0x01AC 0x0474 0x0000 0x3 0x0
+#define MX6SLL_PAD_ECSPI1_SCLK__SD2_RESET                         0x01AC 0x0474 0x0000 0x4 0x0
+#define MX6SLL_PAD_ECSPI1_SCLK__GPIO4_IO08                        0x01AC 0x0474 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI1_SCLK__USB_OTG2_OC                       0x01AC 0x0474 0x0768 0x6 0x1
+#define MX6SLL_PAD_ECSPI1_MOSI__ECSPI1_MOSI                       0x01B0 0x0478 0x0608 0x0 0x1
+#define MX6SLL_PAD_ECSPI1_MOSI__AUD4_TXC                          0x01B0 0x0478 0x0574 0x1 0x1
+#define MX6SLL_PAD_ECSPI1_MOSI__UART5_DCE_TX                      0x01B0 0x0478 0x0000 0x2 0x0
+#define MX6SLL_PAD_ECSPI1_MOSI__UART5_DTE_RX                      0x01B0 0x0478 0x0764 0x2 0x3
+#define MX6SLL_PAD_ECSPI1_MOSI__EPDC_VCOM1                        0x01B0 0x0478 0x0000 0x3 0x0
+#define MX6SLL_PAD_ECSPI1_MOSI__SD2_VSELECT                       0x01B0 0x0478 0x0000 0x4 0x0
+#define MX6SLL_PAD_ECSPI1_MOSI__GPIO4_IO09                        0x01B0 0x0478 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI1_MISO__ECSPI1_MISO                       0x01B4 0x047C 0x0604 0x0 0x1
+#define MX6SLL_PAD_ECSPI1_MISO__AUD4_TXFS                         0x01B4 0x047C 0x0578 0x1 0x1
+#define MX6SLL_PAD_ECSPI1_MISO__UART5_DCE_RTS                     0x01B4 0x047C 0x0760 0x2 0x2
+#define MX6SLL_PAD_ECSPI1_MISO__UART5_DTE_CTS                     0x01B4 0x047C 0x0000 0x2 0x0
+#define MX6SLL_PAD_ECSPI1_MISO__EPDC_BDR0                         0x01B4 0x047C 0x0000 0x3 0x0
+#define MX6SLL_PAD_ECSPI1_MISO__SD2_WP                            0x01B4 0x047C 0x077C 0x4 0x0
+#define MX6SLL_PAD_ECSPI1_MISO__GPIO4_IO10                        0x01B4 0x047C 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI1_SS0__ECSPI1_SS0                         0x01B8 0x0480 0x0614 0x0 0x1
+#define MX6SLL_PAD_ECSPI1_SS0__AUD4_RXD                           0x01B8 0x0480 0x0564 0x1 0x1
+#define MX6SLL_PAD_ECSPI1_SS0__UART5_DCE_CTS                      0x01B8 0x0480 0x0000 0x2 0x0
+#define MX6SLL_PAD_ECSPI1_SS0__UART5_DTE_RTS                      0x01B8 0x0480 0x0760 0x2 0x3
+#define MX6SLL_PAD_ECSPI1_SS0__EPDC_BDR1                          0x01B8 0x0480 0x0000 0x3 0x0
+#define MX6SLL_PAD_ECSPI1_SS0__SD2_CD_B                           0x01B8 0x0480 0x0778 0x4 0x0
+#define MX6SLL_PAD_ECSPI1_SS0__GPIO4_IO11                         0x01B8 0x0480 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI1_SS0__USB_OTG2_PWR                       0x01B8 0x0480 0x0000 0x6 0x0
+#define MX6SLL_PAD_ECSPI2_SCLK__ECSPI2_SCLK                       0x01BC 0x0484 0x061C 0x0 0x1
+#define MX6SLL_PAD_ECSPI2_SCLK__SPDIF_EXT_CLK                     0x01BC 0x0484 0x073C 0x1 0x2
+#define MX6SLL_PAD_ECSPI2_SCLK__UART3_DCE_RX                      0x01BC 0x0484 0x0754 0x2 0x2
+#define MX6SLL_PAD_ECSPI2_SCLK__UART3_DTE_TX                      0x01BC 0x0484 0x0000 0x2 0x0
+#define MX6SLL_PAD_ECSPI2_SCLK__CSI_PIXCLK                        0x01BC 0x0484 0x05F4 0x3 0x1
+#define MX6SLL_PAD_ECSPI2_SCLK__SD1_RESET                         0x01BC 0x0484 0x0000 0x4 0x0
+#define MX6SLL_PAD_ECSPI2_SCLK__GPIO4_IO12                        0x01BC 0x0484 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI2_SCLK__USB_OTG2_OC                       0x01BC 0x0484 0x0768 0x6 0x2
+#define MX6SLL_PAD_ECSPI2_MOSI__ECSPI2_MOSI                       0x01C0 0x0488 0x0624 0x0 0x1
+#define MX6SLL_PAD_ECSPI2_MOSI__SDMA_EXT_EVENT1                   0x01C0 0x0488 0x0000 0x1 0x0
+#define MX6SLL_PAD_ECSPI2_MOSI__UART3_DCE_TX                      0x01C0 0x0488 0x0000 0x2 0x0
+#define MX6SLL_PAD_ECSPI2_MOSI__UART3_DTE_RX                      0x01C0 0x0488 0x0754 0x2 0x3
+#define MX6SLL_PAD_ECSPI2_MOSI__CSI_HSYNC                         0x01C0 0x0488 0x05F0 0x3 0x1
+#define MX6SLL_PAD_ECSPI2_MOSI__SD1_VSELECT                       0x01C0 0x0488 0x0000 0x4 0x0
+#define MX6SLL_PAD_ECSPI2_MOSI__GPIO4_IO13                        0x01C0 0x0488 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI2_MISO__ECSPI2_MISO                       0x01C4 0x048C 0x0620 0x0 0x1
+#define MX6SLL_PAD_ECSPI2_MISO__SDMA_EXT_EVENT0                   0x01C4 0x048C 0x0000 0x1 0x0
+#define MX6SLL_PAD_ECSPI2_MISO__UART3_DCE_RTS                     0x01C4 0x048C 0x0750 0x2 0x0
+#define MX6SLL_PAD_ECSPI2_MISO__UART3_DTE_CTS                     0x01C4 0x048C 0x0000 0x2 0x0
+#define MX6SLL_PAD_ECSPI2_MISO__CSI_MCLK                          0x01C4 0x048C 0x0000 0x3 0x0
+#define MX6SLL_PAD_ECSPI2_MISO__SD1_WP                            0x01C4 0x048C 0x0774 0x4 0x2
+#define MX6SLL_PAD_ECSPI2_MISO__GPIO4_IO14                        0x01C4 0x048C 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI2_MISO__USB_OTG1_OC                       0x01C4 0x048C 0x076C 0x6 0x1
+#define MX6SLL_PAD_ECSPI2_SS0__ECSPI2_SS0                         0x01C8 0x0490 0x0628 0x0 0x0
+#define MX6SLL_PAD_ECSPI2_SS0__ECSPI1_SS3                         0x01C8 0x0490 0x0618 0x1 0x1
+#define MX6SLL_PAD_ECSPI2_SS0__UART3_DCE_CTS                      0x01C8 0x0490 0x0000 0x2 0x0
+#define MX6SLL_PAD_ECSPI2_SS0__UART3_DTE_RTS                      0x01C8 0x0490 0x0750 0x2 0x1
+#define MX6SLL_PAD_ECSPI2_SS0__CSI_VSYNC                          0x01C8 0x0490 0x05F8 0x3 0x1
+#define MX6SLL_PAD_ECSPI2_SS0__SD1_CD_B                           0x01C8 0x0490 0x0770 0x4 0x2
+#define MX6SLL_PAD_ECSPI2_SS0__GPIO4_IO15                         0x01C8 0x0490 0x0000 0x5 0x0
+#define MX6SLL_PAD_ECSPI2_SS0__USB_OTG1_PWR                       0x01C8 0x0490 0x0000 0x6 0x0
+#define MX6SLL_PAD_SD1_CLK__SD1_CLK                               0x01CC 0x0494 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_CLK__KEY_COL0                              0x01CC 0x0494 0x06A0 0x2 0x2
+#define MX6SLL_PAD_SD1_CLK__EPDC_SDCE4                            0x01CC 0x0494 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_CLK__GPIO5_IO15                            0x01CC 0x0494 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_CMD__SD1_CMD                               0x01D0 0x0498 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_CMD__KEY_ROW0                              0x01D0 0x0498 0x06C0 0x2 0x2
+#define MX6SLL_PAD_SD1_CMD__EPDC_SDCE5                            0x01D0 0x0498 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_CMD__GPIO5_IO14                            0x01D0 0x0498 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_DATA0__SD1_DATA0                           0x01D4 0x049C 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_DATA0__KEY_COL1                            0x01D4 0x049C 0x06A4 0x2 0x2
+#define MX6SLL_PAD_SD1_DATA0__EPDC_SDCE6                          0x01D4 0x049C 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_DATA0__GPIO5_IO11                          0x01D4 0x049C 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_DATA1__SD1_DATA1                           0x01D8 0x04A0 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_DATA1__KEY_ROW1                            0x01D8 0x04A0 0x06C4 0x2 0x2
+#define MX6SLL_PAD_SD1_DATA1__EPDC_SDCE7                          0x01D8 0x04A0 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_DATA1__GPIO5_IO08                          0x01D8 0x04A0 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_DATA2__SD1_DATA2                           0x01DC 0x04A4 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_DATA2__KEY_COL2                            0x01DC 0x04A4 0x06A8 0x2 0x2
+#define MX6SLL_PAD_SD1_DATA2__EPDC_SDCE8                          0x01DC 0x04A4 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_DATA2__GPIO5_IO13                          0x01DC 0x04A4 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_DATA3__SD1_DATA3                           0x01E0 0x04A8 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_DATA3__KEY_ROW2                            0x01E0 0x04A8 0x06C8 0x2 0x2
+#define MX6SLL_PAD_SD1_DATA3__EPDC_SDCE9                          0x01E0 0x04A8 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_DATA3__GPIO5_IO06                          0x01E0 0x04A8 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_DATA4__SD1_DATA4                           0x01E4 0x04AC 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_DATA4__KEY_COL3                            0x01E4 0x04AC 0x06AC 0x2 0x2
+#define MX6SLL_PAD_SD1_DATA4__EPDC_SDCLK_N                        0x01E4 0x04AC 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_DATA4__UART4_DCE_RX                        0x01E4 0x04AC 0x075C 0x4 0x6
+#define MX6SLL_PAD_SD1_DATA4__UART4_DTE_TX                        0x01E4 0x04AC 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD1_DATA4__GPIO5_IO12                          0x01E4 0x04AC 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_DATA5__SD1_DATA5                           0x01E8 0x04B0 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_DATA5__KEY_ROW3                            0x01E8 0x04B0 0x06CC 0x2 0x2
+#define MX6SLL_PAD_SD1_DATA5__EPDC_SDOED                          0x01E8 0x04B0 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_DATA5__UART4_DCE_TX                        0x01E8 0x04B0 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD1_DATA5__UART4_DTE_RX                        0x01E8 0x04B0 0x075C 0x4 0x7
+#define MX6SLL_PAD_SD1_DATA5__GPIO5_IO09                          0x01E8 0x04B0 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_DATA6__SD1_DATA6                           0x01EC 0x04B4 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_DATA6__KEY_COL4                            0x01EC 0x04B4 0x06B0 0x2 0x2
+#define MX6SLL_PAD_SD1_DATA6__EPDC_SDOEZ                          0x01EC 0x04B4 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD1_DATA6__UART4_DCE_RTS                       0x01EC 0x04B4 0x0758 0x4 0x4
+#define MX6SLL_PAD_SD1_DATA6__UART4_DTE_CTS                       0x01EC 0x04B4 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD1_DATA6__GPIO5_IO07                          0x01EC 0x04B4 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD1_DATA7__SD1_DATA7                           0x01F0 0x04B8 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD1_DATA7__KEY_ROW4                            0x01F0 0x04B8 0x06D0 0x2 0x2
+#define MX6SLL_PAD_SD1_DATA7__CCM_PMIC_READY                      0x01F0 0x04B8 0x05AC 0x3 0x3
+#define MX6SLL_PAD_SD1_DATA7__UART4_DCE_CTS                       0x01F0 0x04B8 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD1_DATA7__UART4_DTE_RTS                       0x01F0 0x04B8 0x0758 0x4 0x5
+#define MX6SLL_PAD_SD1_DATA7__GPIO5_IO10                          0x01F0 0x04B8 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_RESET__SD2_RESET                           0x01F4 0x04BC 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_RESET__WDOG2_B                             0x01F4 0x04BC 0x0000 0x2 0x0
+#define MX6SLL_PAD_SD2_RESET__SPDIF_OUT                           0x01F4 0x04BC 0x0000 0x3 0x0
+#define MX6SLL_PAD_SD2_RESET__CSI_MCLK                            0x01F4 0x04BC 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD2_RESET__GPIO4_IO27                          0x01F4 0x04BC 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_CLK__SD2_CLK                               0x01F8 0x04C0 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_CLK__AUD4_RXFS                             0x01F8 0x04C0 0x0570 0x1 0x1
+#define MX6SLL_PAD_SD2_CLK__ECSPI3_SCLK                           0x01F8 0x04C0 0x0630 0x2 0x1
+#define MX6SLL_PAD_SD2_CLK__CSI_DATA00                            0x01F8 0x04C0 0x05C8 0x3 0x1
+#define MX6SLL_PAD_SD2_CLK__GPIO5_IO05                            0x01F8 0x04C0 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_CMD__SD2_CMD                               0x01FC 0x04C4 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_CMD__AUD4_RXC                              0x01FC 0x04C4 0x056C 0x1 0x1
+#define MX6SLL_PAD_SD2_CMD__ECSPI3_SS0                            0x01FC 0x04C4 0x0648 0x2 0x1
+#define MX6SLL_PAD_SD2_CMD__CSI_DATA01                            0x01FC 0x04C4 0x05CC 0x3 0x1
+#define MX6SLL_PAD_SD2_CMD__EPIT1_OUT                             0x01FC 0x04C4 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD2_CMD__GPIO5_IO04                            0x01FC 0x04C4 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_DATA0__SD2_DATA0                           0x0200 0x04C8 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_DATA0__AUD4_RXD                            0x0200 0x04C8 0x0564 0x1 0x2
+#define MX6SLL_PAD_SD2_DATA0__ECSPI3_MOSI                         0x0200 0x04C8 0x063C 0x2 0x1
+#define MX6SLL_PAD_SD2_DATA0__CSI_DATA02                          0x0200 0x04C8 0x05D0 0x3 0x1
+#define MX6SLL_PAD_SD2_DATA0__UART5_DCE_RTS                       0x0200 0x04C8 0x0760 0x4 0x4
+#define MX6SLL_PAD_SD2_DATA0__UART5_DTE_CTS                       0x0200 0x04C8 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD2_DATA0__GPIO5_IO01                          0x0200 0x04C8 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_DATA1__SD2_DATA1                           0x0204 0x04CC 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_DATA1__AUD4_TXC                            0x0204 0x04CC 0x0574 0x1 0x2
+#define MX6SLL_PAD_SD2_DATA1__ECSPI3_MISO                         0x0204 0x04CC 0x0638 0x2 0x1
+#define MX6SLL_PAD_SD2_DATA1__CSI_DATA03                          0x0204 0x04CC 0x05D4 0x3 0x1
+#define MX6SLL_PAD_SD2_DATA1__UART5_DCE_CTS                       0x0204 0x04CC 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD2_DATA1__UART5_DTE_RTS                       0x0204 0x04CC 0x0760 0x4 0x5
+#define MX6SLL_PAD_SD2_DATA1__GPIO4_IO30                          0x0204 0x04CC 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_DATA2__SD2_DATA2                           0x0208 0x04D0 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_DATA2__AUD4_TXFS                           0x0208 0x04D0 0x0578 0x1 0x2
+#define MX6SLL_PAD_SD2_DATA2__CSI_DATA04                          0x0208 0x04D0 0x05D8 0x3 0x1
+#define MX6SLL_PAD_SD2_DATA2__UART5_DCE_RX                        0x0208 0x04D0 0x0764 0x4 0x4
+#define MX6SLL_PAD_SD2_DATA2__UART5_DTE_TX                        0x0208 0x04D0 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD2_DATA2__GPIO5_IO03                          0x0208 0x04D0 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_DATA3__SD2_DATA3                           0x020C 0x04D4 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_DATA3__AUD4_TXD                            0x020C 0x04D4 0x0568 0x1 0x2
+#define MX6SLL_PAD_SD2_DATA3__CSI_DATA05                          0x020C 0x04D4 0x05DC 0x3 0x1
+#define MX6SLL_PAD_SD2_DATA3__UART5_DCE_TX                        0x020C 0x04D4 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD2_DATA3__UART5_DTE_RX                        0x020C 0x04D4 0x0764 0x4 0x5
+#define MX6SLL_PAD_SD2_DATA3__GPIO4_IO28                          0x020C 0x04D4 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_DATA4__SD2_DATA4                           0x0210 0x04D8 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_DATA4__SD3_DATA4                           0x0210 0x04D8 0x0784 0x1 0x1
+#define MX6SLL_PAD_SD2_DATA4__UART2_DCE_RX                        0x0210 0x04D8 0x074C 0x2 0x2
+#define MX6SLL_PAD_SD2_DATA4__UART2_DTE_TX                        0x0210 0x04D8 0x0000 0x2 0x0
+#define MX6SLL_PAD_SD2_DATA4__CSI_DATA06                          0x0210 0x04D8 0x05E0 0x3 0x1
+#define MX6SLL_PAD_SD2_DATA4__SPDIF_OUT                           0x0210 0x04D8 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD2_DATA4__GPIO5_IO02                          0x0210 0x04D8 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_DATA5__SD2_DATA5                           0x0214 0x04DC 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_DATA5__SD3_DATA5                           0x0214 0x04DC 0x0788 0x1 0x1
+#define MX6SLL_PAD_SD2_DATA5__UART2_DCE_TX                        0x0214 0x04DC 0x0000 0x2 0x0
+#define MX6SLL_PAD_SD2_DATA5__UART2_DTE_RX                        0x0214 0x04DC 0x074C 0x2 0x3
+#define MX6SLL_PAD_SD2_DATA5__CSI_DATA07                          0x0214 0x04DC 0x05E4 0x3 0x1
+#define MX6SLL_PAD_SD2_DATA5__SPDIF_IN                            0x0214 0x04DC 0x0738 0x4 0x1
+#define MX6SLL_PAD_SD2_DATA5__GPIO4_IO31                          0x0214 0x04DC 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_DATA6__SD2_DATA6                           0x0218 0x04E0 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_DATA6__SD3_DATA6                           0x0218 0x04E0 0x078C 0x1 0x1
+#define MX6SLL_PAD_SD2_DATA6__UART2_DCE_RTS                       0x0218 0x04E0 0x0748 0x2 0x2
+#define MX6SLL_PAD_SD2_DATA6__UART2_DTE_CTS                       0x0218 0x04E0 0x0000 0x2 0x0
+#define MX6SLL_PAD_SD2_DATA6__CSI_DATA08                          0x0218 0x04E0 0x05E8 0x3 0x1
+#define MX6SLL_PAD_SD2_DATA6__SD2_WP                              0x0218 0x04E0 0x077C 0x4 0x1
+#define MX6SLL_PAD_SD2_DATA6__GPIO4_IO29                          0x0218 0x04E0 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD2_DATA7__SD2_DATA7                           0x021C 0x04E4 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD2_DATA7__SD3_DATA7                           0x021C 0x04E4 0x0790 0x1 0x1
+#define MX6SLL_PAD_SD2_DATA7__UART2_DCE_CTS                       0x021C 0x04E4 0x0000 0x2 0x0
+#define MX6SLL_PAD_SD2_DATA7__UART2_DTE_RTS                       0x021C 0x04E4 0x0748 0x2 0x3
+#define MX6SLL_PAD_SD2_DATA7__CSI_DATA09                          0x021C 0x04E4 0x05EC 0x3 0x1
+#define MX6SLL_PAD_SD2_DATA7__SD2_CD_B                            0x021C 0x04E4 0x0778 0x4 0x1
+#define MX6SLL_PAD_SD2_DATA7__GPIO5_IO00                          0x021C 0x04E4 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD3_CLK__SD3_CLK                               0x0220 0x04E8 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD3_CLK__AUD5_RXFS                             0x0220 0x04E8 0x0588 0x1 0x0
+#define MX6SLL_PAD_SD3_CLK__KEY_COL5                              0x0220 0x04E8 0x0694 0x2 0x0
+#define MX6SLL_PAD_SD3_CLK__CSI_DATA10                            0x0220 0x04E8 0x05B0 0x3 0x0
+#define MX6SLL_PAD_SD3_CLK__WDOG1_RESET_B_DEB                     0x0220 0x04E8 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD3_CLK__GPIO5_IO18                            0x0220 0x04E8 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD3_CLK__USB_OTG1_PWR                          0x0220 0x04E8 0x0000 0x6 0x0
+#define MX6SLL_PAD_SD3_CMD__SD3_CMD                               0x0224 0x04EC 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD3_CMD__AUD5_RXC                              0x0224 0x04EC 0x0584 0x1 0x0
+#define MX6SLL_PAD_SD3_CMD__KEY_ROW5                              0x0224 0x04EC 0x06B4 0x2 0x0
+#define MX6SLL_PAD_SD3_CMD__CSI_DATA11                            0x0224 0x04EC 0x05B4 0x3 0x0
+#define MX6SLL_PAD_SD3_CMD__USB_OTG2_ID                           0x0224 0x04EC 0x0560 0x4 0x1
+#define MX6SLL_PAD_SD3_CMD__GPIO5_IO21                            0x0224 0x04EC 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD3_CMD__USB_OTG2_PWR                          0x0224 0x04EC 0x0000 0x6 0x0
+#define MX6SLL_PAD_SD3_DATA0__SD3_DATA0                           0x0228 0x04F0 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD3_DATA0__AUD5_RXD                            0x0228 0x04F0 0x057C 0x1 0x0
+#define MX6SLL_PAD_SD3_DATA0__KEY_COL6                            0x0228 0x04F0 0x0698 0x2 0x0
+#define MX6SLL_PAD_SD3_DATA0__CSI_DATA12                          0x0228 0x04F0 0x05B8 0x3 0x0
+#define MX6SLL_PAD_SD3_DATA0__USB_OTG1_ID                         0x0228 0x04F0 0x055C 0x4 0x1
+#define MX6SLL_PAD_SD3_DATA0__GPIO5_IO19                          0x0228 0x04F0 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD3_DATA1__SD3_DATA1                           0x022C 0x04F4 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD3_DATA1__AUD5_TXC                            0x022C 0x04F4 0x058C 0x1 0x0
+#define MX6SLL_PAD_SD3_DATA1__KEY_ROW6                            0x022C 0x04F4 0x06B8 0x2 0x0
+#define MX6SLL_PAD_SD3_DATA1__CSI_DATA13                          0x022C 0x04F4 0x05BC 0x3 0x0
+#define MX6SLL_PAD_SD3_DATA1__SD1_VSELECT                         0x022C 0x04F4 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD3_DATA1__GPIO5_IO20                          0x022C 0x04F4 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD3_DATA1__JTAG_DE_B                           0x022C 0x04F4 0x0000 0x6 0x0
+#define MX6SLL_PAD_SD3_DATA2__SD3_DATA2                           0x0230 0x04F8 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD3_DATA2__AUD5_TXFS                           0x0230 0x04F8 0x0590 0x1 0x0
+#define MX6SLL_PAD_SD3_DATA2__KEY_COL7                            0x0230 0x04F8 0x069C 0x2 0x0
+#define MX6SLL_PAD_SD3_DATA2__CSI_DATA14                          0x0230 0x04F8 0x05C0 0x3 0x0
+#define MX6SLL_PAD_SD3_DATA2__EPIT1_OUT                           0x0230 0x04F8 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD3_DATA2__GPIO5_IO16                          0x0230 0x04F8 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD3_DATA2__USB_OTG2_OC                         0x0230 0x04F8 0x0768 0x6 0x0
+#define MX6SLL_PAD_SD3_DATA3__SD3_DATA3                           0x0234 0x04FC 0x0000 0x0 0x0
+#define MX6SLL_PAD_SD3_DATA3__AUD5_TXD                            0x0234 0x04FC 0x0580 0x1 0x0
+#define MX6SLL_PAD_SD3_DATA3__KEY_ROW7                            0x0234 0x04FC 0x06BC 0x2 0x0
+#define MX6SLL_PAD_SD3_DATA3__CSI_DATA15                          0x0234 0x04FC 0x05C4 0x3 0x0
+#define MX6SLL_PAD_SD3_DATA3__EPIT2_OUT                           0x0234 0x04FC 0x0000 0x4 0x0
+#define MX6SLL_PAD_SD3_DATA3__GPIO5_IO17                          0x0234 0x04FC 0x0000 0x5 0x0
+#define MX6SLL_PAD_SD3_DATA3__USB_OTG1_OC                         0x0234 0x04FC 0x076C 0x6 0x0
+#define MX6SLL_PAD_GPIO4_IO20__SD1_STROBE                         0x0238 0x0500 0x0000 0x0 0x0
+#define MX6SLL_PAD_GPIO4_IO20__AUD6_RXFS                          0x0238 0x0500 0x05A0 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO20__ECSPI4_SS0                         0x0238 0x0500 0x065C 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO20__GPT_CAPTURE1                       0x0238 0x0500 0x0670 0x4 0x0
+#define MX6SLL_PAD_GPIO4_IO20__GPIO4_IO20                         0x0238 0x0500 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO21__SD2_STROBE                         0x023C 0x0504 0x0000 0x0 0x0
+#define MX6SLL_PAD_GPIO4_IO21__AUD6_RXC                           0x023C 0x0504 0x059C 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO21__ECSPI4_SCLK                        0x023C 0x0504 0x0650 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO21__GPT_CAPTURE2                       0x023C 0x0504 0x0674 0x4 0x0
+#define MX6SLL_PAD_GPIO4_IO21__GPIO4_IO21                         0x023C 0x0504 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO19__SD3_STROBE                         0x0240 0x0508 0x0000 0x0 0x0
+#define MX6SLL_PAD_GPIO4_IO19__AUD6_RXD                           0x0240 0x0508 0x0594 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO19__ECSPI4_MOSI                        0x0240 0x0508 0x0658 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO19__GPT_COMPARE1                       0x0240 0x0508 0x0000 0x4 0x0
+#define MX6SLL_PAD_GPIO4_IO19__GPIO4_IO19                         0x0240 0x0508 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO25__AUD6_TXC                           0x0244 0x050C 0x05A4 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO25__ECSPI4_MISO                        0x0244 0x050C 0x0654 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO25__GPT_COMPARE2                       0x0244 0x050C 0x0000 0x4 0x0
+#define MX6SLL_PAD_GPIO4_IO25__GPIO4_IO25                         0x0244 0x050C 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO18__AUD6_TXFS                          0x0248 0x0510 0x05A8 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO18__ECSPI4_SS1                         0x0248 0x0510 0x0660 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO18__GPT_COMPARE3                       0x0248 0x0510 0x0000 0x4 0x0
+#define MX6SLL_PAD_GPIO4_IO18__GPIO4_IO18                         0x0248 0x0510 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO24__AUD6_TXD                           0x024C 0x0514 0x0598 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO24__ECSPI4_SS2                         0x024C 0x0514 0x0664 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO24__GPT_CLKIN                          0x024C 0x0514 0x0678 0x4 0x0
+#define MX6SLL_PAD_GPIO4_IO24__GPIO4_IO24                         0x024C 0x0514 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO23__AUDIO_CLK_OUT                      0x0250 0x0518 0x0000 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO23__SD1_RESET                          0x0250 0x0518 0x0000 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO23__SD3_RESET                          0x0250 0x0518 0x0000 0x4 0x0
+#define MX6SLL_PAD_GPIO4_IO23__GPIO4_IO23                         0x0250 0x0518 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO17__USB_OTG1_ID                        0x0254 0x051C 0x055C 0x2 0x2
+#define MX6SLL_PAD_GPIO4_IO17__SD1_VSELECT                        0x0254 0x051C 0x0000 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO17__SD3_VSELECT                        0x0254 0x051C 0x0000 0x4 0x0
+#define MX6SLL_PAD_GPIO4_IO17__GPIO4_IO17                         0x0254 0x051C 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO22__SPDIF_IN                           0x0258 0x0520 0x0738 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO22__SD1_WP                             0x0258 0x0520 0x0774 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO22__SD3_WP                             0x0258 0x0520 0x0794 0x4 0x1
+#define MX6SLL_PAD_GPIO4_IO22__GPIO4_IO22                         0x0258 0x0520 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO16__SPDIF_OUT                          0x025C 0x0524 0x0000 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO16__SD1_CD_B                           0x025C 0x0524 0x0770 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO16__SD3_CD_B                           0x025C 0x0524 0x0780 0x4 0x1
+#define MX6SLL_PAD_GPIO4_IO16__GPIO4_IO16                         0x025C 0x0524 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO26__WDOG1_B                            0x0260 0x0528 0x0000 0x2 0x0
+#define MX6SLL_PAD_GPIO4_IO26__PWM4_OUT                           0x0260 0x0528 0x0000 0x3 0x0
+#define MX6SLL_PAD_GPIO4_IO26__CCM_PMIC_READY                     0x0260 0x0528 0x05AC 0x4 0x1
+#define MX6SLL_PAD_GPIO4_IO26__GPIO4_IO26                         0x0260 0x0528 0x0000 0x5 0x0
+#define MX6SLL_PAD_GPIO4_IO26__SPDIF_EXT_CLK                      0x0260 0x0528 0x073C 0x6 0x0
+
+#endif /* __DTS_IMX6SLL_PINFUNC_H */
diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi
new file mode 100644 (file)
index 0000000..000e613
--- /dev/null
@@ -0,0 +1,780 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP.
+ *
+ */
+
+#include <dt-bindings/clock/imx6sll-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "imx6sll-pinfunc.h"
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       aliases {
+               gpio0 = &gpio1;
+               gpio1 = &gpio2;
+               gpio2 = &gpio3;
+               gpio3 = &gpio4;
+               gpio4 = &gpio5;
+               gpio5 = &gpio6;
+               i2c0 = &i2c1;
+               i2c1 = &i2c2;
+               i2c2 = &i2c3;
+               mmc0 = &usdhc1;
+               mmc1 = &usdhc2;
+               mmc2 = &usdhc3;
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+               serial3 = &uart4;
+               serial4 = &uart5;
+               spi0 = &ecspi1;
+               spi1 = &ecspi2;
+               spi3 = &ecspi3;
+               spi4 = &ecspi4;
+               usbphy0 = &usbphy1;
+               usbphy1 = &usbphy2;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       compatible = "arm,cortex-a9";
+                       device_type = "cpu";
+                       reg = <0>;
+                       next-level-cache = <&L2>;
+                       operating-points = <
+                               /* kHz    uV */
+                               996000  1275000
+                               792000  1175000
+                               396000  1075000
+                               198000  975000
+                       >;
+                       fsl,soc-operating-points = <
+                               /* ARM kHz      SOC-PU uV */
+                               996000          1175000
+                               792000          1175000
+                               396000          1175000
+                               198000          1175000
+                       >;
+                       clock-latency = <61036>; /* two CLK32 periods */
+                       clocks = <&clks IMX6SLL_CLK_ARM>,
+                                <&clks IMX6SLL_CLK_PLL2_PFD2>,
+                                <&clks IMX6SLL_CLK_STEP>,
+                                <&clks IMX6SLL_CLK_PLL1_SW>,
+                                <&clks IMX6SLL_CLK_PLL1_SYS>;
+                       clock-names = "arm", "pll2_pfd2_396m", "step",
+                                     "pll1_sw", "pll1_sys";
+               };
+       };
+
+       intc: interrupt-controller@a01000 {
+               compatible = "arm,cortex-a9-gic";
+               #interrupt-cells = <3>;
+               interrupt-controller;
+               reg = <0x00a01000 0x1000>,
+                     <0x00a00100 0x100>;
+               interrupt-parent = <&intc>;
+       };
+
+       ckil: clock-ckil {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+               clock-output-names = "ckil";
+       };
+
+       osc: clock-osc-24m {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <24000000>;
+               clock-output-names = "osc";
+       };
+
+       ipp_di0: clock-ipp-di0 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+               clock-output-names = "ipp_di0";
+       };
+
+       ipp_di1: clock-ipp-di1 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+               clock-output-names = "ipp_di1";
+       };
+
+       tempmon: temperature-sensor {
+               compatible = "fsl,imx6sll-tempmon", "fsl,imx6sx-tempmon";
+               interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-parent = <&gpc>;
+               fsl,tempmon = <&anatop>;
+               nvmem-cells = <&tempmon_calib>, <&tempmon_temp_grade>;
+               nvmem-cell-names = "calib", "temp_grade";
+               clocks = <&clks IMX6SLL_CLK_PLL3_USB_OTG>;
+       };
+
+       soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               interrupt-parent = <&gpc>;
+               ranges;
+
+               ocram: sram@900000 {
+                       compatible = "mmio-sram";
+                       reg = <0x00900000 0x20000>;
+               };
+
+               L2: l2-cache@a02000 {
+                       compatible = "arm,pl310-cache";
+                       reg = <0x00a02000 0x1000>;
+                       interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+                       cache-unified;
+                       cache-level = <2>;
+                       arm,tag-latency = <4 2 3>;
+                       arm,data-latency = <4 2 3>;
+               };
+
+               aips1: aips-bus@2000000 {
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x02000000 0x100000>;
+                       ranges;
+
+                       spba: spba-bus@2000000 {
+                               compatible = "fsl,spba-bus", "simple-bus";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0x02000000 0x40000>;
+                               ranges;
+
+                               spdif: spdif@2004000 {
+                                       compatible = "fsl,imx6sl-spdif", "fsl,imx35-spdif";
+                                       reg = <0x02004000 0x4000>;
+                                       interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&sdma 14 18 0>, <&sdma 15 18 0>;
+                                       dma-names = "rx", "tx";
+                                       clocks = <&clks IMX6SLL_CLK_SPDIF_GCLK>,
+                                                <&clks IMX6SLL_CLK_OSC>,
+                                                <&clks IMX6SLL_CLK_SPDIF>,
+                                                <&clks IMX6SLL_CLK_DUMMY>,
+                                                <&clks IMX6SLL_CLK_DUMMY>,
+                                                <&clks IMX6SLL_CLK_DUMMY>,
+                                                <&clks IMX6SLL_CLK_IPG>,
+                                                <&clks IMX6SLL_CLK_DUMMY>,
+                                                <&clks IMX6SLL_CLK_DUMMY>,
+                                                <&clks IMX6SLL_CLK_SPBA>;
+                                       clock-names = "core", "rxtx0",
+                                                     "rxtx1", "rxtx2",
+                                                     "rxtx3", "rxtx4",
+                                                     "rxtx5", "rxtx6",
+                                                     "rxtx7", "dma";
+                                       status = "disabled";
+                               };
+
+                               ecspi1: spi@2008000 {
+                                       compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+                                       reg = <0x02008000 0x4000>;
+                                       interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
+                                       dma-names = "rx", "tx";
+                                       clocks = <&clks IMX6SLL_CLK_ECSPI1>,
+                                                <&clks IMX6SLL_CLK_ECSPI1>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+
+                               ecspi2: spi@200c000 {
+                                       compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+                                       reg = <0x0200c000 0x4000>;
+                                       interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&sdma 5 7 1>, <&sdma 6 7 2>;
+                                       dma-names = "rx", "tx";
+                                       clocks = <&clks IMX6SLL_CLK_ECSPI2>,
+                                                <&clks IMX6SLL_CLK_ECSPI2>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+
+                               ecspi3: spi@2010000 {
+                                       compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+                                       reg = <0x02010000 0x4000>;
+                                       interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&sdma 7 7 1>, <&sdma 8 7 2>;
+                                       dma-names = "rx", "tx";
+                                       clocks = <&clks IMX6SLL_CLK_ECSPI3>,
+                                                <&clks IMX6SLL_CLK_ECSPI3>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+
+                               ecspi4: spi@2014000 {
+                                       compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
+                                       reg = <0x02014000 0x4000>;
+                                       interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
+                                       dma-names = "rx", "tx";
+                                       clocks = <&clks IMX6SLL_CLK_ECSPI4>,
+                                                <&clks IMX6SLL_CLK_ECSPI4>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+
+                               uart4: serial@2018000 {
+                                       compatible = "fsl,imx6sl-uart", "fsl,imx6q-uart",
+                                                    "fsl,imx21-uart";
+                                       reg = <0x02018000 0x4000>;
+                                       interrupts =<GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&sdma 31 4 0>, <&sdma 32 4 0>;
+                                       dma-names = "rx", "tx";
+                                       clocks = <&clks IMX6SLL_CLK_UART4_IPG>,
+                                                <&clks IMX6SLL_CLK_UART4_SERIAL>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+
+                               uart1: serial@2020000 {
+                                       compatible = "fsl,imx6sl-uart", "fsl,imx6q-uart",
+                                                    "fsl,imx21-uart";
+                                       reg = <0x02020000 0x4000>;
+                                       interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&sdma 25 4 0>, <&sdma 26 4 0>;
+                                       dma-names = "rx", "tx";
+                                       clocks = <&clks IMX6SLL_CLK_UART1_IPG>,
+                                                <&clks IMX6SLL_CLK_UART1_SERIAL>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+
+                               uart2: serial@2024000 {
+                                       compatible = "fsl,imx6sl-uart", "fsl,imx6q-uart",
+                                                    "fsl,imx21-uart";
+                                       reg = <0x02024000 0x4000>;
+                                       interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&sdma 27 4 0>, <&sdma 28 4 0>;
+                                       dma-names = "rx", "tx";
+                                       clocks = <&clks IMX6SLL_CLK_UART2_IPG>,
+                                                <&clks IMX6SLL_CLK_UART2_SERIAL>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+
+                               ssi1: ssi-controller@2028000 {
+                                       compatible = "fsl,imx6sl-ssi", "fsl,imx51-ssi";
+                                       reg = <0x02028000 0x4000>;
+                                       interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&sdma 37 22 0>, <&sdma 38 22 0>;
+                                       dma-names = "rx", "tx";
+                                       fsl,fifo-depth = <15>;
+                                       clocks = <&clks IMX6SLL_CLK_SSI1_IPG>,
+                                                <&clks IMX6SLL_CLK_SSI1>;
+                                       clock-names = "ipg", "baud";
+                                       status = "disabled";
+                               };
+
+                               ssi2: ssi-controller@202c000 {
+                                       compatible = "fsl,imx6sl-ssi", "fsl,imx51-ssi";
+                                       reg = <0x0202c000 0x4000>;
+                                       interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&sdma 41 22 0>, <&sdma 42 22 0>;
+                                       dma-names = "rx", "tx";
+                                       fsl,fifo-depth = <15>;
+                                       clocks = <&clks IMX6SLL_CLK_SSI2_IPG>,
+                                                <&clks IMX6SLL_CLK_SSI2>;
+                                       clock-names = "ipg", "baud";
+                                       status = "disabled";
+                               };
+
+                               ssi3: ssi-controller@2030000 {
+                                       compatible = "fsl,imx6sl-ssi", "fsl,imx51-ssi";
+                                       reg = <0x02030000 0x4000>;
+                                       interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&sdma 45 22 0>, <&sdma 46 22 0>;
+                                       dma-names = "rx", "tx";
+                                       fsl,fifo-depth = <15>;
+                                       clocks = <&clks IMX6SLL_CLK_SSI3_IPG>,
+                                                <&clks IMX6SLL_CLK_SSI3>;
+                                       clock-names = "ipg", "baud";
+                                       status = "disabled";
+                               };
+
+                               uart3: serial@2034000 {
+                                       compatible = "fsl,imx6sl-uart", "fsl,imx6q-uart",
+                                                    "fsl,imx21-uart";
+                                       reg = <0x02034000 0x4000>;
+                                       interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&sdma 29 4 0>, <&sdma 30 4 0>;
+                                       dma-name = "rx", "tx";
+                                       clocks = <&clks IMX6SLL_CLK_UART3_IPG>,
+                                                <&clks IMX6SLL_CLK_UART3_SERIAL>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+                       };
+
+                       pwm1: pwm@2080000 {
+                               compatible = "fsl,imx6sll-pwm", "fsl,imx27-pwm";
+                               reg = <0x02080000 0x4000>;
+                               interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_PWM1>,
+                                        <&clks IMX6SLL_CLK_PWM1>;
+                               clock-names = "ipg", "per";
+                               #pwm-cells = <2>;
+                       };
+
+                       pwm2: pwm@2084000 {
+                               compatible = "fsl,imx6sll-pwm", "fsl,imx27-pwm";
+                               reg = <0x02084000 0x4000>;
+                               interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_PWM2>,
+                                        <&clks IMX6SLL_CLK_PWM2>;
+                               clock-names = "ipg", "per";
+                               #pwm-cells = <2>;
+                       };
+
+                       pwm3: pwm@2088000 {
+                               compatible = "fsl,imx6sll-pwm", "fsl,imx27-pwm";
+                               reg = <0x02088000 0x4000>;
+                               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_PWM3>,
+                                        <&clks IMX6SLL_CLK_PWM3>;
+                               clock-names = "ipg", "per";
+                               #pwm-cells = <2>;
+                       };
+
+                       pwm4: pwm@208c000 {
+                               compatible = "fsl,imx6sll-pwm", "fsl,imx27-pwm";
+                               reg = <0x0208c000 0x4000>;
+                               interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_PWM4>,
+                                        <&clks IMX6SLL_CLK_PWM4>;
+                               clock-names = "ipg", "per";
+                               #pwm-cells = <2>;
+                       };
+
+                       gpt1: timer@2098000 {
+                               compatible = "fsl,imx6sl-gpt";
+                               reg = <0x02098000 0x4000>;
+                               interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_GPT_BUS>,
+                                        <&clks IMX6SLL_CLK_GPT_SERIAL>;
+                               clock-names = "ipg", "per";
+                       };
+
+                       gpio1: gpio@209c000 {
+                               compatible = "fsl,imx6sll-gpio", "fsl,imx35-gpio";
+                               reg = <0x0209c000 0x4000>;
+                               interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio2: gpio@20a0000 {
+                               compatible = "fsl,imx6sll-gpio", "fsl,imx35-gpio";
+                               reg = <0x020a0000 0x4000>;
+                               interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio3: gpio@20a4000 {
+                               compatible = "fsl,imx6sll-gpio", "fsl,imx35-gpio";
+                               reg = <0x020a4000 0x4000>;
+                               interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio4: gpio@20a8000 {
+                               compatible = "fsl,imx6sll-gpio", "fsl,imx35-gpio";
+                               reg = <0x020a8000 0x4000>;
+                               interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio5: gpio@20ac000 {
+                               compatible = "fsl,imx6sll-gpio", "fsl,imx35-gpio";
+                               reg = <0x020ac000 0x4000>;
+                               interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio6: gpio@20b0000 {
+                               compatible = "fsl,imx6sll-gpio", "fsl,imx35-gpio";
+                               reg = <0x020b0000 0x4000>;
+                               interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       kpp: keypad@20b8000 {
+                               compatible = "fsl,imx6sll-kpp", "fsl,imx21-kpp";
+                               reg = <0x020b8000 0x4000>;
+                               interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_KPP>;
+                               status = "disabled";
+                       };
+
+                       wdog1: watchdog@20bc000 {
+                               compatible = "fsl,imx6sll-wdt", "fsl,imx21-wdt";
+                               reg = <0x020bc000 0x4000>;
+                               interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_WDOG1>;
+                       };
+
+                       wdog2: watchdog@20c0000 {
+                               compatible = "fsl,imx6sll-wdt", "fsl,imx21-wdt";
+                               reg = <0x020c0000 0x4000>;
+                               interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_WDOG2>;
+                               status = "disabled";
+                       };
+
+                       clks: clock-controller@20c4000 {
+                               compatible = "fsl,imx6sll-ccm";
+                               reg = <0x020c4000 0x4000>;
+                               interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+                               #clock-cells = <1>;
+                               clocks = <&ckil>, <&osc>, <&ipp_di0>, <&ipp_di1>;
+                               clock-names = "ckil", "osc", "ipp_di0", "ipp_di1";
+
+                               assigned-clocks = <&clks IMX6SLL_CLK_PERCLK_SEL>;
+                               assigned-clock-parents = <&clks IMX6SLL_CLK_OSC>;
+                       };
+
+                       anatop: anatop@20c8000 {
+                               compatible = "fsl,imx6sll-anatop",
+                                            "fsl,imx6q-anatop",
+                                            "syscon", "simple-bus";
+                               reg = <0x020c8000 0x4000>;
+                               interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               reg_3p0: regulator-3p0@20c8120 {
+                                       compatible = "fsl,anatop-regulator";
+                                       reg = <0x20c8120>;
+                                       regulator-name = "vdd3p0";
+                                       regulator-min-microvolt = <2625000>;
+                                       regulator-max-microvolt = <3400000>;
+                                       anatop-reg-offset = <0x120>;
+                                       anatop-vol-bit-shift = <8>;
+                                       anatop-vol-bit-width = <5>;
+                                       anatop-min-bit-val = <0>;
+                                       anatop-min-voltage = <2625000>;
+                                       anatop-max-voltage = <3400000>;
+                                       anatop-enable-bit = <0>;
+                               };
+                       };
+
+                       usbphy1: usb-phy@20c9000 {
+                               compatible = "fsl,imx6sll-usbphy", "fsl,imx6ul-usbphy",
+                                               "fsl,imx23-usbphy";
+                               reg = <0x020c9000 0x1000>;
+                               interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_USBPHY1>;
+                               phy-3p0-supply = <&reg_3p0>;
+                               fsl,anatop = <&anatop>;
+                       };
+
+                       usbphy2: usb-phy@20ca000 {
+                               compatible = "fsl,imx6sll-usbphy", "fsl,imx6ul-usbphy",
+                                               "fsl,imx23-usbphy";
+                               reg = <0x020ca000 0x1000>;
+                               interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_USBPHY2>;
+                               phy-reg_3p0-supply = <&reg_3p0>;
+                               fsl,anatop = <&anatop>;
+                       };
+
+                       snvs: snvs@20cc000 {
+                               compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
+                               reg = <0x020cc000 0x4000>;
+
+                               snvs_rtc: snvs-rtc-lp {
+                                       compatible = "fsl,sec-v4.0-mon-rtc-lp";
+                                       regmap = <&snvs>;
+                                       offset = <0x34>;
+                                       interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+                                                    <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+
+                               snvs_poweroff: snvs-poweroff {
+                                       compatible = "syscon-poweroff";
+                                       regmap = <&snvs>;
+                                       offset = <0x38>;
+                                       mask = <0x61>;
+                               };
+
+                               snvs_pwrkey: snvs-powerkey {
+                                       compatible = "fsl,sec-v4.0-pwrkey";
+                                       regmap = <&snvs>;
+                                       interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+                                       linux,keycode = <KEY_POWER>;
+                                       wakeup-source;
+                               };
+                       };
+
+                       src: reset-controller@20d8000 {
+                               compatible = "fsl,imx6sll-src", "fsl,imx51-src";
+                               reg = <0x020d8000 0x4000>;
+                               interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+                               #reset-cells = <1>;
+                       };
+
+                       gpc: interrupt-controller@20dc000 {
+                               compatible = "fsl,imx6sll-gpc", "fsl,imx6q-gpc";
+                               reg = <0x020dc000 0x4000>;
+                               interrupt-controller;
+                               #interrupt-cells = <3>;
+                               interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-parent = <&intc>;
+                               fsl,mf-mix-wakeup-irq = <0x7c00000 0x7d00 0x0 0x1400640>;
+                       };
+
+                       iomuxc: pinctrl@20e0000 {
+                               compatible = "fsl,imx6sll-iomuxc";
+                               reg = <0x020e0000 0x4000>;
+                       };
+
+                       gpr: iomuxc-gpr@20e4000 {
+                               compatible = "fsl,imx6sll-iomuxc-gpr",
+                                            "fsl,imx6q-iomuxc-gpr", "syscon";
+                               reg = <0x020e4000 0x4000>;
+                       };
+
+                       csi: csi@20e8000 {
+                               compatible = "fsl,imx6sll-csi", "fsl,imx6s-csi";
+                               reg = <0x020e8000 0x4000>;
+                               interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_DUMMY>,
+                                        <&clks IMX6SLL_CLK_CSI>,
+                                        <&clks IMX6SLL_CLK_DUMMY>;
+                               clock-names = "disp-axi", "csi_mclk", "disp_dcic";
+                               status = "disabled";
+                       };
+
+                       sdma: dma-controller@20ec000 {
+                               compatible = "fsl,imx6sll-sdma", "fsl,imx35-sdma";
+                               reg = <0x020ec000 0x4000>;
+                               interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_SDMA>,
+                                        <&clks IMX6SLL_CLK_SDMA>;
+                               clock-names = "ipg", "ahb";
+                               #dma-cells = <3>;
+                               iram = <&ocram>;
+                               fsl,sdma-ram-script-name = "imx/sdma/sdma-imx6q.bin";
+                       };
+
+                       lcdif: lcd-controller@20f8000 {
+                               compatible = "fsl,imx6sll-lcdif", "fsl,imx28-lcdif";
+                               reg = <0x020f8000 0x4000>;
+                               interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_LCDIF_PIX>,
+                                        <&clks IMX6SLL_CLK_LCDIF_APB>,
+                                        <&clks IMX6SLL_CLK_DUMMY>;
+                               clock-names = "pix", "axi", "disp_axi";
+                               status = "disabled";
+                       };
+
+                       dcp: dcp@20fc000 {
+                               compatible = "fsl,imx28-dcp";
+                               reg = <0x020fc000 0x4000>;
+                               interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_DCP>;
+                               clock-names = "dcp";
+                       };
+               };
+
+               aips2: aips-bus@2100000 {
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x02100000 0x100000>;
+                       ranges;
+
+                       usbotg1: usb@2184000 {
+                               compatible = "fsl,imx6sll-usb", "fsl,imx6ul-usb",
+                                               "fsl,imx27-usb";
+                               reg = <0x02184000 0x200>;
+                               interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_USBOH3>;
+                               fsl,usbphy = <&usbphy1>;
+                               fsl,usbmisc = <&usbmisc 0>;
+                               fsl,anatop = <&anatop>;
+                               ahb-burst-config = <0x0>;
+                               tx-burst-size-dword = <0x10>;
+                               rx-burst-size-dword = <0x10>;
+                               status = "disabled";
+                       };
+
+                       usbotg2: usb@2184200 {
+                               compatible = "fsl,imx6sll-usb", "fsl,imx6ul-usb",
+                                               "fsl,imx27-usb";
+                               reg = <0x02184200 0x200>;
+                               interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_USBOH3>;
+                               fsl,usbphy = <&usbphy2>;
+                               fsl,usbmisc = <&usbmisc 1>;
+                               ahb-burst-config = <0x0>;
+                               tx-burst-size-dword = <0x10>;
+                               rx-burst-size-dword = <0x10>;
+                               status = "disabled";
+                       };
+
+                       usbmisc: usbmisc@2184800 {
+                               #index-cells = <1>;
+                               compatible = "fsl,imx6sll-usbmisc", "fsl,imx6ul-usbmisc",
+                                               "fsl,imx6q-usbmisc";
+                               reg = <0x02184800 0x200>;
+                       };
+
+                       usdhc1: mmc@2190000 {
+                               compatible = "fsl,imx6sll-usdhc", "fsl,imx6sx-usdhc";
+                               reg = <0x02190000 0x4000>;
+                               interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_USDHC1>,
+                                        <&clks IMX6SLL_CLK_USDHC1>,
+                                        <&clks IMX6SLL_CLK_USDHC1>;
+                               clock-names = "ipg", "ahb", "per";
+                               bus-width = <4>;
+                               fsl,tuning-step = <2>;
+                               fsl,tuning-start-tap = <20>;
+                               status = "disabled";
+                       };
+
+                       usdhc2: mmc@2194000 {
+                               compatible = "fsl,imx6sll-usdhc", "fsl,imx6sx-usdhc";
+                               reg = <0x02194000 0x4000>;
+                               interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_USDHC2>,
+                                        <&clks IMX6SLL_CLK_USDHC2>,
+                                        <&clks IMX6SLL_CLK_USDHC2>;
+                               clock-names = "ipg", "ahb", "per";
+                               bus-width = <4>;
+                               fsl,tuning-step = <2>;
+                               fsl,tuning-start-tap = <20>;
+                               status = "disabled";
+                       };
+
+                       usdhc3: mmc@2198000 {
+                               compatible = "fsl,imx6sll-usdhc", "fsl,imx6sx-usdhc";
+                               reg = <0x02198000 0x4000>;
+                               interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_USDHC3>,
+                                        <&clks IMX6SLL_CLK_USDHC3>,
+                                        <&clks IMX6SLL_CLK_USDHC3>;
+                               clock-names = "ipg", "ahb", "per";
+                               bus-width = <4>;
+                               fsl,tuning-step = <2>;
+                               fsl,tuning-start-tap = <20>;
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@21a0000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fs,imx6sll-i2c", "fsl,imx21-i2c";
+                               reg = <0x021a0000 0x4000>;
+                               interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_I2C1>;
+                               status = "disabled";
+                       };
+
+                       i2c2: i2c@21a4000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx6sll-i2c", "fsl,imx21-i2c";
+                               reg = <0x021a4000 0x4000>;
+                               interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_I2C2>;
+                               status = "disabled";
+                       };
+
+                       i2c3: i2c@21a8000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx6sll-i2c", "fsl,imx21-i2c";
+                               reg = <0x021a8000 0x4000>;
+                               interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_I2C3>;
+                               status = "disabled";
+                       };
+
+                       mmdc: memory-controller@21b0000 {
+                               compatible = "fsl,imx6sll-mmdc", "fsl,imx6q-mmdc";
+                               reg = <0x021b0000 0x4000>;
+                       };
+
+                       ocotp: ocotp-ctrl@21bc000 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "fsl,imx6sll-ocotp", "syscon";
+                               reg = <0x021bc000 0x4000>;
+                               clocks = <&clks IMX6SLL_CLK_OCOTP>;
+
+                               tempmon_calib: calib@38 {
+                                       reg = <0x38 4>;
+                               };
+
+                               tempmon_temp_grade: temp-grade@20 {
+                                       reg = <0x20 4>;
+                               };
+                       };
+
+                       audmux: audmux@21d8000 {
+                               compatible = "fsl,imx6sll-audmux", "fsl,imx31-audmux";
+                               reg = <0x021d8000 0x4000>;
+                               status = "disabled";
+                       };
+
+                       uart5: serial@21f4000 {
+                               compatible = "fsl,imx6sll-uart", "fsl,imx6q-uart",
+                                            "fsl,imx21-uart";
+                               reg = <0x021f4000 0x4000>;
+                               interrupts =<GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&sdma 33 4 0>, <&sdma 34 4 0>;
+                               dma-names = "rx", "tx";
+                               clocks = <&clks IMX6SLL_CLK_UART5_IPG>,
+                                        <&clks IMX6SLL_CLK_UART5_SERIAL>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+               };
+       };
+};
index 59e52f504922f23174ad2c492a7eaf97040c5f56..adb5cc7d8ce2fc3feb189a525ca9061d59b5e56e 100644 (file)
@@ -1,42 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright (C) 2016 Boundary Devices, Inc.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
        model = "Boundary Devices i.MX6 SoloX Nitrogen6sx Board";
        compatible = "boundary,imx6sx-nitrogen6sx", "fsl,imx6sx";
 
-       aliases {
-               fb-lcd = &lcdif1;
-               t-lcd = &t_lcd;
-       };
-
        memory@80000000 {
                reg = <0x80000000 0x40000000>;
        };
        status = "okay";
 };
 
-&lcdif1 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_lcdif1>;
-       lcd-supply = <&reg_3p3v>;
-       display = <&display0>;
-       status = "okay";
-
-       display0: display0 {
-               bits-per-pixel = <16>;
-               bus-width = <24>;
-
-               display-timings {
-                       native-mode = <&t_lcd>;
-                       t_lcd: t_lcd_default {
-                               clock-frequency = <74160000>;
-                               hactive = <1280>;
-                               vactive = <720>;
-                               hback-porch = <220>;
-                               hfront-porch = <110>;
-                               vback-porch = <20>;
-                               vfront-porch = <5>;
-                               hsync-len = <40>;
-                               vsync-len = <5>;
-                               hsync-active = <0>;
-                               vsync-active = <0>;
-                               de-active = <1>;
-                               pixelclk-active = <0>;
-                       };
-               };
-       };
-};
-
 &pcie {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pcie>;
                >;
        };
 
-       pinctrl_lcdif1: lcdif1grp {
-               fsl,pins = <
-                       MX6SX_PAD_LCD1_CLK__LCDIF1_CLK          0x4001b0b0
-                       MX6SX_PAD_LCD1_ENABLE__LCDIF1_ENABLE    0x4001b0b0
-                       MX6SX_PAD_LCD1_HSYNC__LCDIF1_HSYNC      0x4001b0b0
-                       MX6SX_PAD_LCD1_VSYNC__LCDIF1_VSYNC      0x4001b0b0
-                       MX6SX_PAD_LCD1_RESET__GPIO3_IO_27       0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA00__LCDIF1_DATA_0    0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA01__LCDIF1_DATA_1    0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA02__LCDIF1_DATA_2    0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA03__LCDIF1_DATA_3    0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA04__LCDIF1_DATA_4    0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA05__LCDIF1_DATA_5    0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA06__LCDIF1_DATA_6    0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA07__LCDIF1_DATA_7    0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA08__LCDIF1_DATA_8    0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA09__LCDIF1_DATA_9    0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA10__LCDIF1_DATA_10   0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA11__LCDIF1_DATA_11   0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA12__LCDIF1_DATA_12   0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA13__LCDIF1_DATA_13   0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA14__LCDIF1_DATA_14   0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA15__LCDIF1_DATA_15   0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA16__LCDIF1_DATA_16   0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA17__LCDIF1_DATA_17   0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA18__LCDIF1_DATA_18   0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA19__LCDIF1_DATA_19   0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA20__LCDIF1_DATA_20   0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA21__LCDIF1_DATA_21   0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA22__LCDIF1_DATA_22   0x4001b0b0
-                       MX6SX_PAD_LCD1_DATA23__LCDIF1_DATA_23   0x4001b0b0
-               >;
-       };
-
        pinctrl_pcie: pciegrp {
                fsl,pins = <
                        MX6SX_PAD_NAND_DATA05__GPIO4_IO_9       0xb0b0
index e3533e74ccc84bbaa0dbf82aae7d9f5c408102dc..9cc6ff206aeab2fde22bfde47818550bc8806ee6 100644 (file)
@@ -63,6 +63,7 @@
                        sw4_reg: sw4 {
                                regulator-min-microvolt = <800000>;
                                regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
                        };
 
                        swbst_reg: swbst {
index 4e4a55aad5c9ca9aa6fff90deb0ae1c5e99c3a13..844caa39364ffeaabc18093bcf3cf87d6b4c7c32 100644 (file)
@@ -79,6 +79,7 @@
                                198000      1175000
                        >;
                        clock-latency = <61036>; /* two CLK32 periods */
+                       #cooling-cells = <2>;
                        clocks = <&clks IMX6SX_CLK_ARM>,
                                 <&clks IMX6SX_CLK_PLL2_PFD2>,
                                 <&clks IMX6SX_CLK_STEP>,
                interrupt-parent = <&gpc>;
                ranges;
 
+               ocram_s: sram@8f8000 {
+                       compatible = "mmio-sram";
+                       reg = <0x008f8000 0x4000>;
+                       clocks = <&clks IMX6SX_CLK_OCRAM_S>;
+               };
+
                ocram: sram@900000 {
                        compatible = "mmio-sram";
                        reg = <0x00900000 0x20000>;
                                regulator-1p1 {
                                        compatible = "fsl,anatop-regulator";
                                        regulator-name = "vdd1p1";
-                                       regulator-min-microvolt = <800000>;
-                                       regulator-max-microvolt = <1375000>;
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1200000>;
                                        regulator-always-on;
                                        anatop-reg-offset = <0x110>;
                                        anatop-vol-bit-shift = <8>;
                                regulator-2p5 {
                                        compatible = "fsl,anatop-regulator";
                                        regulator-name = "vdd2p5";
-                                       regulator-min-microvolt = <2100000>;
-                                       regulator-max-microvolt = <2875000>;
+                                       regulator-min-microvolt = <2250000>;
+                                       regulator-max-microvolt = <2750000>;
                                        regulator-always-on;
                                        anatop-reg-offset = <0x130>;
                                        anatop-vol-bit-shift = <8>;
 
                        crypto: caam@2100000 {
                                compatible = "fsl,sec-v4.0";
-                               fsl,sec-era = <4>;
                                #address-cells = <1>;
                                #size-cells = <1>;
                                reg = <0x2100000 0x10000>;
diff --git a/arch/arm/boot/dts/imx6ul-ccimx6ulsbcexpress.dts b/arch/arm/boot/dts/imx6ul-ccimx6ulsbcexpress.dts
new file mode 100644 (file)
index 0000000..3792679
--- /dev/null
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Digi International's ConnectCore6UL SBC Express board device tree source
+ *
+ * Copyright 2018 Digi International, Inc.
+ *
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "imx6ul.dtsi"
+#include "imx6ul-ccimx6ulsom.dtsi"
+
+/ {
+       model = "Digi International ConnectCore 6UL SBC Express.";
+       compatible = "digi,ccimx6ulsbcexpress", "digi,ccimx6ulsom",
+                    "fsl,imx6ul";
+};
+
+&adc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_adc1>;
+       status = "okay";
+};
+
+&can1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan1>;
+       xceiver-supply = <&ext_3v3>;
+       status = "okay";
+};
+
+&ecspi3 {
+       cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi3_master>;
+       status = "okay";
+};
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet1>;
+       phy-mode = "rmii";
+       phy-handle = <&ethphy0>;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy0: ethernet-phy@0 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       smsc,disable-energy-detect;
+                       reg = <0>;
+               };
+       };
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+};
+
+&pwm1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm1>;
+       status = "okay";
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart4>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg1 {
+       dr_mode = "host";
+       disable-over-current;
+       status = "okay";
+};
+
+&usbotg2 {
+       dr_mode = "host";
+       disable-over-current;
+       status = "okay";
+};
+
+&usdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       broken-cd;      /* no carrier detect line (use polling) */
+       no-1-8-v;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       pinctrl_adc1: adc1grp {
+               fsl,pins = <
+                       /* GPIO1_4/ADC1_IN4 (pin 7 of the expansion header) */
+                       MX6UL_PAD_GPIO1_IO04__GPIO1_IO04        0xb0
+               >;
+       };
+
+       pinctrl_ecspi3_master: ecspi3grp1 {
+               fsl,pins = <
+                       MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK    0x10b0
+                       MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI      0x10b0
+                       MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO      0x10b0
+                       MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20     0x10b0 /* Chip Select */
+               >;
+       };
+
+       pinctrl_ecspi3_slave: ecspi3grp2 {
+               fsl,pins = <
+                       MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK    0x10b0
+                       MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI      0x10b0
+                       MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO      0x10b0
+                       MX6UL_PAD_UART2_TX_DATA__ECSPI3_SS0     0x10b0 /* Chip Select */
+               >;
+       };
+
+       pinctrl_enet1: enet1grp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO07__ENET1_MDC         0x1b0b0
+                       MX6UL_PAD_GPIO1_IO06__ENET1_MDIO        0x1b0b0
+                       MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN      0x1b0b0
+                       MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER      0x1b0b0
+                       MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
+                       MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
+                       MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN      0x1b0b0
+                       MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
+                       MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
+                       MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x40017051
+               >;
+       };
+
+       pinctrl_flexcan1: flexcan1grp{
+               fsl,pins = <
+                       MX6UL_PAD_LCD_DATA08__FLEXCAN1_TX       0x1b020
+                       MX6UL_PAD_LCD_DATA09__FLEXCAN1_RX       0x1b020
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO00__I2C2_SCL 0x4001b8b0
+                       MX6UL_PAD_GPIO1_IO01__I2C2_SDA 0x4001b8b0
+               >;
+       };
+
+       pinctrl_pwm1: pwm1grp {
+               fsl,pins = <
+                       MX6UL_PAD_LCD_DATA00__PWM1_OUT          0x10b0
+               >;
+       };
+
+       pinctrl_uart4: uart4grp {
+               fsl,pins = <
+                       MX6UL_PAD_LCD_CLK__UART4_DCE_TX         0x1b0b1
+                       MX6UL_PAD_LCD_ENABLE__UART4_DCE_RX      0x1b0b1
+               >;
+       };
+
+       pinctrl_uart5: uart5grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART5_TX_DATA__UART5_DCE_TX   0x1b0b1
+                       MX6UL_PAD_UART5_RX_DATA__UART5_DCE_RX   0x1b0b1
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX6UL_PAD_CSI_HSYNC__USDHC2_CMD         0x17059
+                       MX6UL_PAD_CSI_VSYNC__USDHC2_CLK         0x10071
+                       MX6UL_PAD_CSI_DATA00__USDHC2_DATA0      0x17059
+                       MX6UL_PAD_CSI_DATA01__USDHC2_DATA1      0x17059
+                       MX6UL_PAD_CSI_DATA02__USDHC2_DATA2      0x17059
+                       MX6UL_PAD_CSI_DATA03__USDHC2_DATA3      0x17059
+               >;
+       };
+
+       /* General purpose pinctrl */
+       pinctrl_hog: hoggrp {
+               fsl,pins = <
+                       /* GPIOs BANK 3 */
+                       MX6UL_PAD_LCD_RESET__GPIO3_IO04         0xf030
+               >;
+       };
+};
diff --git a/arch/arm/boot/dts/imx6ul-ccimx6ulsom.dtsi b/arch/arm/boot/dts/imx6ul-ccimx6ulsom.dtsi
new file mode 100644 (file)
index 0000000..c71a84d
--- /dev/null
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Digi International's ConnectCore 6UL System-On-Module device tree source
+ *
+ * Copyright 2018 Digi International, Inc.
+ *
+ */
+
+/ {
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               linux,cma {
+                       compatible = "shared-dma-pool";
+                       reusable;
+                       size = <0x4000000>;
+                       linux,cma-default;
+               };
+       };
+};
+
+&adc1 {
+       vref-supply = <&vdda_adc_3v3>;
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       pfuze3000: pmic@8 {
+               compatible = "fsl,pfuze3000";
+               reg = <0x08>;
+
+               regulators {
+                       int_3v3: sw1a {
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-boot-on;
+                               regulator-always-on;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_arm_soc_in: sw1b {
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1475000>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-boot-on;
+                               regulator-always-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <925000>;
+                               };
+                       };
+
+                       ext_3v3: sw2 {
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_ddr3: sw3 {
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1650000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1300000>;
+                               };
+                       };
+
+                       swbst_reg: swbst {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5150000>;
+                       };
+
+                       vdd_snvs_3v3: vsnvs {
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vrefddr: vrefddr {
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       vdda_adc_3v3: vldo1 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vref-adc-3v3";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       ldo2_ext: vldo2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vdda_wlan: vccsd {
+                               regulator-min-microvolt = <2850000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_high_in: v33 {
+                               regulator-min-microvolt = <2850000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo3_int: vldo3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       ldo4_ext: vldo4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       vcoin_chg: vcoin {
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+               };
+       };
+};
+
+&iomuxc {
+       pinctrl_gpmi_nand: gpmigrp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B     0xb0b1
+                       MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B       0xb0b1
+                       MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B       0xb0b1
+                       MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B       0xb0b1
+                       MX6UL_PAD_NAND_ALE__RAWNAND_ALE         0xb0b1
+                       MX6UL_PAD_NAND_CLE__RAWNAND_CLE         0xb0b1
+                       MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00   0xb0b1
+                       MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01   0xb0b1
+                       MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02   0xb0b1
+                       MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03   0xb0b1
+                       MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04   0xb0b1
+                       MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05   0xb0b1
+                       MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06   0xb0b1
+                       MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07   0xb0b1
+                       MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0xb0b1
+                       >;
+               };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0
+                       MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0
+                       >;
+               };
+};
+
+&reg_arm {
+       vin-supply = <&vdd_arm_soc_in>;
+       regulator-allow-bypass;
+};
+
+&reg_soc {
+       vin-supply = <&vdd_arm_soc_in>;
+       regulator-allow-bypass;
+};
index 47682b8c023ceda449ab62a4b5ca0aa1698bbb16..0c09420f995125d49bba630931185a179a40020d 100644 (file)
@@ -51,8 +51,9 @@
        model = "Technexion Pico i.MX6UL Board";
        compatible = "technexion,imx6ul-pico-hobbit", "fsl,imx6ul";
 
+       /* Will be filled by the bootloader */
        memory@80000000 {
-               reg = <0x80000000 0x10000000>;
+               reg = <0x80000000 0>;
        };
 
        chosen {
index 47a3453a4211fe2bebe5bb72c0d42ae370c66b43..6dc0b569acdf4c803cf0b13667788716028dd159 100644 (file)
@@ -62,6 +62,7 @@
                        device_type = "cpu";
                        reg = <0>;
                        clock-latency = <61036>; /* two CLK32 periods */
+                       #cooling-cells = <2>;
                        operating-points = <
                                /* kHz  uV */
                                696000  1275000
                                reg = <0x0209c000 0x4000>;
                                interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6UL_CLK_GPIO1>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                                reg = <0x020a0000 0x4000>;
                                interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6UL_CLK_GPIO2>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                                reg = <0x020a4000 0x4000>;
                                interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6UL_CLK_GPIO3>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                                reg = <0x020a8000 0x4000>;
                                interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6UL_CLK_GPIO4>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
                                reg = <0x020ac000 0x4000>;
                                interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6UL_CLK_GPIO5>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupt-controller;
index 3dffbcd50bf682a452423f5137f441b612e65af2..183193e8580dd12a99f1d14d365fceff892e0853 100644 (file)
 
 &cpu0 {
        clock-frequency = <792000000>;
-       operating-points = <
-               /* kHz  uV */
-               792000  1225000
-               528000  1175000
-               396000  1025000
-               198000  950000
-       >;
-       fsl,soc-operating-points = <
-               /* KHz  uV */
-               792000  1175000
-               528000  1175000
-               396000  1175000
-               198000  1175000
-       >;
 };
 
 &iomuxc {
index ebc25c98e5e141382e6dde0e90cc8e78af1fb553..cd1776a7015ac0dc6d10630eb45bc93f816b0aae 100644 (file)
@@ -1,43 +1,6 @@
-/*
- * Copyright 2016 Freescale Semiconductor, Inc.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License
- *     version 2 as published by the Free Software Foundation.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright 2016 Freescale Semiconductor, Inc.
 
 #include "imx6ul.dtsi"
 #include "imx6ull-pinfunc.h"
 /* Delete CAAM node in AIPS-2 (i.MX6UL specific) */
 /delete-node/ &crypto;
 
+&cpu0 {
+       operating-points = <
+               /* kHz  uV */
+               900000  1275000
+               792000  1225000
+               528000  1175000
+               396000  1025000
+               198000  950000
+       >;
+       fsl,soc-operating-points = <
+               /* KHz  uV */
+               900000  1175000
+               792000  1175000
+               528000  1175000
+               396000  1175000
+               198000  1175000
+       >;
+};
+
 / {
        soc {
                aips3: aips-bus@2200000 {
index 70c53e50b2fcd2cd9cc4d1cfb91d43faa1dd588c..d8aac4a2d02a2489d1843e2d22f2f4cb317eb481 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0 OR X11
 /*
  * Copyright 2016 Boundary Devices, Inc.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
        model = "Boundary Devices i.MX7 Nitrogen7 Board";
        compatible = "boundary,imx7d-nitrogen7", "fsl,imx7d";
 
-       aliases {
-               fb-lcd = &lcdif;
-               t-lcd = &t_lcd;
-       };
-
        memory@80000000 {
                reg = <0x80000000 0x40000000>;
        };
@@ -65,7 +23,7 @@
                default-on;
        };
 
-       backlight-j20 {
+       backlight_lcd: backlight-j20 {
                compatible = "pwm-backlight";
                pwms = <&pwm1 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                status = "okay";
        };
 
+       panel-lcd {
+               compatible = "okaya,rs800480t-7x0gp";
+               backlight = <&backlight_lcd>;
+
+               port {
+                       panel_in: endpoint {
+                               remote-endpoint = <&lcdif_out>;
+                       };
+               };
+       };
+
        reg_usb_otg1_vbus: regulator-usb-otg1-vbus {
                compatible = "regulator-fixed";
                regulator-name = "usb_otg1_vbus";
 };
 
 &lcdif {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_lcdif_dat
-                    &pinctrl_lcdif_ctrl>;
-       lcd-supply = <&reg_vref_3v3>;
-       display = <&display0>;
        status = "okay";
 
-       display0: lcd-display {
-               bits-per-pixel = <16>;
-               bus-width = <18>;
-
-               display-timings {
-                       native-mode = <&t_lcd>;
-                       t_lcd: t_lcd_default {
-                               /* default to Okaya display */
-                               clock-frequency = <30000000>;
-                               hactive = <800>;
-                               vactive = <480>;
-                               hfront-porch = <40>;
-                               hback-porch = <40>;
-                               hsync-len = <48>;
-                               vback-porch = <29>;
-                               vfront-porch = <13>;
-                               vsync-len = <3>;
-                               hsync-active = <0>;
-                               vsync-active = <0>;
-                               de-active = <1>;
-                               pixelclk-active = <0>;
-                       };
+       port {
+               lcdif_out: endpoint {
+                       remote-endpoint = <&panel_in>;
                };
        };
 };
index 9408491631042d4adc816f7f9dec1c0b87a9aa23..c9b3c60b0eb22fe3ac4f8ab05f1a17209e96ee5d 100644 (file)
        model = "Freescale i.MX7 SabreSD Board";
        compatible = "fsl,imx7d-sdb", "fsl,imx7d";
 
+       chosen {
+               stdout-path = &uart1;
+       };
+
        memory@80000000 {
                reg = <0x80000000 0x80000000>;
        };
                enable-active-high;
        };
 
-       reg_can2_3v3: regulator-can2-3v3 {
-               compatible = "regulator-fixed";
-               regulator-name = "can2-3v3";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               gpio = <&gpio1 7 GPIO_ACTIVE_LOW>;
-       };
-
        reg_vref_1v8: regulator-vref-1v8 {
                compatible = "regulator-fixed";
                regulator-name = "vref-1v8";
                gpio = <&gpio2 14 GPIO_ACTIVE_LOW>;
        };
 
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm1 0 5000000 0>;
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <6>;
+               status = "okay";
+       };
+
        panel {
                compatible = "innolux,at043tn24";
-               pinctrl-0 = <&pinctrl_backlight>;
-               enable-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+               backlight = <&backlight>;
                power-supply = <&reg_lcd_3v3>;
 
                port {
        };
 };
 
+&pwm1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm1>;
+       status = "okay";
+};
+
 &iomuxc_lpsr {
        pinctrl_wdog: wdoggrp {
                fsl,pins = <
                >;
        };
 
-       pinctrl_backlight: backlightgrp {
+       pinctrl_pwm1: pwm1grp {
                fsl,pins = <
-                       MX7D_PAD_LPSR_GPIO1_IO01__GPIO1_IO1             0x110b0
+                       MX7D_PAD_LPSR_GPIO1_IO01__PWM1_OUT              0x30
                >;
        };
 };
index 8d3d123d0a5c679c5fecd7ca756c9cd4d76ef727..7234e8330a576d8a53e7658d394e50211bbe2450 100644 (file)
@@ -11,6 +11,7 @@
                cpu0: cpu@0 {
                        clock-frequency = <996000000>;
                        operating-points-v2 = <&cpu0_opp_table>;
+                       #cooling-cells = <2>;
                };
 
                cpu1: cpu@1 {
                interrupt-names = "msi";
                #interrupt-cells = <1>;
                interrupt-map-mask = <0 0 0 0x7>;
-               interrupt-map = <0 0 0 1 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 0 2 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 0 3 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 0 4 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+               /*
+                * Reference manual lists pci irqs incorrectly
+                * Real hardware ordering is same as imx6: D+MSI, C, B, A
+                */
+               interrupt-map = <0 0 0 1 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 0 0 2 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 0 0 3 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 0 0 4 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&clks IMX7D_PCIE_CTRL_ROOT_CLK>,
                         <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>,
                         <&clks IMX7D_PCIE_PHY_ROOT_CLK>;
index 9ced589bfa9623cc7ee16ea50d0d7f6ad55b2a1f..a052198f6e9631484a7e6d08907110a427db3dc1 100644 (file)
 
                        crypto: caam@30900000 {
                                compatible = "fsl,sec-v4.0";
-                               fsl,sec-era = <8>;
                                #address-cells = <1>;
                                #size-cells = <1>;
                                reg = <0x30900000 0x40000>;
index 66954aaf2c47009d716370ad37d8b0314f06403d..5cae74eb6cddfb41c9d53317c24d389321af0750 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the iWave-RZ/G1M/G1N Qseven carrier board
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /*
index 476273b3f9940bdc5cee10a27e608d30ce5926bd..0e99df21825251b052de8da7b6bf12d4c01f4a37 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the iWave-RZ-G1M/N Daughter Board Camera Module
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 / {
index a17311c602aa5ce3cdbb617a149a526d8c351470..1db17ec744b1155d165d74c00e5dc725ff37b976 100644 (file)
@@ -225,3 +225,23 @@ netcp: netcp@24000000 {
                };
        };
 };
+
+sa_subsys: subsys@24080000 {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "simple-bus";
+       ranges = <0 0x24080000 0x40000>;
+
+       sa_config: subsys@0 {
+               compatible = "syscon";
+               reg = <0x0 0x100>;
+       };
+
+       rng@24000 {
+               compatible = "ti,keystone-rng";
+               reg = <0x24000 0x1000>;
+               ti,syscon-sa-cfg = <&sa_config>;
+               clocks = <&clksa>;
+               clock-names = "fck";
+       };
+};
index 154fdd7a7022c982701db26bc23c012669996ac7..b7f10bf945760e2563fd8c3f84d1ec67eb57b04f 100644 (file)
                regulator-max-microvolt = <3300000>;
                regulator-always-on;
        };
+
+       vcc1v8_ldo1_reg: fixedregulator-vcc1v8-ldo1 {
+               compatible = "regulator-fixed";
+               regulator-name = "ldo1";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+       };
 };
 
 &k2g_pinctrl {
                        K2G_CORE_IOPAD(0x1228) (BUFFER_CLASS_B | PIN_PULLDOWN  | MUX_MODE1)     /* qspicsn3.dcan1rx */
                >;
        };
+
+       emac_pins: pinmux_emac_pins {
+               pinctrl-single,pins = <
+                       K2G_CORE_IOPAD(0x113C) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_RXD1.RGMII_RXD1 */
+                       K2G_CORE_IOPAD(0x1138) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_RXD2.RGMII_RXD2 */
+                       K2G_CORE_IOPAD(0x1134) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_RXD3.RGMII_RXD3 */
+                       K2G_CORE_IOPAD(0x1140) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_RXD0.RGMII_RXD0 */
+                       K2G_CORE_IOPAD(0x1178) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_TXD0.RGMII_TXD0 */
+                       K2G_CORE_IOPAD(0x1174) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_TXD1.RGMII_TXD1 */
+                       K2G_CORE_IOPAD(0x1170) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_TXD2.RGMII_TXD2 */
+                       K2G_CORE_IOPAD(0x116C) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_TXD3.RGMII_TXD3 */
+                       K2G_CORE_IOPAD(0x1154) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_TXCLK.RGMII_TXC */
+                       K2G_CORE_IOPAD(0x117C) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_TXEN.RGMII_TXCTL */
+                       K2G_CORE_IOPAD(0x1120) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_RXCLK.RGMII_RXC */
+                       K2G_CORE_IOPAD(0x1144) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_RXDV.RGMII_RXCTL */
+               >;
+       };
+
+       mdio_pins: pinmux_mdio_pins {
+               pinctrl-single,pins = <
+                       K2G_CORE_IOPAD(0x118C) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0)      /* MDIO_CLK.MDIO_CLK */
+                       K2G_CORE_IOPAD(0x1188) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0)      /* MDIO_DATA.MDIO_DATA */
+               >;
+       };
 };
 
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&mmc0_pins>;
        vmmc-supply = <&vcc3v3_dcin_reg>;
+       vqmmc-supply = <&vcc3v3_dcin_reg>;
        cd-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
        status = "okay";
 };
        pinctrl-names = "default";
        pinctrl-0 = <&mmc1_pins>;
        vmmc-supply = <&vcc3v3_dcin_reg>; /* VCC3V3_EMMC is connected to VCC3V3_DCIN */
+       vqmmc-supply = <&vcc1v8_ldo1_reg>;
        ti,non-removable;
        status = "okay";
 };
        pinctrl-0 = <&dcan1_pins>;
        status = "okay";
 };
+
+&qmss {
+       status = "okay";
+};
+
+&knav_dmas {
+       status = "okay";
+};
+
+&mdio {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mdio_pins>;
+       status = "okay";
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+       };
+};
+
+&gbe0 {
+       phy-handle = <&ethphy0>;
+       phy-mode = "rgmii-id";
+       status = "okay";
+};
+
+&netcp {
+       pinctrl-names = "default";
+       pinctrl-0 = <&emac_pins>;
+       status = "okay";
+};
index d820ed2474bbd5ac29b72584834ace616db4a613..2a2d38cf0fff75fc66d923b881a92bc9dd1baebf 100644 (file)
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "keystone-k2g.dtsi"
+#include <dt-bindings/net/ti-dp83867.h>
 
 / {
        compatible = "ti,k2g-ice", "ti,k2g", "ti,keystone";
                        K2G_CORE_IOPAD(0x11bc) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE3)        /* spi2_scsn1.gpio0_102 */
                >;
        };
+
+       emac_pins: pinmux_emac_pins {
+               pinctrl-single,pins = <
+                       K2G_CORE_IOPAD(0x113C) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_RXD1.RGMII_RXD1 */
+                       K2G_CORE_IOPAD(0x1138) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_RXD2.RGMII_RXD2 */
+                       K2G_CORE_IOPAD(0x1134) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_RXD3.RGMII_RXD3 */
+                       K2G_CORE_IOPAD(0x1140) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_RXD0.RGMII_RXD0 */
+                       K2G_CORE_IOPAD(0x1178) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_TXD0.RGMII_TXD0 */
+                       K2G_CORE_IOPAD(0x1174) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_TXD1.RGMII_TXD1 */
+                       K2G_CORE_IOPAD(0x1170) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_TXD2.RGMII_TXD2 */
+                       K2G_CORE_IOPAD(0x116C) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_TXD3.RGMII_TXD3 */
+                       K2G_CORE_IOPAD(0x1154) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_TXCLK.RGMII_TXC */
+                       K2G_CORE_IOPAD(0x117C) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_TXEN.RGMII_TXCTL */
+                       K2G_CORE_IOPAD(0x1120) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_RXCLK.RGMII_RXC */
+                       K2G_CORE_IOPAD(0x1144) (BUFFER_CLASS_D | PULL_DISABLE | MUX_MODE1)      /* MII_RXDV.RGMII_RXCTL */
+               >;
+       };
+
+       mdio_pins: pinmux_mdio_pins {
+               pinctrl-single,pins = <
+                       K2G_CORE_IOPAD(0x118C) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0)      /* MDIO_CLK.MDIO_CLK */
+                       K2G_CORE_IOPAD(0x1188) (BUFFER_CLASS_B | PULL_DISABLE | MUX_MODE0)      /* MDIO_DATA.MDIO_DATA */
+               >;
+       };
 };
 
 &uart0 {
                vcc-supply = <&vdd_3v3>;
        };
 };
+
+&qmss {
+       status = "okay";
+};
+
+&knav_dmas {
+       status = "okay";
+};
+
+&netcp {
+       pinctrl-names = "default";
+       pinctrl-0 = <&emac_pins>;
+       status = "okay";
+};
+
+&mdio {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mdio_pins>;
+       status = "okay";
+       ethphy0: ethernet-phy@0 {
+               reg = <0>;
+               ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
+               ti,tx-internal-delay = <DP83867_RGMIIDCTL_250_PS>;
+               ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>;
+               ti,min-output-impedance;
+               ti,dp83867-rxctrl-strap-quirk;
+       };
+};
+
+&gbe0 {
+       phy-handle = <&ethphy0>;
+       phy-mode = "rgmii-id";
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/keystone-k2g-netcp.dtsi b/arch/arm/boot/dts/keystone-k2g-netcp.dtsi
new file mode 100644 (file)
index 0000000..d0e6a9a
--- /dev/null
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for K2G Netcp driver
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+qmss: qmss@4020000 {
+       compatible = "ti,66ak2g-navss-qm";
+       dma-coherent;
+       #address-cells = <1>;
+       #size-cells = <1>;
+       power-domains = <&k2g_pds 0x0018>;
+       clocks = <&k2g_clks 0x0018 0>;
+       clock-names = "nss_vclk";
+       ranges;
+       queue-range = <0 0x80>;
+       linkram0 = <0x4020000 0x7ff>;
+       status = "disabled";
+
+       qmgrs {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+               qmgr0 {
+                       managed-queues = <0 0x80>;
+                       reg = <0x4100000 0x800>,
+                             <0x4040000 0x100>,
+                             <0x4080000 0x800>,
+                             <0x40c0000 0x800>;
+                       reg-names = "peek", "config",
+                                   "region", "push";
+               };
+
+       };
+       queue-pools {
+               qpend {
+                       qpend-0 {
+                               qrange = <77 8>;
+                               interrupts =<0 308 0xf04 0 309 0xf04 0 310 0xf04
+                                            0 311 0xf04 0 312 0xf04 0 313 0xf04
+                                            0 314 0xf04 0 315 0xf04>;
+                               qalloc-by-id;
+                       };
+               };
+               general-purpose {
+                       gp-0 {
+                               qrange = <112 8>;
+                       };
+                       netcp-tx {
+                               qrange = <5 8>;
+                               qalloc-by-id;
+                       };
+               };
+       };
+
+       descriptor-regions {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+               region-12 {
+                       id = <12>;
+                       region-spec = <1023 128>; /* num_desc desc_size */
+                       link-index = <0x400>;
+               };
+       };
+}; /* qmss */
+
+knav_dmas: knav_dmas@0 {
+       compatible = "ti,keystone-navigator-dma";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       status = "disabled";
+       power-domains = <&k2g_pds 0x0018>;
+       clocks = <&k2g_clks 0x0018 0>;
+       clock-names = "nss_vclk";
+       ranges;
+       ti,navigator-cloud-address = <0x40c0000 0x40c0000 0x40c0000 0x40c0000>;
+
+       dma_gbe: dma_gbe@0 {
+               reg = <0x4010000 0x100>,
+                     <0x4011000 0x2a0>, /* 21 Tx channels */
+                     <0x4012000 0x400>, /* 32 Rx channels */
+                     <0x4010100 0x80>,
+                     <0x4013000 0x400>; /* 32 Rx flows */
+               reg-names = "global", "txchan", "rxchan",
+                           "txsched", "rxflow";
+       };
+
+};
+
+netcp: netcp@4000000 {
+       reg = <0x2620110 0x8>;
+       reg-names = "efuse";
+       compatible = "ti,netcp-1.0";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       status = "disabled";
+       power-domains = <&k2g_pds 0x0018>;
+       clocks = <&k2g_clks 0x0018 3>, <&k2g_clks 0x0018 8>;
+       clock-names = "ethss_clk", "cpts";
+
+       /* NetCP address range */
+       ranges = <0 0x4000000 0x1000000>;
+
+       dma-coherent;
+
+       ti,navigator-dmas = <&dma_gbe 0>, <&dma_gbe 5>;
+       ti,navigator-dma-names = "netrx0", "nettx";
+
+       netcp-devices {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+               gbe: gbe@200000 {
+                       label = "netcp-gbe";
+                       compatible = "ti,netcp-gbe-2";
+                       reg = <0x200000 0x20>, <0x220000 0x20000>;
+                       enable-ale;
+                       tx-queue = <5>;
+                       tx-channel = "nettx";
+                       cpts-rftclk-sel = <0>;
+                       cpts-ext-ts-inputs = <8>;
+
+                       interfaces {
+                               gbe0: interface-0 {
+                                       slave-port = <0>;
+                                       link-interface  = <5>;
+                               };
+                       };
+               };
+       };
+
+       netcp-interfaces {
+               interface-0 {
+                       rx-channel = "netrx0";
+                       rx-pool = <512 12>;
+                       tx-pool = <511 12>;
+                       rx-queue-depth = <128 128 0 0>;
+                       rx-buffer-size = <1518 4096 0 0>;
+                       rx-queue = <77>;
+                       tx-completion-queue = <78>;
+                       efuse-mac = <1>;
+                       netcp-gbe = <&gbe0>;
+               };
+       };
+};
index da78c00344275a2b8c0369db393a0a6f1fe7f64a..738b44cf2b0bbdd5eb398af5fff2d6eb60095b53 100644 (file)
                };
 
                mmc0: mmc@23000000 {
-                       compatible = "ti,k2g-hsmmc", "ti,omap4-hsmmc";
+                       compatible = "ti,k2g-sdhci";
                        reg = <0x23000000 0x400>;
                        interrupts = <GIC_SPI 96 IRQ_TYPE_EDGE_RISING>;
-                       dmas = <&edma1 24 0>, <&edma1 25 0>;
-                       dma-names = "tx", "rx";
                        bus-width = <4>;
-                       ti,needs-special-reset;
                        no-1-8-v;
                        max-frequency = <96000000>;
                        power-domains = <&k2g_pds 0xb>;
                };
 
                mmc1: mmc@23100000 {
-                       compatible = "ti,k2g-hsmmc", "ti,omap4-hsmmc";
+                       compatible = "ti,k2g-sdhci";
                        reg = <0x23100000 0x400>;
                        interrupts = <GIC_SPI 97 IRQ_TYPE_EDGE_RISING>;
-                       dmas = <&edma1 26 0>, <&edma1 27 0>;
-                       dma-names = "tx", "rx";
                        bus-width = <8>;
-                       ti,needs-special-reset;
+                       no-1-8-v;
+                       non-removable;
                        max-frequency = <96000000>;
                        power-domains = <&k2g_pds 0xc>;
                        clocks = <&k2g_clks 0xc 1>, <&k2g_clks 0xc 2>;
                        reg = <0x21010000 0x200>;
                        interrupts = <GIC_SPI 123 IRQ_TYPE_EDGE_RISING>;
                };
+
+               mdio: mdio@4200f00 {
+                       compatible = "ti,keystone_mdio", "ti,davinci_mdio";
+                       reg = <0x04200f00 0x100>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       clocks = <&k2g_clks 0x0018 3>;
+                       clock-names = "fck";
+                       power-domains = <&k2g_pds 0x0018>;
+                       status = "disabled";
+                       bus_freq = <2500000>;
+               };
+               #include "keystone-k2g-netcp.dtsi"
        };
 };
index b88c0689c285c8de03a4ccdebf4cff5e4e86d28b..e203145acbeab295e01c9979f21bb1f7c6e59633 100644 (file)
@@ -228,3 +228,23 @@ netcp: netcp@2000000 {
                };
        };
 };
+
+sa_subsys: subsys@20c0000 {
+       compatible = "simple-bus";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       ranges = <0 0x20c0000 0x40000>;
+
+       sa_config: subsys@0 {
+               compatible = "syscon";
+               reg = <0x0 0x100>;
+       };
+
+       rng@24000 {
+               compatible = "ti,keystone-rng";
+               reg = <0x24000 0x1000>;
+               ti,syscon-sa-cfg = <&sa_config>;
+               clocks = <&clksa>;
+               clock-names = "fck";
+       };
+};
index 9ec84228bc1669dfb6f5b51163c90f02dde72b04..a2e47bad3307a90290a1c33a98e7a8da5cd4779a 100644 (file)
@@ -208,3 +208,23 @@ netcp: netcp@26000000 {
                };
        };
 };
+
+sa_subsys: subsys@26080000 {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "simple-bus";
+       ranges = <0 0x26080000 0x40000>;
+
+       sa_config: subsys@0 {
+               compatible = "syscon";
+               reg = <0x0 0x100>;
+       };
+
+       rng@24000 {
+               compatible = "ti,keystone-rng";
+               reg = <0x24000 0x1000>;
+               ti,syscon-sa-cfg = <&sa_config>;
+               clocks = <&clksa>;
+               clock-names = "fck";
+       };
+};
index 3bb28c03ca74efb92caf73f06b01cd8428ba6828..ac343330d0c83f203526ba458f6ddad1a5357b0d 100644 (file)
                compatible = "ti,wl1273";
                reg = <2>;
                interrupt-parent = <&gpio1>;
-               interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; /* gpio 2 */
+               interrupts = <2 IRQ_TYPE_EDGE_RISING>; /* gpio 2 */
                ref-clock-frequency = <26000000>;
        };
 };
index 234afd6d60ec57f825744b8105549175ae90c0d0..9d5d53fbe9c0c0212684cae4738a461062a6ed3a 100644 (file)
@@ -48,7 +48,7 @@
                compatible = "ti,wl1283";
                reg = <2>;
                interrupt-parent = <&gpio5>;
-               interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; /* gpio 152 */
+               interrupts = <24 IRQ_TYPE_EDGE_RISING>; /* gpio 152 */
                ref-clock-frequency = <26000000>;
                tcxo-clock-frequency = <26000000>;
        };
index c55d479971ccbc689b67d24edef3403995fca6d3..f18490548c785eed2b4909bc6f8d258135e0ebba 100644 (file)
@@ -84,6 +84,7 @@
                        device_type = "cpu";
                        reg = <0xf01>;
                        clocks = <&clockgen 1 0>;
+                       #cooling-cells = <2>;
                };
        };
 
index d1eb123bc73b8200989a197e3559eb7e2d543441..1cdc346a05e8be4deca54a1a20631f7312d91b57 100644 (file)
@@ -92,6 +92,7 @@
                                 <&apmixedsys CLK_APMIXED_MAINPLL>;
                        clock-names = "cpu", "intermediate";
                        operating-points-v2 = <&cpu_opp_table>;
+                       #cooling-cells = <2>;
                        clock-frequency = <1300000000>;
                };
 
                                 <&apmixedsys CLK_APMIXED_MAINPLL>;
                        clock-names = "cpu", "intermediate";
                        operating-points-v2 = <&cpu_opp_table>;
+                       #cooling-cells = <2>;
                        clock-frequency = <1300000000>;
                };
 
                                 <&apmixedsys CLK_APMIXED_MAINPLL>;
                        clock-names = "cpu", "intermediate";
                        operating-points-v2 = <&cpu_opp_table>;
+                       #cooling-cells = <2>;
                        clock-frequency = <1300000000>;
                };
        };
index 531d905d924ffd027daffe31eafbabb944484c31..2b760f90f38c8996437c4cc9a245d1f7e2b16356 100644 (file)
 
                blue {
                        label = "bpi-r2:pio:blue";
-                       gpios = <&pio 241 GPIO_ACTIVE_HIGH>;
+                       gpios = <&pio 240 GPIO_ACTIVE_LOW>;
                        default-state = "off";
                };
 
                green {
                        label = "bpi-r2:pio:green";
-                       gpios = <&pio 240 GPIO_ACTIVE_HIGH>;
+                       gpios = <&pio 241 GPIO_ACTIVE_LOW>;
                        default-state = "off";
                };
 
                red {
                        label = "bpi-r2:pio:red";
-                       gpios = <&pio 239 GPIO_ACTIVE_HIGH>;
+                       gpios = <&pio 239 GPIO_ACTIVE_LOW>;
                        default-state = "off";
                };
        };
diff --git a/arch/arm/boot/dts/mt7623n-rfb-nand.dts b/arch/arm/boot/dts/mt7623n-rfb-nand.dts
deleted file mode 100644 (file)
index 96ff3c9..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2017 MediaTek Inc.
- * Author: John Crispin <john@phrozen.org>
- *
- */
-
-/dts-v1/;
-#include "mt7623n-rfb.dtsi"
-
-/ {
-       model = "MediaTek MT7623N NAND reference board";
-       compatible = "mediatek,mt7623n-rfb-nand", "mediatek,mt7623";
-};
-
-&bch {
-       status = "okay";
-};
-
-&nandc {
-       status = "okay";
-       pinctrl-names = "default";
-       pinctrl-0 = <&nand_pins_default>;
-
-       nand@0 {
-               reg = <0>;
-               spare_per_sector = <64>;
-               nand-ecc-mode = "hw";
-               nand-ecc-strength = <12>;
-               nand-ecc-step-size = <1024>;
-
-               partitions {
-                       compatible = "fixed-partitions";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-
-                       partition@0 {
-                               label = "preloader";
-                               reg = <0x0 0x40000>;
-                       };
-
-                       partition@40000 {
-                               label = "uboot";
-                               reg = <0x40000 0x80000>;
-                       };
-
-                       partition@c0000 {
-                               label = "uboot-env";
-                               reg = <0xC0000 0x40000>;
-                       };
-
-                       partition@140000 {
-                               label = "bootimg";
-                               reg = <0x140000 0x2000000>;
-                       };
-
-                       partition@2140000 {
-                               label = "recovery";
-                               reg = <0x2140000 0x2000000>;
-                       };
-
-                       partition@4140000 {
-                               label = "rootfs";
-                               reg = <0x4140000 0x1000000>;
-                       };
-
-                       partition@5140000 {
-                               label = "usrdata";
-                               reg = <0x5140000 0x1000000>;
-                       };
-               };
-       };
-};
diff --git a/arch/arm/boot/dts/mt7623n-rfb.dtsi b/arch/arm/boot/dts/mt7623n-rfb.dtsi
deleted file mode 100644 (file)
index 5c5cc7d..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2017 MediaTek Inc.
- * Author: John Crispin <john@phrozen.org>
- *        Sean Wang <sean.wang@mediatek.com>
- *
- */
-
-/dts-v1/;
-#include "mt7623.dtsi"
-#include "mt6323.dtsi"
-
-/ {
-       aliases {
-               serial0 = &uart0;
-               serial1 = &uart1;
-               serial2 = &uart2;
-       };
-
-       chosen {
-               stdout-path = "serial2:115200n8";
-       };
-
-       cpus {
-               cpu0 {
-                       proc-supply = <&mt6323_vproc_reg>;
-               };
-
-               cpu1 {
-                       proc-supply = <&mt6323_vproc_reg>;
-               };
-
-               cpu2 {
-                       proc-supply = <&mt6323_vproc_reg>;
-               };
-
-               cpu3 {
-                       proc-supply = <&mt6323_vproc_reg>;
-               };
-       };
-
-       memory@80000000 {
-               device_type = "memory";
-               reg = <0 0x80000000 0 0x40000000>;
-       };
-
-       usb_p1_vbus: regulator-5v {
-               compatible = "regulator-fixed";
-               regulator-name = "usb_vbus";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               gpio = <&pio 135 GPIO_ACTIVE_HIGH>;
-               enable-active-high;
-       };
-};
-
-&mmc0 {
-       vmmc-supply = <&mt6323_vemc3v3_reg>;
-       vqmmc-supply = <&mt6323_vio18_reg>;
-};
-
-&mmc1 {
-       vmmc-supply = <&mt6323_vmch_reg>;
-       vqmmc-supply = <&mt6323_vmc_reg>;
-};
-
-&uart0 {
-       status = "okay";
-};
-
-&uart1 {
-       status = "okay";
-};
-
-&uart2 {
-       status = "okay";
-};
-
-&usb1 {
-       vbus-supply = <&usb_p1_vbus>;
-       status = "okay";
-};
-
-&u3phy1 {
-       status = "okay";
-};
index 4994e33bf663d7fcbf5de4c2e61a2911029cbab4..632f52efdf980b00f25f134c6a779ed4d8ed4c92 100644 (file)
                compatible = "ti,wl1271";
                reg = <2>;
                interrupt-parent = <&gpio5>;
-               interrupts = <17 IRQ_TYPE_LEVEL_HIGH>; /* gpio 145 */
+               interrupts = <17 IRQ_TYPE_EDGE_RISING>; /* gpio 145 */
                ref-clock-frequency = <38400000>;
        };
 };
index 8c63ac5bbb12297911324d5df0efb687c4ced6e6..6e944dfa0f3d13056e63bc75524b54d528c56379 100644 (file)
@@ -81,7 +81,7 @@
                compatible = "ti,wl1271";
                reg = <2>;
                interrupt-parent = <&gpio5>;
-               interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; /* gpio 136 */
+               interrupts = <8 IRQ_TYPE_EDGE_RISING>; /* gpio 136 */
                ref-clock-frequency = <38400000>;
        };
 };
index ee64191e41ca187b60eda4e36dc7aeb641c34896..4c1227d1e79b399d35bf98777e41be2a69010dc4 100644 (file)
                compatible = "ti,wl1271";
                reg = <2>;
                interrupt-parent = <&gpio5>;
-               interrupts = <21 IRQ_TYPE_LEVEL_HIGH>; /* gpio 149 */
+               interrupts = <21 IRQ_TYPE_EDGE_RISING>; /* gpio 149 */
                ref-clock-frequency = <38400000>;
        };
 };
index 321c2b7a4e9fe1d067ce32d3fdf0409fdabffe91..285681d7af49d4cf4a865db730ece7af7335e321 100644 (file)
@@ -49,6 +49,6 @@
                compatible = "ti,wl1835";
                reg = <2>;
                interrupt-parent = <&gpio6>;
-               interrupts = <17 IRQ_TYPE_LEVEL_HIGH>; /* gpio 177 */
+               interrupts = <17 IRQ_TYPE_EDGE_RISING>; /* gpio 177 */
        };
 };
index 76dc08868bfb65b832c295ef06a4cf30f0a1566a..1adc73bd2ca0a028e3ca53e6f7f4faccfacc5250 100644 (file)
@@ -71,6 +71,6 @@
                compatible = "ti,wl1835";
                reg = <2>;
                interrupt-parent = <&gpio5>;
-               interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; /* gpio 136 */
+               interrupts = <8 IRQ_TYPE_EDGE_RISING>; /* gpio 136 */
        };
 };
index 96d0301a336a9b819828c9f0aef3cfe34d8bb5af..aac27a441331a3ff90b94bf69045fe944b337d34 100644 (file)
                compatible = "ti,wl1271";
                reg = <2>;
                interrupt-parent = <&gpio6>;
-               interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; /* gpio 162 */
+               interrupts = <2 IRQ_TYPE_EDGE_RISING>; /* gpio 162 */
                ref-clock-frequency = <26000000>;
        };
 };
index e7c3c563ff8f5d05bb022ed1c3be513f2e97ff66..04758a2a87f031eb42df555cc85a85bd0bf63816 100644 (file)
                        gpios = <&gpio5 26 GPIO_ACTIVE_LOW>; /* gpio154 */
                        linux,code = <KEY_VOLUMEDOWN>;
                        linux,can-disable;
+                       /* Value above 7.95ms for no GPIO hardware debounce */
+                       debounce-interval = <10>;
                };
 
                slider {
                        linux,input-type = <EV_SW>;
                        linux,code = <SW_KEYPAD_SLIDE>;
                        linux,can-disable;
-
+                       /* Value above 7.95ms for no GPIO hardware debounce */
+                       debounce-interval = <10>;
                };
        };
 
 &mmc2 {
        vmmc-supply = <&vsdio>;
        bus-width = <8>;
-       non-removable;
+       ti,non-removable;
 };
 
 &mmc3 {
                compatible = "ti,wl1285", "ti,wl1283";
                reg = <2>;
                interrupt-parent = <&gpio4>;
-               interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; /* gpio100 */
+               interrupts = <4 IRQ_TYPE_EDGE_RISING>; /* gpio100 */
                ref-clock-frequency = <26000000>;
                tcxo-clock-frequency = <26000000>;
        };
                OMAP4_IOPAD(0x10c, PIN_INPUT | MUX_MODE1)       /* abe_mcbsp3_fsx */
                >;
        };
-};
-
-&omap4_pmx_wkup {
-       usb_gpio_mux_sel2: pinmux_usb_gpio_mux_sel2_pins {
-               /* gpio_wk0 */
-               pinctrl-single,pins = <
-               OMAP4_IOPAD(0x040, PIN_OUTPUT_PULLDOWN | MUX_MODE3)
-               >;
-       };
 
        vibrator_direction_pin: pinmux_vibrator_direction_pin {
                pinctrl-single,pins = <
        };
 };
 
+&omap4_pmx_wkup {
+       usb_gpio_mux_sel2: pinmux_usb_gpio_mux_sel2_pins {
+               /* gpio_wk0 */
+               pinctrl-single,pins = <
+               OMAP4_IOPAD(0x040, PIN_OUTPUT_PULLDOWN | MUX_MODE3)
+               >;
+       };
+};
+
 /*
  * As uart1 is wired to mdm6600 with rts and cts, we can use the cts pin for
  * uart1 wakeirq.
index a9a584b5b9558d737c337806ae7f2d2f34840c7d..cfcac0d73851e3979fd25eb9de41f3156c145408 100644 (file)
@@ -36,6 +36,8 @@
                        label = "button0";
                        linux,code = <BTN_0>;
                        gpios = <&gpio4 25 GPIO_ACTIVE_LOW>;    /* gpio_121 */
+                       /* Value above 7.95ms for no GPIO hardware debounce */
+                       debounce-interval = <10>;
                        wakeup-source;
                };
        };
        ethernet@gpmc {
                reg = <5 0 0xff>;
                interrupt-parent = <&gpio2>;
-               interrupts = <12 IRQ_TYPE_LEVEL_LOW>;           /* gpio_44 */
+               interrupts = <12 IRQ_TYPE_EDGE_FALLING>;        /* gpio_44 */
 
                phy-mode = "mii";
 
index eb123b24c8e330141b7ece42c6dea74f0cc2a837..5e81691534147f256b72cc807109ef064db8cb80 100644 (file)
        ti,bus-width = <4>;
        ti,non-removable;
        cap-power-off-card;
+       keep-power-in-suspend;
 };
 
 &twl_usb_comparator {
diff --git a/arch/arm/boot/dts/omap4-l4.dtsi b/arch/arm/boot/dts/omap4-l4.dtsi
new file mode 100644 (file)
index 0000000..6eb26b8
--- /dev/null
@@ -0,0 +1,2444 @@
+// SPDX-License-Identifier: GPL-2.0
+&l4_cfg {                                              /* 0x4a000000 */
+       compatible = "ti,omap4-l4-cfg", "simple-bus";
+       reg = <0x4a000000 0x800>,
+             <0x4a000800 0x800>,
+             <0x4a001000 0x1000>;
+       reg-names = "ap", "la", "ia0";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       ranges = <0x00000000 0x4a000000 0x080000>,      /* segment 0 */
+                <0x00080000 0x4a080000 0x080000>,      /* segment 1 */
+                <0x00100000 0x4a100000 0x080000>,      /* segment 2 */
+                <0x00180000 0x4a180000 0x080000>,      /* segment 3 */
+                <0x00200000 0x4a200000 0x080000>,      /* segment 4 */
+                <0x00280000 0x4a280000 0x080000>,      /* segment 5 */
+                <0x00300000 0x4a300000 0x080000>;      /* segment 6 */
+
+       segment@0 {                                     /* 0x4a000000 */
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x00000000 0x00000000 0x000800>,      /* ap 0 */
+                        <0x00001000 0x00001000 0x001000>,      /* ap 1 */
+                        <0x00000800 0x00000800 0x000800>,      /* ap 2 */
+                        <0x00002000 0x00002000 0x001000>,      /* ap 3 */
+                        <0x00003000 0x00003000 0x001000>,      /* ap 4 */
+                        <0x00004000 0x00004000 0x001000>,      /* ap 5 */
+                        <0x00005000 0x00005000 0x001000>,      /* ap 6 */
+                        <0x00056000 0x00056000 0x001000>,      /* ap 7 */
+                        <0x00057000 0x00057000 0x001000>,      /* ap 8 */
+                        <0x0005c000 0x0005c000 0x001000>,      /* ap 9 */
+                        <0x00058000 0x00058000 0x004000>,      /* ap 10 */
+                        <0x00062000 0x00062000 0x001000>,      /* ap 11 */
+                        <0x00063000 0x00063000 0x001000>,      /* ap 12 */
+                        <0x00008000 0x00008000 0x002000>,      /* ap 23 */
+                        <0x0000a000 0x0000a000 0x001000>,      /* ap 24 */
+                        <0x00066000 0x00066000 0x001000>,      /* ap 25 */
+                        <0x00067000 0x00067000 0x001000>,      /* ap 26 */
+                        <0x0005e000 0x0005e000 0x002000>,      /* ap 80 */
+                        <0x00060000 0x00060000 0x001000>,      /* ap 81 */
+                        <0x00064000 0x00064000 0x001000>,      /* ap 86 */
+                        <0x00065000 0x00065000 0x001000>;      /* ap 87 */
+
+               target-module@2000 {                    /* 0x4a002000, ap 3 06.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "ctrl_module_core";
+                       reg = <0x2000 0x4>,
+                             <0x2010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, core_pwrdm, l4_cfg_clkdm */
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x2000 0x1000>;
+
+                       omap4_scm_core: scm@0 {
+                               compatible = "ti,omap4-scm-core", "simple-bus";
+                               reg = <0x0 0x1000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0 0x1000>;
+
+                               scm_conf: scm_conf@0 {
+                                       compatible = "syscon";
+                                       reg = <0x0 0x800>;
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+                               };
+
+                               omap_control_usb2phy: control-phy@300 {
+                                       compatible = "ti,control-phy-usb2";
+                                       reg = <0x300 0x4>;
+                                       reg-names = "power";
+                               };
+
+                               omap_control_usbotg: control-phy@33c {
+                                       compatible = "ti,control-phy-otghs";
+                                       reg = <0x33c 0x4>;
+                                       reg-names = "otghs_control";
+                               };
+                       };
+               };
+
+               target-module@4000 {                    /* 0x4a004000, ap 5 02.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0x4000 0x4>;
+                       reg-names = "rev";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x4000 0x1000>;
+
+                       cm1: cm1@0 {
+                               compatible = "ti,omap4-cm1", "simple-bus";
+                               reg = <0x0 0x2000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0 0x2000>;
+
+                               cm1_clocks: clocks {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                               };
+
+                               cm1_clockdomains: clockdomains {
+                               };
+                       };
+               };
+
+               target-module@8000 {                    /* 0x4a008000, ap 23 32.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0x8000 0x4>;
+                       reg-names = "rev";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x8000 0x2000>;
+
+                       cm2: cm2@0 {
+                               compatible = "ti,omap4-cm2", "simple-bus";
+                               reg = <0x0 0x2000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0 0x2000>;
+
+                               cm2_clocks: clocks {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                               };
+
+                               cm2_clockdomains: clockdomains {
+                               };
+                       };
+               };
+
+               target-module@56000 {                   /* 0x4a056000, ap 7 0a.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "dma_system";
+                       reg = <0x56000 0x4>,
+                             <0x5602c 0x4>,
+                             <0x56028 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_EMUFREE |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, core_pwrdm, l3_dma_clkdm */
+                       clocks = <&l3_dma_clkctrl OMAP4_DMA_SYSTEM_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x56000 0x1000>;
+
+                       sdma: dma-controller@0 {
+                               compatible = "ti,omap4430-sdma";
+                               reg = <0x0 0x1000>;
+                               interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+                               #dma-cells = <1>;
+                               dma-channels = <32>;
+                               dma-requests = <127>;
+                       };
+               };
+
+               target-module@58000 {                   /* 0x4a058000, ap 10 0e.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "hsi";
+                       reg = <0x58000 0x4>,
+                             <0x58010 0x4>,
+                             <0x58014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_EMUFREE |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l3init_pwrdm, l3_init_clkdm */
+                       clocks = <&l3_init_clkctrl OMAP4_HSI_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x58000 0x4000>;
+
+                       hsi: hsi@0 {
+                               compatible = "ti,omap4-hsi";
+                               reg = <0x0 0x4000>,
+                                     <0x4a05c000 0x1000>;
+                               reg-names = "sys", "gdd";
+
+                               clocks = <&l3_init_clkctrl OMAP4_HSI_CLKCTRL 0>;
+                               clock-names = "hsi_fck";
+
+                               interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "gdd_mpu";
+
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0 0x4000>;
+
+                               hsi_port1: hsi-port@2000 {
+                                       compatible = "ti,omap4-hsi-port";
+                                       reg = <0x2000 0x800>,
+                                             <0x2800 0x800>;
+                                       reg-names = "tx", "rx";
+                                       interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+
+                               hsi_port2: hsi-port@3000 {
+                                       compatible = "ti,omap4-hsi-port";
+                                       reg = <0x3000 0x800>,
+                                             <0x3800 0x800>;
+                                       reg-names = "tx", "rx";
+                                       interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+                       };
+               };
+
+               target-module@5e000 {                   /* 0x4a05e000, ap 80 68.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x5e000 0x2000>;
+               };
+
+               target-module@62000 {                   /* 0x4a062000, ap 11 16.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "usb_tll_hs";
+                       reg = <0x62000 0x4>,
+                             <0x62010 0x4>,
+                             <0x62014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       /* Domains (V, P, C): core, l3init_pwrdm, l3_init_clkdm */
+                       clocks = <&l3_init_clkctrl OMAP4_USB_TLL_HS_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x62000 0x1000>;
+
+                       usbhstll: usbhstll@0 {
+                               compatible = "ti,usbhs-tll";
+                               reg = <0x0 0x1000>;
+                               interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+               };
+
+               target-module@64000 {                   /* 0x4a064000, ap 86 1e.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "usb_host_hs";
+                       reg = <0x64000 0x4>,
+                             <0x64010 0x4>,
+                             <0x64014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>;
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, l3init_pwrdm, l3_init_clkdm */
+                       clocks = <&l3_init_clkctrl OMAP4_USB_HOST_HS_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x64000 0x1000>;
+
+                       usbhshost: usbhshost@0 {
+                               compatible = "ti,usbhs-host";
+                               reg = <0x0 0x800>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0 0x1000>;
+                               clocks = <&init_60m_fclk>,
+                                        <&xclk60mhsp1_ck>,
+                                        <&xclk60mhsp2_ck>;
+                               clock-names = "refclk_60m_int",
+                                             "refclk_60m_ext_p1",
+                                             "refclk_60m_ext_p2";
+
+                               usbhsohci: ohci@800 {
+                                       compatible = "ti,ohci-omap3";
+                                       reg = <0x800 0x400>;
+                                       interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+                                       remote-wakeup-connected;
+                               };
+
+                               usbhsehci: ehci@c00 {
+                                       compatible = "ti,ehci-omap";
+                                       reg = <0xc00 0x400>;
+                                       interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+                       };
+               };
+
+               target-module@66000 {                   /* 0x4a066000, ap 25 26.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "mmu_dsp";
+                       reg = <0x66000 0x4>,
+                             <0x66010 0x4>,
+                             <0x66014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       /* Domains (V, P, C): iva, tesla_pwrdm, tesla_clkdm */
+                       clocks = <&tesla_clkctrl OMAP4_DSP_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x66000 0x1000>;
+
+                       /* mmu_dsp cannot be moved before reset driver */
+                       status = "disabled";
+               };
+       };
+
+       segment@80000 {                                 /* 0x4a080000 */
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x00059000 0x000d9000 0x001000>,      /* ap 13 */
+                        <0x0005a000 0x000da000 0x001000>,      /* ap 14 */
+                        <0x0005b000 0x000db000 0x001000>,      /* ap 15 */
+                        <0x0005c000 0x000dc000 0x001000>,      /* ap 16 */
+                        <0x0005d000 0x000dd000 0x001000>,      /* ap 17 */
+                        <0x0005e000 0x000de000 0x001000>,      /* ap 18 */
+                        <0x00060000 0x000e0000 0x001000>,      /* ap 19 */
+                        <0x00061000 0x000e1000 0x001000>,      /* ap 20 */
+                        <0x00074000 0x000f4000 0x001000>,      /* ap 27 */
+                        <0x00075000 0x000f5000 0x001000>,      /* ap 28 */
+                        <0x00076000 0x000f6000 0x001000>,      /* ap 29 */
+                        <0x00077000 0x000f7000 0x001000>,      /* ap 30 */
+                        <0x00036000 0x000b6000 0x001000>,      /* ap 69 */
+                        <0x00037000 0x000b7000 0x001000>,      /* ap 70 */
+                        <0x0004d000 0x000cd000 0x001000>,      /* ap 78 */
+                        <0x0004e000 0x000ce000 0x001000>,      /* ap 79 */
+                        <0x00029000 0x000a9000 0x001000>,      /* ap 82 */
+                        <0x0002a000 0x000aa000 0x001000>,      /* ap 83 */
+                        <0x0002b000 0x000ab000 0x001000>,      /* ap 84 */
+                        <0x0002c000 0x000ac000 0x001000>,      /* ap 85 */
+                        <0x0002d000 0x000ad000 0x001000>,      /* ap 88 */
+                        <0x0002e000 0x000ae000 0x001000>;      /* ap 89 */
+
+               target-module@29000 {                   /* 0x4a0a9000, ap 82 04.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x29000 0x1000>;
+               };
+
+               target-module@2b000 {                   /* 0x4a0ab000, ap 84 12.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "usb_otg_hs";
+                       reg = <0x2b400 0x4>,
+                             <0x2b404 0x4>,
+                             <0x2b408 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l3init_pwrdm, l3_init_clkdm */
+                       clocks = <&l3_init_clkctrl OMAP4_USB_OTG_HS_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x2b000 0x1000>;
+
+                       usb_otg_hs: usb_otg_hs@0 {
+                               compatible = "ti,omap4-musb";
+                               reg = <0x0 0x7ff>;
+                               interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "mc", "dma";
+                               usb-phy = <&usb2_phy>;
+                               phys = <&usb2_phy>;
+                               phy-names = "usb2-phy";
+                               multipoint = <1>;
+                               num-eps = <16>;
+                               ram-bits = <12>;
+                               ctrl-module = <&omap_control_usbotg>;
+                       };
+               };
+
+               target-module@2d000 {                   /* 0x4a0ad000, ap 88 0c.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "ocp2scp_usb_phy";
+                       reg = <0x2d000 0x4>,
+                             <0x2d010 0x4>,
+                             <0x2d014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l3init_pwrdm, l3_init_clkdm */
+                       clocks = <&l3_init_clkctrl OMAP4_OCP2SCP_USB_PHY_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x2d000 0x1000>;
+
+                       ocp2scp@0 {
+                               compatible = "ti,omap-ocp2scp";
+                               reg = <0x0 0x1f>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0 0x1000>;
+                               usb2_phy: usb2phy@80 {
+                                       compatible = "ti,omap-usb2";
+                                       reg = <0x80 0x58>;
+                                       ctrl-module = <&omap_control_usb2phy>;
+                                       clocks = <&usb_phy_cm_clk32k>;
+                                       clock-names = "wkupclk";
+                                       #phy-cells = <0>;
+                               };
+                       };
+               };
+
+               target-module@36000 {                   /* 0x4a0b6000, ap 69 60.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x36000 0x1000>;
+               };
+
+               target-module@4d000 {                   /* 0x4a0cd000, ap 78 58.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x4d000 0x1000>;
+               };
+
+               target-module@59000 {                   /* 0x4a0d9000, ap 13 1a.0 */
+                       compatible = "ti,sysc-omap4-sr", "ti,sysc";
+                       ti,hwmods = "smartreflex_mpu";
+                       reg = <0x59038 0x4>;
+                       reg-names = "sysc";
+                       ti,sysc-mask = <SYSC_OMAP3_SR_ENAWAKEUP>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, always_on_core_pwrdm, l4_ao_clkdm */
+                       clocks = <&l4_ao_clkctrl OMAP4_SMARTREFLEX_MPU_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x59000 0x1000>;
+
+                       smartreflex_mpu: smartreflex@0 {
+                               compatible = "ti,omap4-smartreflex-mpu";
+                               reg = <0x0 0x80>;
+                               interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+               };
+
+               target-module@5b000 {                   /* 0x4a0db000, ap 15 08.0 */
+                       compatible = "ti,sysc-omap4-sr", "ti,sysc";
+                       ti,hwmods = "smartreflex_iva";
+                       reg = <0x5b038 0x4>;
+                       reg-names = "sysc";
+                       ti,sysc-mask = <SYSC_OMAP3_SR_ENAWAKEUP>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, always_on_core_pwrdm, l4_ao_clkdm */
+                       clocks = <&l4_ao_clkctrl OMAP4_SMARTREFLEX_IVA_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x5b000 0x1000>;
+
+                       smartreflex_iva: smartreflex@0 {
+                               compatible = "ti,omap4-smartreflex-iva";
+                               reg = <0x0 0x80>;
+                               interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+               };
+
+               target-module@5d000 {                   /* 0x4a0dd000, ap 17 22.0 */
+                       compatible = "ti,sysc-omap4-sr", "ti,sysc";
+                       ti,hwmods = "smartreflex_core";
+                       reg = <0x5d038 0x4>;
+                       reg-names = "sysc";
+                       ti,sysc-mask = <SYSC_OMAP3_SR_ENAWAKEUP>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, always_on_core_pwrdm, l4_ao_clkdm */
+                       clocks = <&l4_ao_clkctrl OMAP4_SMARTREFLEX_CORE_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x5d000 0x1000>;
+
+                       smartreflex_core: smartreflex@0 {
+                               compatible = "ti,omap4-smartreflex-core";
+                               reg = <0x0 0x80>;
+                               interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+               };
+
+               target-module@60000 {                   /* 0x4a0e0000, ap 19 1c.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x60000 0x1000>;
+               };
+
+               target-module@74000 {                   /* 0x4a0f4000, ap 27 24.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "mailbox";
+                       reg = <0x74000 0x4>,
+                             <0x74010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       /* Domains (V, P, C): core, core_pwrdm, l4_cfg_clkdm */
+                       clocks = <&l4_cfg_clkctrl OMAP4_MAILBOX_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x74000 0x1000>;
+
+                       mailbox: mailbox@0 {
+                               compatible = "ti,omap4-mailbox";
+                               reg = <0x0 0x200>;
+                               interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+                               #mbox-cells = <1>;
+                               ti,mbox-num-users = <3>;
+                               ti,mbox-num-fifos = <8>;
+                               mbox_ipu: mbox_ipu {
+                                       ti,mbox-tx = <0 0 0>;
+                                       ti,mbox-rx = <1 0 0>;
+                               };
+                               mbox_dsp: mbox_dsp {
+                                       ti,mbox-tx = <3 0 0>;
+                                       ti,mbox-rx = <2 0 0>;
+                               };
+                       };
+               };
+
+               target-module@76000 {                   /* 0x4a0f6000, ap 29 3a.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "spinlock";
+                       reg = <0x76000 0x4>,
+                             <0x76010 0x4>,
+                             <0x76014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, core_pwrdm, l4_cfg_clkdm */
+                       clocks = <&l4_cfg_clkctrl OMAP4_SPINLOCK_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x76000 0x1000>;
+
+                       hwspinlock: spinlock@0 {
+                               compatible = "ti,omap4-hwspinlock";
+                               reg = <0x0 0x1000>;
+                               #hwlock-cells = <1>;
+                       };
+               };
+       };
+
+       segment@100000 {                                        /* 0x4a100000 */
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x00000000 0x00100000 0x001000>,      /* ap 21 */
+                        <0x00001000 0x00101000 0x001000>,      /* ap 22 */
+                        <0x00002000 0x00102000 0x001000>,      /* ap 61 */
+                        <0x00003000 0x00103000 0x001000>,      /* ap 62 */
+                        <0x00008000 0x00108000 0x001000>,      /* ap 63 */
+                        <0x00009000 0x00109000 0x001000>,      /* ap 64 */
+                        <0x0000a000 0x0010a000 0x001000>,      /* ap 65 */
+                        <0x0000b000 0x0010b000 0x001000>;      /* ap 66 */
+
+               target-module@0 {                       /* 0x4a100000, ap 21 2a.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "ctrl_module_pad_core";
+                       reg = <0x0 0x4>,
+                             <0x10 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, core_pwrdm, l4_cfg_clkdm */
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x0 0x1000>;
+
+                       omap4_pmx_core: pinmux@40 {
+                               compatible = "ti,omap4-padconf",
+                                            "pinctrl-single";
+                               reg = <0x40 0x0196>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               #pinctrl-cells = <1>;
+                               #interrupt-cells = <1>;
+                               interrupt-controller;
+                               pinctrl-single,register-width = <16>;
+                               pinctrl-single,function-mask = <0x7fff>;
+                       };
+
+                       omap4_padconf_global: omap4_padconf_global@5a0 {
+                               compatible = "syscon",
+                                            "simple-bus";
+                               reg = <0x5a0 0x170>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x5a0 0x170>;
+
+                               pbias_regulator: pbias_regulator@60 {
+                                       compatible = "ti,pbias-omap4", "ti,pbias-omap";
+                                       reg = <0x60 0x4>;
+                                       syscon = <&omap4_padconf_global>;
+                                       pbias_mmc_reg: pbias_mmc_omap4 {
+                                               regulator-name = "pbias_mmc_omap4";
+                                               regulator-min-microvolt = <1800000>;
+                                               regulator-max-microvolt = <3000000>;
+                                       };
+                               };
+                       };
+               };
+
+               target-module@2000 {                    /* 0x4a102000, ap 61 3c.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x2000 0x1000>;
+               };
+
+               target-module@8000 {                    /* 0x4a108000, ap 63 62.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x8000 0x1000>;
+               };
+
+               target-module@a000 {                    /* 0x4a10a000, ap 65 50.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "fdif";
+                       reg = <0xa000 0x4>,
+                             <0xa010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>;
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-delay-us = <2>;
+                       /* Domains (V, P, C): core, cam_pwrdm, iss_clkdm */
+                       clocks = <&iss_clkctrl OMAP4_FDIF_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xa000 0x1000>;
+
+                       /* No child device binding or driver in mainline */
+               };
+       };
+
+       segment@180000 {                                        /* 0x4a180000 */
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+
+       segment@200000 {                                        /* 0x4a200000 */
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x0001e000 0x0021e000 0x001000>,      /* ap 31 */
+                        <0x0001f000 0x0021f000 0x001000>,      /* ap 32 */
+                        <0x0000a000 0x0020a000 0x001000>,      /* ap 33 */
+                        <0x0000b000 0x0020b000 0x001000>,      /* ap 34 */
+                        <0x00004000 0x00204000 0x001000>,      /* ap 35 */
+                        <0x00005000 0x00205000 0x001000>,      /* ap 36 */
+                        <0x00006000 0x00206000 0x001000>,      /* ap 37 */
+                        <0x00007000 0x00207000 0x001000>,      /* ap 38 */
+                        <0x00012000 0x00212000 0x001000>,      /* ap 39 */
+                        <0x00013000 0x00213000 0x001000>,      /* ap 40 */
+                        <0x0000c000 0x0020c000 0x001000>,      /* ap 41 */
+                        <0x0000d000 0x0020d000 0x001000>,      /* ap 42 */
+                        <0x00010000 0x00210000 0x001000>,      /* ap 43 */
+                        <0x00011000 0x00211000 0x001000>,      /* ap 44 */
+                        <0x00016000 0x00216000 0x001000>,      /* ap 45 */
+                        <0x00017000 0x00217000 0x001000>,      /* ap 46 */
+                        <0x00014000 0x00214000 0x001000>,      /* ap 47 */
+                        <0x00015000 0x00215000 0x001000>,      /* ap 48 */
+                        <0x00018000 0x00218000 0x001000>,      /* ap 49 */
+                        <0x00019000 0x00219000 0x001000>,      /* ap 50 */
+                        <0x00020000 0x00220000 0x001000>,      /* ap 51 */
+                        <0x00021000 0x00221000 0x001000>,      /* ap 52 */
+                        <0x00026000 0x00226000 0x001000>,      /* ap 53 */
+                        <0x00027000 0x00227000 0x001000>,      /* ap 54 */
+                        <0x00028000 0x00228000 0x001000>,      /* ap 55 */
+                        <0x00029000 0x00229000 0x001000>,      /* ap 56 */
+                        <0x0002a000 0x0022a000 0x001000>,      /* ap 57 */
+                        <0x0002b000 0x0022b000 0x001000>,      /* ap 58 */
+                        <0x0001c000 0x0021c000 0x001000>,      /* ap 59 */
+                        <0x0001d000 0x0021d000 0x001000>;      /* ap 60 */
+
+               target-module@4000 {                    /* 0x4a204000, ap 35 42.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x4000 0x1000>;
+               };
+
+               target-module@6000 {                    /* 0x4a206000, ap 37 4a.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x6000 0x1000>;
+               };
+
+               target-module@a000 {                    /* 0x4a20a000, ap 33 2c.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xa000 0x1000>;
+               };
+
+               target-module@c000 {                    /* 0x4a20c000, ap 41 20.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xc000 0x1000>;
+               };
+
+               target-module@10000 {                   /* 0x4a210000, ap 43 52.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x10000 0x1000>;
+               };
+
+               target-module@12000 {                   /* 0x4a212000, ap 39 18.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x12000 0x1000>;
+               };
+
+               target-module@14000 {                   /* 0x4a214000, ap 47 30.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x14000 0x1000>;
+               };
+
+               target-module@16000 {                   /* 0x4a216000, ap 45 28.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x16000 0x1000>;
+               };
+
+               target-module@18000 {                   /* 0x4a218000, ap 49 38.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x18000 0x1000>;
+               };
+
+               target-module@1c000 {                   /* 0x4a21c000, ap 59 5a.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x1c000 0x1000>;
+               };
+
+               target-module@1e000 {                   /* 0x4a21e000, ap 31 10.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x1e000 0x1000>;
+               };
+
+               target-module@20000 {                   /* 0x4a220000, ap 51 40.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x20000 0x1000>;
+               };
+
+               target-module@26000 {                   /* 0x4a226000, ap 53 34.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x26000 0x1000>;
+               };
+
+               target-module@28000 {                   /* 0x4a228000, ap 55 2e.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x28000 0x1000>;
+               };
+
+               target-module@2a000 {                   /* 0x4a22a000, ap 57 48.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x2a000 0x1000>;
+               };
+       };
+
+       segment@280000 {                                        /* 0x4a280000 */
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+
+       l4_cfg_segment_300000: segment@300000 {                 /* 0x4a300000 */
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x00000000 0x00300000 0x020000>,      /* ap 67 */
+                        <0x00040000 0x00340000 0x001000>,      /* ap 68 */
+                        <0x00020000 0x00320000 0x004000>,      /* ap 71 */
+                        <0x00024000 0x00324000 0x002000>,      /* ap 72 */
+                        <0x00026000 0x00326000 0x001000>,      /* ap 73 */
+                        <0x00027000 0x00327000 0x001000>,      /* ap 74 */
+                        <0x00028000 0x00328000 0x001000>,      /* ap 75 */
+                        <0x00029000 0x00329000 0x001000>,      /* ap 76 */
+                        <0x00030000 0x00330000 0x010000>,      /* ap 77 */
+                        <0x0002a000 0x0032a000 0x002000>,      /* ap 90 */
+                        <0x0002c000 0x0032c000 0x004000>;      /* ap 91 */
+
+               l4_cfg_target_0: target-module@0 {      /* 0x4a300000, ap 67 14.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x00000000 0x00000000 0x00020000>,
+                                <0x00020000 0x00020000 0x00004000>,
+                                <0x00024000 0x00024000 0x00002000>,
+                                <0x00026000 0x00026000 0x00001000>,
+                                <0x00027000 0x00027000 0x00001000>,
+                                <0x00028000 0x00028000 0x00001000>,
+                                <0x00029000 0x00029000 0x00001000>,
+                                <0x0002a000 0x0002a000 0x00002000>,
+                                <0x0002c000 0x0002c000 0x00004000>,
+                                <0x00030000 0x00030000 0x00010000>;
+               };
+       };
+};
+
+&l4_wkup {                                             /* 0x4a300000 */
+       compatible = "ti,omap4-l4-wkup", "simple-bus";
+       reg = <0x4a300000 0x800>,
+             <0x4a300800 0x800>,
+             <0x4a301000 0x1000>;
+       reg-names = "ap", "la", "ia0";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       ranges = <0x00000000 0x4a300000 0x010000>,      /* segment 0 */
+                <0x00010000 0x4a310000 0x010000>,      /* segment 1 */
+                <0x00020000 0x4a320000 0x010000>;      /* segment 2 */
+
+       segment@0 {                                     /* 0x4a300000 */
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x00000000 0x00000000 0x000800>,      /* ap 0 */
+                        <0x00001000 0x00001000 0x001000>,      /* ap 1 */
+                        <0x00000800 0x00000800 0x000800>,      /* ap 2 */
+                        <0x00006000 0x00006000 0x002000>,      /* ap 3 */
+                        <0x00008000 0x00008000 0x001000>,      /* ap 4 */
+                        <0x0000a000 0x0000a000 0x001000>,      /* ap 15 */
+                        <0x0000b000 0x0000b000 0x001000>,      /* ap 16 */
+                        <0x00004000 0x00004000 0x001000>,      /* ap 17 */
+                        <0x00005000 0x00005000 0x001000>,      /* ap 18 */
+                        <0x0000c000 0x0000c000 0x001000>,      /* ap 19 */
+                        <0x0000d000 0x0000d000 0x001000>;      /* ap 20 */
+
+               target-module@4000 {                    /* 0x4a304000, ap 17 24.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "counter_32k";
+                       reg = <0x4000 0x4>,
+                             <0x4004 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>;
+                       /* Domains (V, P, C): wakeup, wkup_pwrdm, l4_wkup_clkdm */
+                       clocks = <&l4_wkup_clkctrl OMAP4_COUNTER_32K_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x4000 0x1000>;
+
+                       counter32k: counter@0 {
+                               compatible = "ti,omap-counter32k";
+                               reg = <0x0 0x20>;
+                       };
+               };
+
+               target-module@6000 {                    /* 0x4a306000, ap 3 08.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0x6000 0x4>;
+                       reg-names = "rev";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x6000 0x2000>;
+
+                       prm: prm@0 {
+                               compatible = "ti,omap4-prm";
+                               reg = <0x0 0x2000>;
+                               interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0 0x2000>;
+
+                               prm_clocks: clocks {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                               };
+
+                               prm_clockdomains: clockdomains {
+                               };
+                       };
+               };
+
+               target-module@a000 {                    /* 0x4a30a000, ap 15 34.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0xa000 0x4>;
+                       reg-names = "rev";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xa000 0x1000>;
+
+                       scrm: scrm@0 {
+                               compatible = "ti,omap4-scrm";
+                               reg = <0x0 0x2000>;
+
+                               scrm_clocks: clocks {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                               };
+
+                               scrm_clockdomains: clockdomains {
+                               };
+                       };
+               };
+
+               target-module@c000 {                    /* 0x4a30c000, ap 19 2c.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "ctrl_module_wkup";
+                       reg = <0xc000 0x4>,
+                             <0xc010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): wakeup, wkup_pwrdm, l4_wkup_clkdm */
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xc000 0x1000>;
+
+                       omap4_scm_wkup: scm@c000 {
+                               compatible = "ti,omap4-scm-wkup";
+                               reg = <0xc000 0x1000>;
+                       };
+               };
+       };
+
+       segment@10000 {                                 /* 0x4a310000 */
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x00000000 0x00010000 0x001000>,      /* ap 5 */
+                        <0x00001000 0x00011000 0x001000>,      /* ap 6 */
+                        <0x00004000 0x00014000 0x001000>,      /* ap 7 */
+                        <0x00005000 0x00015000 0x001000>,      /* ap 8 */
+                        <0x00008000 0x00018000 0x001000>,      /* ap 9 */
+                        <0x00009000 0x00019000 0x001000>,      /* ap 10 */
+                        <0x0000c000 0x0001c000 0x001000>,      /* ap 11 */
+                        <0x0000d000 0x0001d000 0x001000>,      /* ap 12 */
+                        <0x0000e000 0x0001e000 0x001000>,      /* ap 21 */
+                        <0x0000f000 0x0001f000 0x001000>;      /* ap 22 */
+
+               gpio1_target: target-module@0 {                 /* 0x4a310000, ap 5 14.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "gpio1";
+                       reg = <0x0 0x4>,
+                             <0x10 0x4>,
+                             <0x114 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): wakeup, wkup_pwrdm, l4_wkup_clkdm */
+                       clocks = <&l4_wkup_clkctrl OMAP4_GPIO1_CLKCTRL 0>,
+                                <&l4_wkup_clkctrl OMAP4_GPIO1_CLKCTRL 8>;
+                       clock-names = "fck", "dbclk";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x0 0x1000>;
+
+                       gpio1: gpio@0 {
+                               compatible = "ti,omap4-gpio";
+                               reg = <0x0 0x200>;
+                               interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+                               ti,gpio-always-on;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+               };
+
+               target-module@4000 {                    /* 0x4a314000, ap 7 18.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "wd_timer2";
+                       reg = <0x4000 0x4>,
+                             <0x4010 0x4>,
+                             <0x4014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_EMUFREE |
+                                        SYSC_OMAP2_SOFTRESET)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): wakeup, wkup_pwrdm, l4_wkup_clkdm */
+                       clocks = <&l4_wkup_clkctrl OMAP4_WD_TIMER2_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x4000 0x1000>;
+
+                       wdt2: wdt@0 {
+                               compatible = "ti,omap4-wdt", "ti,omap3-wdt";
+                               reg = <0x0 0x80>;
+                               interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+               };
+
+               target-module@8000 {                    /* 0x4a318000, ap 9 1c.0 */
+                       compatible = "ti,sysc-omap2-timer", "ti,sysc";
+                       ti,hwmods = "timer1";
+                       reg = <0x8000 0x4>,
+                             <0x8010 0x4>,
+                             <0x8014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_EMUFREE |
+                                        SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): wakeup, wkup_pwrdm, l4_wkup_clkdm */
+                       clocks = <&l4_wkup_clkctrl OMAP4_TIMER1_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x8000 0x1000>;
+
+                       timer1: timer@0 {
+                               compatible = "ti,omap3430-timer";
+                               reg = <0x0 0x80>;
+                               clocks = <&l4_wkup_clkctrl OMAP4_TIMER1_CLKCTRL 24>;
+                               clock-names = "fck";
+                               interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+                               ti,timer-alwon;
+                       };
+               };
+
+               target-module@c000 {                    /* 0x4a31c000, ap 11 20.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "kbd";
+                       reg = <0xc000 0x4>,
+                             <0xc010 0x4>,
+                             <0xc014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_EMUFREE |
+                                        SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): wakeup, wkup_pwrdm, l4_wkup_clkdm */
+                       clocks = <&l4_wkup_clkctrl OMAP4_KBD_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xc000 0x1000>;
+
+                       keypad: keypad@0 {
+                               compatible = "ti,omap4-keypad";
+                               reg = <0x0 0x80>;
+                               interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+                               reg-names = "mpu";
+                       };
+               };
+
+               target-module@e000 {                    /* 0x4a31e000, ap 21 30.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "ctrl_module_pad_wkup";
+                       reg = <0xe000 0x4>,
+                             <0xe010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): wakeup, wkup_pwrdm, l4_wkup_clkdm */
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xe000 0x1000>;
+
+                       omap4_pmx_wkup: pinmux@40 {
+                               compatible = "ti,omap4-padconf",
+                                            "pinctrl-single";
+                               reg = <0x40 0x0038>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               #pinctrl-cells = <1>;
+                               #interrupt-cells = <1>;
+                               interrupt-controller;
+                               pinctrl-single,register-width = <16>;
+                               pinctrl-single,function-mask = <0x7fff>;
+                       };
+               };
+       };
+
+       segment@20000 {                                 /* 0x4a320000 */
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x00006000 0x00026000 0x001000>,      /* ap 13 */
+                        <0x0000a000 0x0002a000 0x001000>,      /* ap 14 */
+                        <0x00000000 0x00020000 0x001000>,      /* ap 23 */
+                        <0x00001000 0x00021000 0x001000>,      /* ap 24 */
+                        <0x00002000 0x00022000 0x001000>,      /* ap 25 */
+                        <0x00003000 0x00023000 0x001000>,      /* ap 26 */
+                        <0x00004000 0x00024000 0x001000>,      /* ap 27 */
+                        <0x00005000 0x00025000 0x001000>,      /* ap 28 */
+                        <0x00007000 0x00027000 0x000400>,      /* ap 29 */
+                        <0x00008000 0x00028000 0x000800>,      /* ap 30 */
+                        <0x00009000 0x00029000 0x000400>;      /* ap 31 */
+
+               target-module@0 {                       /* 0x4a320000, ap 23 04.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x0 0x1000>;
+               };
+
+               target-module@2000 {                    /* 0x4a322000, ap 25 0c.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x2000 0x1000>;
+               };
+
+               target-module@4000 {                    /* 0x4a324000, ap 27 10.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x4000 0x1000>;
+               };
+
+               target-module@6000 {                    /* 0x4a326000, ap 13 28.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x00000000 0x00006000 0x00001000>,
+                                <0x00001000 0x00007000 0x00000400>,
+                                <0x00002000 0x00008000 0x00000800>,
+                                <0x00003000 0x00009000 0x00000400>;
+               };
+       };
+};
+
+&l4_per {                                              /* 0x48000000 */
+       compatible = "ti,omap4-l4-per", "simple-bus";
+       reg = <0x48000000 0x800>,
+             <0x48000800 0x800>,
+             <0x48001000 0x400>,
+             <0x48001400 0x400>,
+             <0x48001800 0x400>,
+             <0x48001c00 0x400>;
+       reg-names = "ap", "la", "ia0", "ia1", "ia2", "ia3";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       ranges = <0x00000000 0x48000000 0x200000>,      /* segment 0 */
+                <0x00200000 0x48200000 0x200000>;      /* segment 1 */
+
+       segment@0 {                                     /* 0x48000000 */
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x00000000 0x00000000 0x000800>,      /* ap 0 */
+                        <0x00001000 0x00001000 0x000400>,      /* ap 1 */
+                        <0x00000800 0x00000800 0x000800>,      /* ap 2 */
+                        <0x00020000 0x00020000 0x001000>,      /* ap 3 */
+                        <0x00021000 0x00021000 0x001000>,      /* ap 4 */
+                        <0x00032000 0x00032000 0x001000>,      /* ap 5 */
+                        <0x00033000 0x00033000 0x001000>,      /* ap 6 */
+                        <0x00034000 0x00034000 0x001000>,      /* ap 7 */
+                        <0x00035000 0x00035000 0x001000>,      /* ap 8 */
+                        <0x00036000 0x00036000 0x001000>,      /* ap 9 */
+                        <0x00037000 0x00037000 0x001000>,      /* ap 10 */
+                        <0x0003e000 0x0003e000 0x001000>,      /* ap 11 */
+                        <0x0003f000 0x0003f000 0x001000>,      /* ap 12 */
+                        <0x00040000 0x00040000 0x010000>,      /* ap 13 */
+                        <0x00050000 0x00050000 0x001000>,      /* ap 14 */
+                        <0x00055000 0x00055000 0x001000>,      /* ap 15 */
+                        <0x00056000 0x00056000 0x001000>,      /* ap 16 */
+                        <0x00057000 0x00057000 0x001000>,      /* ap 17 */
+                        <0x00058000 0x00058000 0x001000>,      /* ap 18 */
+                        <0x00059000 0x00059000 0x001000>,      /* ap 19 */
+                        <0x0005a000 0x0005a000 0x001000>,      /* ap 20 */
+                        <0x0005b000 0x0005b000 0x001000>,      /* ap 21 */
+                        <0x0005c000 0x0005c000 0x001000>,      /* ap 22 */
+                        <0x0005d000 0x0005d000 0x001000>,      /* ap 23 */
+                        <0x0005e000 0x0005e000 0x001000>,      /* ap 24 */
+                        <0x00060000 0x00060000 0x001000>,      /* ap 25 */
+                        <0x0006a000 0x0006a000 0x001000>,      /* ap 26 */
+                        <0x0006b000 0x0006b000 0x001000>,      /* ap 27 */
+                        <0x0006c000 0x0006c000 0x001000>,      /* ap 28 */
+                        <0x0006d000 0x0006d000 0x001000>,      /* ap 29 */
+                        <0x0006e000 0x0006e000 0x001000>,      /* ap 30 */
+                        <0x0006f000 0x0006f000 0x001000>,      /* ap 31 */
+                        <0x00070000 0x00070000 0x001000>,      /* ap 32 */
+                        <0x00071000 0x00071000 0x001000>,      /* ap 33 */
+                        <0x00072000 0x00072000 0x001000>,      /* ap 34 */
+                        <0x00073000 0x00073000 0x001000>,      /* ap 35 */
+                        <0x00061000 0x00061000 0x001000>,      /* ap 36 */
+                        <0x00096000 0x00096000 0x001000>,      /* ap 37 */
+                        <0x00097000 0x00097000 0x001000>,      /* ap 38 */
+                        <0x00076000 0x00076000 0x001000>,      /* ap 39 */
+                        <0x00077000 0x00077000 0x001000>,      /* ap 40 */
+                        <0x00078000 0x00078000 0x001000>,      /* ap 41 */
+                        <0x00079000 0x00079000 0x001000>,      /* ap 42 */
+                        <0x00086000 0x00086000 0x001000>,      /* ap 43 */
+                        <0x00087000 0x00087000 0x001000>,      /* ap 44 */
+                        <0x00088000 0x00088000 0x001000>,      /* ap 45 */
+                        <0x00089000 0x00089000 0x001000>,      /* ap 46 */
+                        <0x000b0000 0x000b0000 0x001000>,      /* ap 47 */
+                        <0x000b1000 0x000b1000 0x001000>,      /* ap 48 */
+                        <0x00098000 0x00098000 0x001000>,      /* ap 49 */
+                        <0x00099000 0x00099000 0x001000>,      /* ap 50 */
+                        <0x0009a000 0x0009a000 0x001000>,      /* ap 51 */
+                        <0x0009b000 0x0009b000 0x001000>,      /* ap 52 */
+                        <0x0009c000 0x0009c000 0x001000>,      /* ap 53 */
+                        <0x0009d000 0x0009d000 0x001000>,      /* ap 54 */
+                        <0x0009e000 0x0009e000 0x001000>,      /* ap 55 */
+                        <0x0009f000 0x0009f000 0x001000>,      /* ap 56 */
+                        <0x00090000 0x00090000 0x002000>,      /* ap 57 */
+                        <0x00092000 0x00092000 0x001000>,      /* ap 58 */
+                        <0x000a4000 0x000a4000 0x001000>,      /* ap 59 */
+                        <0x000a6000 0x000a6000 0x001000>,      /* ap 60 */
+                        <0x000a8000 0x000a8000 0x004000>,      /* ap 61 */
+                        <0x000ac000 0x000ac000 0x001000>,      /* ap 62 */
+                        <0x000ad000 0x000ad000 0x001000>,      /* ap 63 */
+                        <0x000ae000 0x000ae000 0x001000>,      /* ap 64 */
+                        <0x000b2000 0x000b2000 0x001000>,      /* ap 65 */
+                        <0x000b3000 0x000b3000 0x001000>,      /* ap 66 */
+                        <0x000b4000 0x000b4000 0x001000>,      /* ap 67 */
+                        <0x000b5000 0x000b5000 0x001000>,      /* ap 68 */
+                        <0x000b8000 0x000b8000 0x001000>,      /* ap 69 */
+                        <0x000b9000 0x000b9000 0x001000>,      /* ap 70 */
+                        <0x000ba000 0x000ba000 0x001000>,      /* ap 71 */
+                        <0x000bb000 0x000bb000 0x001000>,      /* ap 72 */
+                        <0x000d1000 0x000d1000 0x001000>,      /* ap 73 */
+                        <0x000d2000 0x000d2000 0x001000>,      /* ap 74 */
+                        <0x000d5000 0x000d5000 0x001000>,      /* ap 75 */
+                        <0x000d6000 0x000d6000 0x001000>,      /* ap 76 */
+                        <0x000a2000 0x000a2000 0x001000>,      /* ap 79 */
+                        <0x000a3000 0x000a3000 0x001000>,      /* ap 80 */
+                        <0x00001400 0x00001400 0x000400>,      /* ap 81 */
+                        <0x00001800 0x00001800 0x000400>,      /* ap 82 */
+                        <0x00001c00 0x00001c00 0x000400>,      /* ap 83 */
+                        <0x000a5000 0x000a5000 0x001000>;      /* ap 84 */
+
+               target-module@20000 {                   /* 0x48020000, ap 3 06.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "uart3";
+                       reg = <0x20050 0x4>,
+                             <0x20054 0x4>,
+                             <0x20058 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_UART3_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x20000 0x1000>;
+
+                       uart3: serial@0 {
+                               compatible = "ti,omap4-uart";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+                               clock-frequency = <48000000>;
+                       };
+               };
+
+               target-module@32000 {                   /* 0x48032000, ap 5 02.0 */
+                       compatible = "ti,sysc-omap2-timer", "ti,sysc";
+                       ti,hwmods = "timer2";
+                       reg = <0x32000 0x4>,
+                             <0x32010 0x4>,
+                             <0x32014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_EMUFREE |
+                                        SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_TIMER2_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x32000 0x1000>;
+
+                       timer2: timer@0 {
+                               compatible = "ti,omap3430-timer";
+                               reg = <0x0 0x80>;
+                               clocks = <&l4_per_clkctrl OMAP4_TIMER2_CLKCTRL 24>;
+                               clock-names = "fck";
+                               interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+               };
+
+               target-module@34000 {                   /* 0x48034000, ap 7 04.0 */
+                       compatible = "ti,sysc-omap4-timer", "ti,sysc";
+                       ti,hwmods = "timer3";
+                       reg = <0x34000 0x4>,
+                             <0x34010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP4_FREEEMU |
+                                        SYSC_OMAP4_SOFTRESET)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_TIMER3_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x34000 0x1000>;
+
+                       timer3: timer@0 {
+                               compatible = "ti,omap4430-timer";
+                               reg = <0x0 0x80>;
+                               clocks = <&l4_per_clkctrl OMAP4_TIMER3_CLKCTRL 24>;
+                               clock-names = "fck";
+                               interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+               };
+
+               target-module@36000 {                   /* 0x48036000, ap 9 0e.0 */
+                       compatible = "ti,sysc-omap4-timer", "ti,sysc";
+                       ti,hwmods = "timer4";
+                       reg = <0x36000 0x4>,
+                             <0x36010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP4_FREEEMU |
+                                        SYSC_OMAP4_SOFTRESET)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_TIMER4_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x36000 0x1000>;
+
+                       timer4: timer@0 {
+                               compatible = "ti,omap4430-timer";
+                               reg = <0x0 0x80>;
+                               clocks = <&l4_per_clkctrl OMAP4_TIMER4_CLKCTRL 24>;
+                               clock-names = "fck";
+                               interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+               };
+
+               target-module@3e000 {                   /* 0x4803e000, ap 11 08.0 */
+                       compatible = "ti,sysc-omap4-timer", "ti,sysc";
+                       ti,hwmods = "timer9";
+                       reg = <0x3e000 0x4>,
+                             <0x3e010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP4_FREEEMU |
+                                        SYSC_OMAP4_SOFTRESET)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_TIMER9_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x3e000 0x1000>;
+
+                       timer9: timer@0 {
+                               compatible = "ti,omap4430-timer";
+                               reg = <0x0 0x80>;
+                               clocks = <&l4_per_clkctrl OMAP4_TIMER9_CLKCTRL 24>;
+                               clock-names = "fck";
+                               interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+                               ti,timer-pwm;
+                       };
+               };
+
+               target-module@40000 {                   /* 0x48040000, ap 13 0a.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x40000 0x10000>;
+               };
+
+               target-module@55000 {                   /* 0x48055000, ap 15 0c.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "gpio2";
+                       reg = <0x55000 0x4>,
+                             <0x55010 0x4>,
+                             <0x55114 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_GPIO2_CLKCTRL 0>,
+                                <&l4_per_clkctrl OMAP4_GPIO2_CLKCTRL 8>;
+                       clock-names = "fck", "dbclk";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x55000 0x1000>;
+
+                       gpio2: gpio@0 {
+                               compatible = "ti,omap4-gpio";
+                               reg = <0x0 0x200>;
+                               interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+               };
+
+               target-module@57000 {                   /* 0x48057000, ap 17 16.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "gpio3";
+                       reg = <0x57000 0x4>,
+                             <0x57010 0x4>,
+                             <0x57114 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_GPIO3_CLKCTRL 0>,
+                                <&l4_per_clkctrl OMAP4_GPIO3_CLKCTRL 8>;
+                       clock-names = "fck", "dbclk";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x57000 0x1000>;
+
+                       gpio3: gpio@0 {
+                               compatible = "ti,omap4-gpio";
+                               reg = <0x0 0x200>;
+                               interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+               };
+
+               target-module@59000 {                   /* 0x48059000, ap 19 10.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "gpio4";
+                       reg = <0x59000 0x4>,
+                             <0x59010 0x4>,
+                             <0x59114 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_GPIO4_CLKCTRL 0>,
+                                <&l4_per_clkctrl OMAP4_GPIO4_CLKCTRL 8>;
+                       clock-names = "fck", "dbclk";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x59000 0x1000>;
+
+                       gpio4: gpio@0 {
+                               compatible = "ti,omap4-gpio";
+                               reg = <0x0 0x200>;
+                               interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+               };
+
+               target-module@5b000 {                   /* 0x4805b000, ap 21 12.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "gpio5";
+                       reg = <0x5b000 0x4>,
+                             <0x5b010 0x4>,
+                             <0x5b114 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_GPIO5_CLKCTRL 0>,
+                                <&l4_per_clkctrl OMAP4_GPIO5_CLKCTRL 8>;
+                       clock-names = "fck", "dbclk";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x5b000 0x1000>;
+
+                       gpio5: gpio@0 {
+                               compatible = "ti,omap4-gpio";
+                               reg = <0x0 0x200>;
+                               interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+               };
+
+               target-module@5d000 {                   /* 0x4805d000, ap 23 14.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "gpio6";
+                       reg = <0x5d000 0x4>,
+                             <0x5d010 0x4>,
+                             <0x5d114 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_GPIO6_CLKCTRL 0>,
+                                <&l4_per_clkctrl OMAP4_GPIO6_CLKCTRL 8>;
+                       clock-names = "fck", "dbclk";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x5d000 0x1000>;
+
+                       gpio6: gpio@0 {
+                               compatible = "ti,omap4-gpio";
+                               reg = <0x0 0x200>;
+                               interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+               };
+
+               target-module@60000 {                   /* 0x48060000, ap 25 1e.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "i2c3";
+                       reg = <0x60000 0x8>,
+                             <0x60010 0x8>,
+                             <0x60090 0x8>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_I2C3_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x60000 0x1000>;
+
+                       i2c3: i2c@0 {
+                               compatible = "ti,omap4-i2c";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                       };
+               };
+
+               target-module@6a000 {                   /* 0x4806a000, ap 26 18.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "uart1";
+                       reg = <0x6a050 0x4>,
+                             <0x6a054 0x4>,
+                             <0x6a058 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_UART1_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x6a000 0x1000>;
+
+                       uart1: serial@0 {
+                               compatible = "ti,omap4-uart";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+                               clock-frequency = <48000000>;
+                       };
+               };
+
+               target-module@6c000 {                   /* 0x4806c000, ap 28 20.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "uart2";
+                       reg = <0x6c050 0x4>,
+                             <0x6c054 0x4>,
+                             <0x6c058 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_UART2_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x6c000 0x1000>;
+
+                       uart2: serial@0 {
+                               compatible = "ti,omap4-uart";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+                               clock-frequency = <48000000>;
+                       };
+               };
+
+               target-module@6e000 {                   /* 0x4806e000, ap 30 1c.1 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "uart4";
+                       reg = <0x6e050 0x4>,
+                             <0x6e054 0x4>,
+                             <0x6e058 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_UART4_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x6e000 0x1000>;
+
+                       uart4: serial@0 {
+                               compatible = "ti,omap4-uart";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+                               clock-frequency = <48000000>;
+                       };
+               };
+
+               target-module@70000 {                   /* 0x48070000, ap 32 28.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "i2c1";
+                       reg = <0x70000 0x8>,
+                             <0x70010 0x8>,
+                             <0x70090 0x8>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_I2C1_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x70000 0x1000>;
+
+                       i2c1: i2c@0 {
+                               compatible = "ti,omap4-i2c";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                       };
+               };
+
+               target-module@72000 {                   /* 0x48072000, ap 34 30.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "i2c2";
+                       reg = <0x72000 0x8>,
+                             <0x72010 0x8>,
+                             <0x72090 0x8>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_I2C2_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x72000 0x1000>;
+
+                       i2c2: i2c@0 {
+                               compatible = "ti,omap4-i2c";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                       };
+               };
+
+               target-module@76000 {                   /* 0x48076000, ap 39 38.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "slimbus2";
+                       reg = <0x76000 0x4>,
+                             <0x76010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_SLIMBUS2_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x76000 0x1000>;
+
+                       /* No child device binding or driver in mainline */
+               };
+
+               target-module@78000 {                   /* 0x48078000, ap 41 1a.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "elm";
+                       reg = <0x78000 0x4>,
+                             <0x78010 0x4>,
+                             <0x78014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_ELM_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x78000 0x1000>;
+
+                       elm: elm@0 {
+                               compatible = "ti,am3352-elm";
+                               reg = <0x0 0x2000>;
+                               interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+               };
+
+               target-module@86000 {                   /* 0x48086000, ap 43 24.0 */
+                       compatible = "ti,sysc-omap2-timer", "ti,sysc";
+                       ti,hwmods = "timer10";
+                       reg = <0x86000 0x4>,
+                             <0x86010 0x4>,
+                             <0x86014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_EMUFREE |
+                                        SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_TIMER10_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x86000 0x1000>;
+
+                       timer10: timer@0 {
+                               compatible = "ti,omap3430-timer";
+                               reg = <0x0 0x80>;
+                               clocks = <&l4_per_clkctrl OMAP4_TIMER10_CLKCTRL 24>;
+                               clock-names = "fck";
+                               interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+                               ti,timer-pwm;
+                       };
+               };
+
+               target-module@88000 {                   /* 0x48088000, ap 45 2e.0 */
+                       compatible = "ti,sysc-omap4-timer", "ti,sysc";
+                       ti,hwmods = "timer11";
+                       reg = <0x88000 0x4>,
+                             <0x88010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP4_FREEEMU |
+                                        SYSC_OMAP4_SOFTRESET)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_TIMER11_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x88000 0x1000>;
+
+                       timer11: timer@0 {
+                               compatible = "ti,omap4430-timer";
+                               reg = <0x0 0x80>;
+                               clocks = <&l4_per_clkctrl OMAP4_TIMER11_CLKCTRL 24>;
+                               clock-names = "fck";
+                               interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+                               ti,timer-pwm;
+                       };
+               };
+
+               target-module@90000 {                   /* 0x48090000, ap 57 2a.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x90000 0x2000>;
+               };
+
+               target-module@96000 {                   /* 0x48096000, ap 37 26.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "mcbsp4";
+                       reg = <0x9608c 0x4>;
+                       reg-names = "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_MCBSP4_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x96000 0x1000>;
+
+                       mcbsp4: mcbsp@0 {
+                               compatible = "ti,omap4-mcbsp";
+                               reg = <0x0 0xff>; /* L4 Interconnect */
+                               reg-names = "mpu";
+                               interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "common";
+                               ti,buffer-size = <128>;
+                               dmas = <&sdma 31>,
+                                      <&sdma 32>;
+                               dma-names = "tx", "rx";
+                               status = "disabled";
+                       };
+               };
+
+               target-module@98000 {                   /* 0x48098000, ap 49 22.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "mcspi1";
+                       reg = <0x98000 0x4>,
+                             <0x98010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP4_FREEEMU |
+                                        SYSC_OMAP4_SOFTRESET)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_MCSPI1_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x98000 0x1000>;
+
+                       mcspi1: spi@0 {
+                               compatible = "ti,omap4-mcspi";
+                               reg = <0x0 0x200>;
+                               interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               ti,spi-num-cs = <4>;
+                               dmas = <&sdma 35>,
+                                      <&sdma 36>,
+                                      <&sdma 37>,
+                                      <&sdma 38>,
+                                      <&sdma 39>,
+                                      <&sdma 40>,
+                                      <&sdma 41>,
+                                      <&sdma 42>;
+                               dma-names = "tx0", "rx0", "tx1", "rx1",
+                                           "tx2", "rx2", "tx3", "rx3";
+                       };
+               };
+
+               target-module@9a000 {                   /* 0x4809a000, ap 51 2c.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "mcspi2";
+                       reg = <0x9a000 0x4>,
+                             <0x9a010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP4_FREEEMU |
+                                        SYSC_OMAP4_SOFTRESET)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_MCSPI2_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x9a000 0x1000>;
+
+                       mcspi2: spi@0 {
+                               compatible = "ti,omap4-mcspi";
+                               reg = <0x0 0x200>;
+                               interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               ti,spi-num-cs = <2>;
+                               dmas = <&sdma 43>,
+                                      <&sdma 44>,
+                                      <&sdma 45>,
+                                      <&sdma 46>;
+                               dma-names = "tx0", "rx0", "tx1", "rx1";
+                       };
+               };
+
+               target-module@9c000 {                   /* 0x4809c000, ap 53 36.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "mmc1";
+                       reg = <0x9c000 0x4>,
+                             <0x9c010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP4_FREEEMU |
+                                        SYSC_OMAP4_SOFTRESET)>;
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, l3init_pwrdm, l3_init_clkdm */
+                       clocks = <&l3_init_clkctrl OMAP4_MMC1_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x9c000 0x1000>;
+
+                       mmc1: mmc@0 {
+                               compatible = "ti,omap4-hsmmc";
+                               reg = <0x0 0x400>;
+                               interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+                               ti,dual-volt;
+                               ti,needs-special-reset;
+                               dmas = <&sdma 61>, <&sdma 62>;
+                               dma-names = "tx", "rx";
+                               pbias-supply = <&pbias_mmc_reg>;
+                       };
+               };
+
+               target-module@9e000 {                   /* 0x4809e000, ap 55 48.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x9e000 0x1000>;
+               };
+
+               target-module@a2000 {                   /* 0x480a2000, ap 79 3a.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xa2000 0x1000>;
+               };
+
+               target-module@a4000 {                   /* 0x480a4000, ap 59 34.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x00000000 0x000a4000 0x00001000>,
+                                <0x00001000 0x000a5000 0x00001000>;
+               };
+
+               target-module@a8000 {                   /* 0x480a8000, ap 61 3e.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xa8000 0x4000>;
+               };
+
+               target-module@ad000 {                   /* 0x480ad000, ap 63 50.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "mmc3";
+                       reg = <0xad000 0x4>,
+                             <0xad010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP4_FREEEMU |
+                                        SYSC_OMAP4_SOFTRESET)>;
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_MMC3_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xad000 0x1000>;
+
+                       mmc3: mmc@0 {
+                               compatible = "ti,omap4-hsmmc";
+                               reg = <0x0 0x400>;
+                               interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+                               ti,needs-special-reset;
+                               dmas = <&sdma 77>, <&sdma 78>;
+                               dma-names = "tx", "rx";
+                       };
+               };
+
+               target-module@b0000 {                   /* 0x480b0000, ap 47 40.0 */
+                       compatible = "ti,sysc";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xb0000 0x1000>;
+               };
+
+               target-module@b2000 {                   /* 0x480b2000, ap 65 3c.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "hdq1w";
+                       reg = <0xb2000 0x4>,
+                             <0xb2014 0x4>,
+                             <0xb2018 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,syss-mask = <1>;
+                       ti,no-reset-on-init;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_HDQ1W_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xb2000 0x1000>;
+
+                       hdqw1w: 1w@0 {
+                               compatible = "ti,omap3-1w";
+                               reg = <0x0 0x1000>;
+                               interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+               };
+
+               target-module@b4000 {                   /* 0x480b4000, ap 67 46.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "mmc2";
+                       reg = <0xb4000 0x4>,
+                             <0xb4010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP4_FREEEMU |
+                                        SYSC_OMAP4_SOFTRESET)>;
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, l3init_pwrdm, l3_init_clkdm */
+                       clocks = <&l3_init_clkctrl OMAP4_MMC2_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xb4000 0x1000>;
+
+                       mmc2: mmc@0 {
+                               compatible = "ti,omap4-hsmmc";
+                               reg = <0x0 0x400>;
+                               interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+                               ti,needs-special-reset;
+                               dmas = <&sdma 47>, <&sdma 48>;
+                               dma-names = "tx", "rx";
+                       };
+               };
+
+               target-module@b8000 {                   /* 0x480b8000, ap 69 58.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "mcspi3";
+                       reg = <0xb8000 0x4>,
+                             <0xb8010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP4_FREEEMU |
+                                        SYSC_OMAP4_SOFTRESET)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_MCSPI3_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xb8000 0x1000>;
+
+                       mcspi3: spi@0 {
+                               compatible = "ti,omap4-mcspi";
+                               reg = <0x0 0x200>;
+                               interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               ti,spi-num-cs = <2>;
+                               dmas = <&sdma 15>, <&sdma 16>;
+                               dma-names = "tx0", "rx0";
+                       };
+               };
+
+               target-module@ba000 {                   /* 0x480ba000, ap 71 32.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "mcspi4";
+                       reg = <0xba000 0x4>,
+                             <0xba010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP4_FREEEMU |
+                                        SYSC_OMAP4_SOFTRESET)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_MCSPI4_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xba000 0x1000>;
+
+                       mcspi4: spi@0 {
+                               compatible = "ti,omap4-mcspi";
+                               reg = <0x0 0x200>;
+                               interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               ti,spi-num-cs = <1>;
+                               dmas = <&sdma 70>, <&sdma 71>;
+                               dma-names = "tx0", "rx0";
+                       };
+               };
+
+               target-module@d1000 {                   /* 0x480d1000, ap 73 44.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "mmc4";
+                       reg = <0xd1000 0x4>,
+                             <0xd1010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP4_FREEEMU |
+                                        SYSC_OMAP4_SOFTRESET)>;
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_MMC4_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xd1000 0x1000>;
+
+                       mmc4: mmc@0 {
+                               compatible = "ti,omap4-hsmmc";
+                               reg = <0x0 0x400>;
+                               interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+                               ti,needs-special-reset;
+                               dmas = <&sdma 57>, <&sdma 58>;
+                               dma-names = "tx", "rx";
+                       };
+               };
+
+               target-module@d5000 {                   /* 0x480d5000, ap 75 4e.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       ti,hwmods = "mmc5";
+                       reg = <0xd5000 0x4>,
+                             <0xd5010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP4_FREEEMU |
+                                        SYSC_OMAP4_SOFTRESET)>;
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_MMC5_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0xd5000 0x1000>;
+
+                       mmc5: mmc@0 {
+                               compatible = "ti,omap4-hsmmc";
+                               reg = <0x0 0x400>;
+                               interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+                               ti,needs-special-reset;
+                               dmas = <&sdma 59>, <&sdma 60>;
+                               dma-names = "tx", "rx";
+                       };
+               };
+       };
+
+       segment@200000 {                                        /* 0x48200000 */
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x00150000 0x00350000 0x001000>,      /* ap 77 */
+                        <0x00151000 0x00351000 0x001000>;      /* ap 78 */
+
+               target-module@150000 {                  /* 0x48350000, ap 77 4c.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       ti,hwmods = "i2c4";
+                       reg = <0x150000 0x8>,
+                             <0x150010 0x8>,
+                             <0x150090 0x8>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, l4per_pwrdm, l4_per_clkdm */
+                       clocks = <&l4_per_clkctrl OMAP4_I2C4_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x150000 0x1000>;
+
+                       i2c4: i2c@0 {
+                               compatible = "ti,omap4-i2c";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                       };
+               };
+       };
+};
+
index 5501d1b4e6cdfa152804b7cbb5b277fcdc0417f6..27895c1604b9bb7837bdb674a3b581c4325c0fdd 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 <dt-bindings/input/input.h>
 #include "elpida_ecb240abacn.dtsi"
 
 / {
                };
        };
 
+       gpio_keys: gpio_keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <
+                       &button_pins
+               >;
+
+               buttonS2 {
+                       label = "button S2";
+                       gpios = <&gpio4 25 GPIO_ACTIVE_LOW>;    /* gpio_121 */
+                       linux,code = <BTN_0>;
+                       wakeup-source;
+               };
+       };
+
        sound: sound {
                compatible = "ti,abe-twl6040";
                ti,model = "PandaBoard";
                        OMAP4_IOPAD(0x152, PIN_INPUT_PULLUP | MUX_MODE0)        /* sdmmc5_dat3.sdmmc5_dat3 */
                >;
        };
+
+       button_pins: pinmux_button_pins {
+               pinctrl-single,pins = <
+                       OMAP4_IOPAD(0x114, PIN_INPUT_PULLUP | MUX_MODE3)        /* gpio_121 */
+               >;
+       };
 };
 
 &omap4_pmx_wkup {
                compatible = "ti,wl1271";
                reg = <2>;
                interrupt-parent = <&gpio2>;
-               interrupts = <21 IRQ_TYPE_LEVEL_HIGH>; /* gpio 53 */
+               interrupts = <21 IRQ_TYPE_EDGE_RISING>; /* gpio 53 */
                ref-clock-frequency = <38400000>;
        };
 };
index 940fe4f7c5f6e148a1e22e7b2daaadc91c627c10..19d02df8d8a5921156fb3c1a6948e0e34e8a85d4 100644 (file)
                        OMAP4_IOPAD(0x0f6, PIN_OUTPUT | MUX_MODE3)      /* gpio_110 */
                >;
        };
+
+       button_pins: pinmux_button_pins {
+               pinctrl-single,pins = <
+                       OMAP4_IOPAD(0x11b, PIN_INPUT_PULLUP | MUX_MODE3) /* gpio_113 */
+               >;
+       };
 };
 
 &led_wkgpio_pins {
        };
 };
 
-&gpio1 {
+&gpio_keys {
+       buttonS2 {
+               gpios = <&gpio4 17 GPIO_ACTIVE_LOW>; /* gpio_113 */
+       };
+};
+
+&gpio1_target {
         ti,no-reset-on-init;
 };
index 280d92d42bf13b12983fca36e7786c13eadaa8cd..490726b522162bd0a11654291889e51d40793ee6 100644 (file)
                compatible = "ti,wl1281";
                reg = <2>;
                interrupt-parent = <&gpio1>;
-               interrupts = <21 IRQ_TYPE_LEVEL_HIGH>; /* gpio 53 */
+               interrupts = <21 IRQ_TYPE_EDGE_RISING>; /* gpio 53 */
                ref-clock-frequency = <26000000>;
                tcxo-clock-frequency = <26000000>;
        };
index 1c5f6f35e1cf0bfcce3c077aea8919cc7a6bfc3c..878923473023372d8a6282c45217330fc3a2a874 100644 (file)
@@ -72,7 +72,7 @@
                compatible = "ti,wl1271";
                reg = <2>;
                interrupt-parent = <&gpio2>;
-               interrupts = <9 IRQ_TYPE_LEVEL_HIGH>; /* gpio 41 */
+               interrupts = <9 IRQ_TYPE_EDGE_RISING>; /* gpio 41 */
                ref-clock-frequency = <38400000>;
        };
 };
index e554b6e039f32fe396386bd6f7c32e9b4869ecf8..1a96d4317c9757e7dc6d991d1a25405b9090e952 100644 (file)
                interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
 
-               l4_cfg: l4@4a000000 {
-                       compatible = "ti,omap4-l4-cfg", "simple-bus";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges = <0 0x4a000000 0x1000000>;
-
-                       cm1: cm1@4000 {
-                               compatible = "ti,omap4-cm1", "simple-bus";
-                               reg = <0x4000 0x2000>;
-                               #address-cells = <1>;
-                               #size-cells = <1>;
-                               ranges = <0 0x4000 0x2000>;
-
-                               cm1_clocks: clocks {
-                                       #address-cells = <1>;
-                                       #size-cells = <0>;
-                               };
-
-                               cm1_clockdomains: clockdomains {
-                               };
-                       };
-
-                       cm2: cm2@8000 {
-                               compatible = "ti,omap4-cm2", "simple-bus";
-                               reg = <0x8000 0x2000>;
-                               #address-cells = <1>;
-                               #size-cells = <1>;
-                               ranges = <0 0x8000 0x2000>;
-
-                               cm2_clocks: clocks {
-                                       #address-cells = <1>;
-                                       #size-cells = <0>;
-                               };
-
-                               cm2_clockdomains: clockdomains {
-                               };
-                       };
-
-                       omap4_scm_core: scm@2000 {
-                               compatible = "ti,omap4-scm-core", "simple-bus";
-                               reg = <0x2000 0x1000>;
-                               #address-cells = <1>;
-                               #size-cells = <1>;
-                               ranges = <0 0x2000 0x1000>;
-                               ti,hwmods = "ctrl_module_core";
-
-                               scm_conf: scm_conf@0 {
-                                       compatible = "syscon";
-                                       reg = <0x0 0x800>;
-                                       #address-cells = <1>;
-                                       #size-cells = <1>;
-                               };
-                       };
-
-                       omap4_padconf_core: scm@100000 {
-                               compatible = "ti,omap4-scm-padconf-core",
-                                            "simple-bus";
-                               reg = <0x100000 0x1000>;
-                               #address-cells = <1>;
-                               #size-cells = <1>;
-                               ranges = <0 0x100000 0x1000>;
-                               ti,hwmods = "ctrl_module_pad_core";
-
-                               omap4_pmx_core: pinmux@40 {
-                                       compatible = "ti,omap4-padconf",
-                                                    "pinctrl-single";
-                                       reg = <0x40 0x0196>;
-                                       #address-cells = <1>;
-                                       #size-cells = <0>;
-                                       #pinctrl-cells = <1>;
-                                       #interrupt-cells = <1>;
-                                       interrupt-controller;
-                                       pinctrl-single,register-width = <16>;
-                                       pinctrl-single,function-mask = <0x7fff>;
-                               };
-
-                               omap4_padconf_global: omap4_padconf_global@5a0 {
-                                       compatible = "syscon",
-                                                    "simple-bus";
-                                       reg = <0x5a0 0x170>;
-                                       #address-cells = <1>;
-                                       #size-cells = <1>;
-                                       ranges = <0 0x5a0 0x170>;
-
-                                       pbias_regulator: pbias_regulator@60 {
-                                               compatible = "ti,pbias-omap4", "ti,pbias-omap";
-                                               reg = <0x60 0x4>;
-                                               syscon = <&omap4_padconf_global>;
-                                               pbias_mmc_reg: pbias_mmc_omap4 {
-                                                       regulator-name = "pbias_mmc_omap4";
-                                                       regulator-min-microvolt = <1800000>;
-                                                       regulator-max-microvolt = <3000000>;
-                                               };
-                                       };
-                               };
-                       };
-
-                       l4_wkup: l4@300000 {
-                               compatible = "ti,omap4-l4-wkup", "simple-bus";
-                               #address-cells = <1>;
-                               #size-cells = <1>;
-                               ranges = <0 0x300000 0x40000>;
-
-                               counter32k: counter@4000 {
-                                       compatible = "ti,omap-counter32k";
-                                       reg = <0x4000 0x20>;
-                                       ti,hwmods = "counter_32k";
-                               };
-
-                               prm: prm@6000 {
-                                       compatible = "ti,omap4-prm";
-                                       reg = <0x6000 0x2000>;
-                                       interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
-                                       #address-cells = <1>;
-                                       #size-cells = <1>;
-                                       ranges = <0 0x6000 0x2000>;
-
-                                       prm_clocks: clocks {
-                                               #address-cells = <1>;
-                                               #size-cells = <0>;
-                                       };
-
-                                       prm_clockdomains: clockdomains {
-                                       };
-                               };
-
-                               scrm: scrm@a000 {
-                                       compatible = "ti,omap4-scrm";
-                                       reg = <0xa000 0x2000>;
-
-                                       scrm_clocks: clocks {
-                                               #address-cells = <1>;
-                                               #size-cells = <0>;
-                                       };
-
-                                       scrm_clockdomains: clockdomains {
-                                       };
-                               };
-
-                               omap4_scm_wkup: scm@c000 {
-                                       compatible = "ti,omap4-scm-wkup";
-                                       reg = <0xc000 0x1000>;
-                                       ti,hwmods = "ctrl_module_wkup";
-                               };
+               l4_wkup: interconnect@4a300000 {
+               };
 
-                               omap4_padconf_wkup: padconf@1e000 {
-                                       compatible = "ti,omap4-scm-padconf-wkup",
-                                                    "simple-bus";
-                                       reg = <0x1e000 0x1000>;
-                                       #address-cells = <1>;
-                                       #size-cells = <1>;
-                                       ranges = <0 0x1e000 0x1000>;
-                                       ti,hwmods = "ctrl_module_pad_wkup";
+               l4_cfg: interconnect@4a000000 {
+               };
 
-                                       omap4_pmx_wkup: pinmux@40 {
-                                               compatible = "ti,omap4-padconf",
-                                                            "pinctrl-single";
-                                               reg = <0x40 0x0038>;
-                                               #address-cells = <1>;
-                                               #size-cells = <0>;
-                                               #pinctrl-cells = <1>;
-                                               #interrupt-cells = <1>;
-                                               interrupt-controller;
-                                               pinctrl-single,register-width = <16>;
-                                               pinctrl-single,function-mask = <0x7fff>;
-                                       };
-                               };
-                       };
+               l4_per: interconnect@48000000 {
                };
 
                ocmcram: ocmcram@40304000 {
                        reg = <0x40304000 0xa000>; /* 40k */
                };
 
-               sdma: dma-controller@4a056000 {
-                       compatible = "ti,omap4430-sdma";
-                       reg = <0x4a056000 0x1000>;
-                       interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
-                       #dma-cells = <1>;
-                       dma-channels = <32>;
-                       dma-requests = <127>;
-                       ti,hwmods = "dma_system";
-               };
-
-               gpio1: gpio@4a310000 {
-                       compatible = "ti,omap4-gpio";
-                       reg = <0x4a310000 0x200>;
-                       interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "gpio1";
-                       ti,gpio-always-on;
-                       gpio-controller;
-                       #gpio-cells = <2>;
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
-               };
-
-               gpio2: gpio@48055000 {
-                       compatible = "ti,omap4-gpio";
-                       reg = <0x48055000 0x200>;
-                       interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "gpio2";
-                       gpio-controller;
-                       #gpio-cells = <2>;
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
-               };
-
-               gpio3: gpio@48057000 {
-                       compatible = "ti,omap4-gpio";
-                       reg = <0x48057000 0x200>;
-                       interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "gpio3";
-                       gpio-controller;
-                       #gpio-cells = <2>;
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
-               };
-
-               gpio4: gpio@48059000 {
-                       compatible = "ti,omap4-gpio";
-                       reg = <0x48059000 0x200>;
-                       interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "gpio4";
-                       gpio-controller;
-                       #gpio-cells = <2>;
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
-               };
-
-               gpio5: gpio@4805b000 {
-                       compatible = "ti,omap4-gpio";
-                       reg = <0x4805b000 0x200>;
-                       interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "gpio5";
-                       gpio-controller;
-                       #gpio-cells = <2>;
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
-               };
-
-               gpio6: gpio@4805d000 {
-                       compatible = "ti,omap4-gpio";
-                       reg = <0x4805d000 0x200>;
-                       interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "gpio6";
-                       gpio-controller;
-                       #gpio-cells = <2>;
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
-               };
-
-               target-module@48076000 {
-                       compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "slimbus2";
-                       reg = <0x48076000 0x4>,
-                             <0x48076010 0x4>;
-                       reg-names = "rev", "sysc";
-                       ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>;
-                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
-                                       <SYSC_IDLE_NO>,
-                                       <SYSC_IDLE_SMART>,
-                                       <SYSC_IDLE_SMART_WKUP>;
-                       clocks = <&l4_per_clkctrl OMAP4_SLIMBUS2_CLKCTRL 0>;
-                       clock-names = "fck";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges = <0 0x48076000 0x001000>;
-
-                       /* No child device binding or driver in mainline */
-               };
-
-               elm: elm@48078000 {
-                       compatible = "ti,am3352-elm";
-                       reg = <0x48078000 0x2000>;
-                       interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "elm";
-                       status = "disabled";
-               };
-
                gpmc: gpmc@50000000 {
                        compatible = "ti,omap4430-gpmc";
                        reg = <0x50000000 0x1000>;
                        #gpio-cells = <2>;
                };
 
-               uart1: serial@4806a000 {
-                       compatible = "ti,omap4-uart";
-                       reg = <0x4806a000 0x100>;
-                       interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "uart1";
-                       clock-frequency = <48000000>;
-               };
-
-               uart2: serial@4806c000 {
-                       compatible = "ti,omap4-uart";
-                       reg = <0x4806c000 0x100>;
-                       interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "uart2";
-                       clock-frequency = <48000000>;
-               };
-
-               uart3: serial@48020000 {
-                       compatible = "ti,omap4-uart";
-                       reg = <0x48020000 0x100>;
-                       interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "uart3";
-                       clock-frequency = <48000000>;
-               };
-
-               uart4: serial@4806e000 {
-                       compatible = "ti,omap4-uart";
-                       reg = <0x4806e000 0x100>;
-                       interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "uart4";
-                       clock-frequency = <48000000>;
-               };
-
-               target-module@4a0db000 {
-                       compatible = "ti,sysc-omap4-sr", "ti,sysc";
-                       ti,hwmods = "smartreflex_iva";
-                       reg = <0x4a0db038 0x4>;
-                       reg-names = "sysc";
-                       ti,sysc-mask = <SYSC_OMAP3_SR_ENAWAKEUP>;
-                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
-                                       <SYSC_IDLE_NO>,
-                                       <SYSC_IDLE_SMART>,
-                                       <SYSC_IDLE_SMART_WKUP>;
-                       clocks = <&l4_ao_clkctrl OMAP4_SMARTREFLEX_IVA_CLKCTRL 0>;
-                       clock-names = "fck";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges = <0 0x4a0db000 0x001000>;
-
-                       smartreflex_iva: smartreflex@0 {
-                               compatible = "ti,omap4-smartreflex-iva";
-                               reg = <0 0x80>;
-                               interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
-                       };
-               };
-
-               target-module@4a0dd000 {
-                       compatible = "ti,sysc-omap4-sr", "ti,sysc";
-                       ti,hwmods = "smartreflex_core";
-                       reg = <0x4a0dd038 0x4>;
-                       reg-names = "sysc";
-                       ti,sysc-mask = <SYSC_OMAP3_SR_ENAWAKEUP>;
-                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
-                                       <SYSC_IDLE_NO>,
-                                       <SYSC_IDLE_SMART>,
-                                       <SYSC_IDLE_SMART_WKUP>;
-                       clocks = <&l4_ao_clkctrl OMAP4_SMARTREFLEX_CORE_CLKCTRL 0>;
-                       clock-names = "fck";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges = <0 0x4a0dd000 0x001000>;
-
-                       smartreflex_core: smartreflex@0 {
-                               compatible = "ti,omap4-smartreflex-core";
-                               reg = <0 0x80>;
-                               interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
-                       };
-               };
-
-               target-module@4a0d9000 {
-                       compatible = "ti,sysc-omap4-sr", "ti,sysc";
-                       ti,hwmods = "smartreflex_mpu";
-                       reg = <0x4a0d9038 0x4>;
-                       reg-names = "sysc";
-                       ti,sysc-mask = <SYSC_OMAP3_SR_ENAWAKEUP>;
-                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
-                                       <SYSC_IDLE_NO>,
-                                       <SYSC_IDLE_SMART>,
-                                       <SYSC_IDLE_SMART_WKUP>;
-                       clocks = <&l4_ao_clkctrl OMAP4_SMARTREFLEX_MPU_CLKCTRL 0>;
-                       clock-names = "fck";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges = <0 0x4a0d9000 0x001000>;
-
-                       smartreflex_mpu: smartreflex@0 {
-                               compatible = "ti,omap4-smartreflex-mpu";
-                               reg = <0 0x80>;
-                               interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
-                       };
-               };
-
-               hwspinlock: spinlock@4a0f6000 {
-                       compatible = "ti,omap4-hwspinlock";
-                       reg = <0x4a0f6000 0x1000>;
-                       ti,hwmods = "spinlock";
-                       #hwlock-cells = <1>;
-               };
-
-               i2c1: i2c@48070000 {
-                       compatible = "ti,omap4-i2c";
-                       reg = <0x48070000 0x100>;
-                       interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       ti,hwmods = "i2c1";
-               };
-
-               i2c2: i2c@48072000 {
-                       compatible = "ti,omap4-i2c";
-                       reg = <0x48072000 0x100>;
-                       interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       ti,hwmods = "i2c2";
-               };
-
-               i2c3: i2c@48060000 {
-                       compatible = "ti,omap4-i2c";
-                       reg = <0x48060000 0x100>;
-                       interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       ti,hwmods = "i2c3";
-               };
-
-               i2c4: i2c@48350000 {
-                       compatible = "ti,omap4-i2c";
-                       reg = <0x48350000 0x100>;
-                       interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       ti,hwmods = "i2c4";
-               };
-
-               mcspi1: spi@48098000 {
-                       compatible = "ti,omap4-mcspi";
-                       reg = <0x48098000 0x200>;
-                       interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       ti,hwmods = "mcspi1";
-                       ti,spi-num-cs = <4>;
-                       dmas = <&sdma 35>,
-                              <&sdma 36>,
-                              <&sdma 37>,
-                              <&sdma 38>,
-                              <&sdma 39>,
-                              <&sdma 40>,
-                              <&sdma 41>,
-                              <&sdma 42>;
-                       dma-names = "tx0", "rx0", "tx1", "rx1",
-                                   "tx2", "rx2", "tx3", "rx3";
-               };
-
-               mcspi2: spi@4809a000 {
-                       compatible = "ti,omap4-mcspi";
-                       reg = <0x4809a000 0x200>;
-                       interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       ti,hwmods = "mcspi2";
-                       ti,spi-num-cs = <2>;
-                       dmas = <&sdma 43>,
-                              <&sdma 44>,
-                              <&sdma 45>,
-                              <&sdma 46>;
-                       dma-names = "tx0", "rx0", "tx1", "rx1";
-               };
-
-               hdqw1w: 1w@480b2000 {
-                       compatible = "ti,omap3-1w";
-                       reg = <0x480b2000 0x1000>;
-                       interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "hdq1w";
-               };
-
-               mcspi3: spi@480b8000 {
-                       compatible = "ti,omap4-mcspi";
-                       reg = <0x480b8000 0x200>;
-                       interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       ti,hwmods = "mcspi3";
-                       ti,spi-num-cs = <2>;
-                       dmas = <&sdma 15>, <&sdma 16>;
-                       dma-names = "tx0", "rx0";
-               };
-
-               mcspi4: spi@480ba000 {
-                       compatible = "ti,omap4-mcspi";
-                       reg = <0x480ba000 0x200>;
-                       interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       ti,hwmods = "mcspi4";
-                       ti,spi-num-cs = <1>;
-                       dmas = <&sdma 70>, <&sdma 71>;
-                       dma-names = "tx0", "rx0";
-               };
-
-               mmc1: mmc@4809c000 {
-                       compatible = "ti,omap4-hsmmc";
-                       reg = <0x4809c000 0x400>;
-                       interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "mmc1";
-                       ti,dual-volt;
-                       ti,needs-special-reset;
-                       dmas = <&sdma 61>, <&sdma 62>;
-                       dma-names = "tx", "rx";
-                       pbias-supply = <&pbias_mmc_reg>;
-               };
-
-               mmc2: mmc@480b4000 {
-                       compatible = "ti,omap4-hsmmc";
-                       reg = <0x480b4000 0x400>;
-                       interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "mmc2";
-                       ti,needs-special-reset;
-                       dmas = <&sdma 47>, <&sdma 48>;
-                       dma-names = "tx", "rx";
-               };
-
-               mmc3: mmc@480ad000 {
-                       compatible = "ti,omap4-hsmmc";
-                       reg = <0x480ad000 0x400>;
-                       interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "mmc3";
-                       ti,needs-special-reset;
-                       dmas = <&sdma 77>, <&sdma 78>;
-                       dma-names = "tx", "rx";
-               };
-
-               mmc4: mmc@480d1000 {
-                       compatible = "ti,omap4-hsmmc";
-                       reg = <0x480d1000 0x400>;
-                       interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "mmc4";
-                       ti,needs-special-reset;
-                       dmas = <&sdma 57>, <&sdma 58>;
-                       dma-names = "tx", "rx";
-               };
-
-               mmc5: mmc@480d5000 {
-                       compatible = "ti,omap4-hsmmc";
-                       reg = <0x480d5000 0x400>;
-                       interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "mmc5";
-                       ti,needs-special-reset;
-                       dmas = <&sdma 59>, <&sdma 60>;
-                       dma-names = "tx", "rx";
-               };
-
-               hsi: hsi@4a058000 {
-                       compatible = "ti,omap4-hsi";
-                       reg = <0x4a058000 0x4000>,
-                             <0x4a05c000 0x1000>;
-                       reg-names = "sys", "gdd";
-                       ti,hwmods = "hsi";
-
-                       clocks = <&l3_init_clkctrl OMAP4_HSI_CLKCTRL 0>;
-                       clock-names = "hsi_fck";
-
-                       interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "gdd_mpu";
-
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges = <0 0x4a058000 0x4000>;
-
-                       hsi_port1: hsi-port@2000 {
-                               compatible = "ti,omap4-hsi-port";
-                               reg = <0x2000 0x800>,
-                                     <0x2800 0x800>;
-                               reg-names = "tx", "rx";
-                               interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
-                       };
-
-                       hsi_port2: hsi-port@3000 {
-                               compatible = "ti,omap4-hsi-port";
-                               reg = <0x3000 0x800>,
-                                     <0x3800 0x800>;
-                               reg-names = "tx", "rx";
-                               interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
-                       };
-               };
-
                mmu_dsp: mmu@4a066000 {
                        compatible = "ti,omap4-iommu";
                        reg = <0x4a066000 0x100>;
                        #iommu-cells = <0>;
                        ti,iommu-bus-err-back;
                };
-
-               wdt2: wdt@4a314000 {
-                       compatible = "ti,omap4-wdt", "ti,omap3-wdt";
-                       reg = <0x4a314000 0x80>;
-                       interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "wd_timer2";
-               };
-
-               wdt3: wdt@40130000 {
-                       compatible = "ti,omap4-wdt", "ti,omap3-wdt";
-                       reg = <0x40130000 0x80>, /* MPU private access */
-                             <0x49030000 0x80>; /* L3 Interconnect */
-                       interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+               target-module@40130000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
                        ti,hwmods = "wd_timer3";
+                       reg = <0x40130000 0x4>,
+                             <0x40130010 0x4>,
+                             <0x40130014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_EMUFREE |
+                                        SYSC_OMAP2_SOFTRESET)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): abe, abe_pwrdm, abe_clkdm */
+                       clocks = <&abe_clkctrl OMAP4_WD_TIMER3_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x00000000 0x40130000 0x1000>, /* MPU private access */
+                                <0x49030000 0x49030000 0x0080>; /* L3 Interconnect */
+
+                       wdt3: wdt@0 {
+                               compatible = "ti,omap4-wdt", "ti,omap3-wdt";
+                               reg = <0x0 0x80>;
+                               interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+                       };
                };
 
                mcpdm: mcpdm@40132000 {
                         */
                };
 
-               mcbsp4: mcbsp@48096000 {
-                       compatible = "ti,omap4-mcbsp";
-                       reg = <0x48096000 0xff>; /* L4 Interconnect */
-                       reg-names = "mpu";
-                       interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "common";
-                       ti,buffer-size = <128>;
-                       ti,hwmods = "mcbsp4";
-                       dmas = <&sdma 31>,
-                              <&sdma 32>;
-                       dma-names = "tx", "rx";
-                       status = "disabled";
-               };
-
-               keypad: keypad@4a31c000 {
-                       compatible = "ti,omap4-keypad";
-                       reg = <0x4a31c000 0x80>;
-                       interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
-                       reg-names = "mpu";
-                       ti,hwmods = "kbd";
-               };
-
                dmm@4e000000 {
                        compatible = "ti,omap4-dmm";
                        reg = <0x4e000000 0x800>;
                        hw-caps-temp-alert;
                };
 
-               ocp2scp@4a0ad000 {
-                       compatible = "ti,omap-ocp2scp";
-                       reg = <0x4a0ad000 0x1f>;
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges;
-                       ti,hwmods = "ocp2scp_usb_phy";
-                       usb2_phy: usb2phy@4a0ad080 {
-                               compatible = "ti,omap-usb2";
-                               reg = <0x4a0ad080 0x58>;
-                               ctrl-module = <&omap_control_usb2phy>;
-                               clocks = <&usb_phy_cm_clk32k>;
-                               clock-names = "wkupclk";
-                               #phy-cells = <0>;
-                       };
-               };
-
-               mailbox: mailbox@4a0f4000 {
-                       compatible = "ti,omap4-mailbox";
-                       reg = <0x4a0f4000 0x200>;
-                       interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "mailbox";
-                       #mbox-cells = <1>;
-                       ti,mbox-num-users = <3>;
-                       ti,mbox-num-fifos = <8>;
-                       mbox_ipu: mbox_ipu {
-                               ti,mbox-tx = <0 0 0>;
-                               ti,mbox-rx = <1 0 0>;
-                       };
-                       mbox_dsp: mbox_dsp {
-                               ti,mbox-tx = <3 0 0>;
-                               ti,mbox-rx = <2 0 0>;
-                       };
-               };
-
-               target-module@4a10a000 {
-                       compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "fdif";
-                       reg = <0x4a10a000 0x4>,
-                             <0x4a10a010 0x4>;
-                       reg-names = "rev", "sysc";
-                       ti,sysc-mask = <SYSC_OMAP4_SOFTRESET>;
-                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
-                                       <SYSC_IDLE_NO>,
-                                       <SYSC_IDLE_SMART>;
-                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
-                                       <SYSC_IDLE_NO>,
-                                       <SYSC_IDLE_SMART>;
-                       ti,sysc-delay-us = <2>;
-                       clocks = <&iss_clkctrl OMAP4_FDIF_CLKCTRL 0>;
-                       clock-names = "fck";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges = <0 0x4a10a000 0x1000>;
-
-                       /* No child device binding or driver in mainline */
-               };
-
-               timer1: timer@4a318000 {
-                       compatible = "ti,omap3430-timer";
-                       reg = <0x4a318000 0x80>;
-                       interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "timer1";
-                       ti,timer-alwon;
-                       clocks = <&l4_wkup_clkctrl OMAP4_TIMER1_CLKCTRL 24>;
-                       clock-names = "fck";
-               };
-
-               timer2: timer@48032000 {
-                       compatible = "ti,omap3430-timer";
-                       reg = <0x48032000 0x80>;
-                       interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "timer2";
-               };
-
-               timer3: timer@48034000 {
-                       compatible = "ti,omap4430-timer";
-                       reg = <0x48034000 0x80>;
-                       interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "timer3";
-               };
-
-               timer4: timer@48036000 {
-                       compatible = "ti,omap4430-timer";
-                       reg = <0x48036000 0x80>;
-                       interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "timer4";
-               };
-
                timer5: timer@40138000 {
                        compatible = "ti,omap4430-timer";
                        reg = <0x40138000 0x80>,
                        ti,timer-dsp;
                };
 
-               timer9: timer@4803e000 {
-                       compatible = "ti,omap4430-timer";
-                       reg = <0x4803e000 0x80>;
-                       interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "timer9";
-                       ti,timer-pwm;
-               };
-
-               timer10: timer@48086000 {
-                       compatible = "ti,omap3430-timer";
-                       reg = <0x48086000 0x80>;
-                       interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "timer10";
-                       ti,timer-pwm;
-               };
-
-               timer11: timer@48088000 {
-                       compatible = "ti,omap4430-timer";
-                       reg = <0x48088000 0x80>;
-                       interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "timer11";
-                       ti,timer-pwm;
-               };
-
-               usbhstll: usbhstll@4a062000 {
-                       compatible = "ti,usbhs-tll";
-                       reg = <0x4a062000 0x1000>;
-                       interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "usb_tll_hs";
-               };
-
-               usbhshost: usbhshost@4a064000 {
-                       compatible = "ti,usbhs-host";
-                       reg = <0x4a064000 0x800>;
-                       ti,hwmods = "usb_host_hs";
-                       #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";
-                               reg = <0x4a064800 0x400>;
-                               interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
-                               remote-wakeup-connected;
-                       };
-
-                       usbhsehci: ehci@4a064c00 {
-                               compatible = "ti,ehci-omap";
-                               reg = <0x4a064c00 0x400>;
-                               interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
-                       };
-               };
-
-               omap_control_usb2phy: control-phy@4a002300 {
-                       compatible = "ti,control-phy-usb2";
-                       reg = <0x4a002300 0x4>;
-                       reg-names = "power";
-               };
-
-               omap_control_usbotg: control-phy@4a00233c {
-                       compatible = "ti,control-phy-otghs";
-                       reg = <0x4a00233c 0x4>;
-                       reg-names = "otghs_control";
-               };
-
-               usb_otg_hs: usb_otg_hs@4a0ab000 {
-                       compatible = "ti,omap4-musb";
-                       reg = <0x4a0ab000 0x7ff>;
-                       interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "mc", "dma";
-                       ti,hwmods = "usb_otg_hs";
-                       usb-phy = <&usb2_phy>;
-                       phys = <&usb2_phy>;
-                       phy-names = "usb2-phy";
-                       multipoint = <1>;
-                       num-eps = <16>;
-                       ram-bits = <12>;
-                       ctrl-module = <&omap_control_usbotg>;
-               };
-
                aes1: aes@4b501000 {
                        compatible = "ti,omap4-aes";
                        ti,hwmods = "aes1";
        };
 };
 
+#include "omap4-l4.dtsi"
 #include "omap44xx-clocks.dtsi"
index ad97493e4e468bd32ccd00ab3aab53fec1f0e99b..2223dc0d63c03a0a33dfa9eb2bed07a446d720aa 100644 (file)
        coefficients = <348 (-9301)>;
 };
 
+/* Only some L4 CFG interconnect ranges are different on 4460 */
+&l4_cfg_segment_300000 {
+       ranges = <0x00000000 0x00300000 0x020000>,      /* ap 67 */
+                <0x00040000 0x00340000 0x001000>,      /* ap 68 */
+                <0x00020000 0x00320000 0x004000>,      /* ap 71 */
+                <0x00024000 0x00324000 0x002000>,      /* ap 72 */
+                <0x00026000 0x00326000 0x001000>,      /* ap 73 */
+                <0x00027000 0x00327000 0x001000>,      /* ap 74 */
+                <0x00028000 0x00328000 0x001000>,      /* ap 75 */
+                <0x00029000 0x00329000 0x001000>,      /* ap 76 */
+                <0x00030000 0x00330000 0x010000>,      /* ap 77 */
+                <0x0002a000 0x0032a000 0x002000>,      /* ap 90 */
+                <0x0002c000 0x0032c000 0x004000>,      /* ap 91 */
+                <0x00010000 0x00310000 0x008000>,      /* ap 92 */
+                <0x00018000 0x00318000 0x004000>,      /* ap 93 */
+                <0x0001c000 0x0031c000 0x002000>,      /* ap 94 */
+                <0x0001e000 0x0031e000 0x002000>;      /* ap 95 */
+};
+
+&l4_cfg_target_0 {
+       ranges = <0x00000000 0x00000000 0x00010000>,
+                <0x00010000 0x00010000 0x00008000>,
+                <0x00018000 0x00018000 0x00004000>,
+                <0x0001c000 0x0001c000 0x00002000>,
+                <0x0001e000 0x0001e000 0x00002000>,
+                <0x00020000 0x00020000 0x00004000>,
+                <0x00024000 0x00024000 0x00002000>,
+                <0x00026000 0x00026000 0x00001000>,
+                <0x00027000 0x00027000 0x00001000>,
+                <0x00028000 0x00028000 0x00001000>,
+                <0x00029000 0x00029000 0x00001000>,
+                <0x0002a000 0x0002a000 0x00002000>,
+                <0x0002c000 0x0002c000 0x00004000>,
+                <0x00030000 0x00030000 0x00010000>;
+};
+
 /include/ "omap446x-clocks.dtsi"
index 3b2244560c28f584466b2bdf45b4c88ad5af330a..ab6f640b282bfc903f115bdb56796447b862b8f8 100644 (file)
                pinctrl-names = "default";
                pinctrl-0 = <&wlcore_irq_pin>;
                interrupt-parent = <&gpio1>;
-               interrupts = <14 IRQ_TYPE_LEVEL_HIGH>;  /* gpio 14 */
+               interrupts = <14 IRQ_TYPE_EDGE_RISING>; /* gpio 14 */
                ref-clock-frequency = <26000000>;
        };
 };
index 732b61a0e9904816b21661eac65e4726738ab1e3..574ac11c04896c3d1728c12a2945a46dafe16e03 100644 (file)
                        device_type = "cpu";
                        compatible = "arm,cortex-a15";
                        reg = <0x1>;
+
+                       operating-points = <
+                               /* kHz    uV */
+                               1000000 1060000
+                               1500000 1250000
+                       >;
+
+                       clocks = <&dpll_mpu_ck>;
+                       clock-names = "cpu";
+
+                       clock-latency = <300000>; /* From omap-cpufreq driver */
+
+                       /* cooling options */
+                       #cooling-cells = <2>; /* min followed by max */
                };
        };
 
index e4ebcde17837c38807544efac9e5ce22c1699047..a520b4c14ea9f5023b11672c17cb438f256f9067 100644 (file)
                        interrupts = <30 31>;
                };
 
-               lcd-controller@40500000 {
+               lcdc: lcd-controller@40500000 {
                        compatible = "marvell,pxa2xx-lcdc";
                        reg = <0x44000000 0x10000>;
                        interrupts = <17>;
index 132a3b8ab14849ad6634f466c2e8320062779662..3a8f0edc3af99dea946c13417946e5a9c0456245 100644 (file)
                        reg = <0x43100000 90>;
                        interrupts = <45>;
                        clocks = <&clks CLK_NAND>;
+                       clock-names = "core";
                        dmas = <&pdma 97 3>;
                        dma-names = "data";
                        #address-cells = <1>;
                        clocks = <&clks CLK_PWM1>;
                        status = "disabled";
                };
+
+               ssp1: ssp@41000000 {
+                       compatible = "mrvl,pxa3xx-ssp";
+                       reg = <0x41000000 0x40>;
+                       interrupts = <24>;
+                       clocks = <&clks CLK_SSP1>;
+                       status = "disabled";
+               };
+
+               ssp2: ssp@41700000 {
+                       compatible = "mrvl,pxa3xx-ssp";
+                       reg = <0x41700000 0x40>;
+                       interrupts = <16>;
+                       clocks = <&clks CLK_SSP2>;
+                       status = "disabled";
+               };
+
+               ssp3: ssp@41900000 {
+                       compatible = "mrvl,pxa3xx-ssp";
+                       reg = <0x41900000 0x40>;
+                       interrupts = <0>;
+                       clocks = <&clks CLK_SSP3>;
+                       status = "disabled";
+               };
+
+               ssp4: ssp@41a00000 {
+                       compatible = "mrvl,pxa3xx-ssp";
+                       reg = <0x41a00000 0x40>;
+                       interrupts = <13>;
+                       clocks = <&clks CLK_SSP4>;
+                       status = "disabled";
+               };
        };
 
        clocks {
index 7bcd7635e723825a418bef408ea79f1fa262573a..78db67337ed4a3ce90a8962f183444296c27fc53 100644 (file)
                        reg = <0x1>;
                        clocks = <&gcc GCC_APPS_CLK_SRC>;
                        clock-frequency = <0>;
+                       operating-points = <
+                               /* kHz  uV (fixed) */
+                               48000   1100000
+                               200000  1100000
+                               500000  1100000
+                               666000  1100000
+                       >;
+                       clock-latency = <256000>;
                };
 
                cpu@2 {
                        reg = <0x2>;
                        clocks = <&gcc GCC_APPS_CLK_SRC>;
                        clock-frequency = <0>;
+                       operating-points = <
+                               /* kHz  uV (fixed) */
+                               48000   1100000
+                               200000  1100000
+                               500000  1100000
+                               666000  1100000
+                       >;
+                       clock-latency = <256000>;
                };
 
                cpu@3 {
                        reg = <0x3>;
                        clocks = <&gcc GCC_APPS_CLK_SRC>;
                        clock-frequency = <0>;
+                       operating-points = <
+                               /* kHz  uV (fixed) */
+                               48000   1100000
+                               200000  1100000
+                               500000  1100000
+                               666000  1100000
+                       >;
+                       clock-latency = <256000>;
                };
        };
 
index 1e0a3b446f7a8ab7a6625dd7cfe093251b73c7bc..70790ac242d180fa2e2d466c901b6be3efb87862 100644 (file)
@@ -5,6 +5,7 @@
 #include <dt-bindings/clock/qcom,gcc-ipq806x.h>
 #include <dt-bindings/clock/qcom,lcc-ipq806x.h>
 #include <dt-bindings/soc/qcom,gsbi.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
 
 / {
        model = "Qualcomm IPQ8064";
@@ -43,7 +44,8 @@
 
        cpu-pmu {
                compatible = "qcom,krait-pmu";
-               interrupts = <1 10 0x304>;
+               interrupts = <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) |
+                                         IRQ_TYPE_LEVEL_HIGH)>;
        };
 
        reserved-memory {
@@ -97,7 +99,7 @@
                        clock-names = "ahbix-clk",
                                        "mi2s-osr-clk",
                                        "mi2s-bit-clk";
-                       interrupts = <0 85 1>;
+                       interrupts = <GIC_SPI 85 IRQ_TYPE_EDGE_RISING>;
                        interrupt-names = "lpass-irq-lpaif";
                        reg = <0x28100000 0x10000>;
                        reg-names = "lpass-lpaif";
                        #gpio-cells = <2>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
-                       interrupts = <0 16 0x4>;
+                       interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
                };
 
                intc: interrupt-controller@2000000 {
                timer@200a000 {
                        compatible = "qcom,kpss-timer",
                                     "qcom,kpss-wdt-ipq8064", "qcom,msm-timer";
-                       interrupts = <1 1 0x301>,
-                                    <1 2 0x301>,
-                                    <1 3 0x301>,
-                                    <1 4 0x301>,
-                                    <1 5 0x301>;
+                       interrupts = <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(2) |
+                                                IRQ_TYPE_EDGE_RISING)>,
+                                    <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(2) |
+                                                IRQ_TYPE_EDGE_RISING)>,
+                                    <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(2) |
+                                                IRQ_TYPE_EDGE_RISING)>,
+                                    <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(2) |
+                                                IRQ_TYPE_EDGE_RISING)>,
+                                    <GIC_PPI 5 (GIC_CPU_MASK_SIMPLE(2) |
+                                                IRQ_TYPE_EDGE_RISING)>;
                        reg = <0x0200a000 0x100>;
                        clock-frequency = <25000000>,
                                          <32768>;
                                compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
                                reg = <0x12490000 0x1000>,
                                      <0x12480000 0x1000>;
-                               interrupts = <0 195 0x0>;
+                               interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&gcc GSBI2_UART_CLK>, <&gcc GSBI2_H_CLK>;
                                clock-names = "core", "iface";
                                status = "disabled";
                        i2c@124a0000 {
                                compatible = "qcom,i2c-qup-v1.1.1";
                                reg = <0x124a0000 0x1000>;
-                               interrupts = <0 196 0>;
+                               interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
 
                                clocks = <&gcc GSBI2_QUP_CLK>, <&gcc GSBI2_H_CLK>;
                                clock-names = "core", "iface";
                                compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
                                reg = <0x16340000 0x1000>,
                                      <0x16300000 0x1000>;
-                               interrupts = <0 152 0x0>;
+                               interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&gcc GSBI4_UART_CLK>, <&gcc GSBI4_H_CLK>;
                                clock-names = "core", "iface";
                                status = "disabled";
                        i2c@16380000 {
                                compatible = "qcom,i2c-qup-v1.1.1";
                                reg = <0x16380000 0x1000>;
-                               interrupts = <0 153 0>;
+                               interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
 
                                clocks = <&gcc GSBI4_QUP_CLK>, <&gcc GSBI4_H_CLK>;
                                clock-names = "core", "iface";
                                compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
                                reg = <0x1a240000 0x1000>,
                                      <0x1a200000 0x1000>;
-                               interrupts = <0 154 0x0>;
+                               interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
                                clock-names = "core", "iface";
                                status = "disabled";
                        i2c@1a280000 {
                                compatible = "qcom,i2c-qup-v1.1.1";
                                reg = <0x1a280000 0x1000>;
-                               interrupts = <0 155 0>;
+                               interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
 
                                clocks = <&gcc GSBI5_QUP_CLK>, <&gcc GSBI5_H_CLK>;
                                clock-names = "core", "iface";
                        spi@1a280000 {
                                compatible = "qcom,spi-qup-v1.1.1";
                                reg = <0x1a280000 0x1000>;
-                               interrupts = <0 155 0>;
+                               interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
 
                                clocks = <&gcc GSBI5_QUP_CLK>, <&gcc GSBI5_H_CLK>;
                                clock-names = "core", "iface";
                                compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
                                reg = <0x16640000 0x1000>,
                                      <0x16600000 0x1000>;
-                               interrupts = <0 158 0x0>;
+                               interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&gcc GSBI7_UART_CLK>, <&gcc GSBI7_H_CLK>;
                                clock-names = "core", "iface";
                                status = "disabled";
                        compatible = "qcom,ipq806x-ahci", "generic-ahci";
                        reg = <0x29000000 0x180>;
 
-                       interrupts = <0 209 0x0>;
+                       interrupts = <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>;
 
                        clocks = <&gcc SFAB_SATA_S_H_CLK>,
                                 <&gcc SATA_H_CLK>,
index 4dc0b347b1eed522e696ecb85b98f8a9f936ab74..c2dc9d09484abd41d43d13a7a70b0f986a926e19 100644 (file)
                                                regulator-max-microvolt = <2950000>;
 
                                                regulator-boot-on;
+                                               regulator-system-load = <200000>;
+                                               regulator-allow-set-load;
                                        };
 
                                        l21 {
index 5af2a0116ff2689a69b850eb304192e3dd7f9312..474baa0c7cfc2cc16f7c704c77884e129d82606f 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Genmai board
  *
  * Copyright (C) 2013-14 Renesas Solutions Corp.
  * Copyright (C) 2014 Wolfram Sang, Sang Engineering <wsa@sang-engineering.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/;
index 779f724b4531defa1eebf6cf5a179a4b8bb1dcc6..fe1a4aa4d7cb3a32c3016303ff39d2513f1dd2bc 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the GR-Peach board
  *
  * Copyright (C) 2017 Jacopo Mondi <jacopo+renesas@jmondi.org>
  * Copyright (C) 2016 Renesas Electronics
- *
- * 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/;
index 5dcaaf131d2788ac55be89d3d4d9f9ced9beac9e..8ee44a100e9a44c41737a1697b0950c6e4001030 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the RZ/A1H RSK board
  *
  * Copyright (C) 2016 Renesas Electronics
- *
- * 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/;
index a54822e97bac42ed017203469a9f5f983bccf1bd..2211f88ede2ad351fdbbd1c2e07865a3448f8a97 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the r7s72100 SoC
  *
  * Copyright (C) 2013-14 Renesas Solutions Corp.
  * Copyright (C) 2014 Wolfram Sang, Sang Engineering <wsa@sang-engineering.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 <dt-bindings/clock/r7s72100-clock.h>
index 125c39c0222fb0cb67c1d8e3f217c765d08a53a2..d530f451467e2df864a836b7b8a492b32b38a2b2 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the APE6EVM board
  *
  * 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/;
index 080d037f5733a8c3352db4d1e65f84fbd2506a8b..dd865f3c2eda76a1d6454c5194b10a0b572187b8 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the r8a73a4 SoC
  *
  * Copyright (C) 2013 Renesas Solutions Corp.
  * Copyright (C) 2013 Magnus Damm
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include <dt-bindings/clock/r8a73a4-clock.h>
index 03b00d87b39bf225cd9f13c097c600a666f87ca1..32757caa258410125a9d10e43e098ec2cd9efa92 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the armadillo 800 eva board
  *
  * Copyright (C) 2012 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/;
index eb9a911deefb0592d58748cb8ada3ee5734dd21f..383cba68dbba642df843a22e29c65ad7cb570537 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the r8a7740 SoC
  *
  * Copyright (C) 2012 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.
  */
 
 #include <dt-bindings/clock/r8a7740-clock.h>
index d90eb8464222e33d2682523f7288f561c38e44af..327545119ee3f04d82ca3412a148e2f8ffd1e602 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the iWave-RZ/G1M Qseven board + camera daughter board
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /dts-v1/;
index 6aa6b7467704bc30dc72435b23e8611a17548927..b683db4da8b17784d17c9d2e69e73cbd8bf43ad4 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the iWave-RZ/G1M Qseven board
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /dts-v1/;
index d364685d91840efe8b684ab228fb1d20af331291..0e2e033cc84982f3d3c9d9f25089afad73f58cd2 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the iWave-RZG1M-20M Qseven SOM
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include "r8a7743.dtsi"
index 3d918d106593d2684eaa7e6e8f95de8695c3efbc..ca0e0fc9b2467743b87ad90589ad00ed312e861f 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the SK-RZG1M board
  *
  * Copyright (C) 2016-2017 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /dts-v1/;
index 142949d7066f3a65cafe3fd065d3043f0841e5d8..24715f74ae08c7c2139ac505821041efea05e564 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the r8a7743 SoC
  *
  * Copyright (C) 2016-2017 Cogent Embedded Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include <dt-bindings/interrupt-controller/irq.h>
                        reg = <1>;
                        clock-frequency = <1500000000>;
                        clocks = <&cpg CPG_CORE R8A7743_CLK_Z>;
+                       clock-latency = <300000>; /* 300 us */
                        power-domains = <&sysc R8A7743_PD_CA15_CPU1>;
                        next-level-cache = <&L2_CA15>;
+
+                       /* kHz - uV - OPPs unknown yet */
+                       operating-points = <1500000 1000000>,
+                                          <1312500 1000000>,
+                                          <1125000 1000000>,
+                                          < 937500 1000000>,
+                                          < 750000 1000000>,
+                                          < 375000 1000000>;
                };
 
                L2_CA15: cache-controller-0 {
index d34de8266ccd063c3aed7532888286943d63979d..2aeebfc9e4f1154b2e910b509818af069c087781 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the iWave-RZG1E SODIMM carrier board + HDMI daughter
  * board
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include "r8a7745-iwg22d-sodimm.dts"
index a4058f4cfbcdce3722a0bdceb43d7bbcca637d52..1db220cfc1a1d0ee5a6de6f44bdfe8ce306b0414 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the iWave-RZG1E SODIMM carrier board
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /*
index 29b6e10fdf96411cb308805c7419f29d994ae02b..41f111b99a759eab29f8d83573dc999c3b69badd 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the iWave-RZG1E-G22M SODIMM SOM
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include "r8a7745.dtsi"
index b4d679b04ad618a98337b9839b314a2d6ace4474..655b10bb42d576ba6ddd660876229780017e1ad2 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the SK-RZG1E board
  *
  * Copyright (C) 2016-2017 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /dts-v1/;
index 1cb7a7ab0418f29df6d98ad24940cb781b2e50c3..c53f7ff20695f04adfff363ef378b364dbc3f6e9 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the r8a7745 SoC
  *
  * Copyright (C) 2016-2017 Cogent Embedded Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include <dt-bindings/interrupt-controller/irq.h>
index c85032f9605b91711580e67362a1c58ea4e6834c..87d32d3e23de2c177efccb146845e98aefd7f217 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/clock/renesas-cpg-mssr.h>
+#include <dt-bindings/clock/r8a77470-cpg-mssr.h>
 / {
        compatible = "renesas,r8a77470";
        #address-cells = <2>;
@@ -22,7 +22,7 @@
                        compatible = "arm,cortex-a7";
                        reg = <0>;
                        clock-frequency = <1000000000>;
-                       clocks = <&cpg CPG_CORE 0>;
+                       clocks = <&cpg CPG_CORE R8A77470_CLK_Z2>;
                        power-domains = <&sysc 5>;
                        next-level-cache = <&L2_CA7>;
                };
                        reg = <0 0xe6e60000 0 0x40>;
                        interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 721>,
-                                <&cpg CPG_CORE 5>, <&scif_clk>;
+                                <&cpg CPG_CORE R8A77470_CLK_ZS>, <&scif_clk>;
                        clock-names = "fck", "brg_int", "scif_clk";
                        dmas = <&dmac0 0x29>, <&dmac0 0x2a>,
                               <&dmac1 0x29>, <&dmac1 0x2a>;
                        reg = <0 0xe6e68000 0 0x40>;
                        interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 720>,
-                                <&cpg CPG_CORE 5>, <&scif_clk>;
+                                <&cpg CPG_CORE R8A77470_CLK_ZS>, <&scif_clk>;
                        clock-names = "fck", "brg_int", "scif_clk";
                        dmas = <&dmac0 0x2d>, <&dmac0 0x2e>,
                               <&dmac1 0x2d>, <&dmac1 0x2e>;
                        reg = <0 0xe6e58000 0 0x40>;
                        interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 719>,
-                                <&cpg CPG_CORE 5>, <&scif_clk>;
+                                <&cpg CPG_CORE R8A77470_CLK_ZS>, <&scif_clk>;
                        clock-names = "fck", "brg_int", "scif_clk";
                        dmas = <&dmac0 0x2b>, <&dmac0 0x2c>,
                               <&dmac1 0x2b>, <&dmac1 0x2c>;
                        reg = <0 0xe6ea8000 0 0x40>;
                        interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 718>,
-                                <&cpg CPG_CORE 5>, <&scif_clk>;
+                                <&cpg CPG_CORE R8A77470_CLK_ZS>, <&scif_clk>;
                        clock-names = "fck", "brg_int", "scif_clk";
                        dmas = <&dmac0 0x2f>, <&dmac0 0x30>,
                               <&dmac1 0x2f>, <&dmac1 0x30>;
                        reg = <0 0xe6ee0000 0 0x40>;
                        interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 715>,
-                                <&cpg CPG_CORE 5>, <&scif_clk>;
+                                <&cpg CPG_CORE R8A77470_CLK_ZS>, <&scif_clk>;
                        clock-names = "fck", "brg_int", "scif_clk";
                        dmas = <&dmac0 0xfb>, <&dmac0 0xfc>,
                               <&dmac1 0xfb>, <&dmac1 0xfc>;
                        reg = <0 0xe6ee8000 0 0x40>;
                        interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 714>,
-                                <&cpg CPG_CORE 5>, <&scif_clk>;
+                                <&cpg CPG_CORE R8A77470_CLK_ZS>, <&scif_clk>;
                        clock-names = "fck", "brg_int", "scif_clk";
                        dmas = <&dmac0 0xfd>, <&dmac0 0xfe>,
                               <&dmac1 0xfd>, <&dmac1 0xfe>;
index c79d55eb43c53fde3d3b0b0a5211c6b6612bdb8f..de808d2ea856b19dffe002ecf7148f58d4bac658 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Reference Device Tree Source for the Bock-W board
  *
@@ -8,10 +9,6 @@
  *
  * Copyright (C) 2013 Renesas Solutions Corp.
  * Copyright (C) 2013 Simon Horman
- *
- * 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/;
index 3b49f9ed2e2b220ac9e65a0a9c4931a4f186eab0..1bce16cc6b209e63f808b6d2190a573c071b30fc 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for Renesas r8a7778
  *
@@ -8,10 +9,6 @@
  *
  * Copyright (C) 2013 Renesas Solutions Corp.
  * Copyright (C) 2013 Simon Horman
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include <dt-bindings/clock/r8a7778-clock.h>
index 4b9006bac3cbc83fbaeeebac6b80c7e67c6def90..a4d0038363f004d43892966e1e733412df54acc5 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Marzen board
  *
  * Copyright (C) 2013 Renesas Solutions Corp.
  * Copyright (C) 2013 Simon Horman
- *
- * 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/;
index e79ae306eeddf7ac204fbd5180e5c2fa6096b278..6b997bc016ee8a9e989a38ce476bb1c4f62d9f26 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for Renesas r8a7779
  *
  * Copyright (C) 2013 Renesas Solutions Corp.
  * Copyright (C) 2013 Simon Horman
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include <dt-bindings/clock/r8a7779-clock.h>
index 092610e3f953167c22b71edf7242aa6e2e29c836..50312e752e2fae3dc42c6a0c6b45b78b0db7dcf1 100644 (file)
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Lager board
  *
  * Copyright (C) 2013-2014 Renesas Solutions Corp.
  * Copyright (C) 2014 Cogent Embedded, Inc.
  * Copyright (C) 2015-2016 Renesas Electronics Corporation
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /*
index 4d06b154bd7ebd9eaa07436e6235bdacd76289f9..0925bdca438feedaa8ee956f8109fcca75dbbe1f 100644 (file)
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the r8a7790 SoC
  *
  * Copyright (C) 2015 Renesas Electronics Corporation
  * 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
- * kind, whether express or implied.
  */
 
 #include <dt-bindings/clock/r8a7790-cpg-mssr.h>
                        compatible = "arm,cortex-a15";
                        reg = <0>;
                        clock-frequency = <1300000000>;
-                       voltage-tolerance = <1>; /* 1% */
                        clocks = <&cpg CPG_CORE R8A7790_CLK_Z>;
-                       clock-latency = <300000>; /* 300 us */
                        power-domains = <&sysc R8A7790_PD_CA15_CPU0>;
                        next-level-cache = <&L2_CA15>;
                        capacity-dmips-mhz = <1024>;
+                       voltage-tolerance = <1>; /* 1% */
+                       clock-latency = <300000>; /* 300 us */
 
                        /* kHz - uV - OPPs unknown yet */
                        operating-points = <1400000 1000000>,
                        power-domains = <&sysc R8A7790_PD_CA15_CPU1>;
                        next-level-cache = <&L2_CA15>;
                        capacity-dmips-mhz = <1024>;
+                       voltage-tolerance = <1>; /* 1% */
+                       clock-latency = <300000>; /* 300 us */
+
+                       /* kHz - uV - OPPs unknown yet */
+                       operating-points = <1400000 1000000>,
+                                          <1225000 1000000>,
+                                          <1050000 1000000>,
+                                          < 875000 1000000>,
+                                          < 700000 1000000>,
+                                          < 350000 1000000>;
                };
 
                cpu2: cpu@2 {
                        power-domains = <&sysc R8A7790_PD_CA15_CPU2>;
                        next-level-cache = <&L2_CA15>;
                        capacity-dmips-mhz = <1024>;
+                       voltage-tolerance = <1>; /* 1% */
+                       clock-latency = <300000>; /* 300 us */
+
+                       /* kHz - uV - OPPs unknown yet */
+                       operating-points = <1400000 1000000>,
+                                          <1225000 1000000>,
+                                          <1050000 1000000>,
+                                          < 875000 1000000>,
+                                          < 700000 1000000>,
+                                          < 350000 1000000>;
                };
 
                cpu3: cpu@3 {
                        power-domains = <&sysc R8A7790_PD_CA15_CPU3>;
                        next-level-cache = <&L2_CA15>;
                        capacity-dmips-mhz = <1024>;
+                       voltage-tolerance = <1>; /* 1% */
+                       clock-latency = <300000>; /* 300 us */
+
+                       /* kHz - uV - OPPs unknown yet */
+                       operating-points = <1400000 1000000>,
+                                          <1225000 1000000>,
+                                          <1050000 1000000>,
+                                          < 875000 1000000>,
+                                          < 700000 1000000>,
+                                          < 350000 1000000>;
                };
 
                cpu4: cpu@100 {
index 8ab793d8b2fd76c894b28e79de34c6b97ddea308..ce22db01fbbaafb4689cc736cc357f8ec7f7f335 100644 (file)
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Koelsch board
  *
  * Copyright (C) 2013 Renesas Electronics Corporation
  * 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
- * kind, whether express or implied.
  */
 
 /*
index a01101b49d993c185249009b063d6ef0b80d13bc..f02036e5de015a95feec05c47ead06e91cb3daee 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Porter board
  *
  * Copyright (C) 2015 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /*
        clock-frequency = <400000>;
 };
 
+&i2c6 {
+       status = "okay";
+       clock-frequency = <100000>;
+
+       pmic@5a {
+               compatible = "dlg,da9063l";
+               reg = <0x5a>;
+               interrupt-parent = <&irqc0>;
+               interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+               interrupt-controller;
+
+               wdt {
+                       compatible = "dlg,da9063-watchdog";
+               };
+       };
+
+       vdd_dvfs: regulator@68 {
+               compatible = "dlg,da9210";
+               reg = <0x68>;
+               interrupt-parent = <&irqc0>;
+               interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+
+               regulator-min-microvolt = <1000000>;
+               regulator-max-microvolt = <1000000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+};
+
 &sata0 {
        status = "okay";
 };
 
+&cpu0 {
+       cpu0-supply = <&vdd_dvfs>;
+};
+
 /* composite video input */
 &vin0 {
        status = "okay";
index 6e1dd7ad7bd647e7db66c1db8947c1d9718957ce..991ac6feedd5beb6123f7a12f98c8799d89f9565 100644 (file)
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the r8a7791 SoC
  *
  * Copyright (C) 2013-2015 Renesas Electronics Corporation
  * 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
- * kind, whether express or implied.
  */
 
 #include <dt-bindings/clock/r8a7791-cpg-mssr.h>
                        compatible = "arm,cortex-a15";
                        reg = <0>;
                        clock-frequency = <1500000000>;
-                       voltage-tolerance = <1>; /* 1% */
                        clocks = <&cpg CPG_CORE R8A7791_CLK_Z>;
-                       clock-latency = <300000>; /* 300 us */
                        power-domains = <&sysc R8A7791_PD_CA15_CPU0>;
                        next-level-cache = <&L2_CA15>;
+                       voltage-tolerance = <1>; /* 1% */
+                       clock-latency = <300000>; /* 300 us */
 
                        /* kHz - uV - OPPs unknown yet */
                        operating-points = <1500000 1000000>,
                        clocks = <&cpg CPG_CORE R8A7791_CLK_Z>;
                        power-domains = <&sysc R8A7791_PD_CA15_CPU1>;
                        next-level-cache = <&L2_CA15>;
+                       voltage-tolerance = <1>; /* 1% */
+                       clock-latency = <300000>; /* 300 us */
+
+                       /* kHz - uV - OPPs unknown yet */
+                       operating-points = <1500000 1000000>,
+                                          <1312500 1000000>,
+                                          <1125000 1000000>,
+                                          < 937500 1000000>,
+                                          < 750000 1000000>,
+                                          < 375000 1000000>;
                };
 
                L2_CA15: cache-controller-0 {
index 04fb70931b3b077269a2bbc2a79ae9cd4fd168e7..f92301290b026fdbb9d223b9da6907c7b06b6bd9 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Blanche board
  *
  * Copyright (C) 2014 Renesas Electronics Corporation
  * Copyright (C) 2016 Cogent  Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /dts-v1/;
index db01de7a3811ecce28461ecc6dc6334d334aeaf8..f46f4567b3d41484d9e47c874f92d34b827994e5 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Wheat board
  *
  * Copyright (C) 2016 Renesas Electronics Corporation
  * Copyright (C) 2016 Cogent  Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /dts-v1/;
index f44257dd86f6628962e3cf1df4f026829b886c5a..63a978ec81cc09f0a4d989fff7171d893ba07387 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the r8a7792 SoC
  *
  * Copyright (C) 2016 Cogent Embedded Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include <dt-bindings/clock/r8a7792-cpg-mssr.h>
index aa209f6e5d712e6cf021e9712c8287f1e98104ec..6b2f3a4fd13d646c35e48fc46a7efa31ab42035e 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Gose board
  *
  * Copyright (C) 2014-2015 Renesas Electronics Corporation
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /*
index 4abecfc0ca98c48346114b5f44600e795182aedb..620a570307ffcffa0ac2cc42918684882952b4b2 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the r8a7793 SoC
  *
  * Copyright (C) 2014-2015 Renesas Electronics Corporation
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include <dt-bindings/clock/r8a7793-cpg-mssr.h>
                        compatible = "arm,cortex-a15";
                        reg = <0>;
                        clock-frequency = <1500000000>;
-                       voltage-tolerance = <1>; /* 1% */
                        clocks = <&cpg CPG_CORE R8A7793_CLK_Z>;
-                       clock-latency = <300000>; /* 300 us */
                        power-domains = <&sysc R8A7793_PD_CA15_CPU0>;
+                       voltage-tolerance = <1>; /* 1% */
+                       clock-latency = <300000>; /* 300 us */
 
                        /* kHz - uV - OPPs unknown yet */
                        operating-points = <1500000 1000000>,
                        clock-frequency = <1500000000>;
                        clocks = <&cpg CPG_CORE R8A7793_CLK_Z>;
                        power-domains = <&sysc R8A7793_PD_CA15_CPU1>;
+                       voltage-tolerance = <1>; /* 1% */
+                       clock-latency = <300000>; /* 300 us */
+
+                       /* kHz - uV - OPPs unknown yet */
+                       operating-points = <1500000 1000000>,
+                                          <1312500 1000000>,
+                                          <1125000 1000000>,
+                                          < 937500 1000000>,
+                                          < 750000 1000000>,
+                                          < 375000 1000000>;
+                       next-level-cache = <&L2_CA15>;
                };
 
                L2_CA15: cache-controller-0 {
index e17027532941f57c753fed893d6d0f2ff2873fbb..ef7e2a837df6da79596339e15bd0db2000fd27c5 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Alt board
  *
  * Copyright (C) 2014 Renesas Electronics Corporation
- *
- * 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/;
index 7808aaee6644a95dcfdaf1d6e001c3293c265375..daec965889d3e5fe18e764daaf77758e24aacd0c 100644 (file)
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the SILK board
  *
  * Copyright (C) 2014 Renesas Electronics Corporation
  * Copyright (C) 2014-2015 Renesas Solutions Corp.
  * Copyright (C) 2014-2015 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /*
index 736196903d22f0e09650ac9b7644476369040603..ea2ca4bdaf1c129c3932644a45bce1145ebabfb6 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the r8a7794 SoC
  *
  * Copyright (C) 2014 Renesas Electronics Corporation
  * Copyright (C) 2014 Ulrich Hecht
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include <dt-bindings/clock/r8a7794-cpg-mssr.h>
index 238d14bb0ebebf52b644ff2c27fca867fd8795c7..79fce67ebb1c81e711ee8c9e90117ab7d12000fe 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Common file for the AA104XD12 panel connected to Renesas R-Car boards
  *
  * Copyright (C) 2014 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 / {
index 04aafd4797750c3db8a3fe43855fdb1fe62c8081..6e7589ea756240f6dc2c2f59cdaa79ad7c053447 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Common file for the AA121TD01 panel connected to Renesas R-Car boards
  *
  * Copyright (C) 2015 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 / {
diff --git a/arch/arm/boot/dts/r9a06g032-rzn1d400-db.dts b/arch/arm/boot/dts/r9a06g032-rzn1d400-db.dts
new file mode 100644 (file)
index 0000000..4e57ae2
--- /dev/null
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the RZN1D-DB Board
+ *
+ * Copyright (C) 2018 Renesas Electronics Europe Limited
+ *
+ */
+
+/dts-v1/;
+
+#include "r9a06g032.dtsi"
+
+/ {
+       model = "RZN1D-DB Board";
+       compatible = "renesas,rzn1d400-db", "renesas,r9a06g032";
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       aliases {
+               serial0 = &uart0;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi
new file mode 100644 (file)
index 0000000..afe29c9
--- /dev/null
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Base Device Tree Source for the Renesas RZ/N1D (R9A06G032)
+ *
+ * Copyright (C) 2018 Renesas Electronics Europe Limited
+ *
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+       compatible = "renesas,r9a06g032";
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0>;
+                       clocks = <&sysctrl 84>;
+               };
+
+               cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <1>;
+                       clocks = <&sysctrl 84>;
+                       enable-method = "renesas,r9a06g032-smp";
+                       cpu-release-addr = <0 0x4000c204>;
+               };
+       };
+
+       ext_jtag_clk: extjtagclk {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <0>;
+       };
+
+       ext_mclk: extmclk {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <40000000>;
+       };
+
+       ext_rgmii_ref: extrgmiiref {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <0>;
+       };
+
+       ext_rtc_clk: extrtcclk {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+               clock-frequency = <0>;
+       };
+
+       soc {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               interrupt-parent = <&gic>;
+               ranges;
+
+               sysctrl: system-controller@4000c000 {
+                       compatible = "renesas,r9a06g032-sysctrl";
+                       reg = <0x4000c000 0x1000>;
+                       status = "okay";
+                       #clock-cells = <1>;
+
+                       clocks = <&ext_mclk>, <&ext_rtc_clk>,
+                                       <&ext_jtag_clk>, <&ext_rgmii_ref>;
+                       clock-names = "mclk", "rtc", "jtag", "rgmii_ref_ext";
+               };
+
+               uart0: serial@40060000 {
+                       compatible = "snps,dw-apb-uart";
+                       reg = <0x40060000 0x400>;
+                       interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clocks = <&sysctrl 146>;
+                       clock-names = "baudclk";
+                       status = "disabled";
+               };
+
+               gic: gic@44101000 {
+                       compatible = "arm,cortex-a7-gic", "arm,gic-400";
+                       interrupt-controller;
+                       #interrupt-cells = <3>;
+                       reg = <0x44101000 0x1000>, /* Distributer */
+                             <0x44102000 0x2000>, /* CPU interface */
+                             <0x44104000 0x2000>, /* Virt interface control */
+                             <0x44106000 0x2000>; /* Virt CPU interface */
+                       interrupts =
+                               <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+               };
+       };
+
+       timer {
+               compatible = "arm,cortex-a7-timer",
+                            "arm,armv7-timer";
+               interrupt-parent = <&gic>;
+               arm,cpu-registers-not-fw-configured;
+               always-on;
+               interrupts =
+                       <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                       <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                       <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                       <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+       };
+};
index c0953410121ba4c2494a52dfd3094371e960af21..2a7e6624efb93127ab3167bad028b21dab33ad2a 100644 (file)
@@ -1,42 +1,4 @@
-/*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 
 /dts-v1/;
 
index e2a0f576946f0884bb091d8a2ff6bc71e7b47949..0fd19f9723dfcd73fda9f285588bb005a1c4627f 100644 (file)
@@ -1,42 +1,4 @@
-/*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 
 /dts-v1/;
 
index 567a6a725f9cc889ce19a81aad4b8dbb24bb96bb..67f57200d9a06ba1a2dde2b123aca62a1571230e 100644 (file)
@@ -1,42 +1,4 @@
-/*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
index ef1eabf2512c5eec210b8694ca50e1072ba85960..1c925f20dba0c8b714b7b3e24725ea7c5a43352d 100644 (file)
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2013 MundoReader S.L.
  * Author: Heiko Stuebner <heiko@sntech.de>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index d23ee6d911acf55cb9330b66330966c33816ac7f..ce525b956ae5ce9d640642452b1bb3edf0da005a 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2014 Romain Perier <romain.perier@gmail.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 13e285c53defd633967f3058b4b3ce12e673dfa7..b6a8a82d219ef9e02e705596217b7c7194751f3b 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Paweł Jarosz <paweljarosz3691@gmail.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 4d7057a10a4cc1eac3598b9225af699bc466e43f..cd126b927ba88e6fca1b6ebd84569e8fed6834f0 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2014, 2015 FUKAUMI Naoki <naobsd@gmail.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 06523caca27d6d09058fbe3b6983266fbae3858c..2ab3c4b32003698e504049f925165ebca92ae52d 100644 (file)
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2013 MundoReader S.L.
  * Author: Heiko Stuebner <heiko@sntech.de>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/gpio/gpio.h>
index 8ba9e06062f3e05434cf954fa1027146abbdb3d6..375129b621021bbdff016c6964bd4083577ab2c1 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Andy Yan <andy.yan@rock-chips.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 00e05a6662acd5bb19c42540fd0d22c857fdf4af..45fd2b302dda1d1c3c995149f2386c1d1db97af9 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index aa10caae51c3021f4cef19ade6bd3ca517e3c24f..aa123f93f181c0d1b01f210fdee5e134518bfdc2 100644 (file)
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2013 MundoReader S.L.
  * Author: Heiko Stuebner <heiko@sntech.de>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/gpio/gpio.h>
index 1be9daacc4f91448ad9f467376922f065385ab53..5670b33fd1bd0a4c431fc138bc77a0ccdc128714 100644 (file)
@@ -1,42 +1,4 @@
-/*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 
 /dts-v1/;
 
index 73e38458575541d4571758989d4ecb073eac7d23..4df7accc3ad7a2bf7d969405dd0c051c429df1f9 100644 (file)
@@ -1,42 +1,4 @@
-/*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 
 /dts-v1/;
 
index 6fe6c15fc13a348369ad9358f3940621538c0ab8..cb7d3fad8e60e3e68d6cc6f2403a4d095b27651f 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "rk322x.dtsi"
index be80e9a2c9af16fbf10e9cb6ee143a4f0d3151c7..cd8f2a3b0e910c6b0ab05628e73885e6b06025b7 100644 (file)
@@ -1,42 +1,4 @@
-/*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
@@ -80,6 +42,7 @@
                        reg = <0xf01>;
                        resets = <&cru SRST_CORE1>;
                        operating-points-v2 = <&cpu0_opp_table>;
+                       #cooling-cells = <2>; /* min followed by max */
                        enable-method = "psci";
                };
 
@@ -89,6 +52,7 @@
                        reg = <0xf02>;
                        resets = <&cru SRST_CORE2>;
                        operating-points-v2 = <&cpu0_opp_table>;
+                       #cooling-cells = <2>; /* min followed by max */
                        enable-method = "psci";
                };
 
@@ -98,6 +62,7 @@
                        reg = <0xf03>;
                        resets = <&cru SRST_CORE3>;
                        operating-points-v2 = <&cpu0_opp_table>;
+                       #cooling-cells = <2>; /* min followed by max */
                        enable-method = "psci";
                };
        };
index b9418d170502915e81d74f59ec1b15dc39d41996..6592c809e2a54140086cdd0444dd1959eadcb6df 100644 (file)
@@ -1,42 +1,4 @@
-/*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 
 /dts-v1/;
 #include "rk3288-evb.dtsi"
index 56c266df01c1016db18ff3a404723e59abc5dbfc..16788209625b08fc26647d40bc9b90d92d9a64eb 100644 (file)
@@ -1,42 +1,4 @@
-/*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 
 /dts-v1/;
 #include "rk3288-evb.dtsi"
index 39b61dce97ad344e0884a02f87ff66c6155eb51d..97e4d552ff0f050c0214226bc55e83196480e55b 100644 (file)
@@ -1,42 +1,4 @@
-/*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/pwm/pwm.h>
                        #address-cells = <1>;
                        #size-cells = <0>;
 
-                       edp_out_panel: endpoint {
+                       edp_out_panel: endpoint@0 {
                                reg = <0>;
                                remote-endpoint = <&panel_in_edp>;
                        };
index 41405974253a4ba945362ecac43d8eb61484538c..b1b56dfdfdba1d98632502c10ccd2754aa29e121 100644 (file)
@@ -1,42 +1,4 @@
-/*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 
 /dts-v1/;
 
index 0195d972166052e0a3a493299b69aa34c6cab404..0f3c29d7fbab0e029fdb33b14b99458c46597749 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2014, 2015 FUKAUMI Naoki <naobsd@gmail.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 5f1e336dbaac7a85c300c1a5f395a7d4cd127953..f57f286a93c3e7540d8b2890d3eea6918d44b73d 100644 (file)
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device tree file for Firefly Rockchip RK3288 Core board
  * Copyright (c) 2016 Randy Li <ayaka@soulik.info>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/input/input.h>
index eab176e3dfc3011149ecefc91745a4ee3a20e89f..58ea8bed040ab0524877e5a03833246bea662ca4 100644 (file)
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device tree file for Firefly Rockchip RK3288 Core board
  * Copyright (c) 2016 Randy Li <ayaka@soulik.info>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 14271be72f302731581035ab54eb2fe67f9314ce..556ab42dd81cfa914501a711b599721a27300c84 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2014, 2015 FUKAUMI Naoki <naobsd@gmail.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index b9e6f3a97240c4a8e422cc44052604e05893fcdc..a6ff7eac4aa847a7621b9925a4f3214fa443e879 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2014, 2015 FUKAUMI Naoki <naobsd@gmail.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/input/input.h>
index 4d923aa6ed1196395897cd6abefa56dc557ff5a4..504ab1177aa79175a86dd92ac04276c1992a3b08 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Heiko Stuebner <heiko@sntech.de>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 985743fa134cd91416177f92c98a372c55fefdd4..7077c3403483e7453c1e2471d4f1564f96b8a355 100644 (file)
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device tree file for Phytec PCM-947 carrier board
  * Copyright (C) 2017 PHYTEC Messtechnik GmbH
  * Author: Wadim Egorov <w.egorov@phytec.de>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index aaab2d171ffe1da4716fbd959d1e6eacd3e891b9..c218dd54c9b5896146583926781d04f181374227 100644 (file)
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device tree file for Phytec phyCORE-RK3288 SoM
  * Copyright (C) 2017 PHYTEC Messtechnik GmbH
  * Author: Wadim Egorov <w.egorov@phytec.de>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/net/ti-dp83867.h>
index c06d0f4ceb8153811752a2d31e0e85779288ec5d..596435e0313292109238189468ab1fb9ce139fdc 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2014, 2015 Andy Yan <andy.yan@rock-chips.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index e95215c9788b38376a78cc8d2567798662d0d51f..28972fb4e221a90b8fee239697542a2608c19494 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2015 Heiko Stuebner <heiko@sntech.de>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 51f36a1b698ef8a30ca5cc29fe50df2f1dec5b8b..50325489c0ced4d21306801d2fabaf1e0261a97f 100644 (file)
@@ -1,42 +1,4 @@
-/*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 
 #include <dt-bindings/pwm/pwm.h>
 #include "rk3288.dtsi"
index 8ccc89dbdfaf0164c2d780b6732baa6397ef6248..6a30cadad88a15d52f225c49745855c6e75307bf 100644 (file)
@@ -1,42 +1,4 @@
-/*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 
 /dts-v1/;
 #include <dt-bindings/input/input.h>
index 127488f9f17460133f802e206f598c11a766735c..ceade5962899e64ab1733ed937f669b1ff94c256 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 280aceae25d5021afc15a8c2d905803026b6145c..eaf921694e6814c3e28d900f5df9313a274c2bcf 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Google Veyron (and derivatives) fragment for the  max98090 audio
  * codec and analog headphone jack.
  *
  * Copyright 2016 Google, Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 / {
index ed4255294ad4e191c2261e107169183b4b0b319b..5c94a33d695d47f95e1b4fad04dd63f661646eaf 100644 (file)
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Google Veyron Brain Rev 0 board device tree source
  *
  * Copyright 2014 Google, Inc
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index b16d570ff029b74da108fa1df3d0d60e1c314953..b54746df3661afe92d746909ba02c9fb3ee45432 100644 (file)
@@ -1,46 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Google Veyron (and derivatives) board device tree source
  * Chromebook specific parts
  *
  * Copyright 2015 Google, Inc
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/clock/rockchip,rk808.h>
                        reg = <1>;
                        #address-cells = <1>;
                        #size-cells = <0>;
-                       edp_out_panel: endpoint {
+                       edp_out_panel: endpoint@0 {
                                reg = <0>;
                                remote-endpoint = <&panel_in_edp>;
                        };
index d33f5763c39c6abcf95ebd8a7ba38c7ef9b871dc..9d6814c7f285f9ac0384eb9622f6bf30b92c44e6 100644 (file)
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Google Veyron Jaq Rev 1+ board device tree source
  *
  * Copyright 2015 Google, Inc
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index cdea751f2a8cb6f10ac67425808151008beaf70e..2ba89895c33a436fa4193b48e628d5ab8931769a 100644 (file)
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Google Veyron Jerry Rev 3+ board device tree source
  *
  * Copyright 2015 Google, Inc
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index f0994f0e577454ceef15f371841ee145506f62eb..1e0158acf895d99f8bde234891011e019e172a92 100644 (file)
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Google Veyron Mickey Rev 0 board device tree source
  *
  * Copyright 2015 Google, Inc
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 4c5307e62001e4fc6172e4a1b80a63bdb73c6f20..f95d0c5fcf71263f044cb84a7efd6599878895be 100644 (file)
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Google Veyron Minnie Rev 0+ board device tree source
  *
  * Copyright 2015 Google, Inc
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 995cff42fa43a2fb19fab79a68dcdec0473f7b3d..2950aadf49f0564aae51a5471db83a808f55577b 100644 (file)
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Google Veyron Pinky Rev 2 board device tree source
  *
  * Copyright 2015 Google, Inc
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 95e9bee8bca2bd0c6c619dcd58670a298661548c..a4570444cc79527efeb725be0207de6845b70f0a 100644 (file)
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Google Veyron (and derivatives) fragment for sdmmc cards
  *
  * Copyright 2015 Google, Inc
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 &io_domains {
index cc0b78cefe34651843e8a9bc9cc388014137e375..e16421d80d2280aeb2452168737550216753e7f3 100644 (file)
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Google Veyron Speedy Rev 1+ board device tree source
  *
  * Copyright 2015 Google, Inc
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 6e5bd8974f22dc9aac0fdf7daeeae8ca490f82d0..2075120cfc4d780482a89b4cd8203419f3860a6d 100644 (file)
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Google Veyron (and derivatives) board device tree source
  *
  * Copyright 2015 Google, Inc
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/clock/rockchip,rk808.h>
 
 &cpu0 {
        cpu0-supply = <&vdd_cpu>;
-       operating-points = <
-               /* KHz    uV */
-               1800000 1400000
-               1704000 1350000
-               1608000 1300000
-               1512000 1250000
-               1416000 1200000
-               1200000 1100000
-               1008000 1050000
-                816000 1000000
-                696000  950000
-                600000  900000
-                408000  900000
-                216000  900000
-                126000  900000
-       >;
+};
+
+/* rk3288-c used in Veyron Chrome-devices has slightly changed OPPs */
+&cpu_opp_table {
+       /delete-node/ opp-312000000;
+
+       opp-1512000000 {
+               opp-microvolt = <1250000>;
+       };
+       opp-1608000000 {
+               opp-microvolt = <1300000>;
+       };
+       opp-1704000000 {
+               opp-hz = /bits/ 64 <1704000000>;
+               opp-microvolt = <1350000>;
+       };
+       opp-1800000000 {
+               opp-hz = /bits/ 64 <1800000000>;
+               opp-microvolt = <1400000>;
+       };
 };
 
 &emmc {
index 14c896bfc6397365ebc0b3dc115a3025604ea7f6..4856a9fc0aea90df4888dfcfcde7b5fef7f50705 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (C) 2017 Jagan Teki <jagan@amarulasolutions.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index d7e49d29ace540fe4022b8822b84840ebdb5b65a..0840ffb3205cebb7cc7932228b74dad0b920b1c7 100644 (file)
@@ -1,42 +1,4 @@
-/*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
                        compatible = "arm,cortex-a12";
                        reg = <0x500>;
                        resets = <&cru SRST_CORE0>;
-                       operating-points = <
-                               /* KHz    uV */
-                               1608000 1350000
-                               1512000 1300000
-                               1416000 1200000
-                               1200000 1100000
-                               1008000 1050000
-                                816000 1000000
-                                696000  950000
-                                600000  900000
-                                408000  900000
-                                312000  900000
-                                216000  900000
-                                126000  900000
-                       >;
+                       operating-points-v2 = <&cpu_opp_table>;
                        #cooling-cells = <2>; /* min followed by max */
                        clock-latency = <40000>;
                        clocks = <&cru ARMCLK>;
                        compatible = "arm,cortex-a12";
                        reg = <0x501>;
                        resets = <&cru SRST_CORE1>;
+                       operating-points = <&cpu_opp_table>;
+                       #cooling-cells = <2>; /* min followed by max */
+                       clock-latency = <40000>;
+                       clocks = <&cru ARMCLK>;
                };
                cpu2: cpu@502 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a12";
                        reg = <0x502>;
                        resets = <&cru SRST_CORE2>;
+                       operating-points = <&cpu_opp_table>;
+                       #cooling-cells = <2>; /* min followed by max */
+                       clock-latency = <40000>;
+                       clocks = <&cru ARMCLK>;
                };
                cpu3: cpu@503 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a12";
                        reg = <0x503>;
                        resets = <&cru SRST_CORE3>;
+                       operating-points = <&cpu_opp_table>;
+                       #cooling-cells = <2>; /* min followed by max */
+                       clock-latency = <40000>;
+                       clocks = <&cru ARMCLK>;
+               };
+       };
+
+       cpu_opp_table: cpu-opp-table {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp-126000000 {
+                       opp-hz = /bits/ 64 <126000000>;
+                       opp-microvolt = <900000>;
+               };
+               opp-216000000 {
+                       opp-hz = /bits/ 64 <216000000>;
+                       opp-microvolt = <900000>;
+               };
+               opp-312000000 {
+                       opp-hz = /bits/ 64 <312000000>;
+                       opp-microvolt = <900000>;
+               };
+               opp-408000000 {
+                       opp-hz = /bits/ 64 <408000000>;
+                       opp-microvolt = <900000>;
+               };
+               opp-600000000 {
+                       opp-hz = /bits/ 64 <600000000>;
+                       opp-microvolt = <900000>;
+               };
+               opp-696000000 {
+                       opp-hz = /bits/ 64 <696000000>;
+                       opp-microvolt = <950000>;
+               };
+               opp-816000000 {
+                       opp-hz = /bits/ 64 <816000000>;
+                       opp-microvolt = <1000000>;
+               };
+               opp-1008000000 {
+                       opp-hz = /bits/ 64 <1008000000>;
+                       opp-microvolt = <1050000>;
+               };
+               opp-1200000000 {
+                       opp-hz = /bits/ 64 <1200000000>;
+                       opp-microvolt = <1100000>;
+               };
+               opp-1416000000 {
+                       opp-hz = /bits/ 64 <1416000000>;
+                       opp-microvolt = <1200000>;
+               };
+               opp-1512000000 {
+                       opp-hz = /bits/ 64 <1512000000>;
+                       opp-microvolt = <1300000>;
+               };
+               opp-1608000000 {
+                       opp-hz = /bits/ 64 <1608000000>;
+                       opp-microvolt = <1350000>;
                };
        };
 
index 49584b6a4195281916d1bec1b02bfa15fa91d012..d752dc611fd7410b80dc1b7e9c8f5e971e0939cc 100644 (file)
@@ -1,44 +1,7 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2013 MundoReader S.L.
  * Author: Heiko Stuebner <heiko@sntech.de>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/interrupt-controller/irq.h>
index 70f0106d1252b26b7062d354758c9e2468ee16e3..203d83e3bbf57950564125a31d7a67ff332cf784 100644 (file)
@@ -1,42 +1,4 @@
-/*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 
 /dts-v1/;
 
index 76ea24636feb12026e0708c6c256cf0465722787..ed8f6ca52c5bc979777aa54a6d2e011593c9f92f 100644 (file)
@@ -1,42 +1,4 @@
-/*
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
diff --git a/arch/arm/boot/dts/s5pv210-aries.dtsi b/arch/arm/boot/dts/s5pv210-aries.dtsi
new file mode 100644 (file)
index 0000000..575094e
--- /dev/null
@@ -0,0 +1,419 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung's S5PV210 based Galaxy Aries board device tree source
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "s5pv210.dtsi"
+
+/ {
+       compatible = "samsung,aries", "samsung,s5pv210";
+
+       aliases {
+               i2c6 = &i2c_pmic;
+               i2c9 = &i2c_fuel;
+       };
+
+       memory@30000000 {
+               device_type = "memory";
+               reg = <0x30000000 0x05000000
+                       0x40000000 0x10000000
+                       0x50000000 0x08000000>;
+       };
+
+       wifi_pwrseq: wifi-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               reset-gpios = <&gpg1 2 GPIO_ACTIVE_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&wlan_gpio_rst>;
+               post-power-on-delay-ms = <500>;
+               power-off-delay-us = <500>;
+       };
+
+       i2c_pmic: i2c-gpio-0 {
+               compatible = "i2c-gpio";
+               sda-gpios = <&gpj4 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+               scl-gpios = <&gpj4 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+               i2c-gpio,delay-us = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               pmic@66 {
+                       compatible = "maxim,max8998";
+                       reg = <0x66>;
+                       interrupt-parent = <&gph0>;
+                       interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
+
+                       max8998,pmic-buck1-default-dvs-idx = <1>;
+                       max8998,pmic-buck1-dvs-gpios = <&gph0 3 GPIO_ACTIVE_HIGH>,
+                                                       <&gph0 4 GPIO_ACTIVE_HIGH>;
+                       max8998,pmic-buck1-dvs-voltage = <1275000>, <1200000>,
+                                                       <1050000>, <950000>;
+
+                       max8998,pmic-buck2-default-dvs-idx = <0>;
+                       max8998,pmic-buck2-dvs-gpio = <&gph0 5 GPIO_ACTIVE_HIGH>;
+                       max8998,pmic-buck2-dvs-voltage = <1100000>, <1000000>;
+
+                       regulators {
+                               ldo2_reg: LDO2 {
+                                       regulator-name = "VALIVE_1.2V";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+
+                                       regulator-state-mem {
+                                               regulator-on-in-suspend;
+                                       };
+                               };
+
+                               ldo3_reg: LDO3 {
+                                       regulator-name = "VUSB_1.1V";
+                                       regulator-min-microvolt = <1100000>;
+                                       regulator-max-microvolt = <1100000>;
+
+                                       regulator-state-mem {
+                                               regulator-off-in-suspend;
+                                       };
+                               };
+
+                               ldo4_reg: LDO4 {
+                                       regulator-name = "VADC_3.3V";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                                       regulator-always-on;
+
+                                       regulator-state-mem {
+                                               regulator-off-in-suspend;
+                                       };
+                               };
+
+                               ldo5_reg: LDO5 {
+                                       regulator-name = "VTF_2.8V";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+
+                                       regulator-state-mem {
+                                               regulator-off-in-suspend;
+                                       };
+                               };
+
+                               ldo6_reg: LDO6 {
+                                       regulator-name = "LDO6";
+                                       regulator-min-microvolt = <1600000>;
+                                       regulator-max-microvolt = <3600000>;
+                               };
+
+                               ldo7_reg: LDO7 {
+                                       regulator-name = "VLCD_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       /* Till we get panel driver */
+                                       regulator-always-on;
+
+                                       regulator-state-mem {
+                                               regulator-off-in-suspend;
+                                       };
+                               };
+
+                               ldo8_reg: LDO8 {
+                                       regulator-name = "VUSB_3.3V";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+
+                                       regulator-state-mem {
+                                               regulator-off-in-suspend;
+                                       };
+                               };
+
+                               ldo9_reg: LDO9 {
+                                       regulator-name = "VCC_2.8V_PDA";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo10_reg: LDO10 {
+                                       regulator-name = "VPLL_1.2V";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+
+                                       regulator-state-mem {
+                                               regulator-on-in-suspend;
+                                       };
+                               };
+
+                               ldo11_reg: LDO11 {
+                                       regulator-name = "CAM_AF_3.0V";
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3000000>;
+
+                                       regulator-state-mem {
+                                               regulator-off-in-suspend;
+                                       };
+                               };
+
+                               ldo12_reg: LDO12 {
+                                       regulator-name = "CAM_SENSOR_CORE_1.2V";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+
+                                       regulator-state-mem {
+                                               regulator-off-in-suspend;
+                                       };
+                               };
+
+                               ldo13_reg: LDO13 {
+                                       regulator-name = "VGA_VDDIO_2.8V";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+
+                                       regulator-state-mem {
+                                               regulator-off-in-suspend;
+                                       };
+                               };
+
+                               ldo14_reg: LDO14 {
+                                       regulator-name = "VGA_DVDD_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+
+                                       regulator-state-mem {
+                                               regulator-off-in-suspend;
+                                       };
+                               };
+
+                               ldo15_reg: LDO15 {
+                                       regulator-name = "CAM_ISP_HOST_2.8V";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+
+                                       regulator-state-mem {
+                                               regulator-off-in-suspend;
+                                       };
+                               };
+
+                               ldo16_reg: LDO16 {
+                                       regulator-name = "VGA_AVDD_2.8V";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+
+                                       regulator-state-mem {
+                                               regulator-off-in-suspend;
+                                       };
+                               };
+
+                               ldo17_reg: LDO17 {
+                                       regulator-name = "VCC_3.0V_LCD";
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3000000>;
+                                       /* Till we get panel driver */
+                                       regulator-always-on;
+
+                                       regulator-state-mem {
+                                               regulator-off-in-suspend;
+                                       };
+                               };
+
+                               buck1_reg: BUCK1 {
+                                       regulator-name = "vddarm";
+                                       regulator-min-microvolt = <750000>;
+                                       regulator-max-microvolt = <1500000>;
+
+                                       regulator-state-mem {
+                                               regulator-off-in-suspend;
+                                               regulator-suspend-microvolt = <1250000>;
+                                       };
+                               };
+
+                               buck2_reg: BUCK2 {
+                                       regulator-name = "vddint";
+                                       regulator-min-microvolt = <750000>;
+                                       regulator-max-microvolt = <1500000>;
+
+                                       regulator-state-mem {
+                                               regulator-off-in-suspend;
+                                               regulator-suspend-microvolt = <1100000>;
+                                       };
+                               };
+
+                               buck3_reg: BUCK3 {
+                                       regulator-name = "VCC_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               buck4_reg: BUCK4 {
+                                       regulator-name = "CAM_ISP_CORE_1.2V";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+
+                                       regulator-state-mem {
+                                               regulator-off-in-suspend;
+                                       };
+                               };
+
+                               ap32khz_reg: EN32KHz-AP {
+                                       regulator-name = "32KHz AP";
+                                       regulator-always-on;
+                               };
+
+                               cp32khz_reg: EN32KHz-CP {
+                                       regulator-name = "32KHz CP";
+                               };
+
+                               vichg_reg: ENVICHG {
+                                       regulator-name = "VICHG";
+                                       regulator-always-on;
+                               };
+
+                               safe1_sreg: ESAFEOUT1 {
+                                       regulator-name = "SAFEOUT1";
+                               };
+
+                               safe2_sreg: ESAFEOUT2 {
+                                       regulator-name = "SAFEOUT2";
+                               };
+                       };
+               };
+       };
+
+       i2c_fuel: i2c-gpio-1 {
+               compatible = "i2c-gpio";
+               sda-gpios = <&mp05 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+               scl-gpios = <&mp05 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+               i2c-gpio,delay-us = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               fuelgauge@36 {
+                       compatible = "maxim,max17040";
+                       interrupt-parent = <&vic0>;
+                       interrupts = <7>;
+                       reg = <0x36>;
+               };
+       };
+};
+
+&fimd {
+       pinctrl-names = "default";
+       pinctrl-0 = <&lcd_clk &lcd_data24>;
+       status = "okay";
+
+       samsung,invert-vden;
+       samsung,invert-vclk;
+
+       display-timings {
+               timing-0 {
+                       /* 480x800@60Hz */
+                       clock-frequency = <25628040>;
+                       hactive = <480>;
+                       vactive = <800>;
+                       hfront-porch = <16>;
+                       hback-porch = <16>;
+                       hsync-len = <2>;
+                       vfront-porch = <28>;
+                       vback-porch = <1>;
+                       vsync-len = <2>;
+               };
+       };
+};
+
+&hsotg {
+       vusb_a-supply = <&ldo8_reg>;
+       vusb_d-supply = <&ldo3_reg>;
+       dr_mode = "peripheral";
+       status = "okay";
+};
+
+&pinctrl0 {
+       wlan_bt_en: wlan-bt-en {
+               samsung,pins = "gpb-5";
+               samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+               samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
+               samsung,pin-val = <1>;
+       };
+
+       wlan_gpio_rst: wlan-gpio-rst {
+               samsung,pins = "gpg1-2";
+               samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+               samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
+       };
+
+       wifi_host_wake: wifi-host-wake {
+               samsung,pins = "gph2-4";
+               samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+               samsung,pin-pud = <S3C64XX_PIN_PULL_DOWN>;
+               samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+       };
+
+       tf_detect: tf-detect {
+               samsung,pins = "gph3-4";
+               samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+               samsung,pin-pud = <S3C64XX_PIN_PULL_DOWN>;
+               samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+       };
+
+       wifi_wake: wifi-wake {
+               samsung,pins = "gph3-5";
+               samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+               samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
+       };
+};
+
+&sdhci1 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       bus-width = <4>;
+       max-frequency = <38400000>;
+       pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus4 &wifi_wake &wifi_host_wake &wlan_bt_en>;
+       pinctrl-names = "default";
+       cap-sd-highspeed;
+       cap-mmc-highspeed;
+
+       mmc-pwrseq = <&wifi_pwrseq>;
+       non-removable;
+       status = "okay";
+
+       wlan@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+               interrupt-parent = <&gph2>;
+               interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "host-wake";
+       };
+};
+
+&sdhci2 {
+       bus-width = <4>;
+       cd-gpios = <&gph3 4 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&ldo5_reg>;
+       pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &tf_detect>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&uart1 {
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&usbphy {
+       status = "okay";
+       vbus-supply = <&safe1_sreg>;
+};
+
+&xusbxti {
+       clock-frequency = <24000000>;
+};
diff --git a/arch/arm/boot/dts/s5pv210-fascinate4g.dts b/arch/arm/boot/dts/s5pv210-fascinate4g.dts
new file mode 100644 (file)
index 0000000..ccf761b
--- /dev/null
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "s5pv210-aries.dtsi"
+
+/ {
+       model = "Samsung Galaxy S Fascinate 4G (SGH-T959P) based on S5PV210";
+       compatible = "samsung,fascinate4g", "samsung,aries", "samsung,s5pv210";
+
+       chosen {
+               stdout-path = &uart2;
+               /*
+                * It's hard to change those parameters in stock bootloader,
+                * since it requires special hardware/cable.
+                * Let's hardocde bootargs for now, till u-boot port is finished,
+                * with which it should be easier.
+                */
+               bootargs = "root=/dev/mmcblk1p1 rw rootwait ignore_loglevel earlyprintk";
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               power {
+                       label = "power";
+                       gpios = <&gph2 6 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_POWER>;
+                       wakeup-source;
+               };
+
+               vol-down {
+                       label = "volume_down";
+                       gpios = <&gph3 2 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEDOWN>;
+               };
+
+               vol-up {
+                       label = "volume_up";
+                       gpios = <&gph3 1 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEUP>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/s5pv210-galaxys.dts b/arch/arm/boot/dts/s5pv210-galaxys.dts
new file mode 100644 (file)
index 0000000..8422767
--- /dev/null
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "s5pv210-aries.dtsi"
+
+/ {
+       model = "Samsung Galaxy S1 (GT-I9000) based on S5PV210";
+       compatible = "samsung,galaxys", "samsung,aries", "samsung,s5pv210";
+
+       chosen {
+               stdout-path = &uart2;
+               /*
+                * It's hard to change those parameters in stock bootloader,
+                * since it requires special hardware/cable.
+                * Let's hardocde bootargs for now, till u-boot port is finished,
+                * with which it should be easier.
+                */
+               bootargs = "root=/dev/mmcblk2p1 rw rootwait ignore_loglevel earlyprintk";
+       };
+
+       nand_pwrseq: nand-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               reset-gpios = <&gpj2 7 GPIO_ACTIVE_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&massmemory_en>;
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               power {
+                       label = "power";
+                       gpios = <&gph2 6 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_POWER>;
+                       wakeup-source;
+               };
+
+               vol-down {
+                       label = "volume_down";
+                       gpios = <&gph3 1 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEDOWN>;
+               };
+
+               vol-up {
+                       label = "volume_up";
+                       gpios = <&gph3 2 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEUP>;
+               };
+
+               home {
+                       label = "home";
+                       gpios = <&gph3 5 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_HOME>;
+                       wakeup-source;
+               };
+       };
+};
+
+&pinctrl0 {
+       massmemory_en: massmemory-en {
+               samsung,pins = "gpj2-7";
+               samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+               samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
+               samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+       };
+};
+
+&sdhci0 {
+       bus-width = <4>;
+       non-removable;
+       mmc-pwrseq = <&nand_pwrseq>;
+       pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4>;
+       pinctrl-names = "default";
+       status = "okay";
+};
index 3a79feab11c303a15fc112a23f848b304a8800f5..7f0c9d447871e12261f60f5a3e2f10e25c4720d4 100644 (file)
        gph2: gph2 {
                gpio-controller;
                #gpio-cells = <2>;
+
+               interrupt-controller;
                #interrupt-cells = <2>;
        };
 
index e57191fb83de895ae0675966b2b3319410f7ed99..1c01a6f843d8a43c07ab25dd18ffb57acd044c0b 100644 (file)
 #define PIN_PB22__GPIO                 PINMUX_PIN(PIN_PB22, 0, 0)
 #define PIN_PB22__LCDDAT11             PINMUX_PIN(PIN_PB22, 1, 1)
 #define PIN_PB22__A11                  PINMUX_PIN(PIN_PB22, 2, 1)
-#define PIN_PB22__TDO                  PINMUX_PIN(PIN_PB22, 3, 1)
+#define PIN_PB22__TD0                  PINMUX_PIN(PIN_PB22, 3, 1)
 #define PIN_PB22__TIOA2                        PINMUX_PIN(PIN_PB22, 4, 2)
 #define PIN_PB22__FLEXCOM3_IO1         PINMUX_PIN(PIN_PB22, 5, 3)
 #define PIN_PB22__GMDC                 PINMUX_PIN(PIN_PB22, 6, 3)
 #define PIN_PC14__LCDDAT6              PINMUX_PIN(PIN_PC14, 1, 2)
 #define PIN_PC14__GRX0                 PINMUX_PIN(PIN_PC14, 2, 1)
 #define PIN_PC14__ISC_D5               PINMUX_PIN(PIN_PC14, 3, 1)
-#define PIN_PC14__TDO                  PINMUX_PIN(PIN_PC14, 5, 2)
+#define PIN_PC14__TD0                  PINMUX_PIN(PIN_PC14, 5, 2)
 #define PIN_PC14__A3                   PINMUX_PIN(PIN_PC14, 6, 2)
 #define PIN_PC15                       79
 #define PIN_PC15__GPIO                 PINMUX_PIN(PIN_PC15, 0, 0)
index eae5e1ee9cd827a8886a11eab0c8a05860daee3b..1408fa4a62e4410708804f06826cbf3a7a691065 100644 (file)
                                atmel,external-irqs = <47>;
                        };
 
-                       pinctrl@fffff200 {
+                       pinctrl: pinctrl@fffff200 {
                                #address-cells = <1>;
                                #size-cells = <1>;
                                compatible = "atmel,sama5d3-pinctrl", "atmel,at91sam9x5-pinctrl", "simple-bus";
                                };
                        };
 
-                       rstc@fffffe00 {
+                       reset_controller: rstc@fffffe00 {
                                compatible = "atmel,sama5d3-rstc", "atmel,at91sam9g45-rstc";
                                reg = <0xfffffe00 0x10>;
                                clocks = <&clk32k>;
                        };
 
-                       shutdown-controller@fffffe10 {
+                       shutdown_controller: shutdown-controller@fffffe10 {
                                compatible = "atmel,at91sam9x5-shdwc";
                                reg = <0xfffffe10 0x10>;
                                clocks = <&clk32k>;
                                clocks = <&mck>;
                        };
 
-                       watchdog@fffffe40 {
+                       watchdog: watchdog@fffffe40 {
                                compatible = "atmel,at91sam9260-wdt";
                                reg = <0xfffffe40 0x10>;
                                interrupts = <4 IRQ_TYPE_LEVEL_HIGH 7>;
index 0cf9beddd55601220be889bd06d4f1a29f0cca37..92a35a1942b6a1b75c750a8a96eb1cea0e6355b0 100644 (file)
                        };
 
                        pmc: pmc@f0018000 {
-                               compatible = "atmel,sama5d3-pmc", "syscon";
+                               compatible = "atmel,sama5d4-pmc", "syscon";
                                reg = <0xf0018000 0x120>;
                                interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
                                interrupt-controller;
index 3d65f1f6d78b62a4a863584dfb7274e9abcb2b8f..daac0c6078c5b68fd0c53fecf802e0c598d15489 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the KZM-A9-GT board
  *
@@ -5,10 +6,6 @@
  *
  * Based on sh73a0-kzm9g.dts
  * Copyright (C) 2012 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/;
index c953648a5f4106b9d996c14866138ab04d6d633c..e8f0a07c456457375ab5abed301e767e5d318b08 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the SH73A0 SoC
  *
  * Copyright (C) 2012 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.
  */
 
 #include <dt-bindings/clock/sh73a0-clock.h>
index 791ca15c799eba98850cbc3d4b96be7a509c422f..a4dcb68f4322e2c96dd8bad240bb94b7eb307c9e 100644 (file)
                        status = "disabled";
                };
 
+               spi0: spi@ffda4000 {
+                       compatible = "snps,dw-apb-ssi";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0xffda4000 0x100>;
+                       interrupts = <0 101 4>;
+                       num-cs = <4>;
+                       /*32bit_access;*/
+                       clocks = <&spi_m_clk>;
+                       status = "disabled";
+               };
+
                spi1: spi@ffda5000 {
                        compatible = "snps,dw-apb-ssi";
                        #address-cells = <1>;
index 733678b75b88b75d65c648896cebc6dc070d4a54..fca76a696d9d7a939b9f18172453ba1941c91a7f 100644 (file)
                reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd";
                clocks = <&hclksmc>;
                status = "okay";
-               timings = /bits/ 8 <0 0 0 0x10 0x0a 0>;
 
                partition@0 {
                label = "X-Loader(NAND)";
index ede77e0f1c41d044829bf7488959800736e3e514..e35d782e7e5f2f0281d1c8936bb90ea70b8d83b8 100644 (file)
                        interrupt-parent = <&exti>;
                        interrupts = <17 1>;
                        interrupt-names = "alarm";
-                       st,syscfg = <&pwrcfg>;
+                       st,syscfg = <&pwrcfg 0x00 0x100>;
                        status = "disabled";
                };
 
                        compatible = "st,stm32-iwdg";
                        reg = <0x40003000 0x400>;
                        clocks = <&clk_lsi>;
+                       clock-names = "lsi";
                        status = "disabled";
                };
 
index 1479e3eb05fa455d88dbbbc2c25dc6cc1961ea10..f48d06a80d1d67e09cb2e0ba2a9873583df28947 100644 (file)
                        interrupt-parent = <&exti>;
                        interrupts = <17 1>;
                        interrupt-names = "alarm";
-                       st,syscfg = <&pwrcfg>;
+                       st,syscfg = <&pwrcfg 0x00 0x100>;
                        status = "disabled";
                };
 
index 4839db146890fd59480ce7c00b075cf381b7d498..c4851271e8105ebe4f92196cd808d64ccea626d9 100644 (file)
                                };
                        };
 
+                       ethernet0_rgmii_pins_a: rgmii-0 {
+                               pins1 {
+                                       pinmux = <STM32_PINMUX('G', 5, AF11)>, /* ETH_RGMII_CLK125 */
+                                                <STM32_PINMUX('G', 4, AF11)>, /* ETH_RGMII_GTX_CLK */
+                                                <STM32_PINMUX('G', 13, AF11)>, /* ETH_RGMII_TXD0 */
+                                                <STM32_PINMUX('G', 14, AF11)>, /* ETH_RGMII_TXD1 */
+                                                <STM32_PINMUX('C', 2, AF11)>, /* ETH_RGMII_TXD2 */
+                                                <STM32_PINMUX('E', 2, AF11)>, /* ETH_RGMII_TXD3 */
+                                                <STM32_PINMUX('B', 11, AF11)>, /* ETH_RGMII_TX_CTL */
+                                                <STM32_PINMUX('A', 2, AF11)>, /* ETH_MDIO */
+                                                <STM32_PINMUX('C', 1, AF11)>; /* ETH_MDC */
+                                       bias-disable;
+                                       drive-push-pull;
+                                       slew-rate = <3>;
+                               };
+                               pins2 {
+                                       pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RGMII_RXD0 */
+                                                <STM32_PINMUX('C', 5, AF11)>, /* ETH_RGMII_RXD1 */
+                                                <STM32_PINMUX('B', 0, AF11)>, /* ETH_RGMII_RXD2 */
+                                                <STM32_PINMUX('B', 1, AF11)>, /* ETH_RGMII_RXD3 */
+                                                <STM32_PINMUX('A', 1, AF11)>, /* ETH_RGMII_RX_CLK */
+                                                <STM32_PINMUX('A', 7, AF11)>; /* ETH_RGMII_RX_CTL */
+                                       bias-disable;
+                               };
+                       };
+
+                       ethernet0_rgmii_pins_sleep_a: rgmii-sleep-0 {
+                               pins1 {
+                                       pinmux = <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_RGMII_CLK125 */
+                                                <STM32_PINMUX('G', 4, ANALOG)>, /* ETH_RGMII_GTX_CLK */
+                                                <STM32_PINMUX('G', 13, ANALOG)>, /* ETH_RGMII_TXD0 */
+                                                <STM32_PINMUX('G', 14, ANALOG)>, /* ETH_RGMII_TXD1 */
+                                                <STM32_PINMUX('C', 2, ANALOG)>, /* ETH_RGMII_TXD2 */
+                                                <STM32_PINMUX('E', 2, ANALOG)>, /* ETH_RGMII_TXD3 */
+                                                <STM32_PINMUX('B', 11, ANALOG)>, /* ETH_RGMII_TX_CTL */
+                                                <STM32_PINMUX('A', 2, ANALOG)>, /* ETH_MDIO */
+                                                <STM32_PINMUX('C', 1, ANALOG)>, /* ETH_MDC */
+                                                <STM32_PINMUX('C', 4, ANALOG)>, /* ETH_RGMII_RXD0 */
+                                                <STM32_PINMUX('C', 5, ANALOG)>, /* ETH_RGMII_RXD1 */
+                                                <STM32_PINMUX('B', 0, ANALOG)>, /* ETH_RGMII_RXD2 */
+                                                <STM32_PINMUX('B', 1, ANALOG)>, /* ETH_RGMII_RXD3 */
+                                                <STM32_PINMUX('A', 1, ANALOG)>, /* ETH_RGMII_RX_CLK */
+                                                <STM32_PINMUX('A', 7, ANALOG)>; /* ETH_RGMII_RX_CTL */
+                               };
+                       };
+
                        i2c1_pins_a: i2c1-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('D', 12, AF5)>, /* I2C1_SCL */
                                };
                        };
 
+                       m_can1_pins_a: m-can1-0 {
+                               pins1 {
+                                       pinmux = <STM32_PINMUX('H', 13, AF9)>; /* CAN1_TX */
+                                       slew-rate = <1>;
+                                       drive-push-pull;
+                                       bias-disable;
+                               };
+                               pins2 {
+                                       pinmux = <STM32_PINMUX('I', 9, AF9)>; /* CAN1_RX */
+                                       bias-disable;
+                               };
+                       };
+
                        pwm2_pins_a: pwm2-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('A', 3, AF1)>; /* TIM2_CH4 */
                        pins-are-numbered;
                        interrupt-parent = <&exti>;
                        st,syscfg = <&exti 0x60 0xff>;
-                       status = "disabled";
 
                        gpioz: gpio@54004000 {
                                gpio-controller;
                                        slew-rate = <0>;
                                };
                        };
+
+                       spi1_pins_a: spi1-0 {
+                               pins1 {
+                                       pinmux = <STM32_PINMUX('Z', 0, AF5)>, /* SPI1_SCK */
+                                                <STM32_PINMUX('Z', 2, AF5)>; /* SPI1_MOSI */
+                                       bias-disable;
+                                       drive-push-pull;
+                                       slew-rate = <1>;
+                               };
+
+                               pins2 {
+                                       pinmux = <STM32_PINMUX('Z', 1, AF5)>; /* SPI1_MISO */
+                                       bias-disable;
+                               };
+                       };
                };
        };
 };
index ae336530b59b8ec0970a9baef8eabc76378414d6..f77bea49c0793f4f07cb2cd912945f4c199c9e10 100644 (file)
        };
 };
 
+&i2c4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c4_pins_a>;
+       i2c-scl-rising-time-ns = <185>;
+       i2c-scl-falling-time-ns = <20>;
+       status = "okay";
+};
+
+&iwdg2 {
+       timeout-sec = <32>;
+       status = "okay";
+};
+
 &rng1 {
        status = "okay";
 };
 
+&rtc {
+       status = "okay";
+};
+
 &timers6 {
        status = "okay";
        timer@5 {
        };
 };
 
-&i2c4 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&i2c4_pins_a>;
-       i2c-scl-rising-time-ns = <185>;
-       i2c-scl-falling-time-ns = <20>;
-       status = "okay";
-};
-
 &uart4 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart4_pins_a>;
index 9382d80630318dde15d69d0b9fa9e62b65b70594..372bc2ea6b92192422368bf8413fe62849321d08 100644 (file)
 
        aliases {
                serial0 = &uart4;
+               ethernet0 = &ethernet0;
+       };
+};
+
+&ethernet0 {
+       status = "okay";
+       pinctrl-0 = <&ethernet0_rgmii_pins_a>;
+       pinctrl-1 = <&ethernet0_rgmii_pins_sleep_a>;
+       pinctrl-names = "default", "sleep";
+       phy-mode = "rgmii";
+       max-speed = <1000>;
+       phy-handle = <&phy0>;
+
+       mdio0 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "snps,dwmac-mdio";
+               phy0: ethernet-phy@0 {
+                       reg = <0>;
+               };
        };
 };
 
        status = "okay";
 };
 
+&m_can1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&m_can1_pins_a>;
+       status = "okay";
+};
+
 &qspi {
        pinctrl-names = "default";
        pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>;
        };
 };
 
+&spi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi1_pins_a>;
+       status = "disabled";
+};
+
 &timers2 {
        status = "disabled";
        pwm {
        };
 };
 
+&usbh_ehci {
+       phys = <&usbphyc_port0>;
+       phy-names = "usb";
+       status = "okay";
+};
+
+&usbotg_hs {
+       dr_mode = "peripheral";
+       phys = <&usbphyc_port1 0>;
+       phy-names = "usb2-phy";
+       status = "okay";
+};
+
 &usbphyc {
        status = "okay";
 };
index 7d17538934538239c7634e7cdde7eb5cd2117971..661be948ab7424759ebfdb2d1c780822d17f38b0 100644 (file)
                cpu_on = <0x84000003>;
        };
 
-       aliases {
-               gpio0 = &gpioa;
-               gpio1 = &gpiob;
-               gpio2 = &gpioc;
-               gpio3 = &gpiod;
-               gpio4 = &gpioe;
-               gpio5 = &gpiof;
-               gpio6 = &gpiog;
-               gpio7 = &gpioh;
-               gpio8 = &gpioi;
-               gpio9 = &gpioj;
-               gpio10 = &gpiok;
-       };
-
        intc: interrupt-controller@a0021000 {
                compatible = "arm,cortex-a7-gic";
                #interrupt-cells = <3>;
                        };
                };
 
+               spi2: spi@4000b000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "st,stm32h7-spi";
+                       reg = <0x4000b000 0x400>;
+                       interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc SPI2_K>;
+                       resets = <&rcc SPI2_R>;
+                       dmas = <&dmamux1 39 0x400 0x05>,
+                              <&dmamux1 40 0x400 0x05>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+               };
+
+               spi3: spi@4000c000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "st,stm32h7-spi";
+                       reg = <0x4000c000 0x400>;
+                       interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc SPI3_K>;
+                       resets = <&rcc SPI3_R>;
+                       dmas = <&dmamux1 61 0x400 0x05>,
+                              <&dmamux1 62 0x400 0x05>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+               };
+
                usart2: serial@4000e000 {
                        compatible = "st,stm32h7-uart";
                        reg = <0x4000e000 0x400>;
                        status = "disabled";
                };
 
+               spi1: spi@44004000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "st,stm32h7-spi";
+                       reg = <0x44004000 0x400>;
+                       interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc SPI1_K>;
+                       resets = <&rcc SPI1_R>;
+                       dmas = <&dmamux1 37 0x400 0x05>,
+                              <&dmamux1 38 0x400 0x05>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+               };
+
+               spi4: spi@44005000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "st,stm32h7-spi";
+                       reg = <0x44005000 0x400>;
+                       interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc SPI4_K>;
+                       resets = <&rcc SPI4_R>;
+                       dmas = <&dmamux1 83 0x400 0x05>,
+                              <&dmamux1 84 0x400 0x05>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+               };
+
                timers15: timer@44006000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        };
                };
 
+               spi5: spi@44009000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "st,stm32h7-spi";
+                       reg = <0x44009000 0x400>;
+                       interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc SPI5_K>;
+                       resets = <&rcc SPI5_R>;
+                       dmas = <&dmamux1 85 0x400 0x05>,
+                              <&dmamux1 86 0x400 0x05>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+               };
+
+               dfsdm: dfsdm@4400d000 {
+                       compatible = "st,stm32mp1-dfsdm";
+                       reg = <0x4400d000 0x800>;
+                       clocks = <&rcc DFSDM_K>;
+                       clock-names = "dfsdm";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+
+                       dfsdm0: filter@0 {
+                               compatible = "st,stm32-dfsdm-adc";
+                               #io-channel-cells = <1>;
+                               reg = <0>;
+                               interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&dmamux1 101 0x400 0x01>;
+                               dma-names = "rx";
+                               status = "disabled";
+                       };
+
+                       dfsdm1: filter@1 {
+                               compatible = "st,stm32-dfsdm-adc";
+                               #io-channel-cells = <1>;
+                               reg = <1>;
+                               interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&dmamux1 102 0x400 0x01>;
+                               dma-names = "rx";
+                               status = "disabled";
+                       };
+
+                       dfsdm2: filter@2 {
+                               compatible = "st,stm32-dfsdm-adc";
+                               #io-channel-cells = <1>;
+                               reg = <2>;
+                               interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&dmamux1 103 0x400 0x01>;
+                               dma-names = "rx";
+                               status = "disabled";
+                       };
+
+                       dfsdm3: filter@3 {
+                               compatible = "st,stm32-dfsdm-adc";
+                               #io-channel-cells = <1>;
+                               reg = <3>;
+                               interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&dmamux1 104 0x400 0x01>;
+                               dma-names = "rx";
+                               status = "disabled";
+                       };
+
+                       dfsdm4: filter@4 {
+                               compatible = "st,stm32-dfsdm-adc";
+                               #io-channel-cells = <1>;
+                               reg = <4>;
+                               interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&dmamux1 91 0x400 0x01>;
+                               dma-names = "rx";
+                               status = "disabled";
+                       };
+
+                       dfsdm5: filter@5 {
+                               compatible = "st,stm32-dfsdm-adc";
+                               #io-channel-cells = <1>;
+                               reg = <5>;
+                               interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&dmamux1 92 0x400 0x01>;
+                               dma-names = "rx";
+                               status = "disabled";
+                       };
+               };
+
+               m_can1: can@4400e000 {
+                       compatible = "bosch,m_can";
+                       reg = <0x4400e000 0x400>, <0x44011000 0x2800>;
+                       reg-names = "m_can", "message_ram";
+                       interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "int0", "int1";
+                       clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
+                       clock-names = "hclk", "cclk";
+                       bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>;
+                       status = "disabled";
+               };
+
+               m_can2: can@4400f000 {
+                       compatible = "bosch,m_can";
+                       reg = <0x4400f000 0x400>, <0x44011000 0x2800>;
+                       reg-names = "m_can", "message_ram";
+                       interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "int0", "int1";
+                       clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
+                       clock-names = "hclk", "cclk";
+                       bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>;
+                       status = "disabled";
+               };
+
                dma1: dma@48000000 {
                        compatible = "st,stm32-dma";
                        reg = <0x48000000 0x400>;
                        clocks = <&rcc DMAMUX>;
                };
 
+               adc: adc@48003000 {
+                       compatible = "st,stm32mp1-adc-core";
+                       reg = <0x48003000 0x400>;
+                       interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc ADC12>, <&rcc ADC12_K>;
+                       clock-names = "bus", "adc";
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+
+                       adc1: adc@0 {
+                               compatible = "st,stm32mp1-adc";
+                               #io-channel-cells = <1>;
+                               reg = <0x0>;
+                               interrupt-parent = <&adc>;
+                               interrupts = <0>;
+                               dmas = <&dmamux1 9 0x400 0x01>;
+                               dma-names = "rx";
+                               status = "disabled";
+                       };
+
+                       adc2: adc@100 {
+                               compatible = "st,stm32mp1-adc";
+                               #io-channel-cells = <1>;
+                               reg = <0x100>;
+                               interrupt-parent = <&adc>;
+                               interrupts = <1>;
+                               dmas = <&dmamux1 10 0x400 0x01>;
+                               dma-names = "rx";
+                               status = "disabled";
+                       };
+               };
+
+               usbotg_hs: usb-otg@49000000 {
+                       compatible = "snps,dwc2";
+                       reg = <0x49000000 0x10000>;
+                       clocks = <&rcc USBO_K>;
+                       clock-names = "otg";
+                       resets = <&rcc USBO_R>;
+                       reset-names = "dwc2";
+                       interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+                       g-rx-fifo-size = <256>;
+                       g-np-tx-fifo-size = <32>;
+                       g-tx-fifo-size = <128 128 64 64 64 64 32 32>;
+                       dr_mode = "otg";
+                       status = "disabled";
+               };
+
                rcc: rcc@50000000 {
                        compatible = "st,stm32mp1-rcc", "syscon";
                        reg = <0x50000000 0x1000>;
                        reg = <0x5000d000 0x400>;
                };
 
+               syscfg: syscon@50020000 {
+                       compatible = "st,stm32mp157-syscfg", "syscon";
+                       reg = <0x50020000 0x400>;
+               };
+
                lptimer2: timer@50021000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                };
 
+               hash1: hash@54002000 {
+                       compatible = "st,stm32f756-hash";
+                       reg = <0x54002000 0x400>;
+                       interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc HASH1>;
+                       resets = <&rcc HASH1_R>;
+                       dmas = <&mdma1 31 0x10 0x1000A02 0x0 0x0 0x0>;
+                       dma-names = "in";
+                       dma-maxburst = <2>;
+                       status = "disabled";
+               };
+
                rng1: rng@54003000 {
                        compatible = "st,stm32-rng";
                        reg = <0x54003000 0x400>;
                        status = "disabled";
                };
 
+               stmmac_axi_config_0: stmmac-axi-config {
+                       snps,wr_osr_lmt = <0x7>;
+                       snps,rd_osr_lmt = <0x7>;
+                       snps,blen = <0 0 0 0 16 8 4>;
+               };
+
+               ethernet0: ethernet@5800a000 {
+                       compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a";
+                       reg = <0x5800a000 0x2000>;
+                       reg-names = "stmmaceth";
+                       interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "macirq";
+                       clock-names = "stmmaceth",
+                                     "mac-clk-tx",
+                                     "mac-clk-rx",
+                                     "ethstp",
+                                     "syscfg-clk";
+                       clocks = <&rcc ETHMAC>,
+                                <&rcc ETHTX>,
+                                <&rcc ETHRX>,
+                                <&rcc ETHSTP>,
+                                <&rcc SYSCFG>;
+                       st,syscon = <&syscfg 0x4>;
+                       snps,mixed-burst;
+                       snps,pbl = <2>;
+                       snps,axi-config = <&stmmac_axi_config_0>;
+                       snps,tso;
+                       status = "disabled";
+               };
+
                usbh_ohci: usbh-ohci@5800c000 {
                        compatible = "generic-ohci";
                        reg = <0x5800c000 0x1000>;
                        status = "disabled";
                };
 
+               iwdg2: watchdog@5a002000 {
+                       compatible = "st,stm32mp1-iwdg";
+                       reg = <0x5a002000 0x400>;
+                       clocks = <&rcc IWDG2>, <&rcc CK_LSI>;
+                       clock-names = "pclk", "lsi";
+                       status = "disabled";
+               };
+
                usbphyc: usbphyc@5a006000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                };
 
+               spi6: spi@5c001000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "st,stm32h7-spi";
+                       reg = <0x5c001000 0x400>;
+                       interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc SPI6_K>;
+                       resets = <&rcc SPI6_R>;
+                       dmas = <&mdma1 34 0x0 0x40008 0x0 0x0 0>,
+                              <&mdma1 35 0x0 0x40002 0x0 0x0 0>;
+                       dma-names = "rx", "tx";
+                       status = "disabled";
+               };
+
                i2c4: i2c@5c002000 {
                        compatible = "st,stm32f7-i2c";
                        reg = <0x5c002000 0x400>;
                        status = "disabled";
                };
 
+               rtc: rtc@5c004000 {
+                       compatible = "st,stm32mp1-rtc";
+                       reg = <0x5c004000 0x400>;
+                       clocks = <&rcc RTCAPB>, <&rcc RTC>;
+                       clock-names = "pclk", "rtc_ck";
+                       interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
                i2c6: i2c@5c009000 {
                        compatible = "st,stm32f7-i2c";
                        reg = <0x5c009000 0x400>;
index 5d096528e75a541e0ae1809a70b09139019da6c5..71c27ea0b53e18142ff9e371e2a05913f859c287 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2014 Open Source Support GmbH
  *
- * David Lanzendörfer <david.lanzendoerfer@o2s.ch>
+ * David Lanzendörfer <david.lanzendoerfer@o2s.ch>
  *
  * This file is dual-licensed: you can use it either under the terms
  * of the GPL or the X11 license, at your option. Note that this dual
index 3a1c6b45c9a1cd3e6ef699d9c3b45fdb2712fcfd..3d62a895072071c57ca69a531190d729492a5044 100644 (file)
                #size-cells = <1>;
                ranges;
 
-               sram-controller@1c00000 {
-                       compatible = "allwinner,sun4i-a10-sram-controller";
+               system-control@1c00000 {
+                       compatible = "allwinner,sun4i-a10-system-control";
                        reg = <0x01c00000 0x30>;
                        #address-cells = <1>;
                        #size-cells = <1>;
                        status = "disabled";
                };
 
+               mali: gpu@1c40000 {
+                       compatible = "allwinner,sun4i-a10-mali", "arm,mali-400";
+                       reg = <0x01c40000 0x10000>;
+                       interrupts = <69>,
+                                    <70>,
+                                    <71>,
+                                    <72>,
+                                    <73>;
+                       interrupt-names = "gp",
+                                         "gpmmu",
+                                         "pp0",
+                                         "ppmmu0",
+                                         "pmu";
+                       clocks = <&ccu CLK_AHB_GPU>, <&ccu CLK_GPU>;
+                       clock-names = "bus", "core";
+                       resets = <&ccu RST_GPU>;
+
+                       assigned-clocks = <&ccu CLK_GPU>;
+                       assigned-clock-rates = <384000000>;
+               };
+
                fe0: display-frontend@1e00000 {
                        compatible = "allwinner,sun4i-a10-display-frontend";
                        reg = <0x01e00000 0x20000>;
index 07f2248ed5f8b5931978bd5c3fee53c58cc6ec38..8bfb36651177d715cd213e16fd2bb0dd2686d7f0 100644 (file)
                #size-cells = <1>;
                ranges;
 
-               sram-controller@1c00000 {
-                       compatible = "allwinner,sun4i-a10-sram-controller";
+               system-control@1c00000 {
+                       compatible = "allwinner,sun5i-a13-system-control";
                        reg = <0x01c00000 0x30>;
                        #address-cells = <1>;
                        #size-cells = <1>;
                                #address-cells = <1>;
                                #size-cells = <1>;
                                ranges = <0 0x00000000 0xc000>;
-                       };
 
-                       emac_sram: sram-section@8000 {
-                               compatible = "allwinner,sun4i-a10-sram-a3-a4";
-                               reg = <0x8000 0x4000>;
-                               status = "disabled";
+                               emac_sram: sram-section@8000 {
+                                       compatible = "allwinner,sun5i-a13-sram-a3-a4",
+                                                    "allwinner,sun4i-a10-sram-a3-a4";
+                                       reg = <0x8000 0x4000>;
+                                       status = "disabled";
+                               };
                        };
 
                        sram_d: sram@10000 {
                                ranges = <0 0x00010000 0x1000>;
 
                                otg_sram: sram-section@0 {
-                                       compatible = "allwinner,sun4i-a10-sram-d";
+                                       compatible = "allwinner,sun5i-a13-sram-d",
+                                                    "allwinner,sun4i-a10-sram-d";
                                        reg = <0x0000 0x1000>;
                                        status = "disabled";
                                };
                        };
+
+                       sram_c: sram@1d00000 {
+                               compatible = "mmio-sram";
+                               reg = <0x01d00000 0xd0000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x01d00000 0xd0000>;
+
+                               ve_sram: sram-section@0 {
+                                       compatible = "allwinner,sun5i-a13-sram-c1",
+                                                    "allwinner,sun4i-a10-sram-c1";
+                                       reg = <0x000000 0x80000>;
+                               };
+                       };
                };
 
                dma: dma-controller@1c02000 {
index c72992556a86857098deca7ff69a84379d27c6bf..debc0bf22ea3b063192e458140bcab68ad10e6a5 100644 (file)
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <1>;
+                       clocks = <&ccu CLK_CPU>;
+                       clock-latency = <244144>; /* 8 32k periods */
+                       operating-points = <
+                               /* kHz    uV */
+                               1008000 1200000
+                               864000  1200000
+                               720000  1100000
+                               480000  1000000
+                               >;
+                       #cooling-cells = <2>;
                };
 
                cpu@2 {
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <2>;
+                       clocks = <&ccu CLK_CPU>;
+                       clock-latency = <244144>; /* 8 32k periods */
+                       operating-points = <
+                               /* kHz    uV */
+                               1008000 1200000
+                               864000  1200000
+                               720000  1100000
+                               480000  1000000
+                               >;
+                       #cooling-cells = <2>;
                };
 
                cpu@3 {
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <3>;
+                       clocks = <&ccu CLK_CPU>;
+                       clock-latency = <244144>; /* 8 32k periods */
+                       operating-points = <
+                               /* kHz    uV */
+                               1008000 1200000
+                               864000  1200000
+                               720000  1100000
+                               480000  1000000
+                               >;
+                       #cooling-cells = <2>;
                };
        };
 
index e529e4ff21749b31d83a0690f2e7ada3afb7f5d1..9c52712af24111daeb7e94a8be2ebabcc94c55c9 100644 (file)
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <1>;
+                       clocks = <&ccu CLK_CPU>;
+                       clock-latency = <244144>; /* 8 32k periods */
+                       operating-points = <
+                               /* kHz    uV */
+                               960000  1400000
+                               912000  1400000
+                               864000  1300000
+                               720000  1200000
+                               528000  1100000
+                               312000  1000000
+                               144000  1000000
+                               >;
+                       #cooling-cells = <2>;
                };
        };
 
                #size-cells = <1>;
                ranges;
 
-               sram-controller@1c00000 {
-                       compatible = "allwinner,sun4i-a10-sram-controller";
+               system-control@1c00000 {
+                       compatible = "allwinner,sun7i-a20-system-control",
+                                    "allwinner,sun4i-a10-system-control";
                        reg = <0x01c00000 0x30>;
                        #address-cells = <1>;
                        #size-cells = <1>;
                                ranges = <0 0x00000000 0xc000>;
 
                                emac_sram: sram-section@8000 {
-                                       compatible = "allwinner,sun4i-a10-sram-a3-a4";
+                                       compatible = "allwinner,sun7i-a20-sram-a3-a4",
+                                                    "allwinner,sun4i-a10-sram-a3-a4";
                                        reg = <0x8000 0x4000>;
                                        status = "disabled";
                                };
                                ranges = <0 0x00010000 0x1000>;
 
                                otg_sram: sram-section@0 {
-                                       compatible = "allwinner,sun4i-a10-sram-d";
+                                       compatible = "allwinner,sun7i-a20-sram-d",
+                                                    "allwinner,sun4i-a10-sram-d";
                                        reg = <0x0000 0x1000>;
                                        status = "disabled";
                                };
                        };
+
+                       sram_c: sram@1d00000 {
+                               compatible = "mmio-sram";
+                               reg = <0x01d00000 0xd0000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x01d00000 0xd0000>;
+
+                               ve_sram: sram-section@0 {
+                                       compatible = "allwinner,sun7i-a20-sram-c1",
+                                                    "allwinner,sun4i-a10-sram-c1";
+                                       reg = <0x000000 0x80000>;
+                               };
+                       };
                };
 
                nmi_intc: interrupt-controller@1c00030 {
index 44f3cad3de75b44514cb19a4cecb6e86fe9f6417..c16ffcc4db7da0831dc16a84e4c2fcb093c90987 100644 (file)
                #size-cells = <1>;
                ranges;
 
+               system-control@1c00000 {
+                       compatible = "allwinner,sun8i-a23-system-control";
+                       reg = <0x01c00000 0x30>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       sram_c: sram@1d00000 {
+                               compatible = "mmio-sram";
+                               reg = <0x01d00000 0x80000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x01d00000 0x80000>;
+
+                               ve_sram: sram-section@0 {
+                                       compatible = "allwinner,sun8i-a23-sram-c1",
+                                                    "allwinner,sun4i-a10-sram-c1";
+                                       reg = <0x000000 0x80000>;
+                               };
+                       };
+               };
+
                dma: dma-controller@1c02000 {
                        compatible = "allwinner,sun8i-a23-dma";
                        reg = <0x01c02000 0x1000>;
index 8d278ee001e97a63b40143393b7d044ac3f7d5cf..4e92741b24a70e222992f977e94d4f09d4486f41 100644 (file)
                };
 
                cpu@1 {
+                       clocks = <&ccu CLK_CPUX>;
+                       clock-names = "cpu";
                        operating-points-v2 = <&cpu0_opp_table>;
+                       #cooling-cells = <2>;
                };
 
                cpu@2 {
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <2>;
+                       clocks = <&ccu CLK_CPUX>;
+                       clock-names = "cpu";
                        operating-points-v2 = <&cpu0_opp_table>;
+                       #cooling-cells = <2>;
                };
 
                cpu@3 {
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <3>;
+                       clocks = <&ccu CLK_CPUX>;
+                       clock-names = "cpu";
                        operating-points-v2 = <&cpu0_opp_table>;
+                       #cooling-cells = <2>;
                };
        };
 
index 36ecebaff3c0427610526ebf8441b933cd470b4e..1c012a4def16da475e07c09ace00dd26e796c81c 100644 (file)
        };
 };
 
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu100 {
+       cpu-supply = <&reg_dcdc3>;
+};
+
 &ehci0 {
        status = "okay";
 };
index 3b579d7567c80caa9b84036ab315c46aaee43945..c7ce4158d6c8bccc3eb1b5322d8fe18a2d3aa34c 100644 (file)
        };
 };
 
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu100 {
+       cpu-supply = <&reg_dcdc3>;
+};
+
 &de {
        status = "okay";
 };
index 88decb0747ac3ca6f5ead59a885a2929a54cde67..e5f0645e53a7b3173b2dcf29cbdcd368ee49cd24 100644 (file)
        };
 };
 
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu100 {
+       cpu-supply = <&reg_dcdc3>;
+};
+
 &ehci0 {
        /* GL830 USB-to-SATA bridge here */
        status = "okay";
index 2be23d600957ce4ed8a99fbf82c84667502a6e2b..00a02b037320c75ffe313e1c847f7a19b9d3bd93 100644 (file)
                        reset-names = "stmmaceth";
                        clocks = <&ccu 27>;
                        clock-names = "stmmaceth";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
                        status = "disabled";
 
                        mdio: mdio {
index 7d01f9322658611e351d3d1c9c6c2ca793ad3597..1db2541135a74427e7a0cc0900af4fa789622cee 100644 (file)
                };
        };
 
+       reg_vdd_cpux: vdd-cpux-regulator {
+               compatible = "regulator-gpio";
+               regulator-name = "vdd-cpux";
+               regulator-type = "voltage";
+               regulator-boot-on;
+               regulator-always-on;
+               regulator-min-microvolt = <1100000>;
+               regulator-max-microvolt = <1300000>;
+               regulator-ramp-delay = <50>; /* 4ms */
+
+               gpios = <&r_pio 0 1 GPIO_ACTIVE_HIGH>; /* PL1 */
+               enable-active-high;
+               gpios-states = <0x1>;
+               states = <1100000 0x0
+                         1300000 0x1>;
+       };
+
        wifi_pwrseq: wifi_pwrseq {
                compatible = "mmc-pwrseq-simple";
                pinctrl-names = "default";
        };
 };
 
+&cpu0 {
+       cpu-supply = <&reg_vdd_cpux>;
+};
+
 &ehci0 {
        status = "okay";
 };
index cf1f970b0c6f7beec4eac4ecfb096c7e3aae4613..5d23667dc2d2e72f3fc557c0fa387c69b45ac3a2 100644 (file)
        status = "okay";
 };
 
+&emac {
+       phy-handle = <&int_mii_phy>;
+       phy-mode = "mii";
+       allwinner,leds-active-low;
+       status = "okay";
+};
+
 &hdmi {
        status = "okay";
 };
index 41d57c76f29052c4bb1724810bc0c5c9a50c09b1..f0096074a46786cf36c6a824aa6a7ce8bba824ac 100644 (file)
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <1>;
+                       clocks = <&ccu CLK_CPUX>;
+                       clock-names = "cpu";
                        operating-points-v2 = <&cpu0_opp_table>;
+                       #cooling-cells = <2>;
                };
 
                cpu@2 {
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <2>;
+                       clocks = <&ccu CLK_CPUX>;
+                       clock-names = "cpu";
                        operating-points-v2 = <&cpu0_opp_table>;
+                       #cooling-cells = <2>;
                };
 
                cpu@3 {
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <3>;
+                       clocks = <&ccu CLK_CPUX>;
+                       clock-names = "cpu";
                        operating-points-v2 = <&cpu0_opp_table>;
+                       #cooling-cells = <2>;
                };
        };
 
        };
 
        soc {
+               system-control@1c00000 {
+                       compatible = "allwinner,sun8i-h3-system-control";
+                       reg = <0x01c00000 0x30>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       sram_c: sram@1d00000 {
+                               compatible = "mmio-sram";
+                               reg = <0x01d00000 0x80000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x01d00000 0x80000>;
+
+                               ve_sram: sram-section@0 {
+                                       compatible = "allwinner,sun8i-h3-sram-c1",
+                                                    "allwinner,sun4i-a10-sram-c1";
+                                       reg = <0x000000 0x80000>;
+                               };
+                       };
+               };
+
                mali: gpu@1c40000 {
                        compatible = "allwinner,sun8i-h3-mali", "arm,mali-400";
                        reg = <0x01c40000 0x10000>;
index 25fb048c7df2389a5d9ded7f44886efafb36b5d0..c39b9169ea64144e4ecc7aece7b06c9def1c52fe 100644 (file)
                stdout-path = "serial0:115200n8";
        };
 
+       connector {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_con_in: endpoint {
+                               remote-endpoint = <&hdmi_out_con>;
+                       };
+               };
+       };
+
        leds {
                compatible = "gpio-leds";
 
        };
 };
 
+&de {
+       status = "okay";
+};
+
 &ehci1 {
        status = "okay";
 };
        };
 };
 
+&hdmi {
+       status = "okay";
+};
+
+&hdmi_out {
+       hdmi_out_con: endpoint {
+               remote-endpoint = <&hdmi_con_in>;
+       };
+};
+
 &i2c0 {
        status = "okay";
 
        regulator-name = "vcc-wifi";
 };
 
+&tcon_tv0 {
+       status = "okay";
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_pb_pins>;
index bd97ca3dc2fa0ca264144af345870cea784deac6..ffd9f00f74a46da89d88040db9178c8ef01a37d4 100644 (file)
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/sun8i-de2.h>
 #include <dt-bindings/clock/sun8i-r40-ccu.h>
 #include <dt-bindings/reset/sun8i-r40-ccu.h>
+#include <dt-bindings/reset/sun8i-de2.h>
 
 / {
        #address-cells = <1>;
                };
        };
 
+       de: display-engine {
+               compatible = "allwinner,sun8i-r40-display-engine";
+               allwinner,pipelines = <&mixer0>, <&mixer1>;
+               status = "disabled";
+       };
+
        soc {
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
                ranges;
 
+               display_clocks: clock@1000000 {
+                       compatible = "allwinner,sun8i-r40-de2-clk",
+                                    "allwinner,sun8i-h3-de2-clk";
+                       reg = <0x01000000 0x100000>;
+                       clocks = <&ccu CLK_DE>,
+                                <&ccu CLK_BUS_DE>;
+                       clock-names = "mod",
+                                     "bus";
+                       resets = <&ccu RST_BUS_DE>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+               };
+
+               mixer0: mixer@1100000 {
+                       compatible = "allwinner,sun8i-r40-de2-mixer-0";
+                       reg = <0x01100000 0x100000>;
+                       clocks = <&display_clocks CLK_BUS_MIXER0>,
+                                <&display_clocks CLK_MIXER0>;
+                       clock-names = "bus",
+                                     "mod";
+                       resets = <&display_clocks RST_MIXER0>;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               mixer0_out: port@1 {
+                                       reg = <1>;
+                                       mixer0_out_tcon_top: endpoint {
+                                               remote-endpoint = <&tcon_top_mixer0_in_mixer0>;
+                                       };
+                               };
+                       };
+               };
+
+               mixer1: mixer@1200000 {
+                       compatible = "allwinner,sun8i-r40-de2-mixer-1";
+                       reg = <0x01200000 0x100000>;
+                       clocks = <&display_clocks CLK_BUS_MIXER1>,
+                                <&display_clocks CLK_MIXER1>;
+                       clock-names = "bus",
+                                     "mod";
+                       resets = <&display_clocks RST_WB>;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               mixer1_out: port@1 {
+                                       reg = <1>;
+                                       mixer1_out_tcon_top: endpoint {
+                                               remote-endpoint = <&tcon_top_mixer1_in_mixer1>;
+                                       };
+                               };
+                       };
+               };
+
                nmi_intc: interrupt-controller@1c00030 {
                        compatible = "allwinner,sun7i-a20-sc-nmi";
                        interrupt-controller;
                        reset-names = "stmmaceth";
                        clocks = <&ccu CLK_BUS_GMAC>;
                        clock-names = "stmmaceth";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
                        status = "disabled";
 
                        gmac_mdio: mdio {
                        };
                };
 
+               tcon_top: tcon-top@1c70000 {
+                       compatible = "allwinner,sun8i-r40-tcon-top";
+                       reg = <0x01c70000 0x1000>;
+                       clocks = <&ccu CLK_BUS_TCON_TOP>,
+                                <&ccu CLK_TCON_TV0>,
+                                <&ccu CLK_TVE0>,
+                                <&ccu CLK_TCON_TV1>,
+                                <&ccu CLK_TVE1>,
+                                <&ccu CLK_DSI_DPHY>;
+                       clock-names = "bus",
+                                     "tcon-tv0",
+                                     "tve0",
+                                     "tcon-tv1",
+                                     "tve1",
+                                     "dsi";
+                       clock-output-names = "tcon-top-tv0",
+                                            "tcon-top-tv1",
+                                            "tcon-top-dsi";
+                       resets = <&ccu RST_BUS_TCON_TOP>;
+                       #clock-cells = <1>;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               tcon_top_mixer0_in: port@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <0>;
+
+                                       tcon_top_mixer0_in_mixer0: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&mixer0_out_tcon_top>;
+                                       };
+                               };
+
+                               tcon_top_mixer0_out: port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <1>;
+
+                                       tcon_top_mixer0_out_tcon_lcd0: endpoint@0 {
+                                               reg = <0>;
+                                       };
+
+                                       tcon_top_mixer0_out_tcon_lcd1: endpoint@1 {
+                                               reg = <1>;
+                                       };
+
+                                       tcon_top_mixer0_out_tcon_tv0: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&tcon_tv0_in_tcon_top_mixer0>;
+                                       };
+
+                                       tcon_top_mixer0_out_tcon_tv1: endpoint@3 {
+                                               reg = <3>;
+                                               remote-endpoint = <&tcon_tv1_in_tcon_top_mixer0>;
+                                       };
+                               };
+
+                               tcon_top_mixer1_in: port@2 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <2>;
+
+                                       tcon_top_mixer1_in_mixer1: endpoint@1 {
+                                               reg = <1>;
+                                               remote-endpoint = <&mixer1_out_tcon_top>;
+                                       };
+                               };
+
+                               tcon_top_mixer1_out: port@3 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <3>;
+
+                                       tcon_top_mixer1_out_tcon_lcd0: endpoint@0 {
+                                               reg = <0>;
+                                       };
+
+                                       tcon_top_mixer1_out_tcon_lcd1: endpoint@1 {
+                                               reg = <1>;
+                                       };
+
+                                       tcon_top_mixer1_out_tcon_tv0: endpoint@2 {
+                                               reg = <2>;
+                                               remote-endpoint = <&tcon_tv0_in_tcon_top_mixer1>;
+                                       };
+
+                                       tcon_top_mixer1_out_tcon_tv1: endpoint@3 {
+                                               reg = <3>;
+                                               remote-endpoint = <&tcon_tv1_in_tcon_top_mixer1>;
+                                       };
+                               };
+
+                               tcon_top_hdmi_in: port@4 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <4>;
+
+                                       tcon_top_hdmi_in_tcon_tv0: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&tcon_tv0_out_tcon_top>;
+                                       };
+
+                                       tcon_top_hdmi_in_tcon_tv1: endpoint@1 {
+                                               reg = <1>;
+                                               remote-endpoint = <&tcon_tv1_out_tcon_top>;
+                                       };
+                               };
+
+                               tcon_top_hdmi_out: port@5 {
+                                       reg = <5>;
+
+                                       tcon_top_hdmi_out_hdmi: endpoint {
+                                               remote-endpoint = <&hdmi_in_tcon_top>;
+                                       };
+                               };
+                       };
+               };
+
+               tcon_tv0: lcd-controller@1c73000 {
+                       compatible = "allwinner,sun8i-r40-tcon-tv";
+                       reg = <0x01c73000 0x1000>;
+                       interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_TCON_TV0>, <&tcon_top 0>;
+                       clock-names = "ahb", "tcon-ch1";
+                       resets = <&ccu RST_BUS_TCON_TV0>;
+                       reset-names = "lcd";
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               tcon_tv0_in: port@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <0>;
+
+                                       tcon_tv0_in_tcon_top_mixer0: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&tcon_top_mixer0_out_tcon_tv0>;
+                                       };
+
+                                       tcon_tv0_in_tcon_top_mixer1: endpoint@1 {
+                                               reg = <1>;
+                                               remote-endpoint = <&tcon_top_mixer1_out_tcon_tv0>;
+                                       };
+                               };
+
+                               tcon_tv0_out: port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <1>;
+
+                                       tcon_tv0_out_tcon_top: endpoint@1 {
+                                               reg = <1>;
+                                               remote-endpoint = <&tcon_top_hdmi_in_tcon_tv0>;
+                                       };
+                               };
+                       };
+               };
+
+               tcon_tv1: lcd-controller@1c74000 {
+                       compatible = "allwinner,sun8i-r40-tcon-tv";
+                       reg = <0x01c74000 0x1000>;
+                       interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_TCON_TV1>, <&tcon_top 1>;
+                       clock-names = "ahb", "tcon-ch1";
+                       resets = <&ccu RST_BUS_TCON_TV1>;
+                       reset-names = "lcd";
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               tcon_tv1_in: port@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <0>;
+
+                                       tcon_tv1_in_tcon_top_mixer0: endpoint@0 {
+                                               reg = <0>;
+                                               remote-endpoint = <&tcon_top_mixer0_out_tcon_tv1>;
+                                       };
+
+                                       tcon_tv1_in_tcon_top_mixer1: endpoint@1 {
+                                               reg = <1>;
+                                               remote-endpoint = <&tcon_top_mixer1_out_tcon_tv1>;
+                                       };
+                               };
+
+                               tcon_tv1_out: port@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <1>;
+
+                                       tcon_tv1_out_tcon_top: endpoint@1 {
+                                               reg = <1>;
+                                               remote-endpoint = <&tcon_top_hdmi_in_tcon_tv1>;
+                                       };
+                               };
+                       };
+               };
+
                gic: interrupt-controller@1c81000 {
                        compatible = "arm,gic-400";
                        reg = <0x01c81000 0x1000>,
                        #interrupt-cells = <3>;
                        interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
                };
+
+               hdmi: hdmi@1ee0000 {
+                       compatible = "allwinner,sun8i-r40-dw-hdmi",
+                                    "allwinner,sun8i-a83t-dw-hdmi";
+                       reg = <0x01ee0000 0x10000>;
+                       reg-io-width = <1>;
+                       interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_HDMI0>, <&ccu CLK_HDMI_SLOW>,
+                                <&ccu CLK_HDMI>;
+                       clock-names = "iahb", "isfr", "tmds";
+                       resets = <&ccu RST_BUS_HDMI1>;
+                       reset-names = "ctrl";
+                       phys = <&hdmi_phy>;
+                       phy-names = "hdmi-phy";
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               hdmi_in: port@0 {
+                                       reg = <0>;
+
+                                       hdmi_in_tcon_top: endpoint {
+                                               remote-endpoint = <&tcon_top_hdmi_out_hdmi>;
+                                       };
+                               };
+
+                               hdmi_out: port@1 {
+                                       reg = <1>;
+                               };
+                       };
+               };
+
+               hdmi_phy: hdmi-phy@1ef0000 {
+                       compatible = "allwinner,sun8i-r40-hdmi-phy",
+                                    "allwinner,sun50i-a64-hdmi-phy";
+                       reg = <0x01ef0000 0x10000>;
+                       clocks = <&ccu CLK_BUS_HDMI1>, <&ccu CLK_HDMI_SLOW>,
+                                <&ccu 7>, <&ccu 16>;
+                       clock-names = "bus", "mod", "pll-0", "pll-1";
+                       resets = <&ccu RST_BUS_HDMI0>;
+                       reset-names = "phy";
+                       #phy-cells = <0>;
+               };
        };
 
        timer {
index c3bff1105e5da6169972888fb70327f2ff8e7c81..fc6131315c47ffe695a4db6cbf0f7e38a8b89221 100644 (file)
                        reset-names = "stmmaceth";
                        clocks = <&ccu CLK_BUS_EMAC>;
                        clock-names = "stmmaceth";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
                        status = "disabled";
 
                        mdio: mdio {
index f7ffdd6658a2610c77ecad7565732eb64b9d2181..1eadc132390ca1c97634adcef038e8025540af3b 100644 (file)
        status = "okay";
 };
 
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_8bit_pins>;
+       vmmc-supply = <&reg_vcc_io>;
+       bus-width = <8>;
+       non-removable;
+       status = "okay";
+};
+
 &ohci0 {
        status = "okay";
 };
index eafff16765b4ae6be20f0c77a1454c4d02c00f09..1788556b497790e5bee3fe7f643e43198f9ad1da 100644 (file)
@@ -23,7 +23,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@80000000 {
                reg = <0x80000000 0x40000000>;
        };
 
index 7ed7370ee67a9e3b12d7e4134a9a05fbd0374863..3d3835591cd2ceee0d1d6ff55378d3394c6f0a77 100644 (file)
@@ -28,7 +28,7 @@
                };
        };
 
-       memory {
+       memory@80000000 {
                /* memory >= 0x79600000 is reserved for firmware usage */
                reg = <0x80000000 0x79600000>;
        };
index 7fc4a8b31e45c2a694dbd9b64a148a1668fd6313..bfdd1bf618161b403d9f75cbd5cea5ca927ce5af 100644 (file)
@@ -28,7 +28,7 @@
                };
        };
 
-       memory {
+       memory@80000000 {
                /* memory >= 0x37e00000 is reserved for firmware usage */
                reg = <0x80000000 0x37e00000>;
        };
index 84c4358dacac7e7cc71fbdae100f0d04e1af72b6..0d7a6327e404a6eca0353de81eb2acd18b5b0e2b 100644 (file)
@@ -5,11 +5,16 @@
 #include <dt-bindings/pinctrl/pinctrl-tegra.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
-#include "skeleton.dtsi"
-
 / {
        compatible = "nvidia,tegra114";
        interrupt-parent = <&lic>;
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0x0>;
+       };
 
        host1x@50000000 {
                compatible = "nvidia,tegra114-host1x", "simple-bus";
index 3455822350c5984fb483d7e7f5d66708436af3e6..573aaa50fff1c47f0eae1492bc8ed575a3510f0f 100644 (file)
@@ -15,7 +15,7 @@
        compatible = "toradex,apalis-tk1-v1.2", "toradex,apalis-tk1",
                     "nvidia,tegra124";
 
-       memory {
+       memory@80000000 {
                reg = <0x0 0x80000000 0x0 0x80000000>;
        };
 
index 9f960c84ba10ce0c0b2e0ec5e37e067b5cc7ef20..0f0d4a4988b90fafb9f4ab39c1825b9b3a635055 100644 (file)
@@ -50,7 +50,7 @@
        model = "Toradex Apalis TK1";
        compatible = "toradex,apalis-tk1", "nvidia,tegra124";
 
-       memory {
+       memory@80000000 {
                reg = <0x0 0x80000000 0x0 0x80000000>;
        };
 
index 6dbcf84dafbc1cb6d845d7cb53adb288758abc2b..9151b3ebb839c9623445906d117936b20d744429 100644 (file)
@@ -24,7 +24,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@80000000 {
                reg = <0x0 0x80000000 0x0 0x80000000>;
        };
 
index 3609367037a6cbb3bcf4b924deb11dfd9c59ac13..d5f11d6d987ea52236b113b49e761b329c948e08 100644 (file)
@@ -13,7 +13,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@80000000 {
                reg = <0x0 0x80000000 0x0 0x80000000>;
        };
 
index 89bcc178994df75967527eb40f75ccf81b7f3669..82d139648ef144f2c6c6fd6d996eacd83cb4785a 100644 (file)
@@ -18,7 +18,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@80000000 {
                reg = <0x0 0x80000000 0x0 0x80000000>;
        };
 
index 174092bfac908ca0c359f756d165c26b8cef6ff1..183c5acafb22b5a653d07f47d747c90bd7684c34 100644 (file)
@@ -7,14 +7,17 @@
 #include <dt-bindings/reset/tegra124-car.h>
 #include <dt-bindings/thermal/tegra124-soctherm.h>
 
-#include "skeleton.dtsi"
-
 / {
        compatible = "nvidia,tegra124";
        interrupt-parent = <&lic>;
        #address-cells = <2>;
        #size-cells = <2>;
 
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x0 0x80000000 0x0 0x0>;
+       };
+
        pcie@1003000 {
                compatible = "nvidia,tegra124-pcie";
                device_type = "pci";
diff --git a/arch/arm/boot/dts/tegra20-colibri-512.dtsi b/arch/arm/boot/dts/tegra20-colibri-512.dtsi
deleted file mode 100644 (file)
index 5c202b3..0000000
+++ /dev/null
@@ -1,540 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include "tegra20.dtsi"
-
-/ {
-       model = "Toradex Colibri T20 512MB";
-       compatible = "toradex,colibri_t20-512", "nvidia,tegra20";
-
-       aliases {
-               rtc0 = "/i2c@7000d000/tps6586x@34";
-               rtc1 = "/rtc@7000e000";
-       };
-
-       memory {
-               reg = <0x00000000 0x20000000>;
-       };
-
-       host1x@50000000 {
-               hdmi@54280000 {
-                       vdd-supply = <&hdmi_vdd_reg>;
-                       pll-supply = <&hdmi_pll_reg>;
-
-                       nvidia,ddc-i2c-bus = <&i2c_ddc>;
-                       nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
-                               GPIO_ACTIVE_HIGH>;
-               };
-       };
-
-       pinmux@70000014 {
-               pinctrl-names = "default";
-               pinctrl-0 = <&state_default>;
-
-               state_default: pinmux {
-                       audio_refclk {
-                               nvidia,pins = "cdev1";
-                               nvidia,function = "plla_out";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-                       crt {
-                               nvidia,pins = "crtp";
-                               nvidia,function = "crt";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-                       dap3 {
-                               nvidia,pins = "dap3";
-                               nvidia,function = "dap3";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-                       displaya {
-                               nvidia,pins = "ld0", "ld1", "ld2", "ld3",
-                                       "ld4", "ld5", "ld6", "ld7", "ld8",
-                                       "ld9", "ld10", "ld11", "ld12", "ld13",
-                                       "ld14", "ld15", "ld16", "ld17",
-                                       "lhs", "lpw0", "lpw2", "lsc0",
-                                       "lsc1", "lsck", "lsda", "lspi", "lvs";
-                               nvidia,function = "displaya";
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-                       gpio_dte {
-                               nvidia,pins = "dte";
-                               nvidia,function = "rsvd1";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-                       gpio_gmi {
-                               nvidia,pins = "ata", "atc", "atd", "ate",
-                                       "dap1", "dap2", "dap4", "gpu", "irrx",
-                                       "irtx", "spia", "spib", "spic";
-                               nvidia,function = "gmi";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-                       gpio_pta {
-                               nvidia,pins = "pta";
-                               nvidia,function = "rsvd4";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-                       gpio_uac {
-                               nvidia,pins = "uac";
-                               nvidia,function = "rsvd2";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-                       hdint {
-                               nvidia,pins = "hdint";
-                               nvidia,function = "hdmi";
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-                       i2c1 {
-                               nvidia,pins = "rm";
-                               nvidia,function = "i2c1";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-                       i2c3 {
-                               nvidia,pins = "dtf";
-                               nvidia,function = "i2c3";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-                       i2cddc {
-                               nvidia,pins = "ddc";
-                               nvidia,function = "i2c2";
-                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-                       i2cp {
-                               nvidia,pins = "i2cp";
-                               nvidia,function = "i2cp";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-                       irda {
-                               nvidia,pins = "uad";
-                               nvidia,function = "irda";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-                       nand {
-                               nvidia,pins = "kbca", "kbcc", "kbcd",
-                                       "kbce", "kbcf";
-                               nvidia,function = "nand";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-                       owc {
-                               nvidia,pins = "owc";
-                               nvidia,function = "owr";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-                       pmc {
-                               nvidia,pins = "pmc";
-                               nvidia,function = "pwr_on";
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-                       pwm {
-                               nvidia,pins = "sdb", "sdc", "sdd";
-                               nvidia,function = "pwm";
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-                       sdio4 {
-                               nvidia,pins = "atb", "gma", "gme";
-                               nvidia,function = "sdio4";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-                       spi1 {
-                               nvidia,pins = "spid", "spie", "spif";
-                               nvidia,function = "spi1";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-                       spi4 {
-                               nvidia,pins = "slxa", "slxc", "slxd", "slxk";
-                               nvidia,function = "spi4";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-                       uarta {
-                               nvidia,pins = "sdio1";
-                               nvidia,function = "uarta";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-                       uartd {
-                               nvidia,pins = "gmc";
-                               nvidia,function = "uartd";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-                       ulpi {
-                               nvidia,pins = "uaa", "uab", "uda";
-                               nvidia,function = "ulpi";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-                       ulpi_refclk {
-                               nvidia,pins = "cdev2";
-                               nvidia,function = "pllp_out4";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-                       usb_gpio {
-                               nvidia,pins = "spig", "spih";
-                               nvidia,function = "spi2_alt";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-                       vi {
-                               nvidia,pins = "dta", "dtb", "dtc", "dtd";
-                               nvidia,function = "vi";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-                       vi_sc {
-                               nvidia,pins = "csus";
-                               nvidia,function = "vi_sensor_clk";
-                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
-                       };
-               };
-       };
-
-       ac97: ac97@70002000 {
-               status = "okay";
-               nvidia,codec-reset-gpio = <&gpio TEGRA_GPIO(V, 0)
-                       GPIO_ACTIVE_HIGH>;
-               nvidia,codec-sync-gpio = <&gpio TEGRA_GPIO(P, 0)
-                       GPIO_ACTIVE_HIGH>;
-       };
-
-       /*
-        * GEN1_I2C: I2C_SDA/SCL on SODIMM pin 194/196 (e.g. RTC on carrier
-        * board)
-        */
-       i2c@7000c000 {
-               clock-frequency = <400000>;
-       };
-
-       /* DDC_SCL/SDA on X3 pin 15/16 (e.g. display EDID) */
-       i2c_ddc: i2c@7000c400 {
-               clock-frequency = <10000>;
-       };
-
-       /* GEN2_I2C: unused */
-
-       /* CAM/GEN3_I2C: used as EXT_IO1/2 GPIOs on SODIMM pin 133/127 */
-
-       /* PWR_I2C: power I2C to PMIC and temperature sensor (On-module) */
-       i2c@7000d000 {
-               status = "okay";
-               clock-frequency = <100000>;
-
-               pmic: tps6586x@34 {
-                       compatible = "ti,tps6586x";
-                       reg = <0x34>;
-                       interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
-
-                       ti,system-power-controller;
-
-                       #gpio-cells = <2>;
-                       gpio-controller;
-
-                       sys-supply = <&vdd_3v3_reg>;
-                       vin-sm0-supply = <&sys_reg>;
-                       vin-sm1-supply = <&sys_reg>;
-                       vin-sm2-supply = <&sys_reg>;
-                       vinldo01-supply = <&sm2_reg>;
-                       vinldo23-supply = <&vdd_3v3_reg>;
-                       vinldo4-supply = <&vdd_3v3_reg>;
-                       vinldo678-supply = <&vdd_3v3_reg>;
-                       vinldo9-supply = <&vdd_3v3_reg>;
-
-                       regulators {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               sys_reg: regulator@0 {
-                                       reg = <0>;
-                                       regulator-compatible = "sys";
-                                       regulator-name = "vdd_sys";
-                                       regulator-always-on;
-                               };
-
-                               regulator@1 {
-                                       reg = <1>;
-                                       regulator-compatible = "sm0";
-                                       regulator-name = "vdd_sm0,vdd_core";
-                                       regulator-min-microvolt = <1200000>;
-                                       regulator-max-microvolt = <1200000>;
-                                       regulator-always-on;
-                               };
-
-                               regulator@2 {
-                                       reg = <2>;
-                                       regulator-compatible = "sm1";
-                                       regulator-name = "vdd_sm1,vdd_cpu";
-                                       regulator-min-microvolt = <1000000>;
-                                       regulator-max-microvolt = <1000000>;
-                                       regulator-always-on;
-                               };
-
-                               sm2_reg: regulator@3 {
-                                       reg = <3>;
-                                       regulator-compatible = "sm2";
-                                       regulator-name = "vdd_sm2,vin_ldo*";
-                                       regulator-min-microvolt = <1800000>;
-                                       regulator-max-microvolt = <1800000>;
-                                       regulator-always-on;
-                               };
-
-                               /* LDO0 is not connected to anything */
-
-                               regulator@5 {
-                                       reg = <5>;
-                                       regulator-compatible = "ldo1";
-                                       regulator-name = "vdd_ldo1,avdd_pll*";
-                                       regulator-min-microvolt = <1100000>;
-                                       regulator-max-microvolt = <1100000>;
-                                       regulator-always-on;
-                               };
-
-                               regulator@6 {
-                                       reg = <6>;
-                                       regulator-compatible = "ldo2";
-                                       regulator-name = "vdd_ldo2,vdd_rtc";
-                                       regulator-min-microvolt = <1200000>;
-                                       regulator-max-microvolt = <1200000>;
-                               };
-
-                               /* LDO3 is not connected to anything */
-
-                               regulator@8 {
-                                       reg = <8>;
-                                       regulator-compatible = "ldo4";
-                                       regulator-name = "vdd_ldo4,avdd_osc,vddio_sys";
-                                       regulator-min-microvolt = <1800000>;
-                                       regulator-max-microvolt = <1800000>;
-                                       regulator-always-on;
-                               };
-
-                               ldo5_reg: regulator@9 {
-                                       reg = <9>;
-                                       regulator-compatible = "ldo5";
-                                       regulator-name = "vdd_ldo5,vdd_fuse";
-                                       regulator-min-microvolt = <3300000>;
-                                       regulator-max-microvolt = <3300000>;
-                                       regulator-always-on;
-                               };
-
-                               regulator@10 {
-                                       reg = <10>;
-                                       regulator-compatible = "ldo6";
-                                       regulator-name = "vdd_ldo6,avdd_vdac,vddio_vi,vddio_cam";
-                                       regulator-min-microvolt = <2850000>;
-                                       regulator-max-microvolt = <2850000>;
-                               };
-
-                               hdmi_vdd_reg: regulator@11 {
-                                       reg = <11>;
-                                       regulator-compatible = "ldo7";
-                                       regulator-name = "vdd_ldo7,avdd_hdmi";
-                                       regulator-min-microvolt = <3300000>;
-                                       regulator-max-microvolt = <3300000>;
-                               };
-
-                               hdmi_pll_reg: regulator@12 {
-                                       reg = <12>;
-                                       regulator-compatible = "ldo8";
-                                       regulator-name = "vdd_ldo8,avdd_hdmi_pll";
-                                       regulator-min-microvolt = <1800000>;
-                                       regulator-max-microvolt = <1800000>;
-                               };
-
-                               regulator@13 {
-                                       reg = <13>;
-                                       regulator-compatible = "ldo9";
-                                       regulator-name = "vdd_ldo9,avdd_2v85,vdd_ddr_rx";
-                                       regulator-min-microvolt = <2850000>;
-                                       regulator-max-microvolt = <2850000>;
-                                       regulator-always-on;
-                               };
-
-                               regulator@14 {
-                                       reg = <14>;
-                                       regulator-compatible = "ldo_rtc";
-                                       regulator-name = "vdd_rtc_out,vdd_cell";
-                                       regulator-min-microvolt = <3300000>;
-                                       regulator-max-microvolt = <3300000>;
-                                       regulator-always-on;
-                               };
-                       };
-               };
-
-               temperature-sensor@4c {
-                       compatible = "national,lm95245";
-                       reg = <0x4c>;
-               };
-       };
-
-       pmc@7000e400 {
-               nvidia,suspend-mode = <1>;
-               nvidia,cpu-pwr-good-time = <5000>;
-               nvidia,cpu-pwr-off-time = <5000>;
-               nvidia,core-pwr-good-time = <3845 3845>;
-               nvidia,core-pwr-off-time = <3875>;
-               nvidia,sys-clock-req-active-high;
-       };
-
-       memory-controller@7000f400 {
-               emc-table@83250 {
-                       reg = <83250>;
-                       compatible = "nvidia,tegra20-emc-table";
-                       clock-frequency = <83250>;
-                       nvidia,emc-registers =   <0x00000005 0x00000011
-                               0x00000004 0x00000002 0x00000004 0x00000004
-                               0x00000001 0x0000000a 0x00000002 0x00000002
-                               0x00000001 0x00000001 0x00000003 0x00000004
-                               0x00000003 0x00000009 0x0000000c 0x0000025f
-                               0x00000000 0x00000003 0x00000003 0x00000002
-                               0x00000002 0x00000001 0x00000008 0x000000c8
-                               0x00000003 0x00000005 0x00000003 0x0000000c
-                               0x00000002 0x00000000 0x00000000 0x00000002
-                               0x00000000 0x00000000 0x00000083 0x00520006
-                               0x00000010 0x00000008 0x00000000 0x00000000
-                               0x00000000 0x00000000 0x00000000 0x00000000>;
-               };
-               emc-table@133200 {
-                       reg = <133200>;
-                       compatible = "nvidia,tegra20-emc-table";
-                       clock-frequency = <133200>;
-                       nvidia,emc-registers =   <0x00000008 0x00000019
-                               0x00000006 0x00000002 0x00000004 0x00000004
-                               0x00000001 0x0000000a 0x00000002 0x00000002
-                               0x00000002 0x00000001 0x00000003 0x00000004
-                               0x00000003 0x00000009 0x0000000c 0x0000039f
-                               0x00000000 0x00000003 0x00000003 0x00000002
-                               0x00000002 0x00000001 0x00000008 0x000000c8
-                               0x00000003 0x00000007 0x00000003 0x0000000c
-                               0x00000002 0x00000000 0x00000000 0x00000002
-                               0x00000000 0x00000000 0x00000083 0x00510006
-                               0x00000010 0x00000008 0x00000000 0x00000000
-                               0x00000000 0x00000000 0x00000000 0x00000000>;
-               };
-               emc-table@166500 {
-                       reg = <166500>;
-                       compatible = "nvidia,tegra20-emc-table";
-                       clock-frequency = <166500>;
-                       nvidia,emc-registers =   <0x0000000a 0x00000021
-                               0x00000008 0x00000003 0x00000004 0x00000004
-                               0x00000002 0x0000000a 0x00000003 0x00000003
-                               0x00000002 0x00000001 0x00000003 0x00000004
-                               0x00000003 0x00000009 0x0000000c 0x000004df
-                               0x00000000 0x00000003 0x00000003 0x00000003
-                               0x00000003 0x00000001 0x00000009 0x000000c8
-                               0x00000003 0x00000009 0x00000004 0x0000000c
-                               0x00000002 0x00000000 0x00000000 0x00000002
-                               0x00000000 0x00000000 0x00000083 0x004f0006
-                               0x00000010 0x00000008 0x00000000 0x00000000
-                               0x00000000 0x00000000 0x00000000 0x00000000>;
-               };
-               emc-table@333000 {
-                       reg = <333000>;
-                       compatible = "nvidia,tegra20-emc-table";
-                       clock-frequency = <333000>;
-                       nvidia,emc-registers =   <0x00000014 0x00000041
-                               0x0000000f 0x00000005 0x00000004 0x00000005
-                               0x00000003 0x0000000a 0x00000005 0x00000005
-                               0x00000004 0x00000001 0x00000003 0x00000004
-                               0x00000003 0x00000009 0x0000000c 0x000009ff
-                               0x00000000 0x00000003 0x00000003 0x00000005
-                               0x00000005 0x00000001 0x0000000e 0x000000c8
-                               0x00000003 0x00000011 0x00000006 0x0000000c
-                               0x00000002 0x00000000 0x00000000 0x00000002
-                               0x00000000 0x00000000 0x00000083 0x00380006
-                               0x00000010 0x00000008 0x00000000 0x00000000
-                               0x00000000 0x00000000 0x00000000 0x00000000>;
-               };
-       };
-
-       usb@c5004000 {
-               status = "okay";
-               nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
-                       GPIO_ACTIVE_LOW>;
-       };
-
-       usb-phy@c5004000 {
-               status = "okay";
-               nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
-                       GPIO_ACTIVE_LOW>;
-       };
-
-       sdhci@c8000600 {
-               cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>;
-       };
-
-       clocks {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               clk32k_in: clock@0 {
-                       compatible = "fixed-clock";
-                       reg = <0>;
-                       #clock-cells = <0>;
-                       clock-frequency = <32768>;
-               };
-       };
-
-       regulators {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               vdd_3v3_reg: regulator@100 {
-                       compatible = "regulator-fixed";
-                       reg = <100>;
-                       regulator-name = "vdd_3v3";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-                       regulator-always-on;
-               };
-
-               regulator@101 {
-                       compatible = "regulator-fixed";
-                       reg = <101>;
-                       regulator-name = "internal_usb";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-                       enable-active-high;
-                       regulator-boot-on;
-                       regulator-always-on;
-                       gpio = <&gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_HIGH>;
-               };
-       };
-
-       sound {
-               compatible = "nvidia,tegra-audio-wm9712-colibri_t20",
-                                "nvidia,tegra-audio-wm9712";
-               nvidia,model = "Colibri T20 AC97 Audio";
-
-               nvidia,audio-routing =
-                       "Headphone", "HPOUTL",
-                       "Headphone", "HPOUTR",
-                       "LineIn", "LINEINL",
-                       "LineIn", "LINEINR",
-                       "Mic", "MIC1";
-
-               nvidia,ac97-controller = <&ac97>;
-
-               clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
-                        <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
-                        <&tegra_car TEGRA20_CLK_CDEV1>;
-               clock-names = "pll_a", "pll_a_out0", "mclk";
-       };
-};
diff --git a/arch/arm/boot/dts/tegra20-colibri-iris.dts b/arch/arm/boot/dts/tegra20-colibri-iris.dts
new file mode 100644 (file)
index 0000000..57f16c0
--- /dev/null
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "tegra20-colibri.dtsi"
+
+/ {
+       model = "Toradex Colibri T20 256/512 MB on Iris";
+       compatible = "toradex,iris", "toradex,colibri_t20-512", "nvidia,tegra20";
+
+       aliases {
+               serial0 = &uarta;
+               serial1 = &uartd;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       host1x@50000000 {
+               hdmi@54280000 {
+                       status = "okay";
+               };
+       };
+
+       pinmux@70000014 {
+               state_default: pinmux {
+                       hdint {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       i2cddc {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       sdio4 {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       uarta {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+
+                       uartd {
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+               };
+       };
+
+       serial@70006000 {
+               status = "okay";
+       };
+
+       serial@70006300 {
+               status = "okay";
+       };
+
+       i2c_ddc: i2c@7000c400 {
+               status = "okay";
+       };
+
+       usb@c5000000 {
+               status = "okay";
+       };
+
+       usb-phy@c5000000 {
+               status = "okay";
+       };
+
+       usb@c5008000 {
+               status = "okay";
+       };
+
+       usb-phy@c5008000 {
+               status = "okay";
+       };
+
+       sdhci@c8000600 {
+               status = "okay";
+               bus-width = <4>;
+               vmmc-supply = <&vcc_sd_reg>;
+               vqmmc-supply = <&vcc_sd_reg>;
+       };
+
+       regulators {
+               regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "usb_host_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+                       gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>;
+               };
+
+               vcc_sd_reg: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "vcc_sd";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/tegra20-colibri.dtsi b/arch/arm/boot/dts/tegra20-colibri.dtsi
new file mode 100644 (file)
index 0000000..e7b9ab0
--- /dev/null
@@ -0,0 +1,561 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "tegra20.dtsi"
+
+/ {
+       model = "Toradex Colibri T20 256/512 MB";
+       compatible = "toradex,colibri_t20-512", "nvidia,tegra20";
+
+       aliases {
+               rtc0 = "/i2c@7000d000/tps6586x@34";
+               rtc1 = "/rtc@7000e000";
+       };
+
+       memory@0 {
+               /*
+                * Set memory to 256 MB to be safe as this could be used on
+                * 256 or 512 MB module. It is expected from bootloader
+                * to fix this up for 512 MB version.
+                */
+               reg = <0x00000000 0x10000000>;
+       };
+
+       host1x@50000000 {
+               hdmi@54280000 {
+                       vdd-supply = <&hdmi_vdd_reg>;
+                       pll-supply = <&hdmi_pll_reg>;
+
+                       nvidia,ddc-i2c-bus = <&i2c_ddc>;
+                       nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+                               GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       pinmux@70000014 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&state_default>;
+
+               state_default: pinmux {
+                       audio_refclk {
+                               nvidia,pins = "cdev1";
+                               nvidia,function = "plla_out";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       crt {
+                               nvidia,pins = "crtp";
+                               nvidia,function = "crt";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       dap3 {
+                               nvidia,pins = "dap3";
+                               nvidia,function = "dap3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       displaya {
+                               nvidia,pins = "ld0", "ld1", "ld2", "ld3",
+                                       "ld4", "ld5", "ld6", "ld7", "ld8",
+                                       "ld9", "ld10", "ld11", "ld12", "ld13",
+                                       "ld14", "ld15", "ld16", "ld17",
+                                       "lhs", "lpw0", "lpw2", "lsc0",
+                                       "lsc1", "lsck", "lsda", "lspi", "lvs";
+                               nvidia,function = "displaya";
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       gpio_dte {
+                               nvidia,pins = "dte";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       gpio_gmi {
+                               nvidia,pins = "ata", "atc", "atd", "ate",
+                                       "dap1", "dap2", "dap4", "gpu", "irrx",
+                                       "irtx", "spia", "spib", "spic";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       gpio_pta {
+                               nvidia,pins = "pta";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       gpio_uac {
+                               nvidia,pins = "uac";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       hdint {
+                               nvidia,pins = "hdint";
+                               nvidia,function = "hdmi";
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       i2c1 {
+                               nvidia,pins = "rm";
+                               nvidia,function = "i2c1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       i2c3 {
+                               nvidia,pins = "dtf";
+                               nvidia,function = "i2c3";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       i2cddc {
+                               nvidia,pins = "ddc";
+                               nvidia,function = "i2c2";
+                               nvidia,pull = <TEGRA_PIN_PULL_UP>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       i2cp {
+                               nvidia,pins = "i2cp";
+                               nvidia,function = "i2cp";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       irda {
+                               nvidia,pins = "uad";
+                               nvidia,function = "irda";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       nand {
+                               nvidia,pins = "kbca", "kbcc", "kbcd",
+                                       "kbce", "kbcf";
+                               nvidia,function = "nand";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       owc {
+                               nvidia,pins = "owc";
+                               nvidia,function = "owr";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       pmc {
+                               nvidia,pins = "pmc";
+                               nvidia,function = "pwr_on";
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       pwm {
+                               nvidia,pins = "sdb", "sdc", "sdd";
+                               nvidia,function = "pwm";
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       sdio4 {
+                               nvidia,pins = "atb", "gma", "gme";
+                               nvidia,function = "sdio4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       spi1 {
+                               nvidia,pins = "spid", "spie", "spif";
+                               nvidia,function = "spi1";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       spi4 {
+                               nvidia,pins = "slxa", "slxc", "slxd", "slxk";
+                               nvidia,function = "spi4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       uarta {
+                               nvidia,pins = "sdio1";
+                               nvidia,function = "uarta";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       uartd {
+                               nvidia,pins = "gmc";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       ulpi {
+                               nvidia,pins = "uaa", "uab", "uda";
+                               nvidia,function = "ulpi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       ulpi_refclk {
+                               nvidia,pins = "cdev2";
+                               nvidia,function = "pllp_out4";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       usb_gpio {
+                               nvidia,pins = "spig", "spih";
+                               nvidia,function = "spi2_alt";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                       };
+                       vi {
+                               nvidia,pins = "dta", "dtb", "dtc", "dtd";
+                               nvidia,function = "vi";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+                       vi_sc {
+                               nvidia,pins = "csus";
+                               nvidia,function = "vi_sensor_clk";
+                               nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+                               nvidia,tristate = <TEGRA_PIN_ENABLE>;
+                       };
+               };
+       };
+
+       ac97: ac97@70002000 {
+               status = "okay";
+               nvidia,codec-reset-gpio = <&gpio TEGRA_GPIO(V, 0)
+                       GPIO_ACTIVE_HIGH>;
+               nvidia,codec-sync-gpio = <&gpio TEGRA_GPIO(P, 0)
+                       GPIO_ACTIVE_HIGH>;
+       };
+
+       nand-controller@70008000 {
+               status = "okay";
+
+               nand@0 {
+                       reg = <0>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       nand-bus-width = <8>;
+                       nand-on-flash-bbt;
+                       nand-ecc-algo = "bch";
+                       nand-is-boot-medium;
+                       nand-ecc-maximize;
+                       wp-gpios = <&gpio TEGRA_GPIO(S, 0) GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       /*
+        * GEN1_I2C: I2C_SDA/SCL on SODIMM pin 194/196 (e.g. RTC on carrier
+        * board)
+        */
+       i2c@7000c000 {
+               clock-frequency = <400000>;
+       };
+
+       /* DDC_SCL/SDA on X3 pin 15/16 (e.g. display EDID) */
+       i2c_ddc: i2c@7000c400 {
+               clock-frequency = <10000>;
+       };
+
+       /* GEN2_I2C: unused */
+
+       /* CAM/GEN3_I2C: used as EXT_IO1/2 GPIOs on SODIMM pin 133/127 */
+
+       /* PWR_I2C: power I2C to PMIC and temperature sensor (On-module) */
+       i2c@7000d000 {
+               status = "okay";
+               clock-frequency = <100000>;
+
+               pmic: tps6586x@34 {
+                       compatible = "ti,tps6586x";
+                       reg = <0x34>;
+                       interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+
+                       ti,system-power-controller;
+
+                       #gpio-cells = <2>;
+                       gpio-controller;
+
+                       sys-supply = <&vdd_3v3_reg>;
+                       vin-sm0-supply = <&sys_reg>;
+                       vin-sm1-supply = <&sys_reg>;
+                       vin-sm2-supply = <&sys_reg>;
+                       vinldo01-supply = <&sm2_reg>;
+                       vinldo23-supply = <&vdd_3v3_reg>;
+                       vinldo4-supply = <&vdd_3v3_reg>;
+                       vinldo678-supply = <&vdd_3v3_reg>;
+                       vinldo9-supply = <&vdd_3v3_reg>;
+
+                       regulators {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               sys_reg: regulator@0 {
+                                       reg = <0>;
+                                       regulator-compatible = "sys";
+                                       regulator-name = "vdd_sys";
+                                       regulator-always-on;
+                               };
+
+                               regulator@1 {
+                                       reg = <1>;
+                                       regulator-compatible = "sm0";
+                                       regulator-name = "vdd_sm0,vdd_core";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                               };
+
+                               regulator@2 {
+                                       reg = <2>;
+                                       regulator-compatible = "sm1";
+                                       regulator-name = "vdd_sm1,vdd_cpu";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                               };
+
+                               sm2_reg: regulator@3 {
+                                       reg = <3>;
+                                       regulator-compatible = "sm2";
+                                       regulator-name = "vdd_sm2,vin_ldo*";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               /* LDO0 is not connected to anything */
+
+                               regulator@5 {
+                                       reg = <5>;
+                                       regulator-compatible = "ldo1";
+                                       regulator-name = "vdd_ldo1,avdd_pll*";
+                                       regulator-min-microvolt = <1100000>;
+                                       regulator-max-microvolt = <1100000>;
+                                       regulator-always-on;
+                               };
+
+                               regulator@6 {
+                                       reg = <6>;
+                                       regulator-compatible = "ldo2";
+                                       regulator-name = "vdd_ldo2,vdd_rtc";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                               };
+
+                               /* LDO3 is not connected to anything */
+
+                               regulator@8 {
+                                       reg = <8>;
+                                       regulator-compatible = "ldo4";
+                                       regulator-name = "vdd_ldo4,avdd_osc,vddio_sys";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo5_reg: regulator@9 {
+                                       reg = <9>;
+                                       regulator-compatible = "ldo5";
+                                       regulator-name = "vdd_ldo5,vdd_fuse";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                                       regulator-always-on;
+                               };
+
+                               regulator@10 {
+                                       reg = <10>;
+                                       regulator-compatible = "ldo6";
+                                       regulator-name = "vdd_ldo6,avdd_vdac,vddio_vi,vddio_cam";
+                                       regulator-min-microvolt = <2850000>;
+                                       regulator-max-microvolt = <2850000>;
+                               };
+
+                               hdmi_vdd_reg: regulator@11 {
+                                       reg = <11>;
+                                       regulator-compatible = "ldo7";
+                                       regulator-name = "vdd_ldo7,avdd_hdmi";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                               };
+
+                               hdmi_pll_reg: regulator@12 {
+                                       reg = <12>;
+                                       regulator-compatible = "ldo8";
+                                       regulator-name = "vdd_ldo8,avdd_hdmi_pll";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                               };
+
+                               regulator@13 {
+                                       reg = <13>;
+                                       regulator-compatible = "ldo9";
+                                       regulator-name = "vdd_ldo9,avdd_2v85,vdd_ddr_rx";
+                                       regulator-min-microvolt = <2850000>;
+                                       regulator-max-microvolt = <2850000>;
+                                       regulator-always-on;
+                               };
+
+                               regulator@14 {
+                                       reg = <14>;
+                                       regulator-compatible = "ldo_rtc";
+                                       regulator-name = "vdd_rtc_out,vdd_cell";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                                       regulator-always-on;
+                               };
+                       };
+               };
+
+               temperature-sensor@4c {
+                       compatible = "national,lm95245";
+                       reg = <0x4c>;
+               };
+       };
+
+       pmc@7000e400 {
+               nvidia,suspend-mode = <1>;
+               nvidia,cpu-pwr-good-time = <5000>;
+               nvidia,cpu-pwr-off-time = <5000>;
+               nvidia,core-pwr-good-time = <3845 3845>;
+               nvidia,core-pwr-off-time = <3875>;
+               nvidia,sys-clock-req-active-high;
+       };
+
+       memory-controller@7000f400 {
+               emc-table@83250 {
+                       reg = <83250>;
+                       compatible = "nvidia,tegra20-emc-table";
+                       clock-frequency = <83250>;
+                       nvidia,emc-registers =   <0x00000005 0x00000011
+                               0x00000004 0x00000002 0x00000004 0x00000004
+                               0x00000001 0x0000000a 0x00000002 0x00000002
+                               0x00000001 0x00000001 0x00000003 0x00000004
+                               0x00000003 0x00000009 0x0000000c 0x0000025f
+                               0x00000000 0x00000003 0x00000003 0x00000002
+                               0x00000002 0x00000001 0x00000008 0x000000c8
+                               0x00000003 0x00000005 0x00000003 0x0000000c
+                               0x00000002 0x00000000 0x00000000 0x00000002
+                               0x00000000 0x00000000 0x00000083 0x00520006
+                               0x00000010 0x00000008 0x00000000 0x00000000
+                               0x00000000 0x00000000 0x00000000 0x00000000>;
+               };
+               emc-table@133200 {
+                       reg = <133200>;
+                       compatible = "nvidia,tegra20-emc-table";
+                       clock-frequency = <133200>;
+                       nvidia,emc-registers =   <0x00000008 0x00000019
+                               0x00000006 0x00000002 0x00000004 0x00000004
+                               0x00000001 0x0000000a 0x00000002 0x00000002
+                               0x00000002 0x00000001 0x00000003 0x00000004
+                               0x00000003 0x00000009 0x0000000c 0x0000039f
+                               0x00000000 0x00000003 0x00000003 0x00000002
+                               0x00000002 0x00000001 0x00000008 0x000000c8
+                               0x00000003 0x00000007 0x00000003 0x0000000c
+                               0x00000002 0x00000000 0x00000000 0x00000002
+                               0x00000000 0x00000000 0x00000083 0x00510006
+                               0x00000010 0x00000008 0x00000000 0x00000000
+                               0x00000000 0x00000000 0x00000000 0x00000000>;
+               };
+               emc-table@166500 {
+                       reg = <166500>;
+                       compatible = "nvidia,tegra20-emc-table";
+                       clock-frequency = <166500>;
+                       nvidia,emc-registers =   <0x0000000a 0x00000021
+                               0x00000008 0x00000003 0x00000004 0x00000004
+                               0x00000002 0x0000000a 0x00000003 0x00000003
+                               0x00000002 0x00000001 0x00000003 0x00000004
+                               0x00000003 0x00000009 0x0000000c 0x000004df
+                               0x00000000 0x00000003 0x00000003 0x00000003
+                               0x00000003 0x00000001 0x00000009 0x000000c8
+                               0x00000003 0x00000009 0x00000004 0x0000000c
+                               0x00000002 0x00000000 0x00000000 0x00000002
+                               0x00000000 0x00000000 0x00000083 0x004f0006
+                               0x00000010 0x00000008 0x00000000 0x00000000
+                               0x00000000 0x00000000 0x00000000 0x00000000>;
+               };
+               emc-table@333000 {
+                       reg = <333000>;
+                       compatible = "nvidia,tegra20-emc-table";
+                       clock-frequency = <333000>;
+                       nvidia,emc-registers =   <0x00000014 0x00000041
+                               0x0000000f 0x00000005 0x00000004 0x00000005
+                               0x00000003 0x0000000a 0x00000005 0x00000005
+                               0x00000004 0x00000001 0x00000003 0x00000004
+                               0x00000003 0x00000009 0x0000000c 0x000009ff
+                               0x00000000 0x00000003 0x00000003 0x00000005
+                               0x00000005 0x00000001 0x0000000e 0x000000c8
+                               0x00000003 0x00000011 0x00000006 0x0000000c
+                               0x00000002 0x00000000 0x00000000 0x00000002
+                               0x00000000 0x00000000 0x00000083 0x00380006
+                               0x00000010 0x00000008 0x00000000 0x00000000
+                               0x00000000 0x00000000 0x00000000 0x00000000>;
+               };
+       };
+
+       usb@c5004000 {
+               status = "okay";
+               nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+                       GPIO_ACTIVE_LOW>;
+       };
+
+       usb-phy@c5004000 {
+               status = "okay";
+               nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1)
+                       GPIO_ACTIVE_LOW>;
+       };
+
+       sdhci@c8000600 {
+               cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>;
+       };
+
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock@0 {
+                       compatible = "fixed-clock";
+                       reg = <0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               vdd_3v3_reg: regulator@100 {
+                       compatible = "regulator-fixed";
+                       reg = <100>;
+                       regulator-name = "vdd_3v3";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               regulator@101 {
+                       compatible = "regulator-fixed";
+                       reg = <101>;
+                       regulator-name = "internal_usb";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       regulator-boot-on;
+                       regulator-always-on;
+                       gpio = <&gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       sound {
+               compatible = "nvidia,tegra-audio-wm9712-colibri_t20",
+                                "nvidia,tegra-audio-wm9712";
+               nvidia,model = "Colibri T20 AC97 Audio";
+
+               nvidia,audio-routing =
+                       "Headphone", "HPOUTL",
+                       "Headphone", "HPOUTR",
+                       "LineIn", "LINEINL",
+                       "LineIn", "LINEINR",
+                       "Mic", "MIC1";
+
+               nvidia,ac97-controller = <&ac97>;
+
+               clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
+                        <&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
+                        <&tegra_car TEGRA20_CLK_CDEV1>;
+               clock-names = "pll_a", "pll_a_out0", "mclk";
+       };
+};
index 628a55a9318befb6e098aaeb3e593185fb544dbc..1d96d92b72a7bf538a54f03a33f064914e418dc1 100644 (file)
@@ -18,7 +18,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@0 {
                reg = <0x00000000 0x40000000>;
        };
 
diff --git a/arch/arm/boot/dts/tegra20-iris-512.dts b/arch/arm/boot/dts/tegra20-iris-512.dts
deleted file mode 100644 (file)
index 4012638..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/dts-v1/;
-
-#include "tegra20-colibri-512.dtsi"
-
-/ {
-       model = "Toradex Colibri T20 512MB on Iris";
-       compatible = "toradex,iris", "toradex,colibri_t20-512", "nvidia,tegra20";
-
-       aliases {
-               serial0 = &uarta;
-               serial1 = &uartd;
-       };
-
-       chosen {
-               stdout-path = "serial0:115200n8";
-       };
-
-       host1x@50000000 {
-               hdmi@54280000 {
-                       status = "okay";
-               };
-       };
-
-       pinmux@70000014 {
-               state_default: pinmux {
-                       hdint {
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-
-                       i2cddc {
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-
-                       sdio4 {
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-
-                       uarta {
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-
-                       uartd {
-                               nvidia,tristate = <TEGRA_PIN_DISABLE>;
-                       };
-               };
-       };
-
-       serial@70006000 {
-               status = "okay";
-       };
-
-       serial@70006300 {
-               status = "okay";
-       };
-
-       i2c_ddc: i2c@7000c400 {
-               status = "okay";
-       };
-
-       usb@c5000000 {
-               status = "okay";
-       };
-
-       usb-phy@c5000000 {
-               status = "okay";
-       };
-
-       usb@c5008000 {
-               status = "okay";
-       };
-
-       usb-phy@c5008000 {
-               status = "okay";
-       };
-
-       sdhci@c8000600 {
-               status = "okay";
-               bus-width = <4>;
-               vmmc-supply = <&vcc_sd_reg>;
-               vqmmc-supply = <&vcc_sd_reg>;
-       };
-
-       regulators {
-               regulator@0 {
-                       compatible = "regulator-fixed";
-                       reg = <0>;
-                       regulator-name = "usb_host_vbus";
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-                       regulator-boot-on;
-                       regulator-always-on;
-                       gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>;
-               };
-
-               vcc_sd_reg: regulator@1 {
-                       compatible = "regulator-fixed";
-                       reg = <1>;
-                       regulator-name = "vcc_sd";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-                       regulator-boot-on;
-                       regulator-always-on;
-               };
-       };
-};
index 30436969adc0e48761cefd136de13bc8e06b071d..ef245291924f076d73aec01d5ad0f68db0e92589 100644 (file)
@@ -19,7 +19,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@0 {
                reg = <0x00000000 0x20000000>;
        };
 
index 284aae351ff234df64928b28d36a882a31bb2876..f91441683aada20c26dd649a72f52761131ee4c5 100644 (file)
@@ -18,7 +18,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@0 {
                reg = <0x00000000 0x40000000>;
        };
 
index 872046d48709a3e5f8abb701432f1891c72ad85c..20137fc578b1b48a7d3c4cfa323f26dbeb322ac8 100644 (file)
@@ -15,7 +15,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@0 {
                reg = <0x00000000 0x20000000>;
        };
 
index d55c6b240a30db3b5dc1c075f642b4deec6bbbf1..9eb26dc15f6b66092dee98f77bd68260933c9204 100644 (file)
@@ -18,7 +18,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@0 {
                reg = <0x00000000 0x40000000>;
        };
 
index ee3fbf941e79871190fbe26c4796b9c33afc7a7f..f44551e2d9d03ede72abe695b17605c703da647e 100644 (file)
@@ -18,7 +18,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@0 {
                reg = <0x00000000 0x40000000>;
        };
 
index 983dd5c1479459f2ba27f43dbefdbaaa411cffb5..15b73bd377f0408b948f80b36a4afaff82f14688 100644 (file)
@@ -1,14 +1,20 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <dt-bindings/clock/tegra20-car.h>
 #include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/memory/tegra20-mc.h>
 #include <dt-bindings/pinctrl/pinctrl-tegra.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
-#include "skeleton.dtsi"
-
 / {
        compatible = "nvidia,tegra20";
        interrupt-parent = <&lic>;
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0 0>;
+       };
 
        iram@40000000 {
                compatible = "mmio-sram";
                             <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; /* SXE interrupt */
                interrupt-names = "sync-token", "bsev", "sxe";
                clocks = <&tegra_car TEGRA20_CLK_VDE>;
-               resets = <&tegra_car 61>;
+               reset-names = "vde", "mc";
+               resets = <&tegra_car 61>, <&mc TEGRA20_MC_RESET_VDE>;
        };
 
        apbmisc@70000800 {
                status = "disabled";
        };
 
+       nand-controller@70008000 {
+               compatible = "nvidia,tegra20-nand";
+               reg = <0x70008000 0x100>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&tegra_car TEGRA20_CLK_NDFLASH>;
+               clock-names = "nand";
+               resets = <&tegra_car 13>;
+               reset-names = "nand";
+               assigned-clocks = <&tegra_car TEGRA20_CLK_NDFLASH>;
+               assigned-clock-rates = <150000000>;
+               status = "disabled";
+       };
+
        pwm: pwm@7000a000 {
                compatible = "nvidia,tegra20-pwm";
                reg = <0x7000a000 0x100>;
                clock-names = "pclk", "clk32k_in";
        };
 
-       memory-controller@7000f000 {
+       mc: memory-controller@7000f000 {
                compatible = "nvidia,tegra20-mc";
                reg = <0x7000f000 0x024
                       0x7000f03c 0x3c4>;
                interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+               #reset-cells = <1>;
        };
 
        iommu@7000f024 {
index d1d21ec2a844905b5831a6c1a1d8098857cc54de..2f807d40c1b792bd35c662bcd243588b7fa91d0b 100644 (file)
        model = "Toradex Apalis T30";
        compatible = "toradex,apalis_t30", "nvidia,tegra30";
 
+       memory@80000000 {
+               reg = <0x80000000 0x40000000>;
+       };
+
        pcie@3000 {
                avdd-pexa-supply = <&vdd2_reg>;
                vdd-pexa-supply = <&vdd2_reg>;
                                nvidia,function = "spi4";
                                nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                                nvidia,tristate = <TEGRA_PIN_DISABLE>;
+                               nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                        };
                        /* CAN_INT2 */
                        spi2_cs2_n_pw3 {
                /* STMPE811 touch screen controller */
                stmpe811@41 {
                        compatible = "st,stmpe811";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
                        reg = <0x41>;
                        interrupts = <TEGRA_GPIO(V, 0) IRQ_TYPE_LEVEL_LOW>;
                        interrupt-parent = <&gpio>;
                        blocks = <0x5>;
                        irq-trigger = <0x1>;
 
-                       stmpe_touchscreen@0 {
+                       stmpe_touchscreen {
                                compatible = "st,stmpe-ts";
                                /* 3.25 MHz ADC clock speed */
                                st,adc-freq = <1>;
index ae52a5039506a2fd58be77cacef44fe97e2148bf..b0d40ac8ac6e056c4aecd31f98bb42095df6a138 100644 (file)
@@ -17,7 +17,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@80000000 {
                reg = <0x80000000 0x7ff00000>;
        };
 
                        vccio-supply = <&vdd_5v_in_reg>;
 
                        regulators {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
                                vdd1_reg: vdd1 {
                                        regulator-name = "vddio_ddr_1v2";
                                        regulator-min-microvolt = <1200000>;
index 92a9740c533f217a10cd6fb4421d2fc6871d015d..fb9222b479d2d91e1bf0b700afdf78abd36c6879 100644 (file)
@@ -40,7 +40,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@80000000 {
                reg = <0x80000000 0x40000000>;
        };
 
                        #address-cells = <1>;
                        #size-cells = <0>;
                        reg = <0x70>;
+                       reset-gpio = <&gpio TEGRA_GPIO(BB, 0) GPIO_ACTIVE_LOW>;
                };
        };
 
index c44d8c40c410b15d7f8c3654252e8bdd116f7f33..526ed71cf7a320f970770213947d6c325e86c181 100644 (file)
@@ -10,7 +10,7 @@
        model = "Toradex Colibri T30";
        compatible = "toradex,colibri_t30", "nvidia,tegra30";
 
-       memory {
+       memory@80000000 {
                reg = <0x80000000 0x40000000>;
        };
 
                /* STMPE811 touch screen controller */
                stmpe811@41 {
                        compatible = "st,stmpe811";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
                        reg = <0x41>;
                        interrupts = <TEGRA_GPIO(V, 0) IRQ_TYPE_LEVEL_LOW>;
                        interrupt-parent = <&gpio>;
index 09087b9c5e26ce2b9989e26ee0f7bae011a5b77c..a6781f6533105e7e27a7bb1e9da8f066cc1814a8 100644 (file)
@@ -5,11 +5,16 @@
 #include <dt-bindings/pinctrl/pinctrl-tegra.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
-#include "skeleton.dtsi"
-
 / {
        compatible = "nvidia,tegra30";
        interrupt-parent = <&lic>;
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0x0>;
+       };
 
        pcie@3000 {
                compatible = "nvidia,tegra30-pcie";
                             <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; /* SXE interrupt */
                interrupt-names = "sync-token", "bsev", "sxe";
                clocks = <&tegra_car TEGRA30_CLK_VDE>;
-               resets = <&tegra_car 61>;
+               reset-names = "vde", "mc";
+               resets = <&tegra_car 61>, <&mc TEGRA30_MC_RESET_VDE>;
        };
 
        apbmisc@70000800 {
                interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
 
                #iommu-cells = <1>;
+               #reset-cells = <1>;
        };
 
        fuse@7000f800 {
index 641d96119d4f9e59dcdbe79ef6caf128f8e77735..e2d1a22c5950d5310838222049891f9ea6fe313d 100644 (file)
@@ -36,6 +36,7 @@
                        enable-method = "psci";
                        next-level-cache = <&l2>;
                        operating-points-v2 = <&cpu_opp>;
+                       #cooling-cells = <2>;
                };
 
                cpu2: cpu@2 {
@@ -46,6 +47,7 @@
                        enable-method = "psci";
                        next-level-cache = <&l2>;
                        operating-points-v2 = <&cpu_opp>;
+                       #cooling-cells = <2>;
                };
 
                cpu3: cpu@3 {
@@ -56,6 +58,7 @@
                        enable-method = "psci";
                        next-level-cache = <&l2>;
                        operating-points-v2 = <&cpu_opp>;
+                       #cooling-cells = <2>;
                };
        };
 
diff --git a/arch/arm/boot/dts/vf610-zii-cfu1.dts b/arch/arm/boot/dts/vf610-zii-cfu1.dts
new file mode 100644 (file)
index 0000000..37777cf
--- /dev/null
@@ -0,0 +1,305 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+/*
+ * Copyright (C) 2018 Zodiac Inflight Innovations
+ */
+
+/dts-v1/;
+#include "vf610.dtsi"
+
+/ {
+       model = "ZII VF610 CFU1 Board";
+       compatible = "zii,vf610cfu1", "zii,vf610dev", "fsl,vf610";
+
+       chosen {
+               stdout-path = &uart0;
+       };
+
+       memory@80000000 {
+               reg = <0x80000000 0x20000000>;
+       };
+
+       gpio-leds {
+               compatible = "gpio-leds";
+               pinctrl-0 = <&pinctrl_leds_debug>;
+               pinctrl-names = "default";
+
+               led-debug {
+                       label = "zii:green:debug1";
+                       gpios = <&gpio2 18 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+                       max-brightness = <1>;
+               };
+
+               led-fail {
+                       label = "zii:red:fail";
+                       gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+                       max-brightness = <1>;
+               };
+
+               led-status {
+                       label = "zii:green:status";
+                       gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+                       max-brightness = <1>;
+               };
+
+               led-debug-a {
+                       label = "zii:green:debug_a";
+                       gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+                       max-brightness = <1>;
+               };
+
+               led-debug-b {
+                       label = "zii:green:debug_b";
+                       gpios = <&gpio3 15 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+                       max-brightness = <1>;
+               };
+       };
+
+       reg_vcc_3v3_mcu: regulator-vcc-3v3-mcu {
+                compatible = "regulator-fixed";
+                regulator-name = "vcc_3v3_mcu";
+                regulator-min-microvolt = <3300000>;
+                regulator-max-microvolt = <3300000>;
+       };
+};
+
+&adc0 {
+       vref-supply = <&reg_vcc_3v3_mcu>;
+       status = "okay";
+};
+
+&adc1 {
+       vref-supply = <&reg_vcc_3v3_mcu>;
+       status = "okay";
+};
+
+&dspi1 {
+       bus-num = <1>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_dspi1>;
+       status = "okay";
+
+       m25p128@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "m25p128", "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <50000000>;
+
+               partition@0 {
+                       label = "m25p128-0";
+                       reg = <0x0 0x01000000>;
+               };
+       };
+};
+
+&edma0 {
+       status = "okay";
+};
+
+&edma1 {
+       status = "okay";
+};
+
+&esdhc0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc0>;
+       bus-width = <8>;
+       non-removable;
+       no-1-8-v;
+       keep-power-in-suspend;
+       status = "okay";
+};
+
+&esdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc1>;
+       bus-width = <4>;
+       status = "okay";
+};
+
+&fec1 {
+       phy-mode = "rmii";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1>;
+       status = "okay";
+
+       fixed-link {
+               speed = <100>;
+               full-duplex;
+       };
+
+       mdio1: mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "okay";
+
+               switch0: switch0@0 {
+                       compatible = "marvell,mv88e6085";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_switch>;
+                       reg = <0>;
+                       eeprom-length = <512>;
+                       interrupt-parent = <&gpio3>;
+                       interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       reset-gpios = <&gpio3 11 GPIO_ACTIVE_LOW>;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       label = "eth_cu_1000_1";
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       label = "eth_cu_1000_2";
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       label = "eth_cu_1000_3";
+                               };
+
+                               port@6 {
+                                       reg = <6>;
+                                       label = "cpu";
+                                       ethernet = <&fec1>;
+
+                                       fixed-link {
+                                               speed = <100>;
+                                               full-duplex;
+                                       };
+                               };
+                       };
+               };
+       };
+};
+
+&i2c0 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c0>;
+       status = "okay";
+
+       pca9554@22 {
+               compatible = "nxp,pca9554";
+               reg = <0x22>;
+               gpio-controller;
+       };
+
+       lm75@48 {
+               compatible = "national,lm75";
+               reg = <0x48>;
+       };
+
+       at24c04@52 {
+               compatible = "atmel,24c04";
+               reg = <0x52>;
+               label = "nvm";
+       };
+
+       at24c04@54 {
+               compatible = "atmel,24c04";
+               reg = <0x54>;
+               label = "nameplate";
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart0>;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_dspi1: dspi1grp {
+               fsl,pins = <
+                       VF610_PAD_PTD5__DSPI1_CS0               0x1182
+                       VF610_PAD_PTC6__DSPI1_SIN               0x1181
+                       VF610_PAD_PTC7__DSPI1_SOUT              0x1182
+                       VF610_PAD_PTC8__DSPI1_SCK               0x1182
+               >;
+       };
+
+       pinctrl_esdhc0: esdhc0grp {
+               fsl,pins = <
+                       VF610_PAD_PTC0__ESDHC0_CLK              0x31ef
+                       VF610_PAD_PTC1__ESDHC0_CMD              0x31ef
+                       VF610_PAD_PTC2__ESDHC0_DAT0             0x31ef
+                       VF610_PAD_PTC3__ESDHC0_DAT1             0x31ef
+                       VF610_PAD_PTC4__ESDHC0_DAT2             0x31ef
+                       VF610_PAD_PTC5__ESDHC0_DAT3             0x31ef
+                       VF610_PAD_PTD23__ESDHC0_DAT4            0x31ef
+                       VF610_PAD_PTD22__ESDHC0_DAT5            0x31ef
+                       VF610_PAD_PTD21__ESDHC0_DAT6            0x31ef
+                       VF610_PAD_PTD20__ESDHC0_DAT7            0x31ef
+               >;
+       };
+
+       pinctrl_esdhc1: esdhc1grp {
+               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
+               >;
+       };
+
+       pinctrl_fec1: fec1grp {
+               fsl,pins = <
+                       VF610_PAD_PTA6__RMII_CLKIN              0x30d1
+                       VF610_PAD_PTC9__ENET_RMII1_MDC          0x30fe
+                       VF610_PAD_PTC10__ENET_RMII1_MDIO        0x30d3
+                       VF610_PAD_PTC11__ENET_RMII1_CRS         0x30d1
+                       VF610_PAD_PTC12__ENET_RMII1_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               0x37ff
+                       VF610_PAD_PTB15__I2C0_SDA               0x37ff
+               >;
+       };
+
+       pinctrl_leds_debug: pinctrl-leds-debug {
+               fsl,pins = <
+                       VF610_PAD_PTD3__GPIO_82                 0x31c2
+                       VF610_PAD_PTE3__GPIO_108                0x31c2
+                       VF610_PAD_PTE4__GPIO_109                0x31c2
+                       VF610_PAD_PTE5__GPIO_110                0x31c2
+                       VF610_PAD_PTE6__GPIO_111                0x31c2
+               >;
+       };
+
+       pinctrl_switch: switch-grp {
+               fsl,pins = <
+                       VF610_PAD_PTB28__GPIO_98                0x3061
+                       VF610_PAD_PTE2__GPIO_107                0x1042
+               >;
+       };
+
+       pinctrl_uart0: uart0grp {
+               fsl,pins = <
+                       VF610_PAD_PTB10__UART0_TX               0x21a2
+                       VF610_PAD_PTB11__UART0_RX               0x21a1
+               >;
+       };
+};
diff --git a/arch/arm/boot/dts/vf610-zii-ssmb-spu3.dts b/arch/arm/boot/dts/vf610-zii-ssmb-spu3.dts
new file mode 100644 (file)
index 0000000..fe35766
--- /dev/null
@@ -0,0 +1,341 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+/*
+ * Device tree file for ZII's SSMB SPU3 board
+ *
+ * SSMB - SPU3 Switch Management Board
+ * SPU - Seat Power Unit
+ *
+ * Copyright (C) 2015, 2016 Zodiac Inflight Innovations
+ *
+ * Based on an original 'vf610-twr.dts' which is Copyright 2015,
+ * Freescale Semiconductor, Inc.
+ */
+
+/dts-v1/;
+#include "vf610.dtsi"
+
+/ {
+       model = "ZII VF610 SSMB SPU3 Board";
+       compatible = "zii,vf610spu3", "zii,vf610dev", "fsl,vf610";
+
+       chosen {
+               stdout-path = &uart0;
+       };
+
+       memory@80000000 {
+               reg = <0x80000000 0x20000000>;
+       };
+
+       gpio-leds {
+               compatible = "gpio-leds";
+               pinctrl-0 = <&pinctrl_leds_debug>;
+               pinctrl-names = "default";
+
+               led-debug {
+                       label = "zii:green:debug1";
+                       gpios = <&gpio2 18 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+                       max-brightness = <1>;
+               };
+       };
+
+       reg_vcc_3v3_mcu: regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_3v3_mcu";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+};
+
+&adc0 {
+       vref-supply = <&reg_vcc_3v3_mcu>;
+       status = "okay";
+};
+
+&adc1 {
+       vref-supply = <&reg_vcc_3v3_mcu>;
+       status = "okay";
+};
+
+&dspi1 {
+       bus-num = <1>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_dspi1>;
+       /*
+        * Some SPU3s come with SPI-NOR chip DNPed, so we leave this
+        * node disabled by default and rely on bootloader to enable
+        * it when appropriate.
+        */
+       status = "disabled";
+
+       m25p128@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "m25p128", "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <50000000>;
+
+               partition@0 {
+                       label = "m25p128-0";
+                       reg = <0x0 0x01000000>;
+               };
+       };
+};
+
+&edma0 {
+       status = "okay";
+};
+
+&edma1 {
+       status = "okay";
+};
+
+&esdhc0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc0>;
+       bus-width = <8>;
+       non-removable;
+       no-1-8-v;
+       keep-power-in-suspend;
+       status = "okay";
+};
+
+&esdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_esdhc1>;
+       bus-width = <4>;
+       status = "okay";
+};
+
+&fec1 {
+       phy-mode = "rmii";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1>;
+       status = "okay";
+
+       fixed-link {
+               speed = <100>;
+               full-duplex;
+       };
+
+       mdio1: mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "okay";
+
+               switch0: switch0@0 {
+                       compatible = "marvell,mv88e6190";
+                       pinctrl-0 = <&pinctrl_gpio_switch0>;
+                       pinctrl-names = "default";
+                       reg = <0>;
+                       eeprom-length = <65536>;
+                       reset-gpios = <&gpio3 11 GPIO_ACTIVE_LOW>;
+                       interrupt-parent = <&gpio3>;
+                       interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       label = "cpu";
+                                       ethernet = <&fec1>;
+
+                                       fixed-link {
+                                               speed = <100>;
+                                               full-duplex;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       label = "eth_cu_1000_1";
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       label = "eth_cu_1000_2";
+                               };
+
+                               port@3 {
+                                       reg = <3>;
+                                       label = "eth_cu_1000_3";
+                               };
+
+                               port@4 {
+                                       reg = <4>;
+                                       label = "eth_cu_1000_4";
+                               };
+
+                               port@5 {
+                                       reg = <5>;
+                                       label = "eth_cu_1000_5";
+                               };
+
+                               port@6 {
+                                       reg = <6>;
+                                       label = "eth_cu_1000_6";
+                               };
+                       };
+               };
+       };
+};
+
+&i2c0 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c0>;
+       status = "okay";
+
+       gpio6: pca9505@22 {
+               compatible = "nxp,pca9554";
+               reg = <0x22>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       lm75@48 {
+               compatible = "national,lm75";
+               reg = <0x48>;
+       };
+
+       at24c04@50 {
+               compatible = "atmel,24c04";
+               reg = <0x50>;
+               label = "nameplate";
+       };
+
+       at24c04@52 {
+               compatible = "atmel,24c04";
+               reg = <0x52>;
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart0>;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+
+       rave-sp {
+               compatible = "zii,rave-sp-rdu2";
+               current-speed = <1000000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               watchdog {
+                       compatible = "zii,rave-sp-watchdog";
+               };
+
+               eeprom@a3 {
+                       compatible = "zii,rave-sp-eeprom";
+                       reg = <0xa3 0x4000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       zii,eeprom-name = "main-eeprom";
+               };
+       };
+};
+
+&iomuxc {
+       pinctrl_dspi1: dspi1grp {
+               fsl,pins = <
+                       VF610_PAD_PTD5__DSPI1_CS0               0x1182
+                       VF610_PAD_PTD4__DSPI1_CS1               0x1182
+                       VF610_PAD_PTC6__DSPI1_SIN               0x1181
+                       VF610_PAD_PTC7__DSPI1_SOUT              0x1182
+                       VF610_PAD_PTC8__DSPI1_SCK               0x1182
+               >;
+       };
+
+       pinctrl_esdhc0: esdhc0grp {
+               fsl,pins = <
+                       VF610_PAD_PTC0__ESDHC0_CLK              0x31ef
+                       VF610_PAD_PTC1__ESDHC0_CMD              0x31ef
+                       VF610_PAD_PTC2__ESDHC0_DAT0             0x31ef
+                       VF610_PAD_PTC3__ESDHC0_DAT1             0x31ef
+                       VF610_PAD_PTC4__ESDHC0_DAT2             0x31ef
+                       VF610_PAD_PTC5__ESDHC0_DAT3             0x31ef
+                       VF610_PAD_PTD23__ESDHC0_DAT4            0x31ef
+                       VF610_PAD_PTD22__ESDHC0_DAT5            0x31ef
+                       VF610_PAD_PTD21__ESDHC0_DAT6            0x31ef
+                       VF610_PAD_PTD20__ESDHC0_DAT7            0x31ef
+               >;
+       };
+
+       pinctrl_esdhc1: esdhc1grp {
+               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
+               >;
+       };
+
+       pinctrl_fec1: fec1grp {
+               fsl,pins = <
+                       VF610_PAD_PTA6__RMII_CLKIN              0x30d1
+                       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_RMII1_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_gpio_switch0: pinctrl-gpio-switch0 {
+               fsl,pins = <
+                       VF610_PAD_PTE2__GPIO_107                0x31c2
+                       VF610_PAD_PTB28__GPIO_98                0x219d
+               >;
+       };
+
+       pinctrl_i2c0: i2c0grp {
+               fsl,pins = <
+                       VF610_PAD_PTB14__I2C0_SCL               0x37ff
+                       VF610_PAD_PTB15__I2C0_SDA               0x37ff
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       VF610_PAD_PTB16__I2C1_SCL               0x37ff
+                       VF610_PAD_PTB17__I2C1_SDA               0x37ff
+               >;
+       };
+
+       pinctrl_leds_debug: pinctrl-leds-debug {
+               fsl,pins = <
+                       VF610_PAD_PTD3__GPIO_82                 0x31c2
+               >;
+       };
+
+       pinctrl_uart0: uart0grp {
+               fsl,pins = <
+                       VF610_PAD_PTB10__UART0_TX               0x21a2
+                       VF610_PAD_PTB11__UART0_RX               0x21a1
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       VF610_PAD_PTB23__UART1_TX               0x21a2
+                       VF610_PAD_PTB24__UART1_RX               0x21a1
+               >;
+       };
+};
index 1a0f631c1d8de37a8235fc129e4e26c8725330cc..8b9ab9bba23bb133634ae70f778555f9ccb9755b 100644 (file)
@@ -12,8 +12,8 @@
 /include/ "zynq-7000.dtsi"
 
 / {
+       model = "Xilinx CC108 board";
        compatible = "xlnx,zynq-cc108", "xlnx,zynq-7000";
-       model = "Xilinx Zynq";
 
        aliases {
                ethernet0 = &gem0;
index aa4a0b6defb84438b56a8c0a0ee358fb885d75fd..6ed84fb1590224c8ca7668bd9634b138a564f589 100644 (file)
@@ -7,8 +7,8 @@
 /include/ "zynq-7000.dtsi"
 
 / {
-       model = "Zynq MicroZED Development Board";
-       compatible = "xlnx,zynq-microzed", "xlnx,zynq-7000";
+       model = "Avnet MicroZed board";
+       compatible = "avnet,zynq-microzed", "xlnx,zynq-microzed", "xlnx,zynq-7000";
 
        aliases {
                ethernet0 = &gem0;
index c05f4b67d4c11faf1e47fdac17e09e940a16b036..54592aeb92b9dde176d21b44327112c1ae3b382f 100644 (file)
@@ -12,7 +12,7 @@
 /include/ "zynq-7000.dtsi"
 
 / {
-       model = "Adapteva Parallella Board";
+       model = "Adapteva Parallella board";
        compatible = "adapteva,parallella", "xlnx,zynq-7000";
 
        aliases {
index f2330b0cb63d355cc60adb7ec389a22ac8b776f2..cc5a3dc2b4a08dc3ceca92112bc6e0206bfd21d1 100644 (file)
@@ -7,13 +7,14 @@
 #include "zynq-7000.dtsi"
 
 / {
-       model = "Zynq ZC702 Development Board";
+       model = "Xilinx ZC702 board";
        compatible = "xlnx,zynq-zc702", "xlnx,zynq-7000";
 
        aliases {
                ethernet0 = &gem0;
                i2c0 = &i2c0;
                serial0 = &uart1;
+               mmc0 = &sdhci0;
        };
 
        memory@0 {
@@ -28,8 +29,6 @@
 
        gpio-keys {
                compatible = "gpio-keys";
-               #address-cells = <1>;
-               #size-cells = <0>;
                autorepeat;
                sw14 {
                        label = "sw14";
index 3ad1260ff2a18d125bf0ec6fe7ff76af5d808d94..77943c16d33fcf57b3e7742a6dd2598eac81263a 100644 (file)
@@ -7,13 +7,14 @@
 #include "zynq-7000.dtsi"
 
 / {
-       model = "Zynq ZC706 Development Board";
+       model = "Xilinx ZC706 board";
        compatible = "xlnx,zynq-zc706", "xlnx,zynq-7000";
 
        aliases {
                ethernet0 = &gem0;
                i2c0 = &i2c0;
                serial0 = &uart1;
+               mmc0 = &sdhci0;
        };
 
        memory@0 {
index 6884f1ad66b77b4844d1e17ae2c4414dbec83503..0e1bfdd3421ff04f31266051546b23f5b9e3cfd0 100644 (file)
@@ -8,8 +8,8 @@
 #include "zynq-7000.dtsi"
 
 / {
+       model = "Xilinx ZC770 XM010 board";
        compatible = "xlnx,zynq-zc770-xm010", "xlnx,zynq-7000";
-       model = "Xilinx Zynq";
 
        aliases {
                ethernet0 = &gem0;
index b78883cee96ab867f6926d43de79f54e608a5068..b7f65862c0221ae456cfd3122e1085c91f9a9990 100644 (file)
@@ -8,8 +8,8 @@
 #include "zynq-7000.dtsi"
 
 / {
+       model = "Xilinx ZC770 XM011 board";
        compatible = "xlnx,zynq-zc770-xm011", "xlnx,zynq-7000";
-       model = "Xilinx Zynq";
 
        aliases {
                i2c0 = &i2c1;
index c3169d63600d14d05a9ececdaab29839e017d083..d2359b789eb890fbd95d863ba8ccb59018af8dd9 100644 (file)
@@ -8,8 +8,8 @@
 #include "zynq-7000.dtsi"
 
 / {
+       model = "Xilinx ZC770 XM012 board";
        compatible = "xlnx,zynq-zc770-xm012", "xlnx,zynq-7000";
-       model = "Xilinx Zynq";
 
        aliases {
                i2c0 = &i2c0;
index 8bb66859d7743f67abb13795cb0ab71c75064f3a..651913f1afa2a06647addfdb6ae415b567031f66 100644 (file)
@@ -8,8 +8,8 @@
 #include "zynq-7000.dtsi"
 
 / {
+       model = "Xilinx ZC770 XM013 board";
        compatible = "xlnx,zynq-zc770-xm013", "xlnx,zynq-7000";
-       model = "Xilinx Zynq";
 
        aliases {
                ethernet0 = &gem1;
index 53c6883ce1f694cc506aa505c9035a06d80ba31e..6a5a93aa6552ce229bf8effc3838c21672f2b91b 100644 (file)
@@ -7,12 +7,13 @@
 #include "zynq-7000.dtsi"
 
 / {
-       model = "Zynq Zed Development Board";
-       compatible = "xlnx,zynq-zed", "xlnx,zynq-7000";
+       model = "Avnet ZedBoard board";
+       compatible = "avnet,zynq-zed", "xlnx,zynq-zed", "xlnx,zynq-7000";
 
        aliases {
                ethernet0 = &gem0;
                serial0 = &uart1;
+               mmc0 = &sdhci0;
        };
 
        memory@0 {
diff --git a/arch/arm/boot/dts/zynq-zturn.dts b/arch/arm/boot/dts/zynq-zturn.dts
new file mode 100644 (file)
index 0000000..b387046
--- /dev/null
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  Copyright (C) 2015 Andrea Merello <adnrea.merello@gmail.com>
+ *  Copyright (C) 2017 Alexander Graf <agraf@suse.de>
+ *
+ *  Based on zynq-zed.dts which is:
+ *  Copyright (C) 2011 - 2014 Xilinx
+ *  Copyright (C) 2012 National Instruments Corp.
+ *
+ */
+
+/dts-v1/;
+/include/ "zynq-7000.dtsi"
+
+/ {
+       model = "Zynq Z-Turn MYIR Board";
+       compatible = "myir,zynq-zturn", "xlnx,zynq-7000";
+
+       aliases {
+               ethernet0 = &gem0;
+               serial0 = &uart1;
+               serial1 = &uart0;
+               mmc0 = &sdhci0;
+       };
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x0 0x40000000>;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       gpio-leds {
+               compatible = "gpio-leds";
+               usr-led1 {
+                       label = "usr-led1";
+                       gpios = <&gpio0 0x0 0x1>;
+                       default-state = "off";
+               };
+
+               usr-led2 {
+                       label = "usr-led2";
+                       gpios = <&gpio0 0x9 0x1>;
+                       default-state = "off";
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               autorepeat;
+               K1 {
+                       label = "K1";
+                       gpios = <&gpio0 0x32 0x1>;
+                       linux,code = <0x66>;
+                       gpio-key,wakeup;
+                       autorepeat;
+               };
+       };
+};
+
+&clkc {
+       ps-clk-frequency = <33333333>;
+};
+
+&gem0 {
+       status = "okay";
+       phy-mode = "rgmii-id";
+       phy-handle = <&ethernet_phy>;
+
+       ethernet_phy: ethernet-phy@0 {
+               reg = <0x0>;
+       };
+};
+
+&sdhci0 {
+       status = "okay";
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&uart1 {
+       status = "okay";
+};
+
+&usb0 {
+       status = "okay";
+       dr_mode = "host";
+};
+
+&can0 {
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+       clock-frequency = <400000>;
+
+       stlm75@49 {
+               status = "okay";
+               compatible = "lm75";
+               reg = <0x49>;
+       };
+
+       accelerometer@53 {
+               compatible = "adi,adxl345", "adxl345", "adi,adxl34x", "adxl34x";
+               reg = <0x53>;
+               interrupt-parent = <&intc>;
+               interrupts = <0x0 0x1e 0x4>;
+       };
+};
index 1e713dc98920d7de4daaa8b396102fe7e00cfa19..357b78a5c11b16aaaffc774bad9fdbe48c69dd9a 100644 (file)
@@ -1,9 +1,10 @@
 // SPDX-License-Identifier: GPL-2.0+
 /dts-v1/;
 #include "zynq-7000.dtsi"
+#include <dt-bindings/gpio/gpio.h>
 
 / {
-       model = "Zynq ZYBO Z7 Development Board";
+       model = "Digilent Zybo Z7 board";
        compatible = "digilent,zynq-zybo-z7", "xlnx,zynq-7000";
 
        aliases {
@@ -13,7 +14,7 @@
 
        memory@0 {
                device_type = "memory";
-               reg = <0x0 0x20000000>;
+               reg = <0x0 0x40000000>;
        };
 
        chosen {
                stdout-path = "serial0:115200n8";
        };
 
+       gpio-leds {
+               compatible = "gpio-leds";
+
+               ld4 {
+                       label = "zynq-zybo-z7:green:ld4";
+                       gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
        usb_phy0: phy0 {
                #phy-cells = <0>;
                compatible = "usb-nop-xceiv";
-               reset-gpios = <&gpio0 46 1>;
+               reset-gpios = <&gpio0 46 GPIO_ACTIVE_LOW>;
        };
 };
 
index a6c00e7fa767c7e750d18361954709e1ee62c205..755f6f109d5aa04fad5dbcc7e0ef92b09205234c 100644 (file)
@@ -7,12 +7,13 @@
 #include "zynq-7000.dtsi"
 
 / {
-       model = "Zynq ZYBO Development Board";
+       model = "Digilent Zybo board";
        compatible = "digilent,zynq-zybo", "xlnx,zynq-7000";
 
        aliases {
                ethernet0 = &gem0;
                serial0 = &uart1;
+               mmc0 = &sdhci0;
        };
 
        memory@0 {
index 95946dee9c77e2a96cf9dff66157b99f2980bd7f..1446262921b483f5f25b812060a4ed6180c2eafc 100644 (file)
@@ -3,30 +3,39 @@ CONFIG_KERNEL_XZ=y
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
-CONFIG_LOG_BUF_SHIFT=14
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
 CONFIG_CGROUPS=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZO is not set
 # CONFIG_RD_LZ4 is not set
-CONFIG_KALLSYMS_ALL=y
-CONFIG_BPF_SYSCALL=y
+# CONFIG_UID16 is not set
+# CONFIG_SYSFS_SYSCALL is not set
 # CONFIG_AIO is not set
+CONFIG_BPF_SYSCALL=y
 CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
+CONFIG_SLAB_FREELIST_RANDOM=y
 CONFIG_JUMP_LABEL=y
+CONFIG_STRICT_KERNEL_RWX=y
 CONFIG_GCC_PLUGINS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
 # CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEBUG_FS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_MQ_IOSCHED_DEADLINE is not set
+# CONFIG_MQ_IOSCHED_KYBER is not set
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_ASPEED=y
 CONFIG_MACH_ASPEED_G4=y
 CONFIG_VMSPLIT_2G=y
 CONFIG_AEABI=y
-# CONFIG_CPU_SW_DOMAIN_PAN is not set
 # CONFIG_COMPACTION is not set
+CONFIG_UACCESS_WITH_MEMCPY=y
 CONFIG_SECCOMP=y
 # CONFIG_ATAGS is not set
 CONFIG_ZBOOT_ROM_TEXT=0x0
@@ -47,8 +56,14 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_ADVANCED is not set
+CONFIG_VLAN_8021Q=y
 CONFIG_NET_NCSI=y
+CONFIG_BPF_STREAM_PARSER=y
 # CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
@@ -58,11 +73,12 @@ CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_PARTITIONED_MASTER=y
 CONFIG_MTD_SPI_NOR=y
+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
 CONFIG_SPI_ASPEED_SMC=y
 CONFIG_MTD_UBI=y
 CONFIG_MTD_UBI_FASTMAP=y
 CONFIG_MTD_UBI_BLOCK=y
-CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_LOOP=y
 CONFIG_ASPEED_LPC_CTRL=y
 CONFIG_ASPEED_LPC_SNOOP=y
 CONFIG_EEPROM_AT24=y
@@ -70,18 +86,26 @@ CONFIG_NETDEVICES=y
 CONFIG_NETCONSOLE=y
 # CONFIG_NET_VENDOR_ALACRITECH is not set
 # CONFIG_NET_VENDOR_AMAZON is not set
+# CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
-# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_AURORA is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CADENCE is not set
+# CONFIG_NET_VENDOR_CAVIUM is not set
 # CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_CORTINA is not set
 # CONFIG_NET_VENDOR_EZCHIP is not set
 CONFIG_FTGMAC100=y
 # CONFIG_NET_VENDOR_HISILICON is not set
+# CONFIG_NET_VENDOR_HUAWEI is not set
 # CONFIG_NET_VENDOR_INTEL is not set
 # CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
 # CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROSEMI is not set
 # CONFIG_NET_VENDOR_NATSEMI is not set
 # CONFIG_NET_VENDOR_NETRONOME is not set
+# CONFIG_NET_VENDOR_NI is not set
 # CONFIG_NET_VENDOR_QUALCOMM is not set
 # CONFIG_NET_VENDOR_RENESAS is not set
 # CONFIG_NET_VENDOR_ROCKER is not set
@@ -89,13 +113,20 @@ CONFIG_FTGMAC100=y
 # CONFIG_NET_VENDOR_SEEQ is not set
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
 # CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_SOCIONEXT is not set
 # CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_BROADCOM_PHY=y
 CONFIG_REALTEK_PHY=y
+# CONFIG_USB_NET_DRIVERS is not set
 # CONFIG_WLAN is not set
-# CONFIG_INPUT is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_GPIO_POLLED=y
+# CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -108,15 +139,16 @@ CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_ASPEED_VUART=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_ASPEED_KCS_IPMI_BMC=y
 CONFIG_ASPEED_BT_IPMI_BMC=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
+CONFIG_HW_RANDOM_TIMERIOMEM=y
 # CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MUX=y
 CONFIG_I2C_MUX_PCA9541=y
 CONFIG_I2C_MUX_PCA954x=y
 CONFIG_I2C_ASPEED=y
+CONFIG_I2C_FSI=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_ASPEED=y
@@ -129,19 +161,45 @@ CONFIG_SENSORS_LM75=y
 CONFIG_SENSORS_NCT7904=y
 CONFIG_PMBUS=y
 CONFIG_SENSORS_ADM1275=y
+CONFIG_SENSORS_IBM_CFFPS=y
+CONFIG_SENSORS_IR35221=y
 CONFIG_SENSORS_LM25066=y
+CONFIG_SENSORS_MAX31785=y
 CONFIG_SENSORS_UCD9000=y
+CONFIG_SENSORS_UCD9200=y
 CONFIG_SENSORS_TMP421=y
+CONFIG_SENSORS_W83773G=y
+CONFIG_WATCHDOG_SYSFS=y
+CONFIG_DRM=y
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_DYNAMIC_MINORS=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_GADGET=y
+CONFIG_U_SERIAL_CONSOLE=y
+CONFIG_USB_ASPEED_VHUB=y
+CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_LB_SS=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_HID=y
+CONFIG_USB_CONFIGFS_F_PRINTER=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_CLASS_FLASH=y
 CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PCA955X=y
+CONFIG_LEDS_PCA955X_GPIO=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
@@ -150,33 +208,56 @@ CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_DS1307=y
 CONFIG_RTC_DRV_PCF8523=y
 CONFIG_RTC_DRV_RV8803=y
-CONFIG_MAILBOX=y
+# CONFIG_VIRTIO_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_IIO=y
 CONFIG_ASPEED_ADC=y
+CONFIG_MAX1363=y
 CONFIG_BMP280=y
+CONFIG_FSI=y
+CONFIG_FSI_MASTER_GPIO=y
+CONFIG_FSI_MASTER_HUB=y
+CONFIG_FSI_MASTER_AST_CF=y
+CONFIG_FSI_SCOM=y
+CONFIG_FSI_SBEFIFO=y
 CONFIG_FIRMWARE_MEMMAP=y
 CONFIG_FANOTIFY=y
 CONFIG_OVERLAY_FS=y
 CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
+# CONFIG_JFFS2_FS_WRITEBUFFER is not set
 CONFIG_JFFS2_SUMMARY=y
 CONFIG_JFFS2_FS_XATTR=y
 CONFIG_UBIFS_FS=y
 CONFIG_SQUASHFS=y
 CONFIG_SQUASHFS_XZ=y
+CONFIG_SQUASHFS_ZSTD=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
 CONFIG_PRINTK_TIME=y
 CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_REDUCED=y
+CONFIG_DEBUG_INFO_DWARF4=y
+CONFIG_GDB_SCRIPTS=y
 CONFIG_STRIP_ASM_SYMS=y
-CONFIG_DEBUG_FS=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+# CONFIG_DETECT_HUNG_TASK is not set
 CONFIG_WQ_WATCHDOG=y
+CONFIG_PANIC_ON_OOPS=y
 CONFIG_PANIC_TIMEOUT=-1
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_SCHED_STACK_END_CHECK=y
-CONFIG_STACKTRACE=y
-# CONFIG_FTRACE is not set
+CONFIG_FUNCTION_TRACER=y
+# CONFIG_TRACING_EVENTS_GPIO is not set
+# CONFIG_RUNTIME_TESTING_MENU is not set
+CONFIG_DEBUG_WX=y
 CONFIG_DEBUG_USER=y
+CONFIG_HARDENED_USERCOPY=y
+CONFIG_FORTIFY_SOURCE=y
 # CONFIG_CRYPTO_ECHAINIV is not set
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_USER_API_HASH=y
 # CONFIG_CRYPTO_HW is not set
 # CONFIG_XZ_DEC_X86 is not set
 # CONFIG_XZ_DEC_POWERPC is not set
index 8c7ea033cdc2663cc39aad183c69d9ffce1fe18e..02fa3a41add5ca5dc1d5b14d48516d76a721bb53 100644 (file)
@@ -3,40 +3,47 @@ CONFIG_KERNEL_XZ=y
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
-CONFIG_LOG_BUF_SHIFT=14
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
 CONFIG_CGROUPS=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZO is not set
 # CONFIG_RD_LZ4 is not set
-CONFIG_KALLSYMS_ALL=y
-CONFIG_BPF_SYSCALL=y
+# CONFIG_UID16 is not set
+# CONFIG_SYSFS_SYSCALL is not set
 # CONFIG_AIO is not set
+CONFIG_BPF_SYSCALL=y
 CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
+CONFIG_SLAB_FREELIST_RANDOM=y
 CONFIG_JUMP_LABEL=y
+CONFIG_STRICT_KERNEL_RWX=y
 CONFIG_GCC_PLUGINS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
 # CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEBUG_FS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_MQ_IOSCHED_DEADLINE is not set
+# CONFIG_MQ_IOSCHED_KYBER is not set
 CONFIG_ARCH_MULTI_V6=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_ASPEED=y
 CONFIG_MACH_ASPEED_G5=y
 # CONFIG_CACHE_L2X0 is not set
 CONFIG_VMSPLIT_2G=y
-CONFIG_AEABI=y
-# CONFIG_CPU_SW_DOMAIN_PAN is not set
 # CONFIG_COMPACTION is not set
+CONFIG_UACCESS_WITH_MEMCPY=y
 CONFIG_SECCOMP=y
 # CONFIG_ATAGS 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_KEXEC=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_SUSPEND is not set
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_PACKET_DIAG=y
@@ -49,8 +56,14 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_ADVANCED is not set
+CONFIG_VLAN_8021Q=y
 CONFIG_NET_NCSI=y
+CONFIG_BPF_STREAM_PARSER=y
 # CONFIG_WIRELESS is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
@@ -60,11 +73,12 @@ CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_PARTITIONED_MASTER=y
 CONFIG_MTD_SPI_NOR=y
+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
 CONFIG_SPI_ASPEED_SMC=y
 CONFIG_MTD_UBI=y
 CONFIG_MTD_UBI_FASTMAP=y
 CONFIG_MTD_UBI_BLOCK=y
-CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_LOOP=y
 CONFIG_ASPEED_LPC_CTRL=y
 CONFIG_ASPEED_LPC_SNOOP=y
 CONFIG_EEPROM_AT24=y
@@ -72,18 +86,26 @@ CONFIG_NETDEVICES=y
 CONFIG_NETCONSOLE=y
 # CONFIG_NET_VENDOR_ALACRITECH is not set
 # CONFIG_NET_VENDOR_AMAZON is not set
+# CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
-# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_AURORA is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CADENCE is not set
+# CONFIG_NET_VENDOR_CAVIUM is not set
 # CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_CORTINA is not set
 # CONFIG_NET_VENDOR_EZCHIP is not set
 CONFIG_FTGMAC100=y
 # CONFIG_NET_VENDOR_HISILICON is not set
+# CONFIG_NET_VENDOR_HUAWEI is not set
 # CONFIG_NET_VENDOR_INTEL is not set
 # CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
 # CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROSEMI is not set
 # CONFIG_NET_VENDOR_NATSEMI is not set
 # CONFIG_NET_VENDOR_NETRONOME is not set
+# CONFIG_NET_VENDOR_NI is not set
 # CONFIG_NET_VENDOR_QUALCOMM is not set
 # CONFIG_NET_VENDOR_RENESAS is not set
 # CONFIG_NET_VENDOR_ROCKER is not set
@@ -91,13 +113,20 @@ CONFIG_FTGMAC100=y
 # CONFIG_NET_VENDOR_SEEQ is not set
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
 # CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_SOCIONEXT is not set
 # CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 CONFIG_BROADCOM_PHY=y
 CONFIG_REALTEK_PHY=y
+# CONFIG_USB_NET_DRIVERS is not set
 # CONFIG_WLAN is not set
-# CONFIG_INPUT is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_GPIO_POLLED=y
+# CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -110,15 +139,16 @@ CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_ASPEED_VUART=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_ASPEED_KCS_IPMI_BMC=y
 CONFIG_ASPEED_BT_IPMI_BMC=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
+CONFIG_HW_RANDOM_TIMERIOMEM=y
 # CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MUX=y
 CONFIG_I2C_MUX_PCA9541=y
 CONFIG_I2C_MUX_PCA954x=y
 CONFIG_I2C_ASPEED=y
+CONFIG_I2C_FSI=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_ASPEED=y
@@ -131,19 +161,45 @@ CONFIG_SENSORS_LM75=y
 CONFIG_SENSORS_NCT7904=y
 CONFIG_PMBUS=y
 CONFIG_SENSORS_ADM1275=y
+CONFIG_SENSORS_IBM_CFFPS=y
+CONFIG_SENSORS_IR35221=y
 CONFIG_SENSORS_LM25066=y
+CONFIG_SENSORS_MAX31785=y
 CONFIG_SENSORS_UCD9000=y
+CONFIG_SENSORS_UCD9200=y
 CONFIG_SENSORS_TMP421=y
+CONFIG_SENSORS_W83773G=y
+CONFIG_WATCHDOG_SYSFS=y
+CONFIG_DRM=y
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_DYNAMIC_MINORS=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_GADGET=y
+CONFIG_U_SERIAL_CONSOLE=y
+CONFIG_USB_ASPEED_VHUB=y
+CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_LB_SS=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_HID=y
+CONFIG_USB_CONFIGFS_F_PRINTER=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_CLASS_FLASH=y
 CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PCA955X=y
+CONFIG_LEDS_PCA955X_GPIO=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
@@ -152,33 +208,56 @@ CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_DS1307=y
 CONFIG_RTC_DRV_PCF8523=y
 CONFIG_RTC_DRV_RV8803=y
-CONFIG_MAILBOX=y
+# CONFIG_VIRTIO_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_IIO=y
 CONFIG_ASPEED_ADC=y
+CONFIG_MAX1363=y
 CONFIG_BMP280=y
+CONFIG_FSI=y
+CONFIG_FSI_MASTER_GPIO=y
+CONFIG_FSI_MASTER_HUB=y
+CONFIG_FSI_MASTER_AST_CF=y
+CONFIG_FSI_SCOM=y
+CONFIG_FSI_SBEFIFO=y
 CONFIG_FIRMWARE_MEMMAP=y
 CONFIG_FANOTIFY=y
 CONFIG_OVERLAY_FS=y
 CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
+# CONFIG_JFFS2_FS_WRITEBUFFER is not set
 CONFIG_JFFS2_SUMMARY=y
 CONFIG_JFFS2_FS_XATTR=y
 CONFIG_UBIFS_FS=y
 CONFIG_SQUASHFS=y
 CONFIG_SQUASHFS_XZ=y
+CONFIG_SQUASHFS_ZSTD=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
 CONFIG_PRINTK_TIME=y
 CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_REDUCED=y
+CONFIG_DEBUG_INFO_DWARF4=y
+CONFIG_GDB_SCRIPTS=y
 CONFIG_STRIP_ASM_SYMS=y
-CONFIG_DEBUG_FS=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+# CONFIG_DETECT_HUNG_TASK is not set
 CONFIG_WQ_WATCHDOG=y
+CONFIG_PANIC_ON_OOPS=y
 CONFIG_PANIC_TIMEOUT=-1
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_SCHED_STACK_END_CHECK=y
-CONFIG_STACKTRACE=y
-# CONFIG_FTRACE is not set
+CONFIG_FUNCTION_TRACER=y
+# CONFIG_TRACING_EVENTS_GPIO is not set
+# CONFIG_RUNTIME_TESTING_MENU is not set
+CONFIG_DEBUG_WX=y
 CONFIG_DEBUG_USER=y
+CONFIG_HARDENED_USERCOPY=y
+CONFIG_FORTIFY_SOURCE=y
 # CONFIG_CRYPTO_ECHAINIV is not set
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_USER_API_HASH=y
 # CONFIG_CRYPTO_HW is not set
 # CONFIG_XZ_DEC_X86 is not set
 # CONFIG_XZ_DEC_POWERPC is not set
index e4d188f0a4b498a8922f330c9e868d6e2bd66d3a..e9bc88937b1e43a7d84fdb0ecf445bdee3625d98 100644 (file)
@@ -86,7 +86,7 @@ CONFIG_SPI=y
 CONFIG_SPI_BCM2835=y
 CONFIG_SPI_BCM2835AUX=y
 CONFIG_GPIO_SYSFS=y
-# CONFIG_HWMON is not set
+CONFIG_SENSORS_RASPBERRYPI_HWMON=m
 CONFIG_THERMAL=y
 CONFIG_BCM2835_THERMAL=y
 CONFIG_WATCHDOG=y
index 21b2d7791df444eec304e23381e77ab36a3a0214..07b2eadac3dd5f2a9da6d4e0f3bc3a151d0a8363 100644 (file)
@@ -31,7 +31,6 @@ CONFIG_MACH_MITYOMAPL138=y
 CONFIG_MACH_OMAPL138_HAWKBOARD=y
 CONFIG_DAVINCI_MUX_DEBUG=y
 CONFIG_DAVINCI_MUX_WARNINGS=y
-CONFIG_DAVINCI_RESET_CLOCKS=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_CMA=y
@@ -54,6 +53,13 @@ CONFIG_INET=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_NETFILTER=y
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_BNEP=m
+CONFIG_BT_HIDP=m
+CONFIG_BT_LEDS=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_LL=y
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_FW_LOADER=m
@@ -113,6 +119,7 @@ CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=3
 CONFIG_SERIAL_8250_RUNTIME_UARTS=3
 CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_DEV_BUS=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
@@ -153,6 +160,7 @@ CONFIG_TINYDRM_ST7586=m
 CONFIG_FB=y
 CONFIG_FIRMWARE_EDID=y
 CONFIG_FB_DA8XX=y
+CONFIG_BACKLIGHT_PWM=m
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_LOGO=y
 CONFIG_SOUND=m
@@ -212,6 +220,7 @@ CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_OMAP=m
 CONFIG_DMADEVICES=y
 CONFIG_TI_EDMA=y
+CONFIG_COMMON_CLK_PWM=m
 CONFIG_REMOTEPROC=m
 CONFIG_DA8XX_REMOTEPROC=m
 CONFIG_MEMORY=y
index 200ebda47e0c3bee90eadd948b6f8f522fcfbedc..7eca43ff69bbed1f1d5d431a968826612812ed18 100644 (file)
@@ -81,7 +81,6 @@ CONFIG_CAN=y
 CONFIG_CAN_FLEXCAN=y
 CONFIG_BT=y
 CONFIG_BT_HCIUART=y
-CONFIG_BT_HCIUART_H4=y
 CONFIG_BT_HCIUART_LL=y
 CONFIG_CFG80211=y
 CONFIG_CFG80211_WEXT=y
@@ -258,6 +257,7 @@ CONFIG_IMX_IPUV3_CORE=y
 CONFIG_DRM=y
 CONFIG_DRM_PANEL_LVDS=y
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
 CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
 CONFIG_DRM_DW_HDMI_CEC=y
 CONFIG_DRM_IMX=y
@@ -266,7 +266,8 @@ CONFIG_DRM_IMX_TVE=y
 CONFIG_DRM_IMX_LDB=y
 CONFIG_DRM_IMX_HDMI=y
 CONFIG_DRM_ETNAVIV=y
-CONFIG_FB_MXS=y
+CONFIG_DRM_MXSFB=y
+CONFIG_FB_MODE_HELPERS=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_LCD_L4F00242T03=y
 CONFIG_LCD_PLATFORM=y
@@ -282,7 +283,6 @@ CONFIG_SND_SOC_FSL_ASRC=y
 CONFIG_SND_IMX_SOC=y
 CONFIG_SND_SOC_PHYCORE_AC97=y
 CONFIG_SND_SOC_EUKREA_TLV320=y
-CONFIG_SND_SOC_IMX_WM8962=y
 CONFIG_SND_SOC_IMX_ES8328=y
 CONFIG_SND_SOC_IMX_SGTL5000=y
 CONFIG_SND_SOC_IMX_SPDIF=y
@@ -371,13 +371,16 @@ CONFIG_DMADEVICES=y
 CONFIG_FSL_EDMA=y
 CONFIG_IMX_SDMA=y
 CONFIG_MXS_DMA=y
+CONFIG_DMATEST=m
 CONFIG_STAGING=y
 CONFIG_STAGING_MEDIA=y
 CONFIG_VIDEO_IMX_MEDIA=y
 CONFIG_COMMON_CLK_PWM=y
 CONFIG_IIO=y
+CONFIG_MMA8452=y
 CONFIG_IMX7D_ADC=y
 CONFIG_VF610_ADC=y
+CONFIG_SENSORS_ISL29018=y
 CONFIG_MAG3110=y
 CONFIG_MPL3115=y
 CONFIG_PWM=y
index 2536c231eea10ac0a48b75908d4e8f9c23c5c303..3ded35a07f45a00173c51d987a733c14033c3df3 100644 (file)
@@ -170,7 +170,10 @@ CONFIG_USB_DWC3=y
 CONFIG_NOP_USB_XCEIV=y
 CONFIG_KEYSTONE_USB_PHY=y
 CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_OMAP_HS=y
+CONFIG_MMC_SDHCI_OMAP=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_GPIO=y
@@ -235,3 +238,5 @@ CONFIG_INPUT_GPIO_DECODER=m
 CONFIG_GPIO_PCA953X=m
 CONFIG_LEDS_TRIGGER_ACTIVITY=y
 CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_MICREL_PHY=y
+CONFIG_DP83867_PHY=y
index 7c41bee284630d1403939763600975317be65325..318b76fa26d1fd54c0f8e2ea4785c576587d3b8b 100644 (file)
@@ -1,5 +1,4 @@
 CONFIG_SYSVIPC=y
-CONFIG_FHANDLE=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_LOG_BUF_SHIFT=19
@@ -11,12 +10,10 @@ CONFIG_KPROBES=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_ARCH_MULTI_V7 is not set
-CONFIG_ARCH_MVEBU=y
-CONFIG_MACH_KIRKWOOD=y
-CONFIG_ARCH_AT91=y
-CONFIG_SOC_AT91SAM9=y
 CONFIG_ARCH_ASPEED=y
 CONFIG_MACH_ASPEED_G4=y
+CONFIG_ARCH_AT91=y
+CONFIG_SOC_AT91SAM9=y
 CONFIG_ARCH_MXC=y
 CONFIG_MACH_MX21ADS=y
 CONFIG_MACH_MX27ADS=y
@@ -25,6 +22,8 @@ CONFIG_MACH_IMX27_VISSTRIM_M10=y
 CONFIG_MACH_PCA100=y
 CONFIG_MACH_IMX27_DT=y
 CONFIG_SOC_IMX25=y
+CONFIG_ARCH_MVEBU=y
+CONFIG_MACH_KIRKWOOD=y
 CONFIG_ARCH_ORION5X=y
 CONFIG_MACH_DB88F5281=y
 CONFIG_MACH_RD88F5182=y
@@ -34,7 +33,6 @@ CONFIG_MACH_DNS323=y
 CONFIG_MACH_TS209=y
 CONFIG_MACH_TERASTATION_PRO2=y
 CONFIG_MACH_LINKSTATION_PRO=y
-CONFIG_MACH_LINKSTATION_LSCHL=y
 CONFIG_MACH_LINKSTATION_MINI=y
 CONFIG_MACH_LINKSTATION_LS_HGL=y
 CONFIG_MACH_TS409=y
@@ -71,7 +69,6 @@ CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_NET_DSA=y
-CONFIG_NET_SWITCHDEV=y
 CONFIG_NET_PKTGEN=m
 CONFIG_CFG80211=y
 CONFIG_MAC80211=y
@@ -93,10 +90,14 @@ CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_ATMEL=y
 CONFIG_MTD_NAND_ORION=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_SPI_ASPEED_SMC=y
 CONFIG_MTD_UBI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_ATMEL_TCLIB=y
 CONFIG_ATMEL_SSC=m
+CONFIG_ASPEED_LPC_CTRL=m
+CONFIG_ASPEED_LPC_SNOOP=m
 CONFIG_EEPROM_AT24=y
 # CONFIG_SCSI_PROC_FS is not set
 CONFIG_BLK_DEV_SD=y
@@ -110,10 +111,11 @@ CONFIG_NET_DSA_MV88E6060=y
 CONFIG_NET_DSA_MV88E6XXX=y
 CONFIG_MACB=y
 CONFIG_DM9000=y
+CONFIG_FTGMAC100=m
 CONFIG_MV643XX_ETH=y
 CONFIG_R8169=y
-CONFIG_MARVELL_PHY=y
 CONFIG_DAVICOM_PHY=y
+CONFIG_MARVELL_PHY=y
 CONFIG_MICREL_PHY=y
 CONFIG_LIBERTAS=y
 CONFIG_LIBERTAS_SDIO=y
@@ -125,23 +127,26 @@ CONFIG_KEYBOARD_GPIO=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ADS7846=m
 CONFIG_LEGACY_PTY_COUNT=16
-# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=6
 CONFIG_SERIAL_8250_RUNTIME_UARTS=6
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_ASPEED_VUART=m
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
 CONFIG_SERIAL_ATMEL_TTYAT=y
 CONFIG_SERIAL_IMX=y
 CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_ASPEED_KCS_IPMI_BMC=m
+CONFIG_ASPEED_BT_IPMI_BMC=m
 CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
+CONFIG_HW_RANDOM_TIMERIOMEM=m
 # CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_ASPEED=m
 CONFIG_I2C_AT91=y
 CONFIG_I2C_IMX=y
 CONFIG_I2C_MV64XXX=y
@@ -150,10 +155,12 @@ CONFIG_SPI=y
 CONFIG_SPI_ATMEL=y
 CONFIG_SPI_IMX=y
 CONFIG_SPI_ORION=y
+CONFIG_GPIO_ASPEED=m
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_GPIO=y
 CONFIG_POWER_RESET_QNAP=y
 CONFIG_SENSORS_ADT7475=y
+CONFIG_SENSORS_ASPEED=y
 CONFIG_SENSORS_G762=y
 CONFIG_SENSORS_LM63=y
 CONFIG_SENSORS_LM75=y
@@ -172,11 +179,9 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_SOC_CAMERA=y
 CONFIG_VIDEO_ATMEL_ISI=m
-CONFIG_SOC_CAMERA_OV2640=m
 CONFIG_DRM=y
 CONFIG_DRM_ATMEL_HLCDC=m
 CONFIG_DRM_PANEL_SIMPLE=y
-CONFIG_FB=y
 CONFIG_FB_IMX=y
 CONFIG_FB_ATMEL=y
 CONFIG_BACKLIGHT_ATMEL_LCDC=y
@@ -246,6 +251,7 @@ CONFIG_MV_XOR=y
 CONFIG_STAGING=y
 CONFIG_FB_XGI=y
 CONFIG_IIO=m
+CONFIG_ASPEED_ADC=m
 CONFIG_AT91_ADC=m
 CONFIG_PWM=y
 CONFIG_PWM_ATMEL=m
index be732f382418c66dbd4a0de6c28bf102665c312c..fc33444e94f05c1fac99976bdeadb4b6e785fd19 100644 (file)
@@ -88,6 +88,7 @@ CONFIG_ARCH_R8A7791=y
 CONFIG_ARCH_R8A7792=y
 CONFIG_ARCH_R8A7793=y
 CONFIG_ARCH_R8A7794=y
+CONFIG_ARCH_R9A06G032=y
 CONFIG_ARCH_SH73A0=y
 CONFIG_ARCH_SOCFPGA=y
 CONFIG_PLAT_SPEAR=y
@@ -184,6 +185,7 @@ CONFIG_MTD_NAND_DENALI_DT=y
 CONFIG_MTD_NAND_OMAP2=y
 CONFIG_MTD_NAND_OMAP_BCH=y
 CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_MARVELL=y
 CONFIG_MTD_NAND_GPMI_NAND=y
 CONFIG_MTD_NAND_BRCMNAND=y
 CONFIG_MTD_NAND_VF610_NFC=y
@@ -243,6 +245,7 @@ CONFIG_KS8851=y
 CONFIG_R8169=y
 CONFIG_SH_ETH=y
 CONFIG_SMSC911X=y
+CONFIG_SNI_AVE=y
 CONFIG_STMMAC_ETH=y
 CONFIG_DWMAC_DWC_QOS_ETH=y
 CONFIG_TI_CPSW=y
@@ -447,6 +450,7 @@ CONFIG_SENSORS_LM90=y
 CONFIG_SENSORS_LM95245=y
 CONFIG_SENSORS_NTC_THERMISTOR=m
 CONFIG_SENSORS_PWM_FAN=m
+CONFIG_SENSORS_RASPBERRYPI_HWMON=m
 CONFIG_SENSORS_INA2XX=m
 CONFIG_CPU_THERMAL=y
 CONFIG_IMX_THERMAL=y
@@ -456,6 +460,7 @@ CONFIG_ARMADA_THERMAL=y
 CONFIG_BCM2835_THERMAL=m
 CONFIG_BRCMSTB_THERMAL=m
 CONFIG_ST_THERMAL_MEMMAP=y
+CONFIG_UNIPHIER_THERMAL=y
 CONFIG_WATCHDOG=y
 CONFIG_DA9063_WATCHDOG=m
 CONFIG_XILINX_WATCHDOG=y
@@ -562,6 +567,7 @@ CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_MEDIA_USB_SUPPORT=y
 CONFIG_USB_VIDEO_CLASS=m
 CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_STM32_DCMI=m
 CONFIG_SOC_CAMERA=m
 CONFIG_SOC_CAMERA_PLATFORM=m
 CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS=m
@@ -825,6 +831,7 @@ CONFIG_RTC_DRV_SUNXI=y
 CONFIG_RTC_DRV_MV=y
 CONFIG_RTC_DRV_TEGRA=y
 CONFIG_RTC_DRV_ST_LPC=y
+CONFIG_RTC_DRV_STM32=y
 CONFIG_RTC_DRV_CPCAP=m
 CONFIG_DMADEVICES=y
 CONFIG_AT_HDMAC=y
@@ -840,6 +847,9 @@ CONFIG_PL330_DMA=y
 CONFIG_SIRF_DMA=y
 CONFIG_STE_DMA40=y
 CONFIG_ST_FDMA=m
+CONFIG_STM32_DMA=y
+CONFIG_STM32_DMAMUX=y
+CONFIG_STM32_MDMA=y
 CONFIG_TEGRA20_APB_DMA=y
 CONFIG_XILINX_DMA=y
 CONFIG_QCOM_BAM_DMA=y
index ddaeda4f2e82f7349ba888f184316419f083d864..55140219ab110a88560e2bd3d259309e3fef0bde 100644 (file)
@@ -1,5 +1,4 @@
 CONFIG_SYSVIPC=y
-CONFIG_FHANDLE=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
@@ -16,10 +15,8 @@ CONFIG_MACH_ARMADA_39X=y
 CONFIG_MACH_ARMADA_XP=y
 CONFIG_MACH_DOVE=y
 CONFIG_PCI=y
-CONFIG_PCI_MSI=y
 CONFIG_PCI_MVEBU=y
 CONFIG_SMP=y
-CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 # CONFIG_COMPACTION is not set
 CONFIG_ZBOOT_ROM_TEXT=0x0
@@ -58,7 +55,6 @@ CONFIG_MTD_M25P80=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_MARVELL=y
 CONFIG_MTD_SPI_NOR=y
-CONFIG_SRAM=y
 CONFIG_MTD_UBI=y
 CONFIG_EEPROM_AT24=y
 CONFIG_BLK_DEV_SD=y
@@ -67,12 +63,11 @@ CONFIG_SATA_AHCI=y
 CONFIG_AHCI_MVEBU=y
 CONFIG_SATA_MV=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_DSA_MV88E6XXX=y
 CONFIG_MV643XX_ETH=y
 CONFIG_MVNETA=y
 CONFIG_MVPP2=y
+CONFIG_SFP=y
 CONFIG_MARVELL_PHY=y
-CONFIG_FIXED_PHY=y
 CONFIG_MWIFIEX=y
 CONFIG_MWIFIEX_SDIO=y
 CONFIG_INPUT_EVDEV=y
@@ -88,10 +83,11 @@ CONFIG_SPI=y
 CONFIG_SPI_ORION=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PCA953X=y
-CONFIG_POWER_SUPPLY=y
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_SUPPLY=y
 CONFIG_SENSORS_GPIO_FAN=y
+CONFIG_SENSORS_PWM_FAN=y
 CONFIG_THERMAL=y
 CONFIG_ARMADA_THERMAL=y
 CONFIG_WATCHDOG=y
@@ -135,7 +131,6 @@ CONFIG_MV_XOR=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_MEMORY=y
 CONFIG_PWM=y
-CONFIG_SENSORS_PWM_FAN=y
 CONFIG_EXT4_FS=y
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
@@ -153,10 +148,8 @@ CONFIG_NLS_ISO8859_2=y
 CONFIG_NLS_UTF8=y
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_FS=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_SCHED_DEBUG is not set
-CONFIG_TIMER_STATS=y
 # CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_DEBUG_USER=y
 CONFIG_CRYPTO_DEV_MARVELL_CESA=y
index a508eb302e7a0bcb1493746a571cdab0f39db876..7b82128575351c9285ca5137e79ed73b9741462c 100644 (file)
@@ -94,8 +94,10 @@ CONFIG_STMP3XXX_RTC_WATCHDOG=y
 CONFIG_MFD_MXS_LRADC=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_FB=y
-CONFIG_FB_MXS=y
+CONFIG_DRM=y
+CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
+CONFIG_DRM_MXSFB=y
+CONFIG_FB_MODE_HELPERS=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
index dd2a089f939fc68a46d0194d7ad6079d94b621eb..6aa7046fb91ffeba3e67ab481e730da1ec8e8fa4 100644 (file)
@@ -57,6 +57,8 @@ CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_QCOM=y
 CONFIG_MTD_SPI_NOR=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
index 09b5a738641402af4584411b78c98cbb551341e8..a077597369f18f5bae5937f14686bc987d19f647 100644 (file)
@@ -1,5 +1,7 @@
+CONFIG_SYSVIPC=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_CGROUPS=y
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
@@ -13,28 +15,68 @@ CONFIG_SOLARIS_X86_PARTITION=y
 CONFIG_ARCH_S5PV210=y
 CONFIG_VMSPLIT_2G=y
 CONFIG_PREEMPT=y
-CONFIG_AEABI=y
+CONFIG_ARM_APPENDED_DTB=y
 CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
 CONFIG_VFP=y
 CONFIG_NEON=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
+CONFIG_NETDEVICES=y
+CONFIG_BRCMFMAC=m
 CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_SAMSUNG=y
 CONFIG_SERIAL_SAMSUNG_CONSOLE=y
 CONFIG_HW_RANDOM=y
+CONFIG_I2C_GPIO=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_MAX17040=y
 # CONFIG_HWMON is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_MFD_MAX8998=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_MAX8998=y
+CONFIG_DRM=y
+CONFIG_DRM_EXYNOS=y
+CONFIG_DRM_EXYNOS_FIMD=y
+CONFIG_DRM_EXYNOS_DPI=y
+CONFIG_USB=y
+CONFIG_USB_OTG=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EXYNOS=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_EXYNOS=y
+CONFIG_USB_DWC2=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_S3C=y
+CONFIG_MMC_SDHCI_S3C_DMA=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_MAX8998=m
+CONFIG_PHY_SAMSUNG_USB2=m
+CONFIG_PHY_S5PV210_USB2=y
 CONFIG_EXT2_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_AUTOFS4_FS=y
 CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
@@ -44,6 +86,7 @@ CONFIG_ROMFS_FS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=y
 CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
 CONFIG_DEBUG_INFO=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
index b49887e86a3d82ead3f18aeed5bedd70494e0e0d..f8faf37294647789d6055ba464119cb707556a41 100644 (file)
@@ -22,6 +22,7 @@ CONFIG_ARCH_R8A7791=y
 CONFIG_ARCH_R8A7792=y
 CONFIG_ARCH_R8A7793=y
 CONFIG_ARCH_R8A7794=y
+CONFIG_ARCH_R9A06G032=y
 CONFIG_ARCH_SH73A0=y
 CONFIG_PL310_ERRATA_588369=y
 CONFIG_ARM_ERRATA_754322=y
@@ -57,7 +58,6 @@ CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_CAN=y
 CONFIG_CAN_RCAR=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_DMA_CMA=y
@@ -72,22 +72,9 @@ 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_RAVB=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_MICREL_PHY=y
 CONFIG_SMSC_PHY=y
 CONFIG_INPUT_EVDEV=y
@@ -100,6 +87,7 @@ CONFIG_INPUT_ADXL34X=y
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_DW=y
 CONFIG_SERIAL_8250_EM=y
 CONFIG_SERIAL_SH_SCI=y
 CONFIG_I2C_CHARDEV=y
@@ -205,6 +193,7 @@ CONFIG_AK8975=y
 CONFIG_PWM=y
 CONFIG_PWM_RCAR=y
 CONFIG_PWM_RENESAS_TPU=y
+CONFIG_RESET_CONTROLLER=y
 CONFIG_GENERIC_PHY=y
 CONFIG_PHY_RCAR_GEN2=y
 # CONFIG_DNOTIFY is not set
index df68dc4056e5770253b2995cc54263d20ef8e62f..5282324c7cefba5d9fc11c8c79b6a723053bc1b3 100644 (file)
@@ -5,19 +5,19 @@ CONFIG_HIGH_RES_TIMERS=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_PARTITION_ADVANCED=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_VERSATILE=y
 CONFIG_AEABI=y
 CONFIG_OABI_COMPAT=y
-CONFIG_CMA=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CMDLINE="root=1f03 mem=32M"
 CONFIG_FPE_NWFPE=y
 CONFIG_VFP=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_CMA=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -59,6 +59,7 @@ CONFIG_GPIO_PL061=y
 CONFIG_DRM=y
 CONFIG_DRM_PANEL_ARM_VERSATILE=y
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_DUMB_VGA_DAC=y
 CONFIG_DRM_PL111=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
@@ -89,9 +90,10 @@ CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
 CONFIG_NLS_CODEPAGE_850=m
 CONFIG_NLS_ISO8859_1=m
+CONFIG_FONTS=y
+CONFIG_FONT_ACORN_8x8=y
+CONFIG_DEBUG_FS=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_LL=y
-CONFIG_FONTS=y
-CONFIG_FONT_ACORN_8x8=y
index bf8ccff2c9d06ef6bcdf5fb23abfeb84660c3ca4..0ae900e778f3ba5fab9bfd9c5eaeecbf3a293aaf 100644 (file)
@@ -2,7 +2,7 @@
  * Glue code for the SHA256 Secure Hash Algorithm assembly implementation
  * using optimized ARM assembler and NEON instructions.
  *
- * Copyright © 2015 Google Inc.
+ * Copyright Â© 2015 Google Inc.
  *
  * This file is based on sha256_ssse3_glue.c:
  *   Copyright (C) 2013 Intel Corporation
index 9bbee56fbdc841e72b250b6a319898e4da1ddc93..1d82c6cd31a41c9974816adcdb605112fb274318 100644 (file)
@@ -2,10 +2,10 @@
  * Glue code for the SHA256 Secure Hash Algorithm assembly implementation
  * using NEON instructions.
  *
- * Copyright © 2015 Google Inc.
+ * Copyright Â© 2015 Google Inc.
  *
  * This file is based on sha512_neon_glue.c:
- *   Copyright © 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *   Copyright Â© 2014 Jussi Kivilinna <jussi.kivilinna@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
index 3fb1b5a1dce968d028c8f17057c277e29302caaf..689e6565abfc4bea48e9425901387d6a096ed9d5 100644 (file)
 
 static unsigned long cpu_boot_addr;
 
-static void __naked tf_generic_smc(u32 type, u32 arg1, u32 arg2)
+static void tf_generic_smc(u32 type, u32 arg1, u32 arg2)
 {
+       register u32 r0 asm("r0") = type;
+       register u32 r1 asm("r1") = arg1;
+       register u32 r2 asm("r2") = arg2;
+
        asm volatile(
                ".arch_extension        sec\n\t"
-               "stmfd  sp!, {r4 - r11, lr}\n\t"
+               "stmfd  sp!, {r4 - r11}\n\t"
                __asmeq("%0", "r0")
                __asmeq("%1", "r1")
                __asmeq("%2", "r2")
                "mov    r3, #0\n\t"
                "mov    r4, #0\n\t"
                "smc    #0\n\t"
-               "ldmfd  sp!, {r4 - r11, pc}"
+               "ldmfd  sp!, {r4 - r11}\n\t"
                :
-               : "r" (type), "r" (arg1), "r" (arg2)
-               : "memory");
+               : "r" (r0), "r" (r1), "r" (r2)
+               : "memory", "r3", "r12", "lr");
 }
 
 static int tf_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
index fe2fb1ddd7715bc55182f20f47cd4bd35d40a88d..77121b713bef3adbc4b2c77c559dab1886dec96b 100644 (file)
@@ -107,9 +107,19 @@ static inline unsigned long *vcpu_hcr(const struct kvm_vcpu *vcpu)
        return (unsigned long *)&vcpu->arch.hcr;
 }
 
+static inline void vcpu_clear_wfe_traps(struct kvm_vcpu *vcpu)
+{
+       vcpu->arch.hcr &= ~HCR_TWE;
+}
+
+static inline void vcpu_set_wfe_traps(struct kvm_vcpu *vcpu)
+{
+       vcpu->arch.hcr |= HCR_TWE;
+}
+
 static inline bool vcpu_mode_is_32bit(const struct kvm_vcpu *vcpu)
 {
-       return 1;
+       return true;
 }
 
 static inline unsigned long *vcpu_pc(struct kvm_vcpu *vcpu)
index 1f1fe4109b026690ab80ca0d3e31355f77e78f04..3ad482d2f1eb91c8bfe6b597788e1e70b9521234 100644 (file)
@@ -216,9 +216,13 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
 int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
 unsigned long kvm_call_hyp(void *hypfn, ...);
 void force_vm_exit(const cpumask_t *mask);
+int __kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
+                             struct kvm_vcpu_events *events);
+
+int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
+                             struct kvm_vcpu_events *events);
 
 #define KVM_ARCH_WANT_MMU_NOTIFIER
-int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
 int kvm_unmap_hva_range(struct kvm *kvm,
                        unsigned long start, unsigned long end);
 void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
index 8553d68b7c8a2ac34ec7b22daa44400c1c3b5958..265ea9cf7df773bf7d49926d3eed34be25032463 100644 (file)
@@ -75,17 +75,9 @@ phys_addr_t kvm_get_idmap_vector(void);
 int kvm_mmu_init(void);
 void kvm_clear_hyp_idmap(void);
 
-static inline void kvm_set_pmd(pmd_t *pmd, pmd_t new_pmd)
-{
-       *pmd = new_pmd;
-       dsb(ishst);
-}
-
-static inline void kvm_set_pte(pte_t *pte, pte_t new_pte)
-{
-       *pte = new_pte;
-       dsb(ishst);
-}
+#define kvm_mk_pmd(ptep)       __pmd(__pa(ptep) | PMD_TYPE_TABLE)
+#define kvm_mk_pud(pmdp)       __pud(__pa(pmdp) | PMD_TYPE_TABLE)
+#define kvm_mk_pgd(pudp)       ({ BUILD_BUG(); 0; })
 
 static inline pte_t kvm_s2pte_mkwrite(pte_t pte)
 {
index 97820a8df51ae7456c4f53a97fd5e8744ac4d25a..1c5f795587fc5681bc126dad8a44c7a26ad32f00 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Renesas SCIF(A) debugging macro include header
  *
@@ -5,10 +6,6 @@
  *
  * Copyright (C) 2012-2013 Renesas Electronics Corporation
  * Copyright (C) 1994-1999 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.
  */
 
 #define SCIF_PHYS      CONFIG_DEBUG_UART_PHYS
index 16e006f708ca0cbd44a63135bb996b8db7c3ba9e..4602464ebdfbfccd9296593ed5dd8b15f55305ff 100644 (file)
@@ -27,6 +27,7 @@
 #define __KVM_HAVE_GUEST_DEBUG
 #define __KVM_HAVE_IRQ_LINE
 #define __KVM_HAVE_READONLY_MEM
+#define __KVM_HAVE_VCPU_EVENTS
 
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
 
@@ -125,6 +126,18 @@ struct kvm_sync_regs {
 struct kvm_arch_memory_slot {
 };
 
+/* for KVM_GET/SET_VCPU_EVENTS */
+struct kvm_vcpu_events {
+       struct {
+               __u8 serror_pending;
+               __u8 serror_has_esr;
+               /* Align it to 8 bytes */
+               __u8 pad[6];
+               __u64 serror_esr;
+       } exception;
+       __u32 reserved[12];
+};
+
 /* If you need to interpret the index values, here is the key: */
 #define KVM_REG_ARM_COPROC_MASK                0x000000000FFF0000
 #define KVM_REG_ARM_COPROC_SHIFT       16
index 974d8d7d1bcdd2a68e101296a4fd9649cb4cebe9..3968d6c22455be5057909ea4d928f7ee0054e1a2 100644 (file)
 #error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32
 #endif
 /*
- * GCC 3.0, 3.1: general bad code generation.
- * GCC 3.2.0: incorrect function argument offset calculation.
- * GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c
- *            (http://gcc.gnu.org/PR8896) and incorrect structure
- *           initialisation in fs/jffs2/erase.c
  * GCC 4.8.0-4.8.2: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58854
  *           miscompiles find_get_entry(), and can result in EXT3 and EXT4
  *           filesystem corruption (possibly other FS too).
  */
-#ifdef __GNUC__
-#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
-#error Your compiler is too buggy; it is known to miscompile kernels.
-#error    Known good compilers: 3.3, 4.x
-#endif
-#if GCC_VERSION >= 40800 && GCC_VERSION < 40803
+#if defined(GCC_VERSION) && GCC_VERSION >= 40800 && GCC_VERSION < 40803
 #error Your compiler is too buggy; it is known to miscompile kernels
 #error and result in filesystem corruption and oopses.
 #endif
-#endif
 
 int main(void)
 {
index d9c2991331111617cc3fce04f38fe17fd1a78f6d..82ab015bf42b7bf263cd13d61274e6f4e899d9db 100644 (file)
@@ -330,16 +330,15 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
  * atomic helpers. Insert it into the gate_vma so that it is visible
  * through ptrace and /proc/<pid>/mem.
  */
-static struct vm_area_struct gate_vma = {
-       .vm_start       = 0xffff0000,
-       .vm_end         = 0xffff0000 + PAGE_SIZE,
-       .vm_flags       = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC,
-};
+static struct vm_area_struct gate_vma;
 
 static int __init gate_vma_init(void)
 {
        vma_init(&gate_vma, NULL);
        gate_vma.vm_page_prot = PAGE_READONLY_EXEC;
+       gate_vma.vm_start = 0xffff0000;
+       gate_vma.vm_end = 0xffff0000 + PAGE_SIZE;
+       gate_vma.vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
        return 0;
 }
 arch_initcall(gate_vma_init);
index 3a02e76699a635849d9a3bc1e95d3ef3b76387a5..450c7a4fbc8a15b10bfd0a7e73b0878291e392c9 100644 (file)
@@ -246,6 +246,7 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu,
                           const struct coproc_reg *r)
 {
        u64 reg;
+       bool g1;
 
        if (!p->is_write)
                return read_from_write_only(vcpu, p);
@@ -253,7 +254,25 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu,
        reg = (u64)*vcpu_reg(vcpu, p->Rt2) << 32;
        reg |= *vcpu_reg(vcpu, p->Rt1) ;
 
-       vgic_v3_dispatch_sgi(vcpu, reg);
+       /*
+        * In a system where GICD_CTLR.DS=1, a ICC_SGI0R access generates
+        * Group0 SGIs only, while ICC_SGI1R can generate either group,
+        * depending on the SGI configuration. ICC_ASGI1R is effectively
+        * equivalent to ICC_SGI0R, as there is no "alternative" secure
+        * group.
+        */
+       switch (p->Op1) {
+       default:                /* Keep GCC quiet */
+       case 0:                 /* ICC_SGI1R */
+               g1 = true;
+               break;
+       case 1:                 /* ICC_ASGI1R */
+       case 2:                 /* ICC_SGI0R */
+               g1 = false;
+               break;
+       }
+
+       vgic_v3_dispatch_sgi(vcpu, reg, g1);
 
        return true;
 }
@@ -459,6 +478,10 @@ static const struct coproc_reg cp15_regs[] = {
 
        /* ICC_SGI1R */
        { CRm64(12), Op1( 0), is64, access_gic_sgi},
+       /* ICC_ASGI1R */
+       { CRm64(12), Op1( 1), is64, access_gic_sgi},
+       /* ICC_SGI0R */
+       { CRm64(12), Op1( 2), is64, access_gic_sgi},
 
        /* VBAR: swapped by interrupt.S. */
        { CRn(12), CRm( 0), Op1( 0), Op2( 0), is32,
index a18f33edc471a92fcf6194dbe6601bc4b94f1988..2b8de885b2bf6b8e61ffd1c67adf72a56167633a 100644 (file)
@@ -261,6 +261,29 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
        return -EINVAL;
 }
 
+
+int __kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
+                             struct kvm_vcpu_events *events)
+{
+       events->exception.serror_pending = !!(*vcpu_hcr(vcpu) & HCR_VA);
+
+       return 0;
+}
+
+int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
+                             struct kvm_vcpu_events *events)
+{
+       bool serror_pending = events->exception.serror_pending;
+       bool has_esr = events->exception.serror_has_esr;
+
+       if (serror_pending && has_esr)
+               return -EINVAL;
+       else if (serror_pending)
+               kvm_inject_vabt(vcpu);
+
+       return 0;
+}
+
 int __attribute_const__ kvm_target_cpu(void)
 {
        switch (read_cpuid_part()) {
index 849014c01cf4d62a465ec6e54b829d4ff45f05a6..32fae4dbd63bac62391928de43831520c0bb39bc 100644 (file)
@@ -40,15 +40,16 @@ extern void at91_pinctrl_gpio_resume(void);
 #endif
 
 static const match_table_t pm_modes __initconst = {
-       { 0, "standby" },
-       { AT91_PM_SLOW_CLOCK, "ulp0" },
+       { AT91_PM_STANDBY, "standby" },
+       { AT91_PM_ULP0, "ulp0" },
+       { AT91_PM_ULP1, "ulp1" },
        { AT91_PM_BACKUP, "backup" },
        { -1, NULL },
 };
 
 static struct at91_pm_data pm_data = {
-       .standby_mode = 0,
-       .suspend_mode = AT91_PM_SLOW_CLOCK,
+       .standby_mode = AT91_PM_STANDBY,
+       .suspend_mode = AT91_PM_ULP0,
 };
 
 #define at91_ramc_read(id, field) \
@@ -79,6 +80,90 @@ static struct at91_pm_bu {
        phys_addr_t resume;
 } *pm_bu;
 
+struct wakeup_source_info {
+       unsigned int pmc_fsmr_bit;
+       unsigned int shdwc_mr_bit;
+       bool set_polarity;
+};
+
+static const struct wakeup_source_info ws_info[] = {
+       { .pmc_fsmr_bit = AT91_PMC_FSTT(10),    .set_polarity = true },
+       { .pmc_fsmr_bit = AT91_PMC_RTCAL,       .shdwc_mr_bit = BIT(17) },
+       { .pmc_fsmr_bit = AT91_PMC_USBAL },
+       { .pmc_fsmr_bit = AT91_PMC_SDMMC_CD },
+};
+
+static const struct of_device_id sama5d2_ws_ids[] = {
+       { .compatible = "atmel,sama5d2-gem",            .data = &ws_info[0] },
+       { .compatible = "atmel,at91rm9200-rtc",         .data = &ws_info[1] },
+       { .compatible = "atmel,sama5d3-udc",            .data = &ws_info[2] },
+       { .compatible = "atmel,at91rm9200-ohci",        .data = &ws_info[2] },
+       { .compatible = "usb-ohci",                     .data = &ws_info[2] },
+       { .compatible = "atmel,at91sam9g45-ehci",       .data = &ws_info[2] },
+       { .compatible = "usb-ehci",                     .data = &ws_info[2] },
+       { .compatible = "atmel,sama5d2-sdhci",          .data = &ws_info[3] },
+       { /* sentinel */ }
+};
+
+static int at91_pm_config_ws(unsigned int pm_mode, bool set)
+{
+       const struct wakeup_source_info *wsi;
+       const struct of_device_id *match;
+       struct platform_device *pdev;
+       struct device_node *np;
+       unsigned int mode = 0, polarity = 0, val = 0;
+
+       if (pm_mode != AT91_PM_ULP1)
+               return 0;
+
+       if (!pm_data.pmc || !pm_data.shdwc)
+               return -EPERM;
+
+       if (!set) {
+               writel(mode, pm_data.pmc + AT91_PMC_FSMR);
+               return 0;
+       }
+
+       /* SHDWC.WUIR */
+       val = readl(pm_data.shdwc + 0x0c);
+       mode |= (val & 0x3ff);
+       polarity |= ((val >> 16) & 0x3ff);
+
+       /* SHDWC.MR */
+       val = readl(pm_data.shdwc + 0x04);
+
+       /* Loop through defined wakeup sources. */
+       for_each_matching_node_and_match(np, sama5d2_ws_ids, &match) {
+               pdev = of_find_device_by_node(np);
+               if (!pdev)
+                       continue;
+
+               if (device_may_wakeup(&pdev->dev)) {
+                       wsi = match->data;
+
+                       /* Check if enabled on SHDWC. */
+                       if (wsi->shdwc_mr_bit && !(val & wsi->shdwc_mr_bit))
+                               goto put_node;
+
+                       mode |= wsi->pmc_fsmr_bit;
+                       if (wsi->set_polarity)
+                               polarity |= wsi->pmc_fsmr_bit;
+               }
+
+put_node:
+               of_node_put(np);
+       }
+
+       if (mode) {
+               writel(mode, pm_data.pmc + AT91_PMC_FSMR);
+               writel(polarity, pm_data.pmc + AT91_PMC_FSPR);
+       } else {
+               pr_err("AT91: PM: no ULP1 wakeup sources found!");
+       }
+
+       return mode ? 0 : -EPERM;
+}
+
 /*
  * Called after processes are frozen, but before we shutdown devices.
  */
@@ -97,7 +182,7 @@ static int at91_pm_begin(suspend_state_t state)
                pm_data.mode = -1;
        }
 
-       return 0;
+       return at91_pm_config_ws(pm_data.mode, true);
 }
 
 /*
@@ -145,7 +230,7 @@ static int at91_pm_verify_clocks(void)
  */
 int at91_suspend_entering_slow_clock(void)
 {
-       return (pm_data.mode >= AT91_PM_SLOW_CLOCK);
+       return (pm_data.mode >= AT91_PM_ULP0);
 }
 EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
 
@@ -186,7 +271,7 @@ static void at91_pm_suspend(suspend_state_t state)
  * event sources; and reduces DRAM power.  But otherwise it's identical to
  * PM_SUSPEND_ON: cpu idle, and nothing fancy done with main or cpu clocks.
  *
- * AT91_PM_SLOW_CLOCK is like STANDBY plus slow clock mode, so drivers must
+ * AT91_PM_ULP0 is like STANDBY plus slow clock mode, so drivers must
  * suspend more deeply, the master clock switches to the clk32k and turns off
  * the main oscillator
  *
@@ -204,7 +289,7 @@ static int at91_pm_enter(suspend_state_t state)
                /*
                 * Ensure that clocks are in a valid state.
                 */
-               if ((pm_data.mode >= AT91_PM_SLOW_CLOCK) &&
+               if (pm_data.mode >= AT91_PM_ULP0 &&
                    !at91_pm_verify_clocks())
                        goto error;
 
@@ -233,6 +318,7 @@ error:
  */
 static void at91_pm_end(void)
 {
+       at91_pm_config_ws(pm_data.mode, false);
 }
 
 
@@ -478,31 +564,28 @@ static void __init at91_pm_sram_init(void)
                        &at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz);
 }
 
-static void __init at91_pm_backup_init(void)
+static bool __init at91_is_pm_mode_active(int pm_mode)
+{
+       return (pm_data.standby_mode == pm_mode ||
+               pm_data.suspend_mode == pm_mode);
+}
+
+static int __init at91_pm_backup_init(void)
 {
        struct gen_pool *sram_pool;
        struct device_node *np;
        struct platform_device *pdev = NULL;
+       int ret = -ENODEV;
 
-       if ((pm_data.standby_mode != AT91_PM_BACKUP) &&
-           (pm_data.suspend_mode != AT91_PM_BACKUP))
-               return;
+       if (!at91_is_pm_mode_active(AT91_PM_BACKUP))
+               return 0;
 
        pm_bu = NULL;
 
-       np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-shdwc");
-       if (!np) {
-               pr_warn("%s: failed to find shdwc!\n", __func__);
-               return;
-       }
-
-       pm_data.shdwc = of_iomap(np, 0);
-       of_node_put(np);
-
        np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu");
        if (!np) {
                pr_warn("%s: failed to find sfrbu!\n", __func__);
-               goto sfrbu_fail;
+               return ret;
        }
 
        pm_data.sfrbu = of_iomap(np, 0);
@@ -529,6 +612,7 @@ static void __init at91_pm_backup_init(void)
        pm_bu = (void *)gen_pool_alloc(sram_pool, sizeof(struct at91_pm_bu));
        if (!pm_bu) {
                pr_warn("%s: unable to alloc securam!\n", __func__);
+               ret = -ENOMEM;
                goto securam_fail;
        }
 
@@ -536,19 +620,60 @@ static void __init at91_pm_backup_init(void)
        pm_bu->canary = __pa_symbol(&canary);
        pm_bu->resume = __pa_symbol(cpu_resume);
 
-       return;
+       return 0;
 
-sfrbu_fail:
-       iounmap(pm_data.shdwc);
-       pm_data.shdwc = NULL;
 securam_fail:
        iounmap(pm_data.sfrbu);
        pm_data.sfrbu = NULL;
+       return ret;
+}
 
-       if (pm_data.standby_mode == AT91_PM_BACKUP)
-               pm_data.standby_mode = AT91_PM_SLOW_CLOCK;
-       if (pm_data.suspend_mode == AT91_PM_BACKUP)
-               pm_data.suspend_mode = AT91_PM_SLOW_CLOCK;
+static void __init at91_pm_use_default_mode(int pm_mode)
+{
+       if (pm_mode != AT91_PM_ULP1 && pm_mode != AT91_PM_BACKUP)
+               return;
+
+       if (pm_data.standby_mode == pm_mode)
+               pm_data.standby_mode = AT91_PM_ULP0;
+       if (pm_data.suspend_mode == pm_mode)
+               pm_data.suspend_mode = AT91_PM_ULP0;
+}
+
+static void __init at91_pm_modes_init(void)
+{
+       struct device_node *np;
+       int ret;
+
+       if (!at91_is_pm_mode_active(AT91_PM_BACKUP) &&
+           !at91_is_pm_mode_active(AT91_PM_ULP1))
+               return;
+
+       np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-shdwc");
+       if (!np) {
+               pr_warn("%s: failed to find shdwc!\n", __func__);
+               goto ulp1_default;
+       }
+
+       pm_data.shdwc = of_iomap(np, 0);
+       of_node_put(np);
+
+       ret = at91_pm_backup_init();
+       if (ret) {
+               if (!at91_is_pm_mode_active(AT91_PM_ULP1))
+                       goto unmap;
+               else
+                       goto backup_default;
+       }
+
+       return;
+
+unmap:
+       iounmap(pm_data.shdwc);
+       pm_data.shdwc = NULL;
+ulp1_default:
+       at91_pm_use_default_mode(AT91_PM_ULP1);
+backup_default:
+       at91_pm_use_default_mode(AT91_PM_BACKUP);
 }
 
 struct pmc_info {
@@ -559,15 +684,20 @@ static const struct pmc_info pmc_infos[] __initconst = {
        { .uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP },
        { .uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP },
        { .uhp_udp_mask = AT91SAM926x_PMC_UHP },
+       { .uhp_udp_mask = 0 },
 };
 
 static const struct of_device_id atmel_pmc_ids[] __initconst = {
        { .compatible = "atmel,at91rm9200-pmc", .data = &pmc_infos[0] },
        { .compatible = "atmel,at91sam9260-pmc", .data = &pmc_infos[1] },
+       { .compatible = "atmel,at91sam9261-pmc", .data = &pmc_infos[1] },
+       { .compatible = "atmel,at91sam9263-pmc", .data = &pmc_infos[1] },
        { .compatible = "atmel,at91sam9g45-pmc", .data = &pmc_infos[2] },
        { .compatible = "atmel,at91sam9n12-pmc", .data = &pmc_infos[1] },
+       { .compatible = "atmel,at91sam9rl-pmc", .data = &pmc_infos[3] },
        { .compatible = "atmel,at91sam9x5-pmc", .data = &pmc_infos[1] },
        { .compatible = "atmel,sama5d3-pmc", .data = &pmc_infos[1] },
+       { .compatible = "atmel,sama5d4-pmc", .data = &pmc_infos[1] },
        { .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] },
        { /* sentinel */ },
 };
@@ -644,7 +774,7 @@ void __init sama5d2_pm_init(void)
        if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
                return;
 
-       at91_pm_backup_init();
+       at91_pm_modes_init();
        sama5_pm_init();
 }
 
index f95d31496f08f496242798b7d26911b1098ef363..9bd4e6ca672a3dadfffb9ada1ccc0440f9684eb9 100644 (file)
 #define AT91_MEMCTRL_SDRAMC    1
 #define AT91_MEMCTRL_DDRSDR    2
 
-#define        AT91_PM_SLOW_CLOCK      0x01
-#define        AT91_PM_BACKUP          0x02
+#define        AT91_PM_STANDBY         0x00
+#define AT91_PM_ULP0           0x01
+#define AT91_PM_ULP1           0x02
+#define        AT91_PM_BACKUP          0x03
 
 #ifndef __ASSEMBLY__
 struct at91_pm_data {
index daca91feea6a2603bf45822684adfcd5cf3e9c83..a7c6ae13c9453eb36d54ea3c44bf8bf4430867e2 100644 (file)
@@ -41,6 +41,15 @@ tmp2 .req    r5
        beq     1b
        .endm
 
+/*
+ * Wait for main oscillator selection is done
+ */
+       .macro wait_moscsels
+1:     ldr     tmp1, [pmc, #AT91_PMC_SR]
+       tst     tmp1, #AT91_PMC_MOSCSELS
+       beq     1b
+       .endm
+
 /*
  * Wait until PLLA has locked.
  */
@@ -112,19 +121,20 @@ ENTRY(at91_pm_suspend_in_sram)
        bl      at91_sramc_self_refresh
 
        ldr     r0, .pm_mode
-       cmp     r0, #AT91_PM_SLOW_CLOCK
-       beq     slow_clock
+       cmp     r0, #AT91_PM_STANDBY
+       beq     standby
        cmp     r0, #AT91_PM_BACKUP
        beq     backup_mode
 
+       bl      at91_ulp_mode
+       b       exit_suspend
+
+standby:
        /* Wait for interrupt */
        ldr     pmc, .pmc_base
        at91_cpu_idle
        b       exit_suspend
 
-slow_clock:
-       bl      at91_slowck_mode
-       b       exit_suspend
 backup_mode:
        bl      at91_backup_mode
        b       exit_suspend
@@ -151,7 +161,102 @@ ENTRY(at91_backup_mode)
        str     tmp1, [r0, #0]
 ENDPROC(at91_backup_mode)
 
-ENTRY(at91_slowck_mode)
+.macro at91_pm_ulp0_mode
+       ldr     pmc, .pmc_base
+
+       /* Turn off the crystal oscillator */
+       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
+       bic     tmp1, tmp1, #AT91_PMC_MOSCEN
+       orr     tmp1, tmp1, #AT91_PMC_KEY
+       str     tmp1, [pmc, #AT91_CKGR_MOR]
+
+       /* Wait for interrupt */
+       at91_cpu_idle
+
+       /* Turn on the crystal oscillator */
+       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
+       orr     tmp1, tmp1, #AT91_PMC_MOSCEN
+       orr     tmp1, tmp1, #AT91_PMC_KEY
+       str     tmp1, [pmc, #AT91_CKGR_MOR]
+
+       wait_moscrdy
+.endm
+
+/**
+ * Note: This procedure only applies on the platform which uses
+ * the external crystal oscillator as a main clock source.
+ */
+.macro at91_pm_ulp1_mode
+       ldr     pmc, .pmc_base
+
+       /* Switch the main clock source to 12-MHz RC oscillator */
+       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
+       bic     tmp1, tmp1, #AT91_PMC_MOSCSEL
+       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
+       orr     tmp1, tmp1, #AT91_PMC_KEY
+       str     tmp1, [pmc, #AT91_CKGR_MOR]
+
+       wait_moscsels
+
+       /* Disable the crystal oscillator */
+       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
+       bic     tmp1, tmp1, #AT91_PMC_MOSCEN
+       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
+       orr     tmp1, tmp1, #AT91_PMC_KEY
+       str     tmp1, [pmc, #AT91_CKGR_MOR]
+
+       /* Switch the master clock source to main clock */
+       ldr     tmp1, [pmc, #AT91_PMC_MCKR]
+       bic     tmp1, tmp1, #AT91_PMC_CSS
+       orr     tmp1, tmp1, #AT91_PMC_CSS_MAIN
+       str     tmp1, [pmc, #AT91_PMC_MCKR]
+
+       wait_mckrdy
+
+       /* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */
+       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
+       orr     tmp1, tmp1, #AT91_PMC_WAITMODE
+       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
+       orr     tmp1, tmp1, #AT91_PMC_KEY
+       str     tmp1, [pmc, #AT91_CKGR_MOR]
+
+       wait_mckrdy
+
+       /* Enable the crystal oscillator */
+       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
+       orr     tmp1, tmp1, #AT91_PMC_MOSCEN
+       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
+       orr     tmp1, tmp1, #AT91_PMC_KEY
+       str     tmp1, [pmc, #AT91_CKGR_MOR]
+
+       wait_moscrdy
+
+       /* Switch the master clock source to slow clock */
+       ldr     tmp1, [pmc, #AT91_PMC_MCKR]
+       bic     tmp1, tmp1, #AT91_PMC_CSS
+       str     tmp1, [pmc, #AT91_PMC_MCKR]
+
+       wait_mckrdy
+
+       /* Switch main clock source to crystal oscillator */
+       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
+       orr     tmp1, tmp1, #AT91_PMC_MOSCSEL
+       bic     tmp1, tmp1, #AT91_PMC_KEY_MASK
+       orr     tmp1, tmp1, #AT91_PMC_KEY
+       str     tmp1, [pmc, #AT91_CKGR_MOR]
+
+       wait_moscsels
+
+       /* Switch the master clock source to main clock */
+       ldr     tmp1, [pmc, #AT91_PMC_MCKR]
+       bic     tmp1, tmp1, #AT91_PMC_CSS
+       orr     tmp1, tmp1, #AT91_PMC_CSS_MAIN
+       str     tmp1, [pmc, #AT91_PMC_MCKR]
+
+       wait_mckrdy
+.endm
+
+ENTRY(at91_ulp_mode)
        ldr     pmc, .pmc_base
 
        /* Save Master clock setting */
@@ -174,22 +279,19 @@ ENTRY(at91_slowck_mode)
        orr     tmp1, tmp1, #(1 << 29)          /* bit 29 always set */
        str     tmp1, [pmc, #AT91_CKGR_PLLAR]
 
-       /* Turn off the main oscillator */
-       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
-       bic     tmp1, tmp1, #AT91_PMC_MOSCEN
-       orr     tmp1, tmp1, #AT91_PMC_KEY
-       str     tmp1, [pmc, #AT91_CKGR_MOR]
+       ldr     r0, .pm_mode
+       cmp     r0, #AT91_PM_ULP1
+       beq     ulp1_mode
 
-       /* Wait for interrupt */
-       at91_cpu_idle
+       at91_pm_ulp0_mode
+       b       ulp_exit
 
-       /* Turn on the main oscillator */
-       ldr     tmp1, [pmc, #AT91_CKGR_MOR]
-       orr     tmp1, tmp1, #AT91_PMC_MOSCEN
-       orr     tmp1, tmp1, #AT91_PMC_KEY
-       str     tmp1, [pmc, #AT91_CKGR_MOR]
+ulp1_mode:
+       at91_pm_ulp1_mode
+       b       ulp_exit
 
-       wait_moscrdy
+ulp_exit:
+       ldr     pmc, .pmc_base
 
        /* Restore PLLA setting */
        ldr     tmp1, .saved_pllar
@@ -212,7 +314,7 @@ ENTRY(at91_slowck_mode)
        wait_mckrdy
 
        mov     pc, lr
-ENDPROC(at91_slowck_mode)
+ENDPROC(at91_ulp_mode)
 
 /*
  * void at91_sramc_self_refresh(unsigned int is_active)
index 05c3eecf47cb8364ae6a25f2c53c37dc8803f2fa..da8a039d65f9ac794ccebf80220ac8dcb2a3c928 100644 (file)
@@ -59,6 +59,7 @@ config MACH_DA8XX_DT
        default y
        depends on ARCH_DAVINCI_DA850
        select PINCTRL
+       select TIMER_OF
        help
          Say y here to include support for TI DaVinci DA850 based using
          Flattened Device Tree. More information at Documentation/devicetree
@@ -231,18 +232,6 @@ config DAVINCI_MUX_WARNINGS
          to change the pin multiplexing setup. When there are no warnings
          printed, it's safe to deselect DAVINCI_MUX for your product.
 
-config DAVINCI_RESET_CLOCKS
-       bool "Reset unused clocks during boot"
-       depends on ARCH_DAVINCI
-       help
-         Say Y if you want to reset unused clocks during boot.
-         This option saves power, but assumes all drivers are
-         using the clock framework. Broken drivers that do not
-         yet use clock framework may not work with this option.
-         If you are booting from another operating system, you
-         probably do not want this option enabled until your
-         device drivers work properly.
-
 endmenu
 
 endif
index 4e8178050027458779f6685e921d8953c33a0891..93d271b4d84bef2cbd8abd4d4df198fc4e0d6da1 100644 (file)
@@ -5,8 +5,8 @@
 #
 
 # Common objects
-obj-y                  := time.o clock.o serial.o psc.o \
-                          usb.o common.o sram.o aemif.o
+obj-y                                  := time.o serial.o usb.o \
+                                          common.o sram.o
 
 obj-$(CONFIG_DAVINCI_MUX)              += mux.o
 
diff --git a/arch/arm/mach-davinci/aemif.c b/arch/arm/mach-davinci/aemif.c
deleted file mode 100644 (file)
index e4ab3f3..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * AEMIF support for DaVinci SoCs
- *
- * Copyright (C) 2010 Texas Instruments Incorporated. http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/module.h>
-#include <linux/time.h>
-
-#include <linux/platform_data/mtd-davinci-aemif.h>
-#include <linux/platform_data/mtd-davinci.h>
-
-/* Timing value configuration */
-
-#define TA(x)          ((x) << 2)
-#define RHOLD(x)       ((x) << 4)
-#define RSTROBE(x)     ((x) << 7)
-#define RSETUP(x)      ((x) << 13)
-#define WHOLD(x)       ((x) << 17)
-#define WSTROBE(x)     ((x) << 20)
-#define WSETUP(x)      ((x) << 26)
-
-#define TA_MAX         0x3
-#define RHOLD_MAX      0x7
-#define RSTROBE_MAX    0x3f
-#define RSETUP_MAX     0xf
-#define WHOLD_MAX      0x7
-#define WSTROBE_MAX    0x3f
-#define WSETUP_MAX     0xf
-
-#define TIMING_MASK    (TA(TA_MAX) | \
-                               RHOLD(RHOLD_MAX) | \
-                               RSTROBE(RSTROBE_MAX) |  \
-                               RSETUP(RSETUP_MAX) | \
-                               WHOLD(WHOLD_MAX) | \
-                               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.
- * @clk: The input clock rate in kHz.
- * @max: The maximum divider value that can be programmed.
- *
- * On success, returns the calculated timing value minus 1 for easy
- * programming into AEMIF timing registers, else negative errno.
- */
-static int aemif_calc_rate(int wanted, unsigned long clk, int max)
-{
-       int result;
-
-       result = DIV_ROUND_UP((wanted * clk), NSEC_PER_MSEC) - 1;
-
-       pr_debug("%s: result %d from %ld, %d\n", __func__, result, clk, wanted);
-
-       /* It is generally OK to have a more relaxed timing than requested... */
-       if (result < 0)
-               result = 0;
-
-       /* ... But configuring tighter timings is not an option. */
-       else if (result > max)
-               result = -EINVAL;
-
-       return result;
-}
-
-/**
- * davinci_aemif_setup_timing - setup timing values for a given AEMIF interface
- * @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.
- *
- * 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.
- */
-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;
-
-       if (!t)
-               return 0;       /* Nothing to do */
-
-       clkrate /= 1000;        /* turn clock into kHz for ease of use */
-
-       ta      = aemif_calc_rate(t->ta, clkrate, TA_MAX);
-       rhold   = aemif_calc_rate(t->rhold, clkrate, RHOLD_MAX);
-       rstrobe = aemif_calc_rate(t->rstrobe, clkrate, RSTROBE_MAX);
-       rsetup  = aemif_calc_rate(t->rsetup, clkrate, RSETUP_MAX);
-       whold   = aemif_calc_rate(t->whold, clkrate, WHOLD_MAX);
-       wstrobe = aemif_calc_rate(t->wstrobe, clkrate, WSTROBE_MAX);
-       wsetup  = aemif_calc_rate(t->wsetup, clkrate, WSETUP_MAX);
-
-       if (ta < 0 || rhold < 0 || rstrobe < 0 || rsetup < 0 ||
-                       whold < 0 || wstrobe < 0 || wsetup < 0) {
-               pr_err("%s: cannot get suitable timings\n", __func__);
-               return -EINVAL;
-       }
-
-       set = TA(ta) | RHOLD(rhold) | RSTROBE(rstrobe) | RSETUP(rsetup) |
-               WHOLD(whold) | WSTROBE(wstrobe) | WSETUP(wsetup);
-
-       val = __raw_readl(base + offset);
-       val &= ~TIMING_MASK;
-       val |= set;
-       __raw_writel(val, base + offset);
-
-       return 0;
-}
-
-/**
- * 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 + pdata->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 (pdata->options & NAND_BUSWIDTH_16)
-               val |= 0x1;
-
-       davinci_aemif_writel(base, A1CR_OFFSET + pdata->core_chipsel * 4, val);
-
-       clkrate = clk_get_rate(clk);
-
-       if (pdata->timing)
-               ret = davinci_aemif_setup_timing(pdata->timing, base,
-                                                pdata->core_chipsel, 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 14a6fc06174499ba031e4868add99aac34083d2f..7d8ab36ff83d95f0adee2df7babada977dfafb56 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/platform_data/mtd-davinci-aemif.h>
 #include <linux/platform_data/spi-davinci.h>
 #include <linux/platform_data/usb-davinci.h>
+#include <linux/platform_data/ti-aemif.h>
 #include <linux/regulator/machine.h>
 
 #include <asm/mach-types.h>
@@ -110,15 +111,9 @@ static __init void da830_evm_usb_init(void)
 {
        int ret;
 
-       /* USB_REFCLKIN is not used. */
-       ret = da8xx_register_usb20_phy_clk(false);
+       ret = da8xx_register_usb_phy_clocks();
        if (ret)
-               pr_warn("%s: USB 2.0 PHY CLK registration failed: %d\n",
-                       __func__, ret);
-
-       ret = da8xx_register_usb11_phy_clk(false);
-       if (ret)
-               pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n",
+               pr_warn("%s: USB PHY CLK registration failed: %d\n",
                        __func__, ret);
 
        ret = da8xx_register_usb_phy();
@@ -339,14 +334,48 @@ static struct resource da830_evm_nand_resources[] = {
        },
 };
 
-static struct platform_device da830_evm_nand_device = {
-       .name           = "davinci_nand",
-       .id             = 1,
-       .dev            = {
-               .platform_data  = &da830_evm_nand_pdata,
+static struct platform_device da830_evm_aemif_devices[] = {
+       {
+               .name           = "davinci_nand",
+               .id             = 1,
+               .dev            = {
+                       .platform_data  = &da830_evm_nand_pdata,
+               },
+               .num_resources  = ARRAY_SIZE(da830_evm_nand_resources),
+               .resource       = da830_evm_nand_resources,
+       },
+};
+
+static struct resource da830_evm_aemif_resource[] = {
+       {
+               .start  = DA8XX_AEMIF_CTL_BASE,
+               .end    = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct aemif_abus_data da830_evm_aemif_abus_data[] = {
+       {
+               .cs     = 3,
        },
-       .num_resources  = ARRAY_SIZE(da830_evm_nand_resources),
-       .resource       = da830_evm_nand_resources,
+};
+
+static struct aemif_platform_data da830_evm_aemif_pdata = {
+       .abus_data              = da830_evm_aemif_abus_data,
+       .num_abus_data          = ARRAY_SIZE(da830_evm_aemif_abus_data),
+       .sub_devices            = da830_evm_aemif_devices,
+       .num_sub_devices        = ARRAY_SIZE(da830_evm_aemif_devices),
+       .cs_offset              = 2,
+};
+
+static struct platform_device da830_evm_aemif_device = {
+       .name           = "ti-aemif",
+       .id             = -1,
+       .dev = {
+               .platform_data = &da830_evm_aemif_pdata,
+       },
+       .resource       = da830_evm_aemif_resource,
+       .num_resources  = ARRAY_SIZE(da830_evm_aemif_resource),
 };
 
 /*
@@ -377,12 +406,9 @@ static inline void da830_evm_init_nand(int mux_mode)
        if (ret)
                pr_warn("%s: emif25 mux setup failed: %d\n", __func__, ret);
 
-       ret = platform_device_register(&da830_evm_nand_device);
+       ret = platform_device_register(&da830_evm_aemif_device);
        if (ret)
-               pr_warn("%s: NAND device not registered\n", __func__);
-
-       if (davinci_aemif_setup(&da830_evm_nand_device))
-               pr_warn("%s: Cannot configure AEMIF\n", __func__);
+               pr_warn("%s: AEMIF device not registered\n", __func__);
 
        gpio_direction_output(mux_mode, 1);
 }
@@ -557,6 +583,8 @@ static __init void da830_evm_init(void)
        struct davinci_soc_info *soc_info = &davinci_soc_info;
        int ret;
 
+       da830_register_clocks();
+
        ret = da830_register_gpio();
        if (ret)
                pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
index 6d5beb11bd965a805107328d2522144f4b857f9a..e1a949b47306d2eaf93a14b76e0ac720373e1c10 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/platform_data/gpio-davinci.h>
 #include <linux/platform_data/mtd-davinci.h>
 #include <linux/platform_data/mtd-davinci-aemif.h>
+#include <linux/platform_data/ti-aemif.h>
 #include <linux/platform_data/spi-davinci.h>
 #include <linux/platform_data/uio_pruss.h>
 #include <linux/regulator/machine.h>
@@ -185,16 +186,6 @@ static struct resource da850_evm_norflash_resource[] = {
        },
 };
 
-static struct platform_device da850_evm_norflash_device = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev            = {
-               .platform_data  = &da850_evm_norflash_data,
-       },
-       .num_resources  = 1,
-       .resource       = da850_evm_norflash_resource,
-};
-
 /* DA850/OMAP-L138 EVM includes a 512 MByte large-page NAND flash
  * (128K blocks). It may be used instead of the (default) SPI flash
  * to boot, using TI's tools to install the secondary boot loader
@@ -266,37 +257,58 @@ static struct resource da850_evm_nandflash_resource[] = {
        },
 };
 
-static struct platform_device da850_evm_nandflash_device = {
-       .name           = "davinci_nand",
-       .id             = 1,
-       .dev            = {
-               .platform_data  = &da850_evm_nandflash_data,
-       },
-       .num_resources  = ARRAY_SIZE(da850_evm_nandflash_resource),
-       .resource       = da850_evm_nandflash_resource,
+static struct resource da850_evm_aemif_resource[] = {
+       {
+               .start  = DA8XX_AEMIF_CTL_BASE,
+               .end    = DA8XX_AEMIF_CTL_BASE + SZ_32K,
+               .flags  = IORESOURCE_MEM,
+       }
 };
 
-static struct platform_device *da850_evm_devices[] = {
-       &da850_evm_nandflash_device,
-       &da850_evm_norflash_device,
+static struct aemif_abus_data da850_evm_aemif_abus_data[] = {
+       {
+               .cs     = 3,
+       }
 };
 
-#define DA8XX_AEMIF_CE2CFG_OFFSET      0x10
-#define DA8XX_AEMIF_ASIZE_16BIT                0x1
-
-static void __init da850_evm_init_nor(void)
-{
-       void __iomem *aemif_addr;
-
-       aemif_addr = ioremap(DA8XX_AEMIF_CTL_BASE, SZ_32K);
+static struct platform_device da850_evm_aemif_devices[] = {
+       {
+               .name           = "davinci_nand",
+               .id             = 1,
+               .dev            = {
+                       .platform_data  = &da850_evm_nandflash_data,
+               },
+               .num_resources  = ARRAY_SIZE(da850_evm_nandflash_resource),
+               .resource       = da850_evm_nandflash_resource,
+       },
+       {
+               .name           = "physmap-flash",
+               .id             = 0,
+               .dev            = {
+                       .platform_data  = &da850_evm_norflash_data,
+               },
+               .num_resources  = 1,
+               .resource       = da850_evm_norflash_resource,
+       }
+};
 
-       /* Configure data bus width of CS2 to 16 bit */
-       writel(readl(aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET) |
-               DA8XX_AEMIF_ASIZE_16BIT,
-               aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET);
+static struct aemif_platform_data da850_evm_aemif_pdata = {
+       .cs_offset = 2,
+       .abus_data = da850_evm_aemif_abus_data,
+       .num_abus_data = ARRAY_SIZE(da850_evm_aemif_abus_data),
+       .sub_devices = da850_evm_aemif_devices,
+       .num_sub_devices = ARRAY_SIZE(da850_evm_aemif_devices),
+};
 
-       iounmap(aemif_addr);
-}
+static struct platform_device da850_evm_aemif_device = {
+       .name           = "ti-aemif",
+       .id             = -1,
+       .dev = {
+               .platform_data  = &da850_evm_aemif_pdata,
+       },
+       .resource       = da850_evm_aemif_resource,
+       .num_resources  = ARRAY_SIZE(da850_evm_aemif_resource),
+};
 
 static const short da850_evm_nand_pins[] = {
        DA850_EMA_D_0, DA850_EMA_D_1, DA850_EMA_D_2, DA850_EMA_D_3,
@@ -339,13 +351,10 @@ static inline void da850_evm_setup_nor_nand(void)
                        pr_warn("%s: NOR mux setup failed: %d\n",
                                __func__, ret);
 
-               da850_evm_init_nor();
-
-               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__);
+               ret = platform_device_register(&da850_evm_aemif_device);
+               if (ret)
+                       pr_warn("%s: registering aemif failed: %d\n",
+                               __func__, ret);
        }
 }
 
@@ -1340,6 +1349,8 @@ static __init void da850_evm_init(void)
 {
        int ret;
 
+       da850_register_clocks();
+
        ret = da850_register_gpio();
        if (ret)
                pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
index a3377f95944489ed9051279bccb5a0cc392bba73..f53a461a606f60107e669e122b8acce63d5a37c9 100644 (file)
@@ -394,6 +394,8 @@ static __init void dm355_evm_init(void)
        struct clk *aemif;
        int ret;
 
+       dm355_register_clocks();
+
        ret = dm355_gpio_register();
        if (ret)
                pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
index 8249a0bf69f0426d9ceed1b65a29064b2378dcb2..0fdf1d03eb1107fffe7e69c2322eaffae0555620 100644 (file)
@@ -234,6 +234,8 @@ static __init void dm355_leopard_init(void)
        struct clk *aemif;
        int ret;
 
+       dm355_register_clocks();
+
        ret = dm355_gpio_register();
        if (ret)
                pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
index 435f7ec7d9afa92b4f35a39d7fd365a04b436624..8143756ff38b022be3011fc6c901d9097edcf02b 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/eeprom.h>
 #include <linux/v4l2-dv-timings.h>
+#include <linux/platform_data/ti-aemif.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -159,16 +160,49 @@ static struct resource davinci_nand_resources[] = {
        },
 };
 
-static struct platform_device davinci_nand_device = {
-       .name                   = "davinci_nand",
-       .id                     = 0,
-       .num_resources          = ARRAY_SIZE(davinci_nand_resources),
-       .resource               = davinci_nand_resources,
-       .dev                    = {
-               .platform_data  = &davinci_nand_data,
+static struct platform_device davinci_aemif_devices[] = {
+       {
+               .name           = "davinci_nand",
+               .id             = 0,
+               .num_resources  = ARRAY_SIZE(davinci_nand_resources),
+               .resource       = davinci_nand_resources,
+               .dev            = {
+                       .platform_data  = &davinci_nand_data,
+               },
+       }
+};
+
+static struct resource davinci_aemif_resources[] = {
+       {
+               .start          = DM365_ASYNC_EMIF_CONTROL_BASE,
+               .end            = DM365_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+               .flags          = IORESOURCE_MEM,
        },
 };
 
+static struct aemif_abus_data da850_evm_aemif_abus_data[] = {
+       {
+               .cs             = 1,
+       },
+};
+
+static struct aemif_platform_data davinci_aemif_pdata = {
+       .abus_data              = da850_evm_aemif_abus_data,
+       .num_abus_data          = ARRAY_SIZE(da850_evm_aemif_abus_data),
+       .sub_devices            = davinci_aemif_devices,
+       .num_sub_devices        = ARRAY_SIZE(davinci_aemif_devices),
+};
+
+static struct platform_device davinci_aemif_device = {
+       .name                   = "ti-aemif",
+       .id                     = -1,
+       .dev = {
+               .platform_data  = &davinci_aemif_pdata,
+       },
+       .resource               = davinci_aemif_resources,
+       .num_resources          = ARRAY_SIZE(davinci_aemif_resources),
+};
+
 static struct at24_platform_data eeprom_info = {
        .byte_len       = (256*1024) / 8,
        .page_size      = 64,
@@ -537,10 +571,6 @@ static void __init evm_init_i2c(void)
        i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
 }
 
-static struct platform_device *dm365_evm_nand_devices[] __initdata = {
-       &davinci_nand_device,
-};
-
 static inline int have_leds(void)
 {
 #ifdef CONFIG_LEDS_CLASS
@@ -628,6 +658,7 @@ static void __init evm_init_cpld(void)
        u8 mux, resets;
        const char *label;
        struct clk *aemif_clk;
+       int rc;
 
        /* Make sure we can configure the CPLD through CS1.  Then
         * leave it on for later access to MMC and LED registers.
@@ -660,8 +691,10 @@ fail:
                /* external keypad mux */
                mux |= BIT(7);
 
-               platform_add_devices(dm365_evm_nand_devices,
-                               ARRAY_SIZE(dm365_evm_nand_devices));
+               rc = platform_device_register(&davinci_aemif_device);
+               if (rc)
+                       pr_warn("%s(): error registering the aemif device: %d\n",
+                               __func__, rc);
        } else {
                /* no OneNAND support yet */
        }
@@ -742,6 +775,8 @@ static __init void dm365_evm_init(void)
 {
        int ret;
 
+       dm365_register_clocks();
+
        ret = dm365_gpio_register();
        if (ret)
                pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
index 48436f74fd7108bdc984a0c5af7c9be14e808369..e4a8f9225d1667f7ab733bdf93e423ea9df1426c 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/platform_data/mmc-davinci.h>
 #include <linux/platform_data/usb-davinci.h>
 #include <linux/platform_data/mtd-davinci-aemif.h>
+#include <linux/platform_data/ti-aemif.h>
 
 #include "davinci.h"
 
@@ -174,14 +175,47 @@ static struct resource davinci_evm_nandflash_resource[] = {
        },
 };
 
-static struct platform_device davinci_evm_nandflash_device = {
-       .name           = "davinci_nand",
-       .id             = 0,
-       .dev            = {
-               .platform_data  = &davinci_evm_nandflash_data,
+static struct resource davinci_evm_aemif_resource[] = {
+       {
+               .start          = DM644X_ASYNC_EMIF_CONTROL_BASE,
+               .end            = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+               .flags          = IORESOURCE_MEM,
+       },
+};
+
+static struct aemif_abus_data davinci_evm_aemif_abus_data[] = {
+       {
+               .cs             = 1,
+       },
+};
+
+static struct platform_device davinci_evm_nandflash_devices[] = {
+       {
+               .name           = "davinci_nand",
+               .id             = 0,
+               .dev            = {
+                       .platform_data  = &davinci_evm_nandflash_data,
+               },
+               .num_resources  = ARRAY_SIZE(davinci_evm_nandflash_resource),
+               .resource       = davinci_evm_nandflash_resource,
+       },
+};
+
+static struct aemif_platform_data davinci_evm_aemif_pdata = {
+       .abus_data = davinci_evm_aemif_abus_data,
+       .num_abus_data = ARRAY_SIZE(davinci_evm_aemif_abus_data),
+       .sub_devices = davinci_evm_nandflash_devices,
+       .num_sub_devices = ARRAY_SIZE(davinci_evm_nandflash_devices),
+};
+
+static struct platform_device davinci_evm_aemif_device = {
+       .name                   = "ti-aemif",
+       .id                     = -1,
+       .dev = {
+               .platform_data  = &davinci_evm_aemif_pdata,
        },
-       .num_resources  = ARRAY_SIZE(davinci_evm_nandflash_resource),
-       .resource       = davinci_evm_nandflash_resource,
+       .resource               = davinci_evm_aemif_resource,
+       .num_resources          = ARRAY_SIZE(davinci_evm_aemif_resource),
 };
 
 static u64 davinci_fb_dma_mask = DMA_BIT_MASK(32);
@@ -773,6 +807,8 @@ static __init void davinci_evm_init(void)
        struct clk *aemif_clk;
        struct davinci_soc_info *soc_info = &davinci_soc_info;
 
+       dm644x_register_clocks();
+
        dm644x_init_devices();
 
        ret = dm644x_gpio_register();
@@ -793,12 +829,7 @@ 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__);
-
+                       platform_device_register(&davinci_evm_aemif_device);
 #ifdef CONFIG_I2C
                        evm_leds[7].default_trigger = "nand-disk";
 #endif
index 584064fdabf5bbb6466f7f19e7d686199258e542..3e5ee09ee717ea339428501b2d06b94909de315c 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/i2c.h>
 #include <linux/platform_data/at24.h>
 #include <linux/platform_data/pcf857x.h>
+#include <linux/platform_data/ti-aemif.h>
 
 #include <media/i2c/tvp514x.h>
 #include <media/i2c/adv7343.h>
@@ -106,18 +107,49 @@ static struct resource davinci_nand_resources[] = {
        },
 };
 
-static struct platform_device davinci_nand_device = {
-       .name                   = "davinci_nand",
-       .id                     = 0,
+static struct platform_device davinci_aemif_devices[] = {
+       {
+               .name           = "davinci_nand",
+               .id             = 0,
+               .num_resources  = ARRAY_SIZE(davinci_nand_resources),
+               .resource       = davinci_nand_resources,
+               .dev            = {
+                       .platform_data  = &davinci_nand_data,
+               },
+       },
+};
 
-       .num_resources          = ARRAY_SIZE(davinci_nand_resources),
-       .resource               = davinci_nand_resources,
+static struct resource davinci_aemif_resources[] = {
+       {
+               .start  = DM646X_ASYNC_EMIF_CONTROL_BASE,
+               .end    = DM646X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
 
-       .dev                    = {
-               .platform_data  = &davinci_nand_data,
+static struct aemif_abus_data davinci_aemif_abus_data[] = {
+       {
+               .cs     = 1,
        },
 };
 
+static struct aemif_platform_data davinci_aemif_pdata = {
+       .abus_data              = davinci_aemif_abus_data,
+       .num_abus_data          = ARRAY_SIZE(davinci_aemif_abus_data),
+       .sub_devices            = davinci_aemif_devices,
+       .num_sub_devices        = ARRAY_SIZE(davinci_aemif_devices),
+};
+
+static struct platform_device davinci_aemif_device = {
+       .name           = "ti-aemif",
+       .id             = -1,
+       .dev = {
+               .platform_data  = &davinci_aemif_pdata,
+       },
+       .resource       = davinci_aemif_resources,
+       .num_resources  = ARRAY_SIZE(davinci_aemif_resources),
+};
+
 #define HAS_ATA                (IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
                         IS_ENABLED(CONFIG_PATA_BK3710))
 
@@ -776,6 +808,8 @@ static __init void evm_init(void)
        int ret;
        struct davinci_soc_info *soc_info = &davinci_soc_info;
 
+       dm646x_register_clocks();
+
        ret = dm646x_gpio_register();
        if (ret)
                pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
@@ -791,10 +825,8 @@ static __init void evm_init(void)
        if (machine_is_davinci_dm6467tevm())
                davinci_nand_data.timing = &dm6467tevm_nandflash_timing;
 
-       platform_device_register(&davinci_nand_device);
-
-       if (davinci_aemif_setup(&davinci_nand_device))
-               pr_warn("%s: Cannot configure AEMIF.\n", __func__);
+       if (platform_device_register(&davinci_aemif_device))
+               pr_warn("%s: Cannot register AEMIF device.\n", __func__);
 
        dm646x_init_edma(dm646x_edma_rsv);
 
index 37b3e48a21d1b6d37741857dfbe170af5e2be7b8..2933e0c87cfacfe04d8da175d20b5374bf0cb648 100644 (file)
@@ -30,6 +30,7 @@
 #include <mach/da8xx.h>
 #include <linux/platform_data/mtd-davinci.h>
 #include <linux/platform_data/mtd-davinci-aemif.h>
+#include <linux/platform_data/ti-aemif.h>
 #include <mach/mux.h>
 #include <linux/platform_data/spi-davinci.h>
 
@@ -422,27 +423,53 @@ static struct resource mityomapl138_nandflash_resource[] = {
        },
 };
 
-static struct platform_device mityomapl138_nandflash_device = {
-       .name           = "davinci_nand",
-       .id             = 1,
-       .dev            = {
-               .platform_data  = &mityomapl138_nandflash_data,
+static struct platform_device mityomapl138_aemif_devices[] = {
+       {
+               .name           = "davinci_nand",
+               .id             = 1,
+               .dev            = {
+                       .platform_data  = &mityomapl138_nandflash_data,
+               },
+               .num_resources  = ARRAY_SIZE(mityomapl138_nandflash_resource),
+               .resource       = mityomapl138_nandflash_resource,
+       },
+};
+
+static struct resource mityomapl138_aemif_resources[] = {
+       {
+               .start  = DA8XX_AEMIF_CTL_BASE,
+               .end    = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1,
+               .flags  = IORESOURCE_MEM,
        },
-       .num_resources  = ARRAY_SIZE(mityomapl138_nandflash_resource),
-       .resource       = mityomapl138_nandflash_resource,
 };
 
-static struct platform_device *mityomapl138_devices[] __initdata = {
-       &mityomapl138_nandflash_device,
+static struct aemif_abus_data mityomapl138_aemif_abus_data[] = {
+       {
+               .cs     = 1,
+       },
+};
+
+static struct aemif_platform_data mityomapl138_aemif_pdata = {
+       .abus_data              = mityomapl138_aemif_abus_data,
+       .num_abus_data          = ARRAY_SIZE(mityomapl138_aemif_abus_data),
+       .sub_devices            = mityomapl138_aemif_devices,
+       .num_sub_devices        = ARRAY_SIZE(mityomapl138_aemif_devices),
+};
+
+static struct platform_device mityomapl138_aemif_device = {
+       .name           = "ti-aemif",
+       .id             = -1,
+       .dev = {
+               .platform_data  = &mityomapl138_aemif_pdata,
+       },
+       .resource       = mityomapl138_aemif_resources,
+       .num_resources  = ARRAY_SIZE(mityomapl138_aemif_resources),
 };
 
 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__);
+       if (platform_device_register(&mityomapl138_aemif_device))
+               pr_warn("%s: Cannot register AEMIF device\n", __func__);
 }
 
 static const short mityomap_mii_pins[] = {
@@ -503,6 +530,8 @@ static void __init mityomapl138_init(void)
 {
        int ret;
 
+       da850_register_clocks();
+
        /* for now, no special EDMA channels are reserved */
        ret = da850_register_edma(NULL);
        if (ret)
index 25ad9b0612bee50024f5c35fa1b62f15c134bf56..353f9e5a1454a67d674c90c663ccbabd6e0dcae1 100644 (file)
@@ -175,6 +175,8 @@ static __init void davinci_ntosd2_init(void)
        struct clk *aemif_clk;
        struct davinci_soc_info *soc_info = &davinci_soc_info;
 
+       dm644x_register_clocks();
+
        dm644x_init_devices();
 
        ret = dm644x_gpio_register();
index be8b892a6ea7061a8af9b932e007cc8652701b0f..8e8d51f4a2762275e5c3171ca6b3f988e61dea2b 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
 #include <linux/gpio/machine.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/rawnand.h>
 #include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_data/mtd-davinci.h>
+#include <linux/platform_data/mtd-davinci-aemif.h>
+#include <linux/platform_data/ti-aemif.h>
 #include <linux/regulator/machine.h>
 
 #include <asm/mach-types.h>
@@ -166,6 +171,129 @@ mmc_setup_mmcsd_fail:
        gpiod_remove_lookup_table(&mmc_gpios_table);
 }
 
+static struct mtd_partition omapl138_hawk_nandflash_partition[] = {
+       {
+               .name           = "u-boot env",
+               .offset         = 0,
+               .size           = SZ_128K,
+               .mask_flags     = MTD_WRITEABLE,
+        },
+       {
+               .name           = "u-boot",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = SZ_512K,
+               .mask_flags     = MTD_WRITEABLE,
+       },
+       {
+               .name           = "free space",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = MTDPART_SIZ_FULL,
+               .mask_flags     = 0,
+       },
+};
+
+static struct davinci_aemif_timing omapl138_hawk_nandflash_timing = {
+       .wsetup         = 24,
+       .wstrobe        = 21,
+       .whold          = 14,
+       .rsetup         = 19,
+       .rstrobe        = 50,
+       .rhold          = 0,
+       .ta             = 20,
+};
+
+static struct davinci_nand_pdata omapl138_hawk_nandflash_data = {
+       .core_chipsel   = 1,
+       .parts          = omapl138_hawk_nandflash_partition,
+       .nr_parts       = ARRAY_SIZE(omapl138_hawk_nandflash_partition),
+       .ecc_mode       = NAND_ECC_HW,
+       .ecc_bits       = 4,
+       .bbt_options    = NAND_BBT_USE_FLASH,
+       .options        = NAND_BUSWIDTH_16,
+       .timing         = &omapl138_hawk_nandflash_timing,
+       .mask_chipsel   = 0,
+       .mask_ale       = 0,
+       .mask_cle       = 0,
+};
+
+static struct resource omapl138_hawk_nandflash_resource[] = {
+       {
+               .start  = DA8XX_AEMIF_CS3_BASE,
+               .end    = DA8XX_AEMIF_CS3_BASE + SZ_32M,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = DA8XX_AEMIF_CTL_BASE,
+               .end    = DA8XX_AEMIF_CTL_BASE + SZ_32K,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct resource omapl138_hawk_aemif_resource[] = {
+       {
+               .start  = DA8XX_AEMIF_CTL_BASE,
+               .end    = DA8XX_AEMIF_CTL_BASE + SZ_32K,
+               .flags  = IORESOURCE_MEM,
+       }
+};
+
+static struct aemif_abus_data omapl138_hawk_aemif_abus_data[] = {
+       {
+               .cs     = 3,
+       }
+};
+
+static struct platform_device omapl138_hawk_aemif_devices[] = {
+       {
+               .name           = "davinci_nand",
+               .id             = -1,
+               .dev            = {
+                       .platform_data  = &omapl138_hawk_nandflash_data,
+               },
+               .resource       = omapl138_hawk_nandflash_resource,
+               .num_resources  = ARRAY_SIZE(omapl138_hawk_nandflash_resource),
+       }
+};
+
+static struct aemif_platform_data omapl138_hawk_aemif_pdata = {
+       .cs_offset = 2,
+       .abus_data = omapl138_hawk_aemif_abus_data,
+       .num_abus_data = ARRAY_SIZE(omapl138_hawk_aemif_abus_data),
+       .sub_devices = omapl138_hawk_aemif_devices,
+       .num_sub_devices = ARRAY_SIZE(omapl138_hawk_aemif_devices),
+};
+
+static struct platform_device omapl138_hawk_aemif_device = {
+       .name           = "ti-aemif",
+       .id             = -1,
+       .dev = {
+               .platform_data  = &omapl138_hawk_aemif_pdata,
+       },
+       .resource       = omapl138_hawk_aemif_resource,
+       .num_resources  = ARRAY_SIZE(omapl138_hawk_aemif_resource),
+};
+
+static const short omapl138_hawk_nand_pins[] = {
+       DA850_EMA_WAIT_1, DA850_NEMA_OE, DA850_NEMA_WE, DA850_NEMA_CS_3,
+       DA850_EMA_D_0, DA850_EMA_D_1, DA850_EMA_D_2, DA850_EMA_D_3,
+       DA850_EMA_D_4, DA850_EMA_D_5, DA850_EMA_D_6, DA850_EMA_D_7,
+       DA850_EMA_D_8, DA850_EMA_D_9, DA850_EMA_D_10, DA850_EMA_D_11,
+       DA850_EMA_D_12, DA850_EMA_D_13, DA850_EMA_D_14, DA850_EMA_D_15,
+       DA850_EMA_A_1, DA850_EMA_A_2,
+       -1
+};
+
+static int omapl138_hawk_register_aemif(void)
+{
+       int ret;
+
+       ret = davinci_cfg_reg_list(omapl138_hawk_nand_pins);
+       if (ret)
+               pr_warn("%s: NAND mux setup failed: %d\n", __func__, ret);
+
+       return platform_device_register(&omapl138_hawk_aemif_device);
+}
+
 static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id);
 static da8xx_ocic_handler_t hawk_usb_ocic_handler;
 
@@ -236,14 +364,9 @@ static __init void omapl138_hawk_usb_init(void)
                return;
        }
 
-       ret = da8xx_register_usb20_phy_clk(false);
-       if (ret)
-               pr_warn("%s: USB 2.0 PHY CLK registration failed: %d\n",
-                       __func__, ret);
-
-       ret = da8xx_register_usb11_phy_clk(false);
+       ret = da8xx_register_usb_phy_clocks();
        if (ret)
-               pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n",
+               pr_warn("%s: USB PHY CLK registration failed: %d\n",
                        __func__, ret);
 
        ret = da8xx_register_usb_phy();
@@ -285,6 +408,8 @@ static __init void omapl138_hawk_init(void)
 {
        int ret;
 
+       da850_register_clocks();
+
        ret = da850_register_gpio();
        if (ret)
                pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
@@ -301,6 +426,10 @@ static __init void omapl138_hawk_init(void)
 
        omapl138_hawk_usb_init();
 
+       ret = omapl138_hawk_register_aemif();
+       if (ret)
+               pr_warn("%s: aemif registration failed: %d\n", __func__, ret);
+
        ret = da8xx_register_watchdog();
        if (ret)
                pr_warn("%s: watchdog registration failed: %d\n",
index e7c1728b0833a0b791de802866a3ef7578955c67..792bb84d50111e4e99a3380fee5373f8ed9640db 100644 (file)
@@ -134,6 +134,8 @@ static __init void davinci_sffsdr_init(void)
 {
        struct davinci_soc_info *soc_info = &davinci_soc_info;
 
+       dm644x_register_clocks();
+
        dm644x_init_devices();
 
        platform_add_devices(davinci_sffsdr_devices,
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
deleted file mode 100644 (file)
index f77a4f7..0000000
+++ /dev/null
@@ -1,745 +0,0 @@
-/*
- * Clock and PLL control for DaVinci devices
- *
- * Copyright (C) 2006-2007 Texas Instruments.
- * Copyright (C) 2008-2009 Deep Root Systems, LLC
- *
- * This program is free software; 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/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/mutex.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-
-#include <mach/hardware.h>
-
-#include <mach/clock.h>
-#include "psc.h"
-#include <mach/cputype.h>
-#include "clock.h"
-
-static LIST_HEAD(clocks);
-static DEFINE_MUTEX(clocks_mutex);
-static DEFINE_SPINLOCK(clockfw_lock);
-
-void davinci_clk_enable(struct clk *clk)
-{
-       if (clk->parent)
-               davinci_clk_enable(clk->parent);
-       if (clk->usecount++ == 0) {
-               if (clk->flags & CLK_PSC)
-                       davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
-                                          true, clk->flags);
-               else if (clk->clk_enable)
-                       clk->clk_enable(clk);
-       }
-}
-
-void davinci_clk_disable(struct clk *clk)
-{
-       if (WARN_ON(clk->usecount == 0))
-               return;
-       if (--clk->usecount == 0) {
-               if (!(clk->flags & CLK_PLL) && (clk->flags & CLK_PSC))
-                       davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
-                                          false, clk->flags);
-               else if (clk->clk_disable)
-                       clk->clk_disable(clk);
-       }
-       if (clk->parent)
-               davinci_clk_disable(clk->parent);
-}
-
-int davinci_clk_reset(struct clk *clk, bool reset)
-{
-       unsigned long flags;
-
-       if (clk == NULL || IS_ERR(clk))
-               return -EINVAL;
-
-       spin_lock_irqsave(&clockfw_lock, flags);
-       if (clk->flags & CLK_PSC)
-               davinci_psc_reset(clk->gpsc, clk->lpsc, reset);
-       spin_unlock_irqrestore(&clockfw_lock, flags);
-
-       return 0;
-}
-EXPORT_SYMBOL(davinci_clk_reset);
-
-int davinci_clk_reset_assert(struct clk *clk)
-{
-       if (clk == NULL || IS_ERR(clk) || !clk->reset)
-               return -EINVAL;
-
-       return clk->reset(clk, true);
-}
-EXPORT_SYMBOL(davinci_clk_reset_assert);
-
-int davinci_clk_reset_deassert(struct clk *clk)
-{
-       if (clk == NULL || IS_ERR(clk) || !clk->reset)
-               return -EINVAL;
-
-       return clk->reset(clk, false);
-}
-EXPORT_SYMBOL(davinci_clk_reset_deassert);
-
-int clk_enable(struct clk *clk)
-{
-       unsigned long flags;
-
-       if (!clk)
-               return 0;
-       else if (IS_ERR(clk))
-               return -EINVAL;
-
-       spin_lock_irqsave(&clockfw_lock, flags);
-       davinci_clk_enable(clk);
-       spin_unlock_irqrestore(&clockfw_lock, flags);
-
-       return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-       unsigned long flags;
-
-       if (clk == NULL || IS_ERR(clk))
-               return;
-
-       spin_lock_irqsave(&clockfw_lock, flags);
-       davinci_clk_disable(clk);
-       spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-       if (clk == NULL || IS_ERR(clk))
-               return 0;
-
-       return clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-       if (clk == NULL || IS_ERR(clk))
-               return 0;
-
-       if (clk->round_rate)
-               return clk->round_rate(clk, rate);
-
-       return clk->rate;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-/* Propagate rate to children */
-static void propagate_rate(struct clk *root)
-{
-       struct clk *clk;
-
-       list_for_each_entry(clk, &root->children, childnode) {
-               if (clk->recalc)
-                       clk->rate = clk->recalc(clk);
-               propagate_rate(clk);
-       }
-}
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-       unsigned long flags;
-       int ret = -EINVAL;
-
-       if (!clk)
-               return 0;
-       else if (IS_ERR(clk))
-               return -EINVAL;
-
-       if (clk->set_rate)
-               ret = clk->set_rate(clk, rate);
-
-       spin_lock_irqsave(&clockfw_lock, flags);
-       if (ret == 0) {
-               if (clk->recalc)
-                       clk->rate = clk->recalc(clk);
-               propagate_rate(clk);
-       }
-       spin_unlock_irqrestore(&clockfw_lock, flags);
-
-       return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-       unsigned long flags;
-
-       if (!clk)
-               return 0;
-       else if (IS_ERR(clk))
-               return -EINVAL;
-
-       /* Cannot change parent on enabled clock */
-       if (WARN_ON(clk->usecount))
-               return -EINVAL;
-
-       mutex_lock(&clocks_mutex);
-       if (clk->set_parent) {
-               int ret = clk->set_parent(clk, parent);
-
-               if (ret) {
-                       mutex_unlock(&clocks_mutex);
-                       return ret;
-               }
-       }
-       clk->parent = parent;
-       list_del_init(&clk->childnode);
-       list_add(&clk->childnode, &clk->parent->children);
-       mutex_unlock(&clocks_mutex);
-
-       spin_lock_irqsave(&clockfw_lock, flags);
-       if (clk->recalc)
-               clk->rate = clk->recalc(clk);
-       propagate_rate(clk);
-       spin_unlock_irqrestore(&clockfw_lock, flags);
-
-       return 0;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-struct clk *clk_get_parent(struct clk *clk)
-{
-       if (!clk)
-               return NULL;
-
-       return clk->parent;
-}
-EXPORT_SYMBOL(clk_get_parent);
-
-int clk_register(struct clk *clk)
-{
-       if (clk == NULL || IS_ERR(clk))
-               return -EINVAL;
-
-       if (WARN(clk->parent && !clk->parent->rate,
-                       "CLK: %s parent %s has no rate!\n",
-                       clk->name, clk->parent->name))
-               return -EINVAL;
-
-       INIT_LIST_HEAD(&clk->children);
-
-       mutex_lock(&clocks_mutex);
-       list_add_tail(&clk->node, &clocks);
-       if (clk->parent) {
-               if (clk->set_parent) {
-                       int ret = clk->set_parent(clk, clk->parent);
-
-                       if (ret) {
-                               mutex_unlock(&clocks_mutex);
-                               return ret;
-                       }
-               }
-               list_add_tail(&clk->childnode, &clk->parent->children);
-       }
-       mutex_unlock(&clocks_mutex);
-
-       /* If rate is already set, use it */
-       if (clk->rate)
-               return 0;
-
-       /* Else, see if there is a way to calculate it */
-       if (clk->recalc)
-               clk->rate = clk->recalc(clk);
-
-       /* Otherwise, default to parent rate */
-       else if (clk->parent)
-               clk->rate = clk->parent->rate;
-
-       return 0;
-}
-EXPORT_SYMBOL(clk_register);
-
-void clk_unregister(struct clk *clk)
-{
-       if (clk == NULL || IS_ERR(clk))
-               return;
-
-       mutex_lock(&clocks_mutex);
-       list_del(&clk->node);
-       list_del(&clk->childnode);
-       mutex_unlock(&clocks_mutex);
-}
-EXPORT_SYMBOL(clk_unregister);
-
-#ifdef CONFIG_DAVINCI_RESET_CLOCKS
-/*
- * Disable any unused clocks left on by the bootloader
- */
-int __init davinci_clk_disable_unused(void)
-{
-       struct clk *ck;
-
-       spin_lock_irq(&clockfw_lock);
-       list_for_each_entry(ck, &clocks, node) {
-               if (ck->usecount > 0)
-                       continue;
-               if (!(ck->flags & CLK_PSC))
-                       continue;
-
-               /* ignore if in Disabled or SwRstDisable states */
-               if (!davinci_psc_is_clk_active(ck->gpsc, ck->lpsc))
-                       continue;
-
-               pr_debug("Clocks: disable unused %s\n", ck->name);
-
-               davinci_psc_config(ck->domain, ck->gpsc, ck->lpsc,
-                               false, ck->flags);
-       }
-       spin_unlock_irq(&clockfw_lock);
-
-       return 0;
-}
-#endif
-
-static unsigned long clk_sysclk_recalc(struct clk *clk)
-{
-       u32 v, plldiv;
-       struct pll_data *pll;
-       unsigned long rate = clk->rate;
-
-       /* If this is the PLL base clock, no more calculations needed */
-       if (clk->pll_data)
-               return rate;
-
-       if (WARN_ON(!clk->parent))
-               return rate;
-
-       rate = clk->parent->rate;
-
-       /* Otherwise, the parent must be a PLL */
-       if (WARN_ON(!clk->parent->pll_data))
-               return rate;
-
-       pll = clk->parent->pll_data;
-
-       /* If pre-PLL, source clock is before the multiplier and divider(s) */
-       if (clk->flags & PRE_PLL)
-               rate = pll->input_rate;
-
-       if (!clk->div_reg)
-               return rate;
-
-       v = __raw_readl(pll->base + clk->div_reg);
-       if (v & PLLDIV_EN) {
-               plldiv = (v & pll->div_ratio_mask) + 1;
-               if (plldiv)
-                       rate /= plldiv;
-       }
-
-       return rate;
-}
-
-int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate)
-{
-       unsigned v;
-       struct pll_data *pll;
-       unsigned long input;
-       unsigned ratio = 0;
-
-       /* If this is the PLL base clock, wrong function to call */
-       if (clk->pll_data)
-               return -EINVAL;
-
-       /* There must be a parent... */
-       if (WARN_ON(!clk->parent))
-               return -EINVAL;
-
-       /* ... the parent must be a PLL... */
-       if (WARN_ON(!clk->parent->pll_data))
-               return -EINVAL;
-
-       /* ... and this clock must have a divider. */
-       if (WARN_ON(!clk->div_reg))
-               return -EINVAL;
-
-       pll = clk->parent->pll_data;
-
-       input = clk->parent->rate;
-
-       /* If pre-PLL, source clock is before the multiplier and divider(s) */
-       if (clk->flags & PRE_PLL)
-               input = pll->input_rate;
-
-       if (input > rate) {
-               /*
-                * Can afford to provide an output little higher than requested
-                * only if maximum rate supported by hardware on this sysclk
-                * is known.
-                */
-               if (clk->maxrate) {
-                       ratio = DIV_ROUND_CLOSEST(input, rate);
-                       if (input / ratio > clk->maxrate)
-                               ratio = 0;
-               }
-
-               if (ratio == 0)
-                       ratio = DIV_ROUND_UP(input, rate);
-
-               ratio--;
-       }
-
-       if (ratio > pll->div_ratio_mask)
-               return -EINVAL;
-
-       do {
-               v = __raw_readl(pll->base + PLLSTAT);
-       } while (v & PLLSTAT_GOSTAT);
-
-       v = __raw_readl(pll->base + clk->div_reg);
-       v &= ~pll->div_ratio_mask;
-       v |= ratio | PLLDIV_EN;
-       __raw_writel(v, pll->base + clk->div_reg);
-
-       v = __raw_readl(pll->base + PLLCMD);
-       v |= PLLCMD_GOSET;
-       __raw_writel(v, pll->base + PLLCMD);
-
-       do {
-               v = __raw_readl(pll->base + PLLSTAT);
-       } while (v & PLLSTAT_GOSTAT);
-
-       return 0;
-}
-EXPORT_SYMBOL(davinci_set_sysclk_rate);
-
-static unsigned long clk_leafclk_recalc(struct clk *clk)
-{
-       if (WARN_ON(!clk->parent))
-               return clk->rate;
-
-       return clk->parent->rate;
-}
-
-int davinci_simple_set_rate(struct clk *clk, unsigned long rate)
-{
-       clk->rate = rate;
-       return 0;
-}
-
-static unsigned long clk_pllclk_recalc(struct clk *clk)
-{
-       u32 ctrl, mult = 1, prediv = 1, postdiv = 1;
-       u8 bypass;
-       struct pll_data *pll = clk->pll_data;
-       unsigned long rate = clk->rate;
-
-       ctrl = __raw_readl(pll->base + PLLCTL);
-       rate = pll->input_rate = clk->parent->rate;
-
-       if (ctrl & PLLCTL_PLLEN) {
-               bypass = 0;
-               mult = __raw_readl(pll->base + PLLM);
-               if (cpu_is_davinci_dm365())
-                       mult = 2 * (mult & PLLM_PLLM_MASK);
-               else
-                       mult = (mult & PLLM_PLLM_MASK) + 1;
-       } else
-               bypass = 1;
-
-       if (pll->flags & PLL_HAS_PREDIV) {
-               prediv = __raw_readl(pll->base + PREDIV);
-               if (prediv & PLLDIV_EN)
-                       prediv = (prediv & pll->div_ratio_mask) + 1;
-               else
-                       prediv = 1;
-       }
-
-       /* pre-divider is fixed, but (some?) chips won't report that */
-       if (cpu_is_davinci_dm355() && pll->num == 1)
-               prediv = 8;
-
-       if (pll->flags & PLL_HAS_POSTDIV) {
-               postdiv = __raw_readl(pll->base + POSTDIV);
-               if (postdiv & PLLDIV_EN)
-                       postdiv = (postdiv & pll->div_ratio_mask) + 1;
-               else
-                       postdiv = 1;
-       }
-
-       if (!bypass) {
-               rate /= prediv;
-               rate *= mult;
-               rate /= postdiv;
-       }
-
-       pr_debug("PLL%d: input = %lu MHz [ ",
-                pll->num, clk->parent->rate / 1000000);
-       if (bypass)
-               pr_debug("bypass ");
-       if (prediv > 1)
-               pr_debug("/ %d ", prediv);
-       if (mult > 1)
-               pr_debug("* %d ", mult);
-       if (postdiv > 1)
-               pr_debug("/ %d ", postdiv);
-       pr_debug("] --> %lu MHz output.\n", rate / 1000000);
-
-       return rate;
-}
-
-/**
- * davinci_set_pllrate - set the output rate of a given PLL.
- *
- * Note: Currently tested to work with OMAP-L138 only.
- *
- * @pll: pll whose rate needs to be changed.
- * @prediv: The pre divider value. Passing 0 disables the pre-divider.
- * @pllm: The multiplier value. Passing 0 leads to multiply-by-one.
- * @postdiv: The post divider value. Passing 0 disables the post-divider.
- */
-int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
-                                       unsigned int mult, unsigned int postdiv)
-{
-       u32 ctrl;
-       unsigned int locktime;
-       unsigned long flags;
-
-       if (pll->base == NULL)
-               return -EINVAL;
-
-       /*
-        *  PLL lock time required per OMAP-L138 datasheet is
-        * (2000 * prediv)/sqrt(pllm) OSCIN cycles. We approximate sqrt(pllm)
-        * as 4 and OSCIN cycle as 25 MHz.
-        */
-       if (prediv) {
-               locktime = ((2000 * prediv) / 100);
-               prediv = (prediv - 1) | PLLDIV_EN;
-       } else {
-               locktime = PLL_LOCK_TIME;
-       }
-       if (postdiv)
-               postdiv = (postdiv - 1) | PLLDIV_EN;
-       if (mult)
-               mult = mult - 1;
-
-       /* Protect against simultaneous calls to PLL setting seqeunce */
-       spin_lock_irqsave(&clockfw_lock, flags);
-
-       ctrl = __raw_readl(pll->base + PLLCTL);
-
-       /* Switch the PLL to bypass mode */
-       ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
-       __raw_writel(ctrl, pll->base + PLLCTL);
-
-       udelay(PLL_BYPASS_TIME);
-
-       /* Reset and enable PLL */
-       ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS);
-       __raw_writel(ctrl, pll->base + PLLCTL);
-
-       if (pll->flags & PLL_HAS_PREDIV)
-               __raw_writel(prediv, pll->base + PREDIV);
-
-       __raw_writel(mult, pll->base + PLLM);
-
-       if (pll->flags & PLL_HAS_POSTDIV)
-               __raw_writel(postdiv, pll->base + POSTDIV);
-
-       udelay(PLL_RESET_TIME);
-
-       /* Bring PLL out of reset */
-       ctrl |= PLLCTL_PLLRST;
-       __raw_writel(ctrl, pll->base + PLLCTL);
-
-       udelay(locktime);
-
-       /* Remove PLL from bypass mode */
-       ctrl |= PLLCTL_PLLEN;
-       __raw_writel(ctrl, pll->base + PLLCTL);
-
-       spin_unlock_irqrestore(&clockfw_lock, flags);
-
-       return 0;
-}
-EXPORT_SYMBOL(davinci_set_pllrate);
-
-/**
- * davinci_set_refclk_rate() - Set the reference clock rate
- * @rate:      The new rate.
- *
- * Sets the reference clock rate to a given value. This will most likely
- * result in the entire clock tree getting updated.
- *
- * This is used to support boards which use a reference clock different
- * than that used by default in <soc>.c file. The reference clock rate
- * should be updated early in the boot process; ideally soon after the
- * clock tree has been initialized once with the default reference clock
- * rate (davinci_clk_init()).
- *
- * Returns 0 on success, error otherwise.
- */
-int davinci_set_refclk_rate(unsigned long rate)
-{
-       struct clk *refclk;
-
-       refclk = clk_get(NULL, "ref");
-       if (IS_ERR(refclk)) {
-               pr_err("%s: failed to get reference clock\n", __func__);
-               return PTR_ERR(refclk);
-       }
-
-       clk_set_rate(refclk, rate);
-
-       clk_put(refclk);
-
-       return 0;
-}
-
-int __init davinci_clk_init(struct clk_lookup *clocks)
-{
-       struct clk_lookup *c;
-       struct clk *clk;
-       size_t num_clocks = 0;
-
-       for (c = clocks; c->clk; c++) {
-               clk = c->clk;
-
-               if (!clk->recalc) {
-
-                       /* Check if clock is a PLL */
-                       if (clk->pll_data)
-                               clk->recalc = clk_pllclk_recalc;
-
-                       /* Else, if it is a PLL-derived clock */
-                       else if (clk->flags & CLK_PLL)
-                               clk->recalc = clk_sysclk_recalc;
-
-                       /* Otherwise, it is a leaf clock (PSC clock) */
-                       else if (clk->parent)
-                               clk->recalc = clk_leafclk_recalc;
-               }
-
-               if (clk->pll_data) {
-                       struct pll_data *pll = clk->pll_data;
-
-                       if (!pll->div_ratio_mask)
-                               pll->div_ratio_mask = PLLDIV_RATIO_MASK;
-
-                       if (pll->phys_base && !pll->base) {
-                               pll->base = ioremap(pll->phys_base, SZ_4K);
-                               WARN_ON(!pll->base);
-                       }
-               }
-
-               if (clk->recalc)
-                       clk->rate = clk->recalc(clk);
-
-               if (clk->lpsc)
-                       clk->flags |= CLK_PSC;
-
-               if (clk->flags & PSC_LRST)
-                       clk->reset = davinci_clk_reset;
-
-               clk_register(clk);
-               num_clocks++;
-
-               /* Turn on clocks that Linux doesn't otherwise manage */
-               if (clk->flags & ALWAYS_ENABLED)
-                       clk_enable(clk);
-       }
-
-       clkdev_add_table(clocks, num_clocks);
-
-       return 0;
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-
-#define CLKNAME_MAX    10              /* longest clock name */
-#define NEST_DELTA     2
-#define NEST_MAX       4
-
-static void
-dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
-{
-       char            *state;
-       char            buf[CLKNAME_MAX + NEST_DELTA * NEST_MAX];
-       struct clk      *clk;
-       unsigned        i;
-
-       if (parent->flags & CLK_PLL)
-               state = "pll";
-       else if (parent->flags & CLK_PSC)
-               state = "psc";
-       else
-               state = "";
-
-       /* <nest spaces> name <pad to end> */
-       memset(buf, ' ', sizeof(buf) - 1);
-       buf[sizeof(buf) - 1] = 0;
-       i = strlen(parent->name);
-       memcpy(buf + nest, parent->name,
-                       min(i, (unsigned)(sizeof(buf) - 1 - nest)));
-
-       seq_printf(s, "%s users=%2d %-3s %9ld Hz\n",
-                  buf, parent->usecount, state, clk_get_rate(parent));
-       /* REVISIT show device associations too */
-
-       /* cost is now small, but not linear... */
-       list_for_each_entry(clk, &parent->children, childnode) {
-               dump_clock(s, nest + NEST_DELTA, clk);
-       }
-}
-
-static int davinci_ck_show(struct seq_file *m, void *v)
-{
-       struct clk *clk;
-
-       /*
-        * Show clock tree; We trust nonzero usecounts equate to PSC enables...
-        */
-       mutex_lock(&clocks_mutex);
-       list_for_each_entry(clk, &clocks, node)
-               if (!clk->parent)
-                       dump_clock(m, 0, clk);
-       mutex_unlock(&clocks_mutex);
-
-       return 0;
-}
-
-static int davinci_ck_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, davinci_ck_show, NULL);
-}
-
-static const struct file_operations davinci_ck_operations = {
-       .open           = davinci_ck_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
-static int __init davinci_clk_debugfs_init(void)
-{
-       debugfs_create_file("davinci_clocks", S_IFREG | S_IRUGO, NULL, NULL,
-                                               &davinci_ck_operations);
-       return 0;
-
-}
-device_initcall(davinci_clk_debugfs_init);
-#endif /* CONFIG_DEBUG_FS */
index d7894d5aaa250b027d4f035369b0d3b2ec08efd2..307383472400d103888a4194daff7eeb93c43031 100644 (file)
 #ifndef __ARCH_ARM_DAVINCI_CLOCK_H
 #define __ARCH_ARM_DAVINCI_CLOCK_H
 
-#define DAVINCI_PLL1_BASE 0x01c40800
-#define DAVINCI_PLL2_BASE 0x01c40c00
-#define MAX_PLL 2
-
 /* PLL/Reset register offsets */
 #define PLLCTL          0x100
 #define PLLCTL_PLLEN    BIT(0)
  */
 #define PLL_LOCK_TIME          20
 
-#ifndef __ASSEMBLER__
-
-#include <linux/list.h>
-#include <linux/clkdev.h>
-
-#define PLLSTAT_GOSTAT BIT(0)
-#define PLLCMD_GOSET   BIT(0)
-
-struct pll_data {
-       u32 phys_base;
-       void __iomem *base;
-       u32 num;
-       u32 flags;
-       u32 input_rate;
-       u32 div_ratio_mask;
-};
-#define PLL_HAS_PREDIV          0x01
-#define PLL_HAS_POSTDIV         0x02
-
-struct clk {
-       struct list_head        node;
-       struct module           *owner;
-       const char              *name;
-       unsigned long           rate;
-       unsigned long           maxrate;        /* H/W supported max rate */
-       u8                      usecount;
-       u8                      lpsc;
-       u8                      gpsc;
-       u8                      domain;
-       u32                     flags;
-       struct clk              *parent;
-       struct list_head        children;       /* list of children */
-       struct list_head        childnode;      /* parent's child list node */
-       struct pll_data         *pll_data;
-       u32                     div_reg;
-       unsigned long (*recalc) (struct clk *);
-       int (*set_rate) (struct clk *clk, unsigned long rate);
-       int (*round_rate) (struct clk *clk, unsigned long rate);
-       int (*reset) (struct clk *clk, bool reset);
-       void (*clk_enable) (struct clk *clk);
-       void (*clk_disable) (struct clk *clk);
-       int (*set_parent) (struct clk *clk, struct clk *parent);
-};
-
-/* Clock flags: SoC-specific flags start at BIT(16) */
-#define ALWAYS_ENABLED         BIT(1)
-#define CLK_PSC                        BIT(2)
-#define CLK_PLL                        BIT(3) /* PLL-derived clock */
-#define PRE_PLL                        BIT(4) /* source is before PLL mult/div */
-#define PSC_SWRSTDISABLE       BIT(5) /* Disable state is SwRstDisable */
-#define PSC_FORCE              BIT(6) /* Force module state transtition */
-#define PSC_LRST               BIT(8) /* Use local reset on enable/disable */
-
-#define CLK(dev, con, ck)      \
-       {                       \
-               .dev_id = dev,  \
-               .con_id = con,  \
-               .clk = ck,      \
-       }                       \
-
-int davinci_clk_init(struct clk_lookup *clocks);
-int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
-                               unsigned int mult, unsigned int postdiv);
-int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate);
-int davinci_set_refclk_rate(unsigned long rate);
-int davinci_simple_set_rate(struct clk *clk, unsigned long rate);
-int davinci_clk_reset(struct clk *clk, bool reset);
-void davinci_clk_enable(struct clk *clk);
-void davinci_clk_disable(struct clk *clk);
-
-#endif
-
 #endif
index bcb6a7ba84e9ee4640d1b31e51f734354dff2378..e1d0f0d841ff4908fb2e249e9bdc96fd53ec8cbc 100644 (file)
@@ -20,8 +20,6 @@
 #include <mach/common.h>
 #include <mach/cputype.h>
 
-#include "clock.h"
-
 struct davinci_soc_info davinci_soc_info;
 EXPORT_SYMBOL(davinci_soc_info);
 
@@ -118,5 +116,4 @@ err:
 void __init davinci_init_late(void)
 {
        davinci_cpufreq_init();
-       davinci_clk_disable_unused();
 }
index 350d7673aa4d0222a91c2a2aa13ed87d57cab453..0bc5bd2665df8dd1433a78f93819727ae473b1f0 100644 (file)
@@ -8,21 +8,20 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
+#include <linux/clk-provider.h>
+#include <linux/clk/davinci.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
-#include <linux/clk.h>
 #include <linux/platform_data/gpio-davinci.h>
 
 #include <asm/mach/map.h>
 
-#include "psc.h"
-#include <mach/irqs.h>
-#include <mach/cputype.h>
 #include <mach/common.h>
-#include <mach/time.h>
+#include <mach/cputype.h>
 #include <mach/da8xx.h>
+#include <mach/irqs.h>
+#include <mach/time.h>
 
-#include "clock.h"
 #include "mux.h"
 
 /* Offsets of the 8 compare registers on the da830 */
 
 #define DA830_REF_FREQ         24000000
 
-static struct pll_data pll0_data = {
-       .num            = 1,
-       .phys_base      = DA8XX_PLL0_BASE,
-       .flags          = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
-};
-
-static struct clk ref_clk = {
-       .name           = "ref_clk",
-       .rate           = DA830_REF_FREQ,
-};
-
-static struct clk pll0_clk = {
-       .name           = "pll0",
-       .parent         = &ref_clk,
-       .pll_data       = &pll0_data,
-       .flags          = CLK_PLL,
-};
-
-static struct clk pll0_aux_clk = {
-       .name           = "pll0_aux_clk",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll0_sysclk2 = {
-       .name           = "pll0_sysclk2",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV2,
-};
-
-static struct clk pll0_sysclk3 = {
-       .name           = "pll0_sysclk3",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV3,
-};
-
-static struct clk pll0_sysclk4 = {
-       .name           = "pll0_sysclk4",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV4,
-};
-
-static struct clk pll0_sysclk5 = {
-       .name           = "pll0_sysclk5",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV5,
-};
-
-static struct clk pll0_sysclk6 = {
-       .name           = "pll0_sysclk6",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV6,
-};
-
-static struct clk pll0_sysclk7 = {
-       .name           = "pll0_sysclk7",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV7,
-};
-
-static struct clk i2c0_clk = {
-       .name           = "i2c0",
-       .parent         = &pll0_aux_clk,
-};
-
-static struct clk timerp64_0_clk = {
-       .name           = "timer0",
-       .parent         = &pll0_aux_clk,
-};
-
-static struct clk timerp64_1_clk = {
-       .name           = "timer1",
-       .parent         = &pll0_aux_clk,
-};
-
-static struct clk arm_rom_clk = {
-       .name           = "arm_rom",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_ARM_RAM_ROM,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk scr0_ss_clk = {
-       .name           = "scr0_ss",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_SCR0_SS,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk scr1_ss_clk = {
-       .name           = "scr1_ss",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_SCR1_SS,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk scr2_ss_clk = {
-       .name           = "scr2_ss",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_SCR2_SS,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk dmax_clk = {
-       .name           = "dmax",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_PRUSS,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk tpcc_clk = {
-       .name           = "tpcc",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_TPCC,
-       .flags          = ALWAYS_ENABLED | CLK_PSC,
-};
-
-static struct clk tptc0_clk = {
-       .name           = "tptc0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_TPTC0,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk tptc1_clk = {
-       .name           = "tptc1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_TPTC1,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk mmcsd_clk = {
-       .name           = "mmcsd",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_MMC_SD,
-};
-
-static struct clk uart0_clk = {
-       .name           = "uart0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_UART0,
-};
-
-static struct clk uart1_clk = {
-       .name           = "uart1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_UART1,
-       .gpsc           = 1,
-};
-
-static struct clk uart2_clk = {
-       .name           = "uart2",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_UART2,
-       .gpsc           = 1,
-};
-
-static struct clk spi0_clk = {
-       .name           = "spi0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_SPI0,
-};
-
-static struct clk spi1_clk = {
-       .name           = "spi1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_SPI1,
-       .gpsc           = 1,
-};
-
-static struct clk ecap0_clk = {
-       .name           = "ecap0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_ECAP,
-       .gpsc           = 1,
-};
-
-static struct clk ecap1_clk = {
-       .name           = "ecap1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_ECAP,
-       .gpsc           = 1,
-};
-
-static struct clk ecap2_clk = {
-       .name           = "ecap2",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_ECAP,
-       .gpsc           = 1,
-};
-
-static struct clk pwm0_clk = {
-       .name           = "pwm0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_PWM,
-       .gpsc           = 1,
-};
-
-static struct clk pwm1_clk = {
-       .name           = "pwm1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_PWM,
-       .gpsc           = 1,
-};
-
-static struct clk pwm2_clk = {
-       .name           = "pwm2",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_PWM,
-       .gpsc           = 1,
-};
-
-static struct clk eqep0_clk = {
-       .name           = "eqep0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA830_LPSC1_EQEP,
-       .gpsc           = 1,
-};
-
-static struct clk eqep1_clk = {
-       .name           = "eqep1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA830_LPSC1_EQEP,
-       .gpsc           = 1,
-};
-
-static struct clk lcdc_clk = {
-       .name           = "lcdc",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_LCDC,
-       .gpsc           = 1,
-};
-
-static struct clk mcasp0_clk = {
-       .name           = "mcasp0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_McASP0,
-       .gpsc           = 1,
-};
-
-static struct clk mcasp1_clk = {
-       .name           = "mcasp1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA830_LPSC1_McASP1,
-       .gpsc           = 1,
-};
-
-static struct clk mcasp2_clk = {
-       .name           = "mcasp2",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA830_LPSC1_McASP2,
-       .gpsc           = 1,
-};
-
-static struct clk usb20_clk = {
-       .name           = "usb20",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_USB20,
-       .gpsc           = 1,
-};
-
-static struct clk cppi41_clk = {
-       .name           = "cppi41",
-       .parent         = &usb20_clk,
-};
-
-static struct clk aemif_clk = {
-       .name           = "aemif",
-       .parent         = &pll0_sysclk3,
-       .lpsc           = DA8XX_LPSC0_EMIF25,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk aintc_clk = {
-       .name           = "aintc",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC0_AINTC,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk secu_mgr_clk = {
-       .name           = "secu_mgr",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC0_SECU_MGR,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk emac_clk = {
-       .name           = "emac",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC1_CPGMAC,
-       .gpsc           = 1,
-};
-
-static struct clk gpio_clk = {
-       .name           = "gpio",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC1_GPIO,
-       .gpsc           = 1,
-};
-
-static struct clk i2c1_clk = {
-       .name           = "i2c1",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC1_I2C,
-       .gpsc           = 1,
-};
-
-static struct clk usb11_clk = {
-       .name           = "usb11",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC1_USB11,
-       .gpsc           = 1,
-};
-
-static struct clk emif3_clk = {
-       .name           = "emif3",
-       .parent         = &pll0_sysclk5,
-       .lpsc           = DA8XX_LPSC1_EMIF3C,
-       .gpsc           = 1,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk arm_clk = {
-       .name           = "arm",
-       .parent         = &pll0_sysclk6,
-       .lpsc           = DA8XX_LPSC0_ARM,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk rmii_clk = {
-       .name           = "rmii",
-       .parent         = &pll0_sysclk7,
-};
-
-static struct clk_lookup da830_clks[] = {
-       CLK(NULL,               "ref",          &ref_clk),
-       CLK(NULL,               "pll0",         &pll0_clk),
-       CLK(NULL,               "pll0_aux",     &pll0_aux_clk),
-       CLK(NULL,               "pll0_sysclk2", &pll0_sysclk2),
-       CLK(NULL,               "pll0_sysclk3", &pll0_sysclk3),
-       CLK(NULL,               "pll0_sysclk4", &pll0_sysclk4),
-       CLK(NULL,               "pll0_sysclk5", &pll0_sysclk5),
-       CLK(NULL,               "pll0_sysclk6", &pll0_sysclk6),
-       CLK(NULL,               "pll0_sysclk7", &pll0_sysclk7),
-       CLK("i2c_davinci.1",    NULL,           &i2c0_clk),
-       CLK(NULL,               "timer0",       &timerp64_0_clk),
-       CLK("davinci-wdt",      NULL,           &timerp64_1_clk),
-       CLK(NULL,               "arm_rom",      &arm_rom_clk),
-       CLK(NULL,               "scr0_ss",      &scr0_ss_clk),
-       CLK(NULL,               "scr1_ss",      &scr1_ss_clk),
-       CLK(NULL,               "scr2_ss",      &scr2_ss_clk),
-       CLK(NULL,               "dmax",         &dmax_clk),
-       CLK(NULL,               "tpcc",         &tpcc_clk),
-       CLK(NULL,               "tptc0",        &tptc0_clk),
-       CLK(NULL,               "tptc1",        &tptc1_clk),
-       CLK("da830-mmc.0",      NULL,           &mmcsd_clk),
-       CLK("serial8250.0",     NULL,           &uart0_clk),
-       CLK("serial8250.1",     NULL,           &uart1_clk),
-       CLK("serial8250.2",     NULL,           &uart2_clk),
-       CLK("spi_davinci.0",    NULL,           &spi0_clk),
-       CLK("spi_davinci.1",    NULL,           &spi1_clk),
-       CLK(NULL,               "ecap0",        &ecap0_clk),
-       CLK(NULL,               "ecap1",        &ecap1_clk),
-       CLK(NULL,               "ecap2",        &ecap2_clk),
-       CLK(NULL,               "pwm0",         &pwm0_clk),
-       CLK(NULL,               "pwm1",         &pwm1_clk),
-       CLK(NULL,               "pwm2",         &pwm2_clk),
-       CLK("eqep.0",           NULL,           &eqep0_clk),
-       CLK("eqep.1",           NULL,           &eqep1_clk),
-       CLK("da8xx_lcdc.0",     "fck",          &lcdc_clk),
-       CLK("davinci-mcasp.0",  NULL,           &mcasp0_clk),
-       CLK("davinci-mcasp.1",  NULL,           &mcasp1_clk),
-       CLK("davinci-mcasp.2",  NULL,           &mcasp2_clk),
-       CLK("musb-da8xx",       NULL,           &usb20_clk),
-       CLK("cppi41-dmaengine", NULL,           &cppi41_clk),
-       CLK(NULL,               "aemif",        &aemif_clk),
-       CLK(NULL,               "aintc",        &aintc_clk),
-       CLK(NULL,               "secu_mgr",     &secu_mgr_clk),
-       CLK("davinci_emac.1",   NULL,           &emac_clk),
-       CLK("davinci_mdio.0",   "fck",          &emac_clk),
-       CLK(NULL,               "gpio",         &gpio_clk),
-       CLK("i2c_davinci.2",    NULL,           &i2c1_clk),
-       CLK("ohci-da8xx",       NULL,   &usb11_clk),
-       CLK(NULL,               "emif3",        &emif3_clk),
-       CLK(NULL,               "arm",          &arm_clk),
-       CLK(NULL,               "rmii",         &rmii_clk),
-       CLK(NULL,               NULL,           NULL),
-};
-
 /*
  * Device specific mux setup
  *
@@ -1130,8 +733,6 @@ static struct map_desc da830_io_desc[] = {
        },
 };
 
-static u32 da830_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
-
 /* Contents of JTAG ID register used to identify exact cpu type */
 static struct davinci_id da830_ids[] = {
        {
@@ -1200,8 +801,6 @@ static const struct davinci_soc_info davinci_soc_info_da830 = {
        .jtag_id_reg            = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
        .ids                    = da830_ids,
        .ids_num                = ARRAY_SIZE(da830_ids),
-       .psc_bases              = da830_psc_bases,
-       .psc_bases_num          = ARRAY_SIZE(da830_psc_bases),
        .pinmux_base            = DA8XX_SYSCFG0_BASE + 0x120,
        .pinmux_pins            = da830_pins,
        .pinmux_pins_num        = ARRAY_SIZE(da830_pins),
@@ -1223,6 +822,53 @@ void __init da830_init(void)
 
 void __init da830_init_time(void)
 {
-       davinci_clk_init(da830_clks);
-       davinci_timer_init();
+       void __iomem *pll;
+       struct clk *clk;
+
+       clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DA830_REF_FREQ);
+
+       pll = ioremap(DA8XX_PLL0_BASE, SZ_4K);
+
+       da830_pll_init(NULL, pll, NULL);
+
+       clk = clk_get(NULL, "timer0");
+
+       davinci_timer_init(clk);
+}
+
+static struct resource da830_psc0_resources[] = {
+       {
+               .start  = DA8XX_PSC0_BASE,
+               .end    = DA8XX_PSC0_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device da830_psc0_device = {
+       .name           = "da830-psc0",
+       .id             = -1,
+       .resource       = da830_psc0_resources,
+       .num_resources  = ARRAY_SIZE(da830_psc0_resources),
+};
+
+static struct resource da830_psc1_resources[] = {
+       {
+               .start  = DA8XX_PSC1_BASE,
+               .end    = DA8XX_PSC1_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device da830_psc1_device = {
+       .name           = "da830-psc1",
+       .id             = -1,
+       .resource       = da830_psc1_resources,
+       .num_resources  = ARRAY_SIZE(da830_psc1_resources),
+};
+
+void __init da830_register_clocks(void)
+{
+       /* PLL is registered in da830_init_time() */
+       platform_device_register(&da830_psc0_device);
+       platform_device_register(&da830_psc1_device);
 }
index 34117e614e08ddf692835b97d4776189feeb1268..4528bbf0c86187b91413c74242a5d82cfed4de01 100644 (file)
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
+
+#include <linux/clk-provider.h>
+#include <linux/clk/davinci.h>
 #include <linux/clkdev.h>
+#include <linux/cpufreq.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
-#include <linux/clk.h>
+#include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/platform_data/clk-da8xx-cfgchip.h>
+#include <linux/platform_data/clk-davinci-pll.h>
+#include <linux/platform_data/gpio-davinci.h>
 #include <linux/platform_device.h>
-#include <linux/cpufreq.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
-#include <linux/platform_data/gpio-davinci.h>
 
 #include <asm/mach/map.h>
 
-#include "psc.h"
-#include <mach/irqs.h>
-#include <mach/cputype.h>
 #include <mach/common.h>
-#include <mach/time.h>
-#include <mach/da8xx.h>
 #include <mach/cpufreq.h>
+#include <mach/cputype.h>
+#include <mach/da8xx.h>
+#include <mach/irqs.h>
 #include <mach/pm.h>
+#include <mach/time.h>
 
-#include "clock.h"
 #include "mux.h"
 
 #define DA850_PLL1_BASE                0x01e1a000
 
 #define DA850_REF_FREQ         24000000
 
-#define CFGCHIP3_ASYNC3_CLKSRC BIT(4)
-#define CFGCHIP3_PLL1_MASTER_LOCK      BIT(5)
-#define CFGCHIP0_PLL_MASTER_LOCK       BIT(4)
-
-static int da850_set_armrate(struct clk *clk, unsigned long rate);
-static int da850_round_armrate(struct clk *clk, unsigned long rate);
-static int da850_set_pll0rate(struct clk *clk, unsigned long armrate);
-
-static struct pll_data pll0_data = {
-       .num            = 1,
-       .phys_base      = DA8XX_PLL0_BASE,
-       .flags          = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
-};
-
-static struct clk ref_clk = {
-       .name           = "ref_clk",
-       .rate           = DA850_REF_FREQ,
-       .set_rate       = davinci_simple_set_rate,
-};
-
-static struct clk pll0_clk = {
-       .name           = "pll0",
-       .parent         = &ref_clk,
-       .pll_data       = &pll0_data,
-       .flags          = CLK_PLL,
-       .set_rate       = da850_set_pll0rate,
-};
-
-static struct clk pll0_aux_clk = {
-       .name           = "pll0_aux_clk",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll0_sysclk1 = {
-       .name           = "pll0_sysclk1",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV1,
-};
-
-static struct clk pll0_sysclk2 = {
-       .name           = "pll0_sysclk2",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV2,
-};
-
-static struct clk pll0_sysclk3 = {
-       .name           = "pll0_sysclk3",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV3,
-       .set_rate       = davinci_set_sysclk_rate,
-       .maxrate        = 100000000,
-};
-
-static struct clk pll0_sysclk4 = {
-       .name           = "pll0_sysclk4",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV4,
-};
-
-static struct clk pll0_sysclk5 = {
-       .name           = "pll0_sysclk5",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV5,
-};
-
-static struct clk pll0_sysclk6 = {
-       .name           = "pll0_sysclk6",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV6,
-};
-
-static struct clk pll0_sysclk7 = {
-       .name           = "pll0_sysclk7",
-       .parent         = &pll0_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV7,
-};
-
-static struct pll_data pll1_data = {
-       .num            = 2,
-       .phys_base      = DA850_PLL1_BASE,
-       .flags          = PLL_HAS_POSTDIV,
-};
-
-static struct clk pll1_clk = {
-       .name           = "pll1",
-       .parent         = &ref_clk,
-       .pll_data       = &pll1_data,
-       .flags          = CLK_PLL,
-};
-
-static struct clk pll1_aux_clk = {
-       .name           = "pll1_aux_clk",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll1_sysclk2 = {
-       .name           = "pll1_sysclk2",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV2,
-};
-
-static struct clk pll1_sysclk3 = {
-       .name           = "pll1_sysclk3",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV3,
-};
-
-static int da850_async3_set_parent(struct clk *clk, struct clk *parent)
-{
-       u32 val;
-
-       val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
-
-       if (parent == &pll0_sysclk2) {
-               val &= ~CFGCHIP3_ASYNC3_CLKSRC;
-       } else if (parent == &pll1_sysclk2) {
-               val |= CFGCHIP3_ASYNC3_CLKSRC;
-       } else {
-               pr_err("Bad parent on async3 clock mux\n");
-               return -EINVAL;
-       }
-
-       writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
-
-       return 0;
-}
-
-static struct clk async3_clk = {
-       .name           = "async3",
-       .parent         = &pll1_sysclk2,
-       .set_parent     = da850_async3_set_parent,
-};
-
-static struct clk i2c0_clk = {
-       .name           = "i2c0",
-       .parent         = &pll0_aux_clk,
-};
-
-static struct clk timerp64_0_clk = {
-       .name           = "timer0",
-       .parent         = &pll0_aux_clk,
-};
-
-static struct clk timerp64_1_clk = {
-       .name           = "timer1",
-       .parent         = &pll0_aux_clk,
-};
-
-static struct clk arm_rom_clk = {
-       .name           = "arm_rom",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_ARM_RAM_ROM,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk tpcc0_clk = {
-       .name           = "tpcc0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_TPCC,
-       .flags          = ALWAYS_ENABLED | CLK_PSC,
-};
-
-static struct clk tptc0_clk = {
-       .name           = "tptc0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_TPTC0,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk tptc1_clk = {
-       .name           = "tptc1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_TPTC1,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk tpcc1_clk = {
-       .name           = "tpcc1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA850_LPSC1_TPCC1,
-       .gpsc           = 1,
-       .flags          = CLK_PSC | ALWAYS_ENABLED,
-};
-
-static struct clk tptc2_clk = {
-       .name           = "tptc2",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA850_LPSC1_TPTC2,
-       .gpsc           = 1,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk pruss_clk = {
-       .name           = "pruss",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_PRUSS,
-};
-
-static struct clk uart0_clk = {
-       .name           = "uart0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_UART0,
-};
-
-static struct clk uart1_clk = {
-       .name           = "uart1",
-       .parent         = &async3_clk,
-       .lpsc           = DA8XX_LPSC1_UART1,
-       .gpsc           = 1,
-};
-
-static struct clk uart2_clk = {
-       .name           = "uart2",
-       .parent         = &async3_clk,
-       .lpsc           = DA8XX_LPSC1_UART2,
-       .gpsc           = 1,
-};
-
-static struct clk aintc_clk = {
-       .name           = "aintc",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC0_AINTC,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk gpio_clk = {
-       .name           = "gpio",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC1_GPIO,
-       .gpsc           = 1,
-};
-
-static struct clk i2c1_clk = {
-       .name           = "i2c1",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC1_I2C,
-       .gpsc           = 1,
-};
-
-static struct clk emif3_clk = {
-       .name           = "emif3",
-       .parent         = &pll0_sysclk5,
-       .lpsc           = DA8XX_LPSC1_EMIF3C,
-       .gpsc           = 1,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk arm_clk = {
-       .name           = "arm",
-       .parent         = &pll0_sysclk6,
-       .lpsc           = DA8XX_LPSC0_ARM,
-       .flags          = ALWAYS_ENABLED,
-       .set_rate       = da850_set_armrate,
-       .round_rate     = da850_round_armrate,
-};
-
-static struct clk rmii_clk = {
-       .name           = "rmii",
-       .parent         = &pll0_sysclk7,
-};
-
-static struct clk emac_clk = {
-       .name           = "emac",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC1_CPGMAC,
-       .gpsc           = 1,
-};
-
-/*
- * In order to avoid adding the emac_clk to the clock lookup table twice (and
- * screwing up the linked list in the process) create a separate clock for
- * mdio inheriting the rate from emac_clk.
- */
-static struct clk mdio_clk = {
-       .name           = "mdio",
-       .parent         = &emac_clk,
-};
-
-static struct clk mcasp_clk = {
-       .name           = "mcasp",
-       .parent         = &async3_clk,
-       .lpsc           = DA8XX_LPSC1_McASP0,
-       .gpsc           = 1,
-};
-
-static struct clk mcbsp0_clk = {
-       .name           = "mcbsp0",
-       .parent         = &async3_clk,
-       .lpsc           = DA850_LPSC1_McBSP0,
-       .gpsc           = 1,
-};
-
-static struct clk mcbsp1_clk = {
-       .name           = "mcbsp1",
-       .parent         = &async3_clk,
-       .lpsc           = DA850_LPSC1_McBSP1,
-       .gpsc           = 1,
-};
-
-static struct clk lcdc_clk = {
-       .name           = "lcdc",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_LCDC,
-       .gpsc           = 1,
-};
-
-static struct clk mmcsd0_clk = {
-       .name           = "mmcsd0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_MMC_SD,
-};
-
-static struct clk mmcsd1_clk = {
-       .name           = "mmcsd1",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA850_LPSC1_MMC_SD1,
-       .gpsc           = 1,
-};
-
-static struct clk aemif_clk = {
-       .name           = "aemif",
-       .parent         = &pll0_sysclk3,
-       .lpsc           = DA8XX_LPSC0_EMIF25,
-       .flags          = ALWAYS_ENABLED,
-};
-
-/*
- * In order to avoid adding the aemif_clk to the clock lookup table twice (and
- * screwing up the linked list in the process) create a separate clock for
- * nand inheriting the rate from aemif_clk.
- */
-static struct clk aemif_nand_clk = {
-       .name           = "nand",
-       .parent         = &aemif_clk,
-};
-
-static struct clk usb11_clk = {
-       .name           = "usb11",
-       .parent         = &pll0_sysclk4,
-       .lpsc           = DA8XX_LPSC1_USB11,
-       .gpsc           = 1,
-};
-
-static struct clk usb20_clk = {
-       .name           = "usb20",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC1_USB20,
-       .gpsc           = 1,
-};
-
-static struct clk cppi41_clk = {
-       .name           = "cppi41",
-       .parent         = &usb20_clk,
-};
-
-static struct clk spi0_clk = {
-       .name           = "spi0",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA8XX_LPSC0_SPI0,
-};
-
-static struct clk spi1_clk = {
-       .name           = "spi1",
-       .parent         = &async3_clk,
-       .lpsc           = DA8XX_LPSC1_SPI1,
-       .gpsc           = 1,
-};
-
-static struct clk vpif_clk = {
-       .name           = "vpif",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA850_LPSC1_VPIF,
-       .gpsc           = 1,
-};
-
-static struct clk sata_clk = {
-       .name           = "sata",
-       .parent         = &pll0_sysclk2,
-       .lpsc           = DA850_LPSC1_SATA,
-       .gpsc           = 1,
-       .flags          = PSC_FORCE,
-};
-
-static struct clk dsp_clk = {
-       .name           = "dsp",
-       .parent         = &pll0_sysclk1,
-       .domain         = DAVINCI_GPSC_DSPDOMAIN,
-       .lpsc           = DA8XX_LPSC0_GEM,
-       .flags          = PSC_LRST | PSC_FORCE,
-};
-
-static struct clk ehrpwm_clk = {
-       .name           = "ehrpwm",
-       .parent         = &async3_clk,
-       .lpsc           = DA8XX_LPSC1_PWM,
-       .gpsc           = 1,
-};
-
-static struct clk ehrpwm0_clk = {
-       .name           = "ehrpwm0",
-       .parent         = &ehrpwm_clk,
-};
-
-static struct clk ehrpwm1_clk = {
-       .name           = "ehrpwm1",
-       .parent         = &ehrpwm_clk,
-};
-
-#define DA8XX_EHRPWM_TBCLKSYNC BIT(12)
-
-static void ehrpwm_tblck_enable(struct clk *clk)
-{
-       u32 val;
-
-       val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
-       val |= DA8XX_EHRPWM_TBCLKSYNC;
-       writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
-}
-
-static void ehrpwm_tblck_disable(struct clk *clk)
-{
-       u32 val;
-
-       val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
-       val &= ~DA8XX_EHRPWM_TBCLKSYNC;
-       writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP1_REG));
-}
-
-static struct clk ehrpwm_tbclk = {
-       .name           = "ehrpwm_tbclk",
-       .parent         = &ehrpwm_clk,
-       .clk_enable     = ehrpwm_tblck_enable,
-       .clk_disable    = ehrpwm_tblck_disable,
-};
-
-static struct clk ehrpwm0_tbclk = {
-       .name           = "ehrpwm0_tbclk",
-       .parent         = &ehrpwm_tbclk,
-};
-
-static struct clk ehrpwm1_tbclk = {
-       .name           = "ehrpwm1_tbclk",
-       .parent         = &ehrpwm_tbclk,
-};
-
-static struct clk ecap_clk = {
-       .name           = "ecap",
-       .parent         = &async3_clk,
-       .lpsc           = DA8XX_LPSC1_ECAP,
-       .gpsc           = 1,
-};
-
-static struct clk ecap0_clk = {
-       .name           = "ecap0_clk",
-       .parent         = &ecap_clk,
-};
-
-static struct clk ecap1_clk = {
-       .name           = "ecap1_clk",
-       .parent         = &ecap_clk,
-};
-
-static struct clk ecap2_clk = {
-       .name           = "ecap2_clk",
-       .parent         = &ecap_clk,
-};
-
-static struct clk_lookup da850_clks[] = {
-       CLK(NULL,               "ref",          &ref_clk),
-       CLK(NULL,               "pll0",         &pll0_clk),
-       CLK(NULL,               "pll0_aux",     &pll0_aux_clk),
-       CLK(NULL,               "pll0_sysclk1", &pll0_sysclk1),
-       CLK(NULL,               "pll0_sysclk2", &pll0_sysclk2),
-       CLK(NULL,               "pll0_sysclk3", &pll0_sysclk3),
-       CLK(NULL,               "pll0_sysclk4", &pll0_sysclk4),
-       CLK(NULL,               "pll0_sysclk5", &pll0_sysclk5),
-       CLK(NULL,               "pll0_sysclk6", &pll0_sysclk6),
-       CLK(NULL,               "pll0_sysclk7", &pll0_sysclk7),
-       CLK(NULL,               "pll1",         &pll1_clk),
-       CLK(NULL,               "pll1_aux",     &pll1_aux_clk),
-       CLK(NULL,               "pll1_sysclk2", &pll1_sysclk2),
-       CLK(NULL,               "pll1_sysclk3", &pll1_sysclk3),
-       CLK(NULL,               "async3",       &async3_clk),
-       CLK("i2c_davinci.1",    NULL,           &i2c0_clk),
-       CLK(NULL,               "timer0",       &timerp64_0_clk),
-       CLK("davinci-wdt",      NULL,           &timerp64_1_clk),
-       CLK(NULL,               "arm_rom",      &arm_rom_clk),
-       CLK(NULL,               "tpcc0",        &tpcc0_clk),
-       CLK(NULL,               "tptc0",        &tptc0_clk),
-       CLK(NULL,               "tptc1",        &tptc1_clk),
-       CLK(NULL,               "tpcc1",        &tpcc1_clk),
-       CLK(NULL,               "tptc2",        &tptc2_clk),
-       CLK("pruss_uio",        "pruss",        &pruss_clk),
-       CLK("serial8250.0",     NULL,           &uart0_clk),
-       CLK("serial8250.1",     NULL,           &uart1_clk),
-       CLK("serial8250.2",     NULL,           &uart2_clk),
-       CLK(NULL,               "aintc",        &aintc_clk),
-       CLK(NULL,               "gpio",         &gpio_clk),
-       CLK("i2c_davinci.2",    NULL,           &i2c1_clk),
-       CLK(NULL,               "emif3",        &emif3_clk),
-       CLK(NULL,               "arm",          &arm_clk),
-       CLK(NULL,               "rmii",         &rmii_clk),
-       CLK("davinci_emac.1",   NULL,           &emac_clk),
-       CLK("davinci_mdio.0",   "fck",          &mdio_clk),
-       CLK("davinci-mcasp.0",  NULL,           &mcasp_clk),
-       CLK("davinci-mcbsp.0",  NULL,           &mcbsp0_clk),
-       CLK("davinci-mcbsp.1",  NULL,           &mcbsp1_clk),
-       CLK("da8xx_lcdc.0",     "fck",          &lcdc_clk),
-       CLK("da830-mmc.0",      NULL,           &mmcsd0_clk),
-       CLK("da830-mmc.1",      NULL,           &mmcsd1_clk),
-       CLK("ti-aemif",         NULL,           &aemif_clk),
-       CLK("davinci-nand.0",   "aemif",        &aemif_nand_clk),
-       CLK("ohci-da8xx",       NULL,           &usb11_clk),
-       CLK("musb-da8xx",       NULL,           &usb20_clk),
-       CLK("cppi41-dmaengine", NULL,           &cppi41_clk),
-       CLK("spi_davinci.0",    NULL,           &spi0_clk),
-       CLK("spi_davinci.1",    NULL,           &spi1_clk),
-       CLK("vpif",             NULL,           &vpif_clk),
-       CLK("ahci_da850",       "fck",          &sata_clk),
-       CLK("davinci-rproc.0",  NULL,           &dsp_clk),
-       CLK(NULL,               NULL,           &ehrpwm_clk),
-       CLK("ehrpwm.0",         "fck",          &ehrpwm0_clk),
-       CLK("ehrpwm.1",         "fck",          &ehrpwm1_clk),
-       CLK(NULL,               NULL,           &ehrpwm_tbclk),
-       CLK("ehrpwm.0",         "tbclk",        &ehrpwm0_tbclk),
-       CLK("ehrpwm.1",         "tbclk",        &ehrpwm1_tbclk),
-       CLK(NULL,               NULL,           &ecap_clk),
-       CLK("ecap.0",           "fck",          &ecap0_clk),
-       CLK("ecap.1",           "fck",          &ecap1_clk),
-       CLK("ecap.2",           "fck",          &ecap2_clk),
-       CLK(NULL,               NULL,           NULL),
-};
-
 /*
  * Device specific mux setup
  *
@@ -958,8 +418,6 @@ static struct map_desc da850_io_desc[] = {
        },
 };
 
-static u32 da850_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
-
 /* Contents of JTAG ID register used to identify exact cpu type */
 static struct davinci_id da850_ids[] = {
        {
@@ -1169,89 +627,11 @@ int da850_register_cpufreq(char *async_clk)
 
        return platform_device_register(&da850_cpufreq_device);
 }
-
-static int da850_round_armrate(struct clk *clk, unsigned long rate)
-{
-       int ret = 0, diff;
-       unsigned int best = (unsigned int) -1;
-       struct cpufreq_frequency_table *table = cpufreq_info.freq_table;
-       struct cpufreq_frequency_table *pos;
-
-       rate /= 1000; /* convert to kHz */
-
-       cpufreq_for_each_entry(pos, table) {
-               diff = pos->frequency - rate;
-               if (diff < 0)
-                       diff = -diff;
-
-               if (diff < best) {
-                       best = diff;
-                       ret = pos->frequency;
-               }
-       }
-
-       return ret * 1000;
-}
-
-static int da850_set_armrate(struct clk *clk, unsigned long index)
-{
-       struct clk *pllclk = &pll0_clk;
-
-       return clk_set_rate(pllclk, index);
-}
-
-static int da850_set_pll0rate(struct clk *clk, unsigned long rate)
-{
-       struct pll_data *pll = clk->pll_data;
-       struct cpufreq_frequency_table *freq;
-       unsigned int prediv, mult, postdiv;
-       struct da850_opp *opp = NULL;
-       int ret;
-
-       rate /= 1000;
-
-       for (freq = da850_freq_table;
-            freq->frequency != CPUFREQ_TABLE_END; freq++) {
-               /* rate is in Hz, freq->frequency is in KHz */
-               if (freq->frequency == rate) {
-                       opp = (struct da850_opp *)freq->driver_data;
-                       break;
-               }
-       }
-
-       if (!opp)
-               return -EINVAL;
-
-       prediv = opp->prediv;
-       mult = opp->mult;
-       postdiv = opp->postdiv;
-
-       ret = davinci_set_pllrate(pll, prediv, mult, postdiv);
-       if (WARN_ON(ret))
-               return ret;
-
-       return 0;
-}
 #else
 int __init da850_register_cpufreq(char *async_clk)
 {
        return 0;
 }
-
-static int da850_set_armrate(struct clk *clk, unsigned long rate)
-{
-       return -EINVAL;
-}
-
-static int da850_set_pll0rate(struct clk *clk, unsigned long armrate)
-{
-       return -EINVAL;
-}
-
-static int da850_round_armrate(struct clk *clk, unsigned long rate)
-{
-       return clk->rate;
-}
 #endif
 
 /* VPIF resource, platform data */
@@ -1353,8 +733,6 @@ static const struct davinci_soc_info davinci_soc_info_da850 = {
        .jtag_id_reg            = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
        .ids                    = da850_ids,
        .ids_num                = ARRAY_SIZE(da850_ids),
-       .psc_bases              = da850_psc_bases,
-       .psc_bases_num          = ARRAY_SIZE(da850_psc_bases),
        .pinmux_base            = DA8XX_SYSCFG0_BASE + 0x120,
        .pinmux_pins            = da850_pins,
        .pinmux_pins_num        = ARRAY_SIZE(da850_pins),
@@ -1370,8 +748,6 @@ static const struct davinci_soc_info davinci_soc_info_da850 = {
 
 void __init da850_init(void)
 {
-       unsigned int v;
-
        davinci_common_init(&davinci_soc_info_da850);
 
        da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
@@ -1379,22 +755,124 @@ void __init da850_init(void)
                return;
 
        da8xx_syscfg1_base = ioremap(DA8XX_SYSCFG1_BASE, SZ_4K);
-       if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module"))
-               return;
+       WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module");
+}
+
+void __init da850_init_time(void)
+{
+       void __iomem *pll0;
+       struct regmap *cfgchip;
+       struct clk *clk;
 
-       /* Unlock writing to PLL0 registers */
-       v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG));
-       v &= ~CFGCHIP0_PLL_MASTER_LOCK;
-       __raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG));
+       clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DA850_REF_FREQ);
 
-       /* Unlock writing to PLL1 registers */
-       v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
-       v &= ~CFGCHIP3_PLL1_MASTER_LOCK;
-       __raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
+       pll0 = ioremap(DA8XX_PLL0_BASE, SZ_4K);
+       cfgchip = da8xx_get_cfgchip();
+
+       da850_pll0_init(NULL, pll0, cfgchip);
+
+       clk = clk_get(NULL, "timer0");
+
+       davinci_timer_init(clk);
 }
 
-void __init da850_init_time(void)
+static struct resource da850_pll1_resources[] = {
+       {
+               .start  = DA850_PLL1_BASE,
+               .end    = DA850_PLL1_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct davinci_pll_platform_data da850_pll1_pdata;
+
+static struct platform_device da850_pll1_device = {
+       .name           = "da850-pll1",
+       .id             = -1,
+       .resource       = da850_pll1_resources,
+       .num_resources  = ARRAY_SIZE(da850_pll1_resources),
+       .dev            = {
+               .platform_data  = &da850_pll1_pdata,
+       },
+};
+
+static struct resource da850_psc0_resources[] = {
+       {
+               .start  = DA8XX_PSC0_BASE,
+               .end    = DA8XX_PSC0_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device da850_psc0_device = {
+       .name           = "da850-psc0",
+       .id             = -1,
+       .resource       = da850_psc0_resources,
+       .num_resources  = ARRAY_SIZE(da850_psc0_resources),
+};
+
+static struct resource da850_psc1_resources[] = {
+       {
+               .start  = DA8XX_PSC1_BASE,
+               .end    = DA8XX_PSC1_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device da850_psc1_device = {
+       .name           = "da850-psc1",
+       .id             = -1,
+       .resource       = da850_psc1_resources,
+       .num_resources  = ARRAY_SIZE(da850_psc1_resources),
+};
+
+static struct da8xx_cfgchip_clk_platform_data da850_async1_pdata;
+
+static struct platform_device da850_async1_clksrc_device = {
+       .name           = "da850-async1-clksrc",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &da850_async1_pdata,
+       },
+};
+
+static struct da8xx_cfgchip_clk_platform_data da850_async3_pdata;
+
+static struct platform_device da850_async3_clksrc_device = {
+       .name           = "da850-async3-clksrc",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &da850_async3_pdata,
+       },
+};
+
+static struct da8xx_cfgchip_clk_platform_data da850_tbclksync_pdata;
+
+static struct platform_device da850_tbclksync_device = {
+       .name           = "da830-tbclksync",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &da850_tbclksync_pdata,
+       },
+};
+
+void __init da850_register_clocks(void)
 {
-       davinci_clk_init(da850_clks);
-       davinci_timer_init();
+       /* PLL0 is registered in da850_init_time() */
+
+       da850_pll1_pdata.cfgchip = da8xx_get_cfgchip();
+       platform_device_register(&da850_pll1_device);
+
+       da850_async1_pdata.cfgchip = da8xx_get_cfgchip();
+       platform_device_register(&da850_async1_clksrc_device);
+
+       da850_async3_pdata.cfgchip = da8xx_get_cfgchip();
+       platform_device_register(&da850_async3_clksrc_device);
+
+       platform_device_register(&da850_psc0_device);
+
+       platform_device_register(&da850_psc1_device);
+
+       da850_tbclksync_pdata.cfgchip = da8xx_get_cfgchip();
+       platform_device_register(&da850_tbclksync_device);
 }
index ab199f4b9ce4ca6fcba6acb38a4683124a5e04a2..beac80ec4037bcecd3edf22cb85b862566b3d0ce 100644 (file)
@@ -7,81 +7,16 @@
  * 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/of_irq.h>
-#include <linux/of_platform.h>
-#include <linux/irqdomain.h>
-#include <linux/platform_data/ti-aemif.h>
 
 #include <asm/mach/arch.h>
 
 #include <mach/common.h>
-#include "cp_intc.h"
 #include <mach/da8xx.h>
 
-static struct of_dev_auxdata da850_aemif_auxdata_lookup[] = {
-       OF_DEV_AUXDATA("ti,davinci-nand", 0x62000000, "davinci-nand.0", NULL),
-       {}
-};
-
-static struct aemif_platform_data aemif_data = {
-       .dev_lookup = da850_aemif_auxdata_lookup,
-};
-
-static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
-       OF_DEV_AUXDATA("ti,davinci-i2c", 0x01c22000, "i2c_davinci.1", NULL),
-       OF_DEV_AUXDATA("ti,davinci-i2c", 0x01e28000, "i2c_davinci.2", NULL),
-       OF_DEV_AUXDATA("ti,davinci-wdt", 0x01c21000, "davinci-wdt", NULL),
-       OF_DEV_AUXDATA("ti,da830-mmc", 0x01c40000, "da830-mmc.0", NULL),
-       OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f00000, "ehrpwm.0", NULL),
-       OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f02000, "ehrpwm.1", NULL),
-       OF_DEV_AUXDATA("ti,da850-ecap", 0x01f06000, "ecap.0", NULL),
-       OF_DEV_AUXDATA("ti,da850-ecap", 0x01f07000, "ecap.1", NULL),
-       OF_DEV_AUXDATA("ti,da850-ecap", 0x01f08000, "ecap.2", NULL),
-       OF_DEV_AUXDATA("ti,da830-spi", 0x01c41000, "spi_davinci.0", NULL),
-       OF_DEV_AUXDATA("ti,da830-spi", 0x01f0e000, "spi_davinci.1", NULL),
-       OF_DEV_AUXDATA("ns16550a", 0x01c42000, "serial8250.0", NULL),
-       OF_DEV_AUXDATA("ns16550a", 0x01d0c000, "serial8250.1", NULL),
-       OF_DEV_AUXDATA("ns16550a", 0x01d0d000, "serial8250.2", NULL),
-       OF_DEV_AUXDATA("ti,davinci_mdio", 0x01e24000, "davinci_mdio.0", NULL),
-       OF_DEV_AUXDATA("ti,davinci-dm6467-emac", 0x01e20000, "davinci_emac.1",
-                      NULL),
-       OF_DEV_AUXDATA("ti,da830-mcasp-audio", 0x01d00000, "davinci-mcasp.0", NULL),
-       OF_DEV_AUXDATA("ti,da850-aemif", 0x68000000, "ti-aemif", &aemif_data),
-       OF_DEV_AUXDATA("ti,da850-tilcdc", 0x01e13000, "da8xx_lcdc.0", NULL),
-       OF_DEV_AUXDATA("ti,da830-ohci", 0x01e25000, "ohci-da8xx", NULL),
-       OF_DEV_AUXDATA("ti,da830-musb", 0x01e00000, "musb-da8xx", NULL),
-       OF_DEV_AUXDATA("ti,da830-usb-phy", 0x01c1417c, "da8xx-usb-phy", NULL),
-       OF_DEV_AUXDATA("ti,da850-ahci", 0x01e18000, "ahci_da850", NULL),
-       OF_DEV_AUXDATA("ti,da850-vpif", 0x01e17000, "vpif", NULL),
-       OF_DEV_AUXDATA("ti,da850-dsp", 0x11800000, "davinci-rproc.0", NULL),
-       {}
-};
-
 #ifdef CONFIG_ARCH_DAVINCI_DA850
 
 static void __init da850_init_machine(void)
 {
-       /* All existing boards use 100MHz SATA refclkpn */
-       static const unsigned long sata_refclkpn = 100 * 1000 * 1000;
-
-       int ret;
-
-       ret = da8xx_register_usb20_phy_clk(false);
-       if (ret)
-               pr_warn("%s: registering USB 2.0 PHY clock failed: %d",
-                       __func__, ret);
-       ret = da8xx_register_usb11_phy_clk(false);
-       if (ret)
-               pr_warn("%s: registering USB 1.1 PHY clock failed: %d",
-                       __func__, ret);
-
-       ret = da850_register_sata_refclk(sata_refclkpn);
-       if (ret)
-               pr_warn("%s: registering SATA REFCLK failed: %d",
-                       __func__, ret);
-
-       of_platform_default_populate(NULL, da850_auxdata_lookup, NULL);
        davinci_pm_init();
        pdata_quirks_init();
 }
@@ -96,7 +31,6 @@ static const char *const da850_boards_compat[] __initconst = {
 
 DT_MACHINE_START(DA850_DT, "Generic DA850/OMAP-L138/AM18x")
        .map_io         = da850_init,
-       .init_time      = da850_init_time,
        .init_machine   = da850_init_machine,
        .dt_compat      = da850_boards_compat,
        .init_late      = davinci_init_late,
index 376cdd51ce9d7beb89a5551f4abbe0e501db52b3..db4c95ef4d5c59302a407b7a287a4ece098e7de6 100644 (file)
 #include <media/davinci/vpbe.h>
 #include <media/davinci/vpbe_osd.h>
 
+#define DAVINCI_PLL1_BASE              0x01c40800
+#define DAVINCI_PLL2_BASE              0x01c40c00
+#define DAVINCI_PWR_SLEEP_CNTRL_BASE   0x01c41000
+
 #define DAVINCI_SYSTEM_MODULE_BASE     0x01c40000
 #define SYSMOD_VDAC_CONFIG             0x2c
 #define SYSMOD_VIDCLKCTL               0x38
@@ -84,6 +88,7 @@ int davinci_init_wdt(void);
 /* DM355 function declarations */
 void dm355_init(void);
 void dm355_init_time(void);
+void dm355_register_clocks(void);
 void dm355_init_spi0(unsigned chipselect_mask,
                const struct spi_board_info *info, unsigned len);
 void dm355_init_asp1(u32 evt_enable);
@@ -93,6 +98,7 @@ int dm355_gpio_register(void);
 /* DM365 function declarations */
 void dm365_init(void);
 void dm365_init_time(void);
+void dm365_register_clocks(void);
 void dm365_init_asp(void);
 void dm365_init_vc(void);
 void dm365_init_ks(struct davinci_ks_platform_data *pdata);
@@ -106,6 +112,7 @@ int dm365_gpio_register(void);
 void dm644x_init(void);
 void dm644x_init_devices(void);
 void dm644x_init_time(void);
+void dm644x_register_clocks(void);
 void dm644x_init_asp(void);
 int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
 int dm644x_gpio_register(void);
@@ -113,6 +120,7 @@ int dm644x_gpio_register(void);
 /* DM646x function declarations */
 void dm646x_init(void);
 void dm646x_init_time(unsigned long ref_clk_rate, unsigned long aux_clkin_rate);
+void dm646x_register_clocks(void);
 void dm646x_init_mcasp0(struct snd_platform_data *pdata);
 void dm646x_init_mcasp1(struct snd_platform_data *pdata);
 int dm646x_init_edma(struct edma_rsv_info *rsv);
index 78390c64e6ca5703ef28215f2670e3031390dfdc..1fd3619f6a09f1311eeb8153ab627cedd80d3149 100644 (file)
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  */
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/dma-contiguous.h>
-#include <linux/serial_8250.h>
 #include <linux/ahci_platform.h>
+#include <linux/clk-provider.h>
 #include <linux/clk.h>
-#include <linux/reboot.h>
+#include <linux/clkdev.h>
+#include <linux/dma-contiguous.h>
 #include <linux/dmaengine.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/serial_8250.h>
 
-#include <mach/cputype.h>
 #include <mach/common.h>
-#include <mach/time.h>
+#include <mach/cputype.h>
 #include <mach/da8xx.h>
-#include <mach/clock.h>
-#include "cpuidle.h"
-#include "sram.h"
+#include <mach/time.h>
 
-#include "clock.h"
 #include "asp.h"
+#include "cpuidle.h"
+#include "sram.h"
 
 #define DA8XX_TPCC_BASE                        0x01c00000
 #define DA8XX_TPTC0_BASE               0x01c08000
@@ -1040,26 +1040,15 @@ int __init da8xx_register_spi_bus(int instance, unsigned num_chipselect)
 }
 
 #ifdef CONFIG_ARCH_DAVINCI_DA850
-static struct clk sata_refclk = {
-       .name           = "sata_refclk",
-       .set_rate       = davinci_simple_set_rate,
-};
-
-static struct clk_lookup sata_refclk_lookup =
-               CLK("ahci_da850", "refclk", &sata_refclk);
-
 int __init da850_register_sata_refclk(int rate)
 {
-       int ret;
-
-       sata_refclk.rate = rate;
-       ret = clk_register(&sata_refclk);
-       if (ret)
-               return ret;
+       struct clk *clk;
 
-       clkdev_add(&sata_refclk_lookup);
+       clk = clk_register_fixed_rate(NULL, "sata_refclk", NULL, 0, rate);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
 
-       return 0;
+       return clk_register_clkdev(clk, "refclk", "ahci_da850");
 }
 
 static struct resource da850_sata_resources[] = {
index 0edda4093e47d8b6f24804871a92f08660ea1dd1..e8dbbb7479abc343c390e8323cc6529216cd7ca4 100644 (file)
@@ -26,7 +26,6 @@
 
 
 #include "davinci.h"
-#include "clock.h"
 
 #define DAVINCI_I2C_BASE            0x01C21000
 #define DAVINCI_ATA_BASE            0x01C66000
index f29480495c183c9384119b04810ae41387629c2e..9f7d38d12c8886134a0b4d149b6593bf228efc4a 100644 (file)
@@ -8,31 +8,32 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/serial_8250.h>
-#include <linux/platform_device.h>
+
+#include <linux/clk-provider.h>
+#include <linux/clk/davinci.h>
+#include <linux/clkdev.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
-#include <linux/spi/spi.h>
+#include <linux/init.h>
 #include <linux/platform_data/edma.h>
 #include <linux/platform_data/gpio-davinci.h>
 #include <linux/platform_data/spi-davinci.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/spi/spi.h>
 
 #include <asm/mach/map.h>
 
+#include <mach/common.h>
 #include <mach/cputype.h>
-#include "psc.h"
-#include <mach/mux.h>
 #include <mach/irqs.h>
-#include <mach/time.h>
+#include <mach/mux.h>
 #include <mach/serial.h>
-#include <mach/common.h>
+#include <mach/time.h>
 
+#include "asp.h"
 #include "davinci.h"
-#include "clock.h"
 #include "mux.h"
-#include "asp.h"
 
 #define DM355_UART2_BASE       (IO_PHYS + 0x206000)
 #define DM355_OSD_BASE         (IO_PHYS + 0x70200)
  */
 #define DM355_REF_FREQ         24000000        /* 24 or 36 MHz */
 
-static struct pll_data pll1_data = {
-       .num       = 1,
-       .phys_base = DAVINCI_PLL1_BASE,
-       .flags     = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
-};
-
-static struct pll_data pll2_data = {
-       .num       = 2,
-       .phys_base = DAVINCI_PLL2_BASE,
-       .flags     = PLL_HAS_PREDIV,
-};
-
-static struct clk ref_clk = {
-       .name = "ref_clk",
-       /* FIXME -- crystal rate is board-specific */
-       .rate = DM355_REF_FREQ,
-};
-
-static struct clk pll1_clk = {
-       .name = "pll1",
-       .parent = &ref_clk,
-       .flags = CLK_PLL,
-       .pll_data = &pll1_data,
-};
-
-static struct clk pll1_aux_clk = {
-       .name = "pll1_aux_clk",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll1_sysclk1 = {
-       .name = "pll1_sysclk1",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV1,
-};
-
-static struct clk pll1_sysclk2 = {
-       .name = "pll1_sysclk2",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV2,
-};
-
-static struct clk pll1_sysclk3 = {
-       .name = "pll1_sysclk3",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV3,
-};
-
-static struct clk pll1_sysclk4 = {
-       .name = "pll1_sysclk4",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV4,
-};
-
-static struct clk pll1_sysclkbp = {
-       .name = "pll1_sysclkbp",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL | PRE_PLL,
-       .div_reg = BPDIV
-};
-
-static struct clk vpss_dac_clk = {
-       .name = "vpss_dac",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM355_LPSC_VPSS_DAC,
-};
-
-static struct clk vpss_master_clk = {
-       .name = "vpss_master",
-       .parent = &pll1_sysclk4,
-       .lpsc = DAVINCI_LPSC_VPSSMSTR,
-       .flags = CLK_PSC,
-};
-
-static struct clk vpss_slave_clk = {
-       .name = "vpss_slave",
-       .parent = &pll1_sysclk4,
-       .lpsc = DAVINCI_LPSC_VPSSSLV,
-};
-
-static struct clk clkout1_clk = {
-       .name = "clkout1",
-       .parent = &pll1_aux_clk,
-       /* NOTE:  clkout1 can be externally gated by muxing GPIO-18 */
-};
-
-static struct clk clkout2_clk = {
-       .name = "clkout2",
-       .parent = &pll1_sysclkbp,
-};
-
-static struct clk pll2_clk = {
-       .name = "pll2",
-       .parent = &ref_clk,
-       .flags = CLK_PLL,
-       .pll_data = &pll2_data,
-};
-
-static struct clk pll2_sysclk1 = {
-       .name = "pll2_sysclk1",
-       .parent = &pll2_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV1,
-};
-
-static struct clk pll2_sysclkbp = {
-       .name = "pll2_sysclkbp",
-       .parent = &pll2_clk,
-       .flags = CLK_PLL | PRE_PLL,
-       .div_reg = BPDIV
-};
-
-static struct clk clkout3_clk = {
-       .name = "clkout3",
-       .parent = &pll2_sysclkbp,
-       /* NOTE:  clkout3 can be externally gated by muxing GPIO-16 */
-};
-
-static struct clk arm_clk = {
-       .name = "arm_clk",
-       .parent = &pll1_sysclk1,
-       .lpsc = DAVINCI_LPSC_ARM,
-       .flags = ALWAYS_ENABLED,
-};
-
-/*
- * NOT LISTED below, and not touched by Linux
- *   - in SyncReset state by default
- *     .lpsc = DAVINCI_LPSC_TPCC,
- *     .lpsc = DAVINCI_LPSC_TPTC0,
- *     .lpsc = DAVINCI_LPSC_TPTC1,
- *     .lpsc = DAVINCI_LPSC_DDR_EMIF, .parent = &sysclk2_clk,
- *     .lpsc = DAVINCI_LPSC_MEMSTICK,
- *   - in Enabled state by default
- *     .lpsc = DAVINCI_LPSC_SYSTEM_SUBSYS,
- *     .lpsc = DAVINCI_LPSC_SCR2,      // "bus"
- *     .lpsc = DAVINCI_LPSC_SCR3,      // "bus"
- *     .lpsc = DAVINCI_LPSC_SCR4,      // "bus"
- *     .lpsc = DAVINCI_LPSC_CROSSBAR,  // "emulation"
- *     .lpsc = DAVINCI_LPSC_CFG27,     // "test"
- *     .lpsc = DAVINCI_LPSC_CFG3,      // "test"
- *     .lpsc = DAVINCI_LPSC_CFG5,      // "test"
- */
-
-static struct clk mjcp_clk = {
-       .name = "mjcp",
-       .parent = &pll1_sysclk1,
-       .lpsc = DAVINCI_LPSC_IMCOP,
-};
-
-static struct clk uart0_clk = {
-       .name = "uart0",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_UART0,
-};
-
-static struct clk uart1_clk = {
-       .name = "uart1",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_UART1,
-};
-
-static struct clk uart2_clk = {
-       .name = "uart2",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_UART2,
-};
-
-static struct clk i2c_clk = {
-       .name = "i2c",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_I2C,
-};
-
-static struct clk asp0_clk = {
-       .name = "asp0",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_McBSP,
-};
-
-static struct clk asp1_clk = {
-       .name = "asp1",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM355_LPSC_McBSP1,
-};
-
-static struct clk mmcsd0_clk = {
-       .name = "mmcsd0",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_MMC_SD,
-};
-
-static struct clk mmcsd1_clk = {
-       .name = "mmcsd1",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM355_LPSC_MMC_SD1,
-};
-
-static struct clk spi0_clk = {
-       .name = "spi0",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_SPI,
-};
-
-static struct clk spi1_clk = {
-       .name = "spi1",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM355_LPSC_SPI1,
-};
-
-static struct clk spi2_clk = {
-       .name = "spi2",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM355_LPSC_SPI2,
-};
-
-static struct clk gpio_clk = {
-       .name = "gpio",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_GPIO,
-};
-
-static struct clk aemif_clk = {
-       .name = "aemif",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_AEMIF,
-};
-
-static struct clk pwm0_clk = {
-       .name = "pwm0",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_PWM0,
-};
-
-static struct clk pwm1_clk = {
-       .name = "pwm1",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_PWM1,
-};
-
-static struct clk pwm2_clk = {
-       .name = "pwm2",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_PWM2,
-};
-
-static struct clk pwm3_clk = {
-       .name = "pwm3",
-       .parent = &pll1_aux_clk,
-       .lpsc = DM355_LPSC_PWM3,
-};
-
-static struct clk timer0_clk = {
-       .name = "timer0",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_TIMER0,
-};
-
-static struct clk timer1_clk = {
-       .name = "timer1",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_TIMER1,
-};
-
-static struct clk timer2_clk = {
-       .name = "timer2",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_TIMER2,
-       .usecount = 1,              /* REVISIT: why can't this be disabled? */
-};
-
-static struct clk timer3_clk = {
-       .name = "timer3",
-       .parent = &pll1_aux_clk,
-       .lpsc = DM355_LPSC_TIMER3,
-};
-
-static struct clk rto_clk = {
-       .name = "rto",
-       .parent = &pll1_aux_clk,
-       .lpsc = DM355_LPSC_RTO,
-};
-
-static struct clk usb_clk = {
-       .name = "usb",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_USB,
-};
-
-static struct clk_lookup dm355_clks[] = {
-       CLK(NULL, "ref", &ref_clk),
-       CLK(NULL, "pll1", &pll1_clk),
-       CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
-       CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
-       CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
-       CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
-       CLK(NULL, "pll1_aux", &pll1_aux_clk),
-       CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
-       CLK(NULL, "vpss_dac", &vpss_dac_clk),
-       CLK("vpss", "master", &vpss_master_clk),
-       CLK("vpss", "slave", &vpss_slave_clk),
-       CLK(NULL, "clkout1", &clkout1_clk),
-       CLK(NULL, "clkout2", &clkout2_clk),
-       CLK(NULL, "pll2", &pll2_clk),
-       CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
-       CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
-       CLK(NULL, "clkout3", &clkout3_clk),
-       CLK(NULL, "arm", &arm_clk),
-       CLK(NULL, "mjcp", &mjcp_clk),
-       CLK("serial8250.0", NULL, &uart0_clk),
-       CLK("serial8250.1", NULL, &uart1_clk),
-       CLK("serial8250.2", NULL, &uart2_clk),
-       CLK("i2c_davinci.1", NULL, &i2c_clk),
-       CLK("davinci-mcbsp.0", NULL, &asp0_clk),
-       CLK("davinci-mcbsp.1", NULL, &asp1_clk),
-       CLK("dm6441-mmc.0", NULL, &mmcsd0_clk),
-       CLK("dm6441-mmc.1", NULL, &mmcsd1_clk),
-       CLK("spi_davinci.0", NULL, &spi0_clk),
-       CLK("spi_davinci.1", NULL, &spi1_clk),
-       CLK("spi_davinci.2", NULL, &spi2_clk),
-       CLK(NULL, "gpio", &gpio_clk),
-       CLK(NULL, "aemif", &aemif_clk),
-       CLK(NULL, "pwm0", &pwm0_clk),
-       CLK(NULL, "pwm1", &pwm1_clk),
-       CLK(NULL, "pwm2", &pwm2_clk),
-       CLK(NULL, "pwm3", &pwm3_clk),
-       CLK(NULL, "timer0", &timer0_clk),
-       CLK(NULL, "timer1", &timer1_clk),
-       CLK("davinci-wdt", NULL, &timer2_clk),
-       CLK(NULL, "timer3", &timer3_clk),
-       CLK(NULL, "rto", &rto_clk),
-       CLK(NULL, "usb", &usb_clk),
-       CLK(NULL, NULL, NULL),
-};
-
-/*----------------------------------------------------------------------*/
-
 static u64 dm355_spi0_dma_mask = DMA_BIT_MASK(32);
 
 static struct resource dm355_spi0_resources[] = {
@@ -926,8 +585,6 @@ static struct davinci_id dm355_ids[] = {
        },
 };
 
-static u32 dm355_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-
 /*
  * T0_BOT: Timer 0, bottom:  clockevent source for hrtimers
  * T0_TOP: Timer 0, top   :  clocksource for generic timekeeping
@@ -1012,8 +669,6 @@ static const struct davinci_soc_info davinci_soc_info_dm355 = {
        .jtag_id_reg            = 0x01c40028,
        .ids                    = dm355_ids,
        .ids_num                = ARRAY_SIZE(dm355_ids),
-       .psc_bases              = dm355_psc_bases,
-       .psc_bases_num          = ARRAY_SIZE(dm355_psc_bases),
        .pinmux_base            = DAVINCI_SYSTEM_MODULE_BASE,
        .pinmux_pins            = dm355_pins,
        .pinmux_pins_num        = ARRAY_SIZE(dm355_pins),
@@ -1046,8 +701,41 @@ void __init dm355_init(void)
 
 void __init dm355_init_time(void)
 {
-       davinci_clk_init(dm355_clks);
-       davinci_timer_init();
+       void __iomem *pll1, *psc;
+       struct clk *clk;
+
+       clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM355_REF_FREQ);
+
+       pll1 = ioremap(DAVINCI_PLL1_BASE, SZ_1K);
+       dm355_pll1_init(NULL, pll1, NULL);
+
+       psc = ioremap(DAVINCI_PWR_SLEEP_CNTRL_BASE, SZ_4K);
+       dm355_psc_init(NULL, psc);
+
+       clk = clk_get(NULL, "timer0");
+
+       davinci_timer_init(clk);
+}
+
+static struct resource dm355_pll2_resources[] = {
+       {
+               .start  = DAVINCI_PLL2_BASE,
+               .end    = DAVINCI_PLL2_BASE + SZ_1K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device dm355_pll2_device = {
+       .name           = "dm355-pll2",
+       .id             = -1,
+       .resource       = dm355_pll2_resources,
+       .num_resources  = ARRAY_SIZE(dm355_pll2_resources),
+};
+
+void __init dm355_register_clocks(void)
+{
+       /* PLL1 and PSC are registered in dm355_init_time() */
+       platform_device_register(&dm355_pll2_device);
 }
 
 int __init dm355_init_video(struct vpfe_config *vpfe_cfg,
index 1e3df9df1e10336543f67dd270364ecef122a91e..abcf2a5ed89b5e4780430911b1ef584711cf0142 100644 (file)
  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/serial_8250.h>
-#include <linux/platform_device.h>
+
+#include <linux/clk-provider.h>
+#include <linux/clk/davinci.h>
+#include <linux/clkdev.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
-#include <linux/spi/spi.h>
+#include <linux/init.h>
 #include <linux/platform_data/edma.h>
 #include <linux/platform_data/gpio-davinci.h>
 #include <linux/platform_data/keyscan-davinci.h>
 #include <linux/platform_data/spi-davinci.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/spi/spi.h>
 
 #include <asm/mach/map.h>
 
+#include <mach/common.h>
 #include <mach/cputype.h>
-#include "psc.h"
-#include <mach/mux.h>
 #include <mach/irqs.h>
-#include <mach/time.h>
+#include <mach/mux.h>
 #include <mach/serial.h>
-#include <mach/common.h>
+#include <mach/time.h>
 
+#include "asp.h"
 #include "davinci.h"
-#include "clock.h"
 #include "mux.h"
-#include "asp.h"
 
 #define DM365_REF_FREQ         24000000        /* 24 MHz on the DM365 EVM */
 #define DM365_RTC_BASE                 0x01c69000
 #define DM365_EMAC_CNTRL_RAM_OFFSET    0x1000
 #define DM365_EMAC_CNTRL_RAM_SIZE      0x2000
 
-static struct pll_data pll1_data = {
-       .num            = 1,
-       .phys_base      = DAVINCI_PLL1_BASE,
-       .flags          = PLL_HAS_POSTDIV | PLL_HAS_PREDIV,
-};
-
-static struct pll_data pll2_data = {
-       .num            = 2,
-       .phys_base      = DAVINCI_PLL2_BASE,
-       .flags          = PLL_HAS_POSTDIV | PLL_HAS_PREDIV,
-};
-
-static struct clk ref_clk = {
-       .name           = "ref_clk",
-       .rate           = DM365_REF_FREQ,
-};
-
-static struct clk pll1_clk = {
-       .name           = "pll1",
-       .parent         = &ref_clk,
-       .flags          = CLK_PLL,
-       .pll_data       = &pll1_data,
-};
-
-static struct clk pll1_aux_clk = {
-       .name           = "pll1_aux_clk",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll1_sysclkbp = {
-       .name           = "pll1_sysclkbp",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL | PRE_PLL,
-       .div_reg        = BPDIV
-};
-
-static struct clk clkout0_clk = {
-       .name           = "clkout0",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll1_sysclk1 = {
-       .name           = "pll1_sysclk1",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV1,
-};
-
-static struct clk pll1_sysclk2 = {
-       .name           = "pll1_sysclk2",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV2,
-};
-
-static struct clk pll1_sysclk3 = {
-       .name           = "pll1_sysclk3",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV3,
-};
-
-static struct clk pll1_sysclk4 = {
-       .name           = "pll1_sysclk4",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV4,
-};
-
-static struct clk pll1_sysclk5 = {
-       .name           = "pll1_sysclk5",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV5,
-};
-
-static struct clk pll1_sysclk6 = {
-       .name           = "pll1_sysclk6",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV6,
-};
-
-static struct clk pll1_sysclk7 = {
-       .name           = "pll1_sysclk7",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV7,
-};
-
-static struct clk pll1_sysclk8 = {
-       .name           = "pll1_sysclk8",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV8,
-};
-
-static struct clk pll1_sysclk9 = {
-       .name           = "pll1_sysclk9",
-       .parent         = &pll1_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV9,
-};
-
-static struct clk pll2_clk = {
-       .name           = "pll2",
-       .parent         = &ref_clk,
-       .flags          = CLK_PLL,
-       .pll_data       = &pll2_data,
-};
-
-static struct clk pll2_aux_clk = {
-       .name           = "pll2_aux_clk",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL | PRE_PLL,
-};
-
-static struct clk clkout1_clk = {
-       .name           = "clkout1",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll2_sysclk1 = {
-       .name           = "pll2_sysclk1",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV1,
-};
-
-static struct clk pll2_sysclk2 = {
-       .name           = "pll2_sysclk2",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV2,
-};
-
-static struct clk pll2_sysclk3 = {
-       .name           = "pll2_sysclk3",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV3,
-};
-
-static struct clk pll2_sysclk4 = {
-       .name           = "pll2_sysclk4",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV4,
-};
-
-static struct clk pll2_sysclk5 = {
-       .name           = "pll2_sysclk5",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV5,
-};
-
-static struct clk pll2_sysclk6 = {
-       .name           = "pll2_sysclk6",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV6,
-};
-
-static struct clk pll2_sysclk7 = {
-       .name           = "pll2_sysclk7",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV7,
-};
-
-static struct clk pll2_sysclk8 = {
-       .name           = "pll2_sysclk8",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV8,
-};
-
-static struct clk pll2_sysclk9 = {
-       .name           = "pll2_sysclk9",
-       .parent         = &pll2_clk,
-       .flags          = CLK_PLL,
-       .div_reg        = PLLDIV9,
-};
-
-static struct clk vpss_dac_clk = {
-       .name           = "vpss_dac",
-       .parent         = &pll1_sysclk3,
-       .lpsc           = DM365_LPSC_DAC_CLK,
-};
-
-static struct clk vpss_master_clk = {
-       .name           = "vpss_master",
-       .parent         = &pll1_sysclk5,
-       .lpsc           = DM365_LPSC_VPSSMSTR,
-       .flags          = CLK_PSC,
-};
-
-static struct clk vpss_slave_clk = {
-       .name           = "vpss_slave",
-       .parent         = &pll1_sysclk5,
-       .lpsc           = DAVINCI_LPSC_VPSSSLV,
-};
-
-static struct clk arm_clk = {
-       .name           = "arm_clk",
-       .parent         = &pll2_sysclk2,
-       .lpsc           = DAVINCI_LPSC_ARM,
-       .flags          = ALWAYS_ENABLED,
-};
-
-static struct clk uart0_clk = {
-       .name           = "uart0",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_UART0,
-};
-
-static struct clk uart1_clk = {
-       .name           = "uart1",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DAVINCI_LPSC_UART1,
-};
-
-static struct clk i2c_clk = {
-       .name           = "i2c",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_I2C,
-};
-
-static struct clk mmcsd0_clk = {
-       .name           = "mmcsd0",
-       .parent         = &pll1_sysclk8,
-       .lpsc           = DAVINCI_LPSC_MMC_SD,
-};
-
-static struct clk mmcsd1_clk = {
-       .name           = "mmcsd1",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DM365_LPSC_MMC_SD1,
-};
-
-static struct clk spi0_clk = {
-       .name           = "spi0",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DAVINCI_LPSC_SPI,
-};
-
-static struct clk spi1_clk = {
-       .name           = "spi1",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DM365_LPSC_SPI1,
-};
-
-static struct clk spi2_clk = {
-       .name           = "spi2",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DM365_LPSC_SPI2,
-};
-
-static struct clk spi3_clk = {
-       .name           = "spi3",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DM365_LPSC_SPI3,
-};
-
-static struct clk spi4_clk = {
-       .name           = "spi4",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DM365_LPSC_SPI4,
-};
-
-static struct clk gpio_clk = {
-       .name           = "gpio",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DAVINCI_LPSC_GPIO,
-};
-
-static struct clk aemif_clk = {
-       .name           = "aemif",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DAVINCI_LPSC_AEMIF,
-};
-
-static struct clk pwm0_clk = {
-       .name           = "pwm0",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_PWM0,
-};
-
-static struct clk pwm1_clk = {
-       .name           = "pwm1",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_PWM1,
-};
-
-static struct clk pwm2_clk = {
-       .name           = "pwm2",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_PWM2,
-};
-
-static struct clk pwm3_clk = {
-       .name           = "pwm3",
-       .parent         = &ref_clk,
-       .lpsc           = DM365_LPSC_PWM3,
-};
-
-static struct clk timer0_clk = {
-       .name           = "timer0",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_TIMER0,
-};
-
-static struct clk timer1_clk = {
-       .name           = "timer1",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_TIMER1,
-};
-
-static struct clk timer2_clk = {
-       .name           = "timer2",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_TIMER2,
-       .usecount       = 1,
-};
-
-static struct clk timer3_clk = {
-       .name           = "timer3",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DM365_LPSC_TIMER3,
-};
-
-static struct clk usb_clk = {
-       .name           = "usb",
-       .parent         = &pll1_aux_clk,
-       .lpsc           = DAVINCI_LPSC_USB,
-};
-
-static struct clk emac_clk = {
-       .name           = "emac",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DM365_LPSC_EMAC,
-};
-
-static struct clk voicecodec_clk = {
-       .name           = "voice_codec",
-       .parent         = &pll2_sysclk4,
-       .lpsc           = DM365_LPSC_VOICE_CODEC,
-};
-
-static struct clk asp0_clk = {
-       .name           = "asp0",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DM365_LPSC_McBSP1,
-};
-
-static struct clk rto_clk = {
-       .name           = "rto",
-       .parent         = &pll1_sysclk4,
-       .lpsc           = DM365_LPSC_RTO,
-};
-
-static struct clk mjcp_clk = {
-       .name           = "mjcp",
-       .parent         = &pll1_sysclk3,
-       .lpsc           = DM365_LPSC_MJCP,
-};
-
-static struct clk_lookup dm365_clks[] = {
-       CLK(NULL, "ref", &ref_clk),
-       CLK(NULL, "pll1", &pll1_clk),
-       CLK(NULL, "pll1_aux", &pll1_aux_clk),
-       CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
-       CLK(NULL, "clkout0", &clkout0_clk),
-       CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
-       CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
-       CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
-       CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
-       CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
-       CLK(NULL, "pll1_sysclk6", &pll1_sysclk6),
-       CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
-       CLK(NULL, "pll1_sysclk8", &pll1_sysclk8),
-       CLK(NULL, "pll1_sysclk9", &pll1_sysclk9),
-       CLK(NULL, "pll2", &pll2_clk),
-       CLK(NULL, "pll2_aux", &pll2_aux_clk),
-       CLK(NULL, "clkout1", &clkout1_clk),
-       CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
-       CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
-       CLK(NULL, "pll2_sysclk3", &pll2_sysclk3),
-       CLK(NULL, "pll2_sysclk4", &pll2_sysclk4),
-       CLK(NULL, "pll2_sysclk5", &pll2_sysclk5),
-       CLK(NULL, "pll2_sysclk6", &pll2_sysclk6),
-       CLK(NULL, "pll2_sysclk7", &pll2_sysclk7),
-       CLK(NULL, "pll2_sysclk8", &pll2_sysclk8),
-       CLK(NULL, "pll2_sysclk9", &pll2_sysclk9),
-       CLK(NULL, "vpss_dac", &vpss_dac_clk),
-       CLK("vpss", "master", &vpss_master_clk),
-       CLK("vpss", "slave", &vpss_slave_clk),
-       CLK(NULL, "arm", &arm_clk),
-       CLK("serial8250.0", NULL, &uart0_clk),
-       CLK("serial8250.1", NULL, &uart1_clk),
-       CLK("i2c_davinci.1", NULL, &i2c_clk),
-       CLK("da830-mmc.0", NULL, &mmcsd0_clk),
-       CLK("da830-mmc.1", NULL, &mmcsd1_clk),
-       CLK("spi_davinci.0", NULL, &spi0_clk),
-       CLK("spi_davinci.1", NULL, &spi1_clk),
-       CLK("spi_davinci.2", NULL, &spi2_clk),
-       CLK("spi_davinci.3", NULL, &spi3_clk),
-       CLK("spi_davinci.4", NULL, &spi4_clk),
-       CLK(NULL, "gpio", &gpio_clk),
-       CLK(NULL, "aemif", &aemif_clk),
-       CLK(NULL, "pwm0", &pwm0_clk),
-       CLK(NULL, "pwm1", &pwm1_clk),
-       CLK(NULL, "pwm2", &pwm2_clk),
-       CLK(NULL, "pwm3", &pwm3_clk),
-       CLK(NULL, "timer0", &timer0_clk),
-       CLK(NULL, "timer1", &timer1_clk),
-       CLK("davinci-wdt", NULL, &timer2_clk),
-       CLK(NULL, "timer3", &timer3_clk),
-       CLK(NULL, "usb", &usb_clk),
-       CLK("davinci_emac.1", NULL, &emac_clk),
-       CLK("davinci_mdio.0", "fck", &emac_clk),
-       CLK("davinci_voicecodec", NULL, &voicecodec_clk),
-       CLK("davinci-mcbsp", NULL, &asp0_clk),
-       CLK(NULL, "rto", &rto_clk),
-       CLK(NULL, "mjcp", &mjcp_clk),
-       CLK(NULL, NULL, NULL),
-};
-
-/*----------------------------------------------------------------------*/
-
 #define INTMUX         0x18
 #define EVTMUX         0x1c
 
@@ -1054,8 +621,6 @@ static struct davinci_id dm365_ids[] = {
        },
 };
 
-static u32 dm365_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-
 static struct davinci_timer_info dm365_timer_info = {
        .timers         = davinci_timer_instance,
        .clockevent_id  = T0_BOT,
@@ -1116,8 +681,6 @@ static const struct davinci_soc_info davinci_soc_info_dm365 = {
        .jtag_id_reg            = 0x01c40028,
        .ids                    = dm365_ids,
        .ids_num                = ARRAY_SIZE(dm365_ids),
-       .psc_bases              = dm365_psc_bases,
-       .psc_bases_num          = ARRAY_SIZE(dm365_psc_bases),
        .pinmux_base            = DAVINCI_SYSTEM_MODULE_BASE,
        .pinmux_pins            = dm365_pins,
        .pinmux_pins_num        = ARRAY_SIZE(dm365_pins),
@@ -1171,8 +734,28 @@ void __init dm365_init(void)
 
 void __init dm365_init_time(void)
 {
-       davinci_clk_init(dm365_clks);
-       davinci_timer_init();
+       void __iomem *pll1, *pll2, *psc;
+       struct clk *clk;
+
+       clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM365_REF_FREQ);
+
+       pll1 = ioremap(DAVINCI_PLL1_BASE, SZ_1K);
+       dm365_pll1_init(NULL, pll1, NULL);
+
+       pll2 = ioremap(DAVINCI_PLL2_BASE, SZ_1K);
+       dm365_pll2_init(NULL, pll2, NULL);
+
+       psc = ioremap(DAVINCI_PWR_SLEEP_CNTRL_BASE, SZ_4K);
+       dm365_psc_init(NULL, psc);
+
+       clk = clk_get(NULL, "timer0");
+
+       davinci_timer_init(clk);
+}
+
+void __init dm365_register_clocks(void)
+{
+       /* all clocks are currently registered in dm365_init_time() */
 }
 
 static struct resource dm365_vpss_resources[] = {
index a2e8586c8a6d57229d27665393fa74f26463145d..0720da7809a693eee06c22a80b0449a1cad06e17 100644 (file)
@@ -8,28 +8,29 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/serial_8250.h>
+
+#include <linux/clk-provider.h>
+#include <linux/clk/davinci.h>
+#include <linux/clkdev.h>
 #include <linux/dmaengine.h>
-#include <linux/platform_device.h>
+#include <linux/init.h>
 #include <linux/platform_data/edma.h>
 #include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
 
 #include <asm/mach/map.h>
 
+#include <mach/common.h>
 #include <mach/cputype.h>
 #include <mach/irqs.h>
-#include "psc.h"
 #include <mach/mux.h>
-#include <mach/time.h>
 #include <mach/serial.h>
-#include <mach/common.h>
+#include <mach/time.h>
 
+#include "asp.h"
 #include "davinci.h"
-#include "clock.h"
 #include "mux.h"
-#include "asp.h"
 
 /*
  * Device specific clocks
 #define DM644X_EMAC_CNTRL_RAM_OFFSET   0x2000
 #define DM644X_EMAC_CNTRL_RAM_SIZE     0x2000
 
-static struct pll_data pll1_data = {
-       .num       = 1,
-       .phys_base = DAVINCI_PLL1_BASE,
-};
-
-static struct pll_data pll2_data = {
-       .num       = 2,
-       .phys_base = DAVINCI_PLL2_BASE,
-};
-
-static struct clk ref_clk = {
-       .name = "ref_clk",
-       .rate = DM644X_REF_FREQ,
-};
-
-static struct clk pll1_clk = {
-       .name = "pll1",
-       .parent = &ref_clk,
-       .pll_data = &pll1_data,
-       .flags = CLK_PLL,
-};
-
-static struct clk pll1_sysclk1 = {
-       .name = "pll1_sysclk1",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV1,
-};
-
-static struct clk pll1_sysclk2 = {
-       .name = "pll1_sysclk2",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV2,
-};
-
-static struct clk pll1_sysclk3 = {
-       .name = "pll1_sysclk3",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV3,
-};
-
-static struct clk pll1_sysclk5 = {
-       .name = "pll1_sysclk5",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV5,
-};
-
-static struct clk pll1_aux_clk = {
-       .name = "pll1_aux_clk",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll1_sysclkbp = {
-       .name = "pll1_sysclkbp",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL | PRE_PLL,
-       .div_reg = BPDIV
-};
-
-static struct clk pll2_clk = {
-       .name = "pll2",
-       .parent = &ref_clk,
-       .pll_data = &pll2_data,
-       .flags = CLK_PLL,
-};
-
-static struct clk pll2_sysclk1 = {
-       .name = "pll2_sysclk1",
-       .parent = &pll2_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV1,
-};
-
-static struct clk pll2_sysclk2 = {
-       .name = "pll2_sysclk2",
-       .parent = &pll2_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV2,
-};
-
-static struct clk pll2_sysclkbp = {
-       .name = "pll2_sysclkbp",
-       .parent = &pll2_clk,
-       .flags = CLK_PLL | PRE_PLL,
-       .div_reg = BPDIV
-};
-
-static struct clk dsp_clk = {
-       .name = "dsp",
-       .parent = &pll1_sysclk1,
-       .lpsc = DAVINCI_LPSC_GEM,
-       .domain = DAVINCI_GPSC_DSPDOMAIN,
-       .usecount = 1,                  /* REVISIT how to disable? */
-};
-
-static struct clk arm_clk = {
-       .name = "arm",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_ARM,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk vicp_clk = {
-       .name = "vicp",
-       .parent = &pll1_sysclk2,
-       .lpsc = DAVINCI_LPSC_IMCOP,
-       .domain = DAVINCI_GPSC_DSPDOMAIN,
-       .usecount = 1,                  /* REVISIT how to disable? */
-};
-
-static struct clk vpss_master_clk = {
-       .name = "vpss_master",
-       .parent = &pll1_sysclk3,
-       .lpsc = DAVINCI_LPSC_VPSSMSTR,
-       .flags = CLK_PSC,
-};
-
-static struct clk vpss_slave_clk = {
-       .name = "vpss_slave",
-       .parent = &pll1_sysclk3,
-       .lpsc = DAVINCI_LPSC_VPSSSLV,
-};
-
-static struct clk uart0_clk = {
-       .name = "uart0",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_UART0,
-};
-
-static struct clk uart1_clk = {
-       .name = "uart1",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_UART1,
-};
-
-static struct clk uart2_clk = {
-       .name = "uart2",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_UART2,
-};
-
-static struct clk emac_clk = {
-       .name = "emac",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
-};
-
-static struct clk i2c_clk = {
-       .name = "i2c",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_I2C,
-};
-
-static struct clk ide_clk = {
-       .name = "ide",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_ATA,
-};
-
-static struct clk asp_clk = {
-       .name = "asp0",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_McBSP,
-};
-
-static struct clk mmcsd_clk = {
-       .name = "mmcsd",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_MMC_SD,
-};
-
-static struct clk spi_clk = {
-       .name = "spi",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_SPI,
-};
-
-static struct clk gpio_clk = {
-       .name = "gpio",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_GPIO,
-};
-
-static struct clk usb_clk = {
-       .name = "usb",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_USB,
-};
-
-static struct clk vlynq_clk = {
-       .name = "vlynq",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_VLYNQ,
-};
-
-static struct clk aemif_clk = {
-       .name = "aemif",
-       .parent = &pll1_sysclk5,
-       .lpsc = DAVINCI_LPSC_AEMIF,
-};
-
-static struct clk pwm0_clk = {
-       .name = "pwm0",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_PWM0,
-};
-
-static struct clk pwm1_clk = {
-       .name = "pwm1",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_PWM1,
-};
-
-static struct clk pwm2_clk = {
-       .name = "pwm2",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_PWM2,
-};
-
-static struct clk timer0_clk = {
-       .name = "timer0",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_TIMER0,
-};
-
-static struct clk timer1_clk = {
-       .name = "timer1",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_TIMER1,
-};
-
-static struct clk timer2_clk = {
-       .name = "timer2",
-       .parent = &pll1_aux_clk,
-       .lpsc = DAVINCI_LPSC_TIMER2,
-       .usecount = 1,              /* REVISIT: why can't this be disabled? */
-};
-
-static struct clk_lookup dm644x_clks[] = {
-       CLK(NULL, "ref", &ref_clk),
-       CLK(NULL, "pll1", &pll1_clk),
-       CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
-       CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
-       CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
-       CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
-       CLK(NULL, "pll1_aux", &pll1_aux_clk),
-       CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
-       CLK(NULL, "pll2", &pll2_clk),
-       CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
-       CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
-       CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
-       CLK(NULL, "dsp", &dsp_clk),
-       CLK(NULL, "arm", &arm_clk),
-       CLK(NULL, "vicp", &vicp_clk),
-       CLK("vpss", "master", &vpss_master_clk),
-       CLK("vpss", "slave", &vpss_slave_clk),
-       CLK(NULL, "arm", &arm_clk),
-       CLK("serial8250.0", NULL, &uart0_clk),
-       CLK("serial8250.1", NULL, &uart1_clk),
-       CLK("serial8250.2", NULL, &uart2_clk),
-       CLK("davinci_emac.1", NULL, &emac_clk),
-       CLK("davinci_mdio.0", "fck", &emac_clk),
-       CLK("i2c_davinci.1", NULL, &i2c_clk),
-       CLK("palm_bk3710", NULL, &ide_clk),
-       CLK("davinci-mcbsp", NULL, &asp_clk),
-       CLK("dm6441-mmc.0", NULL, &mmcsd_clk),
-       CLK(NULL, "spi", &spi_clk),
-       CLK(NULL, "gpio", &gpio_clk),
-       CLK(NULL, "usb", &usb_clk),
-       CLK(NULL, "vlynq", &vlynq_clk),
-       CLK(NULL, "aemif", &aemif_clk),
-       CLK(NULL, "pwm0", &pwm0_clk),
-       CLK(NULL, "pwm1", &pwm1_clk),
-       CLK(NULL, "pwm2", &pwm2_clk),
-       CLK(NULL, "timer0", &timer0_clk),
-       CLK(NULL, "timer1", &timer1_clk),
-       CLK("davinci-wdt", NULL, &timer2_clk),
-       CLK(NULL, NULL, NULL),
-};
-
 static struct emac_platform_data dm644x_emac_pdata = {
        .ctrl_reg_offset        = DM644X_EMAC_CNTRL_OFFSET,
        .ctrl_mod_reg_offset    = DM644X_EMAC_CNTRL_MOD_OFFSET,
@@ -819,8 +536,6 @@ static struct davinci_id dm644x_ids[] = {
        },
 };
 
-static u32 dm644x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-
 /*
  * T0_BOT: Timer 0, bottom:  clockevent source for hrtimers
  * T0_TOP: Timer 0, top   :  clocksource for generic timekeeping
@@ -905,8 +620,6 @@ static const struct davinci_soc_info davinci_soc_info_dm644x = {
        .jtag_id_reg            = 0x01c40028,
        .ids                    = dm644x_ids,
        .ids_num                = ARRAY_SIZE(dm644x_ids),
-       .psc_bases              = dm644x_psc_bases,
-       .psc_bases_num          = ARRAY_SIZE(dm644x_psc_bases),
        .pinmux_base            = DAVINCI_SYSTEM_MODULE_BASE,
        .pinmux_pins            = dm644x_pins,
        .pinmux_pins_num        = ARRAY_SIZE(dm644x_pins),
@@ -934,8 +647,41 @@ void __init dm644x_init(void)
 
 void __init dm644x_init_time(void)
 {
-       davinci_clk_init(dm644x_clks);
-       davinci_timer_init();
+       void __iomem *pll1, *psc;
+       struct clk *clk;
+
+       clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM644X_REF_FREQ);
+
+       pll1 = ioremap(DAVINCI_PLL1_BASE, SZ_1K);
+       dm644x_pll1_init(NULL, pll1, NULL);
+
+       psc = ioremap(DAVINCI_PWR_SLEEP_CNTRL_BASE, SZ_4K);
+       dm644x_psc_init(NULL, psc);
+
+       clk = clk_get(NULL, "timer0");
+
+       davinci_timer_init(clk);
+}
+
+static struct resource dm644x_pll2_resources[] = {
+       {
+               .start  = DAVINCI_PLL2_BASE,
+               .end    = DAVINCI_PLL2_BASE + SZ_1K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device dm644x_pll2_device = {
+       .name           = "dm644x-pll2",
+       .id             = -1,
+       .resource       = dm644x_pll2_resources,
+       .num_resources  = ARRAY_SIZE(dm644x_pll2_resources),
+};
+
+void __init dm644x_register_clocks(void)
+{
+       /* PLL1 and PSC are registered in dm644x_init_time() */
+       platform_device_register(&dm644x_pll2_device);
 }
 
 int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
index c32ca27ab343d1258399648b5e9dfb9aa1e215e0..6bd2ed069d0d7491a28b5af9665838e030e41ed3 100644 (file)
@@ -8,29 +8,30 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
+
+#include <linux/clk-provider.h>
+#include <linux/clk/davinci.h>
+#include <linux/clkdev.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
 #include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/serial_8250.h>
-#include <linux/platform_device.h>
 #include <linux/platform_data/edma.h>
 #include <linux/platform_data/gpio-davinci.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
 
 #include <asm/mach/map.h>
 
+#include <mach/common.h>
 #include <mach/cputype.h>
 #include <mach/irqs.h>
-#include "psc.h"
 #include <mach/mux.h>
-#include <mach/time.h>
 #include <mach/serial.h>
-#include <mach/common.h>
+#include <mach/time.h>
 
+#include "asp.h"
 #include "davinci.h"
-#include "clock.h"
 #include "mux.h"
-#include "asp.h"
 
 #define DAVINCI_VPIF_BASE       (0x01C12000)
 
 #define DM646X_EMAC_CNTRL_RAM_OFFSET   0x2000
 #define DM646X_EMAC_CNTRL_RAM_SIZE     0x2000
 
-static struct pll_data pll1_data = {
-       .num       = 1,
-       .phys_base = DAVINCI_PLL1_BASE,
-};
-
-static struct pll_data pll2_data = {
-       .num       = 2,
-       .phys_base = DAVINCI_PLL2_BASE,
-};
-
-static struct clk ref_clk = {
-       .name = "ref_clk",
-       /* rate is initialized in dm646x_init_time() */
-};
-
-static struct clk aux_clkin = {
-       .name = "aux_clkin",
-       /* rate is initialized in dm646x_init_time() */
-};
-
-static struct clk pll1_clk = {
-       .name = "pll1",
-       .parent = &ref_clk,
-       .pll_data = &pll1_data,
-       .flags = CLK_PLL,
-};
-
-static struct clk pll1_sysclk1 = {
-       .name = "pll1_sysclk1",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV1,
-};
-
-static struct clk pll1_sysclk2 = {
-       .name = "pll1_sysclk2",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV2,
-};
-
-static struct clk pll1_sysclk3 = {
-       .name = "pll1_sysclk3",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV3,
-};
-
-static struct clk pll1_sysclk4 = {
-       .name = "pll1_sysclk4",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV4,
-};
-
-static struct clk pll1_sysclk5 = {
-       .name = "pll1_sysclk5",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV5,
-};
-
-static struct clk pll1_sysclk6 = {
-       .name = "pll1_sysclk6",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV6,
-};
-
-static struct clk pll1_sysclk8 = {
-       .name = "pll1_sysclk8",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV8,
-};
-
-static struct clk pll1_sysclk9 = {
-       .name = "pll1_sysclk9",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV9,
-};
-
-static struct clk pll1_sysclkbp = {
-       .name = "pll1_sysclkbp",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL | PRE_PLL,
-       .div_reg = BPDIV,
-};
-
-static struct clk pll1_aux_clk = {
-       .name = "pll1_aux_clk",
-       .parent = &pll1_clk,
-       .flags = CLK_PLL | PRE_PLL,
-};
-
-static struct clk pll2_clk = {
-       .name = "pll2_clk",
-       .parent = &ref_clk,
-       .pll_data = &pll2_data,
-       .flags = CLK_PLL,
-};
-
-static struct clk pll2_sysclk1 = {
-       .name = "pll2_sysclk1",
-       .parent = &pll2_clk,
-       .flags = CLK_PLL,
-       .div_reg = PLLDIV1,
-};
-
-static struct clk dsp_clk = {
-       .name = "dsp",
-       .parent = &pll1_sysclk1,
-       .lpsc = DM646X_LPSC_C64X_CPU,
-       .usecount = 1,                  /* REVISIT how to disable? */
-};
-
-static struct clk arm_clk = {
-       .name = "arm",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM646X_LPSC_ARM,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_cc_clk = {
-       .name = "edma_cc",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM646X_LPSC_TPCC,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_tc0_clk = {
-       .name = "edma_tc0",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM646X_LPSC_TPTC0,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_tc1_clk = {
-       .name = "edma_tc1",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM646X_LPSC_TPTC1,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_tc2_clk = {
-       .name = "edma_tc2",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM646X_LPSC_TPTC2,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk edma_tc3_clk = {
-       .name = "edma_tc3",
-       .parent = &pll1_sysclk2,
-       .lpsc = DM646X_LPSC_TPTC3,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk uart0_clk = {
-       .name = "uart0",
-       .parent = &aux_clkin,
-       .lpsc = DM646X_LPSC_UART0,
-};
-
-static struct clk uart1_clk = {
-       .name = "uart1",
-       .parent = &aux_clkin,
-       .lpsc = DM646X_LPSC_UART1,
-};
-
-static struct clk uart2_clk = {
-       .name = "uart2",
-       .parent = &aux_clkin,
-       .lpsc = DM646X_LPSC_UART2,
-};
-
-static struct clk i2c_clk = {
-       .name = "I2CCLK",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_I2C,
-};
-
-static struct clk gpio_clk = {
-       .name = "gpio",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_GPIO,
-};
-
-static struct clk mcasp0_clk = {
-       .name = "mcasp0",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_McASP0,
-};
-
-static struct clk mcasp1_clk = {
-       .name = "mcasp1",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_McASP1,
-};
-
-static struct clk aemif_clk = {
-       .name = "aemif",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_AEMIF,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk emac_clk = {
-       .name = "emac",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_EMAC,
-};
-
-static struct clk pwm0_clk = {
-       .name = "pwm0",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_PWM0,
-       .usecount = 1,            /* REVIST: disabling hangs system */
-};
-
-static struct clk pwm1_clk = {
-       .name = "pwm1",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_PWM1,
-       .usecount = 1,            /* REVIST: disabling hangs system */
-};
-
-static struct clk timer0_clk = {
-       .name = "timer0",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_TIMER0,
-};
-
-static struct clk timer1_clk = {
-       .name = "timer1",
-       .parent = &pll1_sysclk3,
-       .lpsc = DM646X_LPSC_TIMER1,
-};
-
-static struct clk timer2_clk = {
-       .name = "timer2",
-       .parent = &pll1_sysclk3,
-       .flags = ALWAYS_ENABLED, /* no LPSC, always enabled; c.f. spruep9a */
-};
-
-
-static struct clk ide_clk = {
-       .name = "ide",
-       .parent = &pll1_sysclk4,
-       .lpsc = DAVINCI_LPSC_ATA,
-};
-
-static struct clk vpif0_clk = {
-       .name = "vpif0",
-       .parent = &ref_clk,
-       .lpsc = DM646X_LPSC_VPSSMSTR,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk vpif1_clk = {
-       .name = "vpif1",
-       .parent = &ref_clk,
-       .lpsc = DM646X_LPSC_VPSSSLV,
-       .flags = ALWAYS_ENABLED,
-};
-
-static struct clk_lookup dm646x_clks[] = {
-       CLK(NULL, "ref", &ref_clk),
-       CLK(NULL, "aux", &aux_clkin),
-       CLK(NULL, "pll1", &pll1_clk),
-       CLK(NULL, "pll1_sysclk", &pll1_sysclk1),
-       CLK(NULL, "pll1_sysclk", &pll1_sysclk2),
-       CLK(NULL, "pll1_sysclk", &pll1_sysclk3),
-       CLK(NULL, "pll1_sysclk", &pll1_sysclk4),
-       CLK(NULL, "pll1_sysclk", &pll1_sysclk5),
-       CLK(NULL, "pll1_sysclk", &pll1_sysclk6),
-       CLK(NULL, "pll1_sysclk", &pll1_sysclk8),
-       CLK(NULL, "pll1_sysclk", &pll1_sysclk9),
-       CLK(NULL, "pll1_sysclk", &pll1_sysclkbp),
-       CLK(NULL, "pll1_aux", &pll1_aux_clk),
-       CLK(NULL, "pll2", &pll2_clk),
-       CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
-       CLK(NULL, "dsp", &dsp_clk),
-       CLK(NULL, "arm", &arm_clk),
-       CLK(NULL, "edma_cc", &edma_cc_clk),
-       CLK(NULL, "edma_tc0", &edma_tc0_clk),
-       CLK(NULL, "edma_tc1", &edma_tc1_clk),
-       CLK(NULL, "edma_tc2", &edma_tc2_clk),
-       CLK(NULL, "edma_tc3", &edma_tc3_clk),
-       CLK("serial8250.0", NULL, &uart0_clk),
-       CLK("serial8250.1", NULL, &uart1_clk),
-       CLK("serial8250.2", NULL, &uart2_clk),
-       CLK("i2c_davinci.1", NULL, &i2c_clk),
-       CLK(NULL, "gpio", &gpio_clk),
-       CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
-       CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
-       CLK(NULL, "aemif", &aemif_clk),
-       CLK("davinci_emac.1", NULL, &emac_clk),
-       CLK("davinci_mdio.0", "fck", &emac_clk),
-       CLK(NULL, "pwm0", &pwm0_clk),
-       CLK(NULL, "pwm1", &pwm1_clk),
-       CLK(NULL, "timer0", &timer0_clk),
-       CLK(NULL, "timer1", &timer1_clk),
-       CLK("davinci-wdt", NULL, &timer2_clk),
-       CLK("palm_bk3710", NULL, &ide_clk),
-       CLK(NULL, "vpif0", &vpif0_clk),
-       CLK(NULL, "vpif1", &vpif1_clk),
-       CLK(NULL, NULL, NULL),
-};
-
 static struct emac_platform_data dm646x_emac_pdata = {
        .ctrl_reg_offset        = DM646X_EMAC_CNTRL_OFFSET,
        .ctrl_mod_reg_offset    = DM646X_EMAC_CNTRL_MOD_OFFSET,
@@ -796,8 +486,6 @@ static struct davinci_id dm646x_ids[] = {
        },
 };
 
-static u32 dm646x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
-
 /*
  * T0_BOT: Timer 0, bottom:  clockevent source for hrtimers
  * T0_TOP: Timer 0, top   :  clocksource for generic timekeeping
@@ -882,8 +570,6 @@ static const struct davinci_soc_info davinci_soc_info_dm646x = {
        .jtag_id_reg            = 0x01c40028,
        .ids                    = dm646x_ids,
        .ids_num                = ARRAY_SIZE(dm646x_ids),
-       .psc_bases              = dm646x_psc_bases,
-       .psc_bases_num          = ARRAY_SIZE(dm646x_psc_bases),
        .pinmux_base            = DAVINCI_SYSTEM_MODULE_BASE,
        .pinmux_pins            = dm646x_pins,
        .pinmux_pins_num        = ARRAY_SIZE(dm646x_pins),
@@ -954,10 +640,42 @@ void __init dm646x_init(void)
 void __init dm646x_init_time(unsigned long ref_clk_rate,
                             unsigned long aux_clkin_rate)
 {
-       ref_clk.rate = ref_clk_rate;
-       aux_clkin.rate = aux_clkin_rate;
-       davinci_clk_init(dm646x_clks);
-       davinci_timer_init();
+       void __iomem *pll1, *psc;
+       struct clk *clk;
+
+       clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, ref_clk_rate);
+       clk_register_fixed_rate(NULL, "aux_clkin", NULL, 0, aux_clkin_rate);
+
+       pll1 = ioremap(DAVINCI_PLL1_BASE, SZ_1K);
+       dm646x_pll1_init(NULL, pll1, NULL);
+
+       psc = ioremap(DAVINCI_PWR_SLEEP_CNTRL_BASE, SZ_4K);
+       dm646x_psc_init(NULL, psc);
+
+       clk = clk_get(NULL, "timer0");
+
+       davinci_timer_init(clk);
+}
+
+static struct resource dm646x_pll2_resources[] = {
+       {
+               .start  = DAVINCI_PLL2_BASE,
+               .end    = DAVINCI_PLL2_BASE + SZ_1K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device dm646x_pll2_device = {
+       .name           = "dm646x-pll2",
+       .id             = -1,
+       .resource       = dm646x_pll2_resources,
+       .num_resources  = ARRAY_SIZE(dm646x_pll2_resources),
+};
+
+void __init dm646x_register_clocks(void)
+{
+       /* PLL1 and PSC are registered in dm646x_init_time() */
+       platform_device_register(&dm646x_pll2_device);
 }
 
 static int __init dm646x_init_devices(void)
index 3e8af6a0b64c6aac9f92202a0c732417167005db..42ed4f2f5ce4fa8003de397b35f4c545a6a93ef8 100644 (file)
@@ -15,9 +15,6 @@
 
 struct clk;
 
-extern int clk_register(struct clk *clk);
-extern void clk_unregister(struct clk *clk);
-
 int davinci_clk_reset_assert(struct clk *c);
 int davinci_clk_reset_deassert(struct clk *c);
 
index f0d5e858f15801554ba351388ea6144a06deb3e4..b577e13a9c23f29b52c393427281a4d27b8cf92a 100644 (file)
 #ifndef __ARCH_ARM_MACH_DAVINCI_COMMON_H
 #define __ARCH_ARM_MACH_DAVINCI_COMMON_H
 
+#include <linux/clk.h>
 #include <linux/compiler.h>
 #include <linux/types.h>
 #include <linux/reboot.h>
 
-extern void davinci_timer_init(void);
+void davinci_timer_init(struct clk *clk);
 
 extern void davinci_irq_init(void);
 extern void __iomem *davinci_intc_base;
@@ -53,8 +54,6 @@ struct davinci_soc_info {
        u32                             jtag_id_reg;
        struct davinci_id               *ids;
        unsigned long                   ids_num;
-       u32                             *psc_bases;
-       unsigned long                   psc_bases_num;
        u32                             pinmux_base;
        const struct mux_config         *pinmux_pins;
        unsigned long                   pinmux_pins_num;
@@ -82,12 +81,6 @@ extern void davinci_common_init(const struct davinci_soc_info *soc_info);
 extern void davinci_init_ide(void);
 void davinci_init_late(void);
 
-#ifdef CONFIG_DAVINCI_RESET_CLOCKS
-int davinci_clk_disable_unused(void);
-#else
-static inline int davinci_clk_disable_unused(void) { return 0; }
-#endif
-
 #ifdef CONFIG_CPU_FREQ
 int davinci_cpufreq_init(void);
 #else
index 9fd6d012576216f901dacb8afa9684534294cd18..ab4a57f433f489d0f86c559cfde9f46d2bb8bc30 100644 (file)
@@ -89,9 +89,11 @@ extern unsigned int da850_max_speed;
 
 void da830_init(void);
 void da830_init_time(void);
+void da830_register_clocks(void);
 
 void da850_init(void);
 void da850_init_time(void);
+void da850_register_clocks(void);
 
 int da830_register_edma(struct edma_rsv_info *rsv);
 int da850_register_edma(struct edma_rsv_info *rsv[2]);
@@ -101,9 +103,7 @@ int da8xx_register_watchdog(void);
 int da8xx_register_usb_phy(void);
 int da8xx_register_usb20(unsigned mA, unsigned potpgt);
 int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
-int da8xx_register_usb_refclkin(int rate);
-int da8xx_register_usb20_phy_clk(bool use_usb_refclkin);
-int da8xx_register_usb11_phy_clk(bool use_usb_refclkin);
+int da8xx_register_usb_phy_clocks(void);
 int da850_register_sata_refclk(int rate);
 int da8xx_register_emac(void);
 int da8xx_register_uio_pruss(void);
index 78eac2c0c146bb91a7b51965e2685e3106f67eef..e251fd593bfd18be4c26e7fccb5a8c0809825c0a 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/pm_clock.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 
 static struct dev_pm_domain davinci_pm_domain = {
        .ops = {
@@ -28,6 +29,10 @@ static struct pm_clk_notifier_block platform_bus_notifier = {
 
 static int __init davinci_pm_runtime_init(void)
 {
+       if (of_have_populated_dt())
+               return 0;
+
+       /* Use pm_clk as fallback if we're not using genpd. */
        pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
 
        return 0;
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c
deleted file mode 100644 (file)
index e5dc6bf..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * TI DaVinci Power and Sleep Controller (PSC)
- *
- * Copyright (C) 2006 Texas Instruments.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT 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/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-
-#include <mach/cputype.h>
-#include "psc.h"
-
-#include "clock.h"
-
-/* Return nonzero iff the domain's clock is active */
-int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id)
-{
-       void __iomem *psc_base;
-       u32 mdstat;
-       struct davinci_soc_info *soc_info = &davinci_soc_info;
-
-       if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
-               pr_warn("PSC: Bad psc data: 0x%x[%d]\n",
-                               (int)soc_info->psc_bases, ctlr);
-               return 0;
-       }
-
-       psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
-       mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
-       iounmap(psc_base);
-
-       /* if clocked, state can be "Enable" or "SyncReset" */
-       return mdstat & BIT(12);
-}
-
-/* Control "reset" line associated with PSC domain */
-void davinci_psc_reset(unsigned int ctlr, unsigned int id, bool reset)
-{
-       u32 mdctl;
-       void __iomem *psc_base;
-       struct davinci_soc_info *soc_info = &davinci_soc_info;
-
-       if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
-               pr_warn("PSC: Bad psc data: 0x%x[%d]\n",
-                               (int)soc_info->psc_bases, ctlr);
-               return;
-       }
-
-       psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
-
-       mdctl = readl(psc_base + MDCTL + 4 * id);
-       if (reset)
-               mdctl &= ~MDCTL_LRST;
-       else
-               mdctl |= MDCTL_LRST;
-       writel(mdctl, psc_base + MDCTL + 4 * id);
-
-       iounmap(psc_base);
-}
-
-/* Enable or disable a PSC domain */
-void davinci_psc_config(unsigned int domain, unsigned int ctlr,
-               unsigned int id, bool enable, u32 flags)
-{
-       u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl;
-       void __iomem *psc_base;
-       struct davinci_soc_info *soc_info = &davinci_soc_info;
-       u32 next_state = PSC_STATE_ENABLE;
-
-       if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
-               pr_warn("PSC: Bad psc data: 0x%x[%d]\n",
-                               (int)soc_info->psc_bases, ctlr);
-               return;
-       }
-
-       psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
-
-       if (!enable) {
-               if (flags & PSC_SWRSTDISABLE)
-                       next_state = PSC_STATE_SWRSTDISABLE;
-               else
-                       next_state = PSC_STATE_DISABLE;
-       }
-
-       mdctl = __raw_readl(psc_base + MDCTL + 4 * id);
-       mdctl &= ~MDSTAT_STATE_MASK;
-       mdctl |= next_state;
-       if (flags & PSC_FORCE)
-               mdctl |= MDCTL_FORCE;
-       __raw_writel(mdctl, psc_base + MDCTL + 4 * id);
-
-       pdstat = __raw_readl(psc_base + PDSTAT + 4 * domain);
-       if ((pdstat & PDSTAT_STATE_MASK) == 0) {
-               pdctl = __raw_readl(psc_base + PDCTL + 4 * domain);
-               pdctl |= PDCTL_NEXT;
-               __raw_writel(pdctl, psc_base + PDCTL + 4 * domain);
-
-               ptcmd = 1 << domain;
-               __raw_writel(ptcmd, psc_base + PTCMD);
-
-               do {
-                       epcpr = __raw_readl(psc_base + EPCPR);
-               } while ((((epcpr >> domain) & 1) == 0));
-
-               pdctl = __raw_readl(psc_base + PDCTL + 4 * domain);
-               pdctl |= PDCTL_EPCGOOD;
-               __raw_writel(pdctl, psc_base + PDCTL + 4 * domain);
-       } else {
-               ptcmd = 1 << domain;
-               __raw_writel(ptcmd, psc_base + PTCMD);
-       }
-
-       do {
-               ptstat = __raw_readl(psc_base + PTSTAT);
-       } while (!(((ptstat >> domain) & 1) == 0));
-
-       do {
-               mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
-       } while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
-
-       iounmap(psc_base);
-}
index 8af9f09fc10ce1dcab351389c77c706e86520cc4..68cd9d3fc82b825a26ffb8b4ea98d0081c15d958 100644 (file)
@@ -27,8 +27,6 @@
 #ifndef __ASM_ARCH_PSC_H
 #define __ASM_ARCH_PSC_H
 
-#define        DAVINCI_PWR_SLEEP_CNTRL_BASE    0x01C41000
-
 /* Power and Sleep Controller (PSC) Domains */
 #define DAVINCI_GPSC_ARMDOMAIN         0
 #define DAVINCI_GPSC_DSPDOMAIN         1
 #define PDCTL_NEXT             BIT(0)
 #define PDCTL_EPCGOOD          BIT(8)
 
-#ifndef __ASSEMBLER__
-
-extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
-extern void davinci_psc_reset(unsigned int ctlr, unsigned int id,
-               bool reset);
-extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
-               unsigned int id, bool enable, u32 flags);
-
-#endif
-
 #endif /* __ASM_ARCH_PSC_H */
index 1bb991ad9c1ed6678b55918b66f47e26b7dc0884..5a6de5368ab08cb51351ffeac3493870613cadeb 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/sched_clock.h>
 
@@ -27,8 +28,6 @@
 #include <mach/hardware.h>
 #include <mach/time.h>
 
-#include "clock.h"
-
 static struct clock_event_device clockevent_davinci;
 static unsigned int davinci_clock_tick_rate;
 
@@ -334,10 +333,8 @@ static struct clock_event_device clockevent_davinci = {
        .set_state_oneshot      = davinci_set_oneshot,
 };
 
-
-void __init davinci_timer_init(void)
+void __init davinci_timer_init(struct clk *timer_clk)
 {
-       struct clk *timer_clk;
        struct davinci_soc_info *soc_info = &davinci_soc_info;
        unsigned int clockevent_id;
        unsigned int clocksource_id;
@@ -373,7 +370,6 @@ void __init davinci_timer_init(void)
                }
        }
 
-       timer_clk = clk_get(NULL, "timer0");
        BUG_ON(IS_ERR(timer_clk));
        clk_prepare_enable(timer_clk);
 
@@ -402,3 +398,17 @@ void __init davinci_timer_init(void)
        for (i=0; i< ARRAY_SIZE(timers); i++)
                timer32_config(&timers[i]);
 }
+
+static int __init of_davinci_timer_init(struct device_node *np)
+{
+       struct clk *clk;
+
+       clk = of_clk_get(np, 0);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+
+       davinci_timer_init(clk);
+
+       return 0;
+}
+TIMER_OF_DECLARE(davinci_timer, "ti,da830-timer", of_davinci_timer_init);
index 50445f0e98def51ac1e261d03746fb36ab8628fe..c17ce66a3d9511b270f18b4ba44f631f5853dc53 100644 (file)
@@ -2,29 +2,30 @@
 /*
  * DA8xx USB
  */
-#include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/init.h>
 #include <linux/mfd/da8xx-cfgchip.h>
+#include <linux/mfd/syscon.h>
 #include <linux/phy/phy.h>
+#include <linux/platform_data/clk-da8xx-cfgchip.h>
 #include <linux/platform_data/phy-da8xx-usb.h>
 #include <linux/platform_data/usb-davinci.h>
 #include <linux/platform_device.h>
 #include <linux/usb/musb.h>
 
-#include <mach/clock.h>
 #include <mach/common.h>
 #include <mach/cputype.h>
 #include <mach/da8xx.h>
 #include <mach/irqs.h>
 
-#include "clock.h"
-
 #define DA8XX_USB0_BASE                0x01e00000
 #define DA8XX_USB1_BASE                0x01e25000
 
+#ifndef CONFIG_COMMON_CLK
 static struct clk *usb20_clk;
+#endif
 
 static struct da8xx_usb_phy_platform_data da8xx_usb_phy_pdata;
 
@@ -81,11 +82,6 @@ static struct platform_device da8xx_usb20_dev = {
        .name           = "musb-da8xx",
        .id             = -1,
        .dev = {
-               /*
-                * Setting init_name so that clock lookup will work in
-                * usb20_phy_clk_enable() even if this device is not registered.
-                */
-               .init_name              = "musb-da8xx",
                .platform_data          = &usb_data,
                .dma_mask               = &usb_dmamask,
                .coherent_dma_mask      = DMA_BIT_MASK(32),
@@ -134,229 +130,17 @@ int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata)
        return platform_device_register(&da8xx_usb11_device);
 }
 
-static struct clk usb_refclkin = {
-       .name           = "usb_refclkin",
-       .set_rate       = davinci_simple_set_rate,
-};
-
-static struct clk_lookup usb_refclkin_lookup =
-       CLK(NULL, "usb_refclkin", &usb_refclkin);
-
-/**
- * da8xx_register_usb_refclkin - register USB_REFCLKIN clock
- *
- * @rate: The clock rate in Hz
- *
- * This clock is only needed if the board provides an external USB_REFCLKIN
- * signal, in which case it will be used as the parent of usb20_phy_clk and/or
- * usb11_phy_clk.
- */
-int __init da8xx_register_usb_refclkin(int rate)
-{
-       int ret;
-
-       usb_refclkin.rate = rate;
-       ret = clk_register(&usb_refclkin);
-       if (ret)
-               return ret;
-
-       clkdev_add(&usb_refclkin_lookup);
-
-       return 0;
-}
-
-static void usb20_phy_clk_enable(struct clk *clk)
-{
-       u32 val;
-       u32 timeout = 500000; /* 500 msec */
-
-       val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
-       /* The USB 2.O PLL requires that the USB 2.O PSC is enabled as well. */
-       davinci_clk_enable(usb20_clk);
-
-       /*
-        * Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
-        * host may use the PLL clock without USB 2.0 OTG being used.
-        */
-       val &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN);
-       val |= CFGCHIP2_PHY_PLLON;
-
-       writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
-       while (--timeout) {
-               val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-               if (val & CFGCHIP2_PHYCLKGD)
-                       goto done;
-               udelay(1);
-       }
-
-       pr_err("Timeout waiting for USB 2.0 PHY clock good\n");
-done:
-       davinci_clk_disable(usb20_clk);
-}
-
-static void usb20_phy_clk_disable(struct clk *clk)
-{
-       u32 val;
-
-       val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-       val |= CFGCHIP2_PHYPWRDN;
-       writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-}
-
-static int usb20_phy_clk_set_parent(struct clk *clk, struct clk *parent)
-{
-       u32 val;
-
-       val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
-       /* Set the mux depending on the parent clock. */
-       if (parent == &usb_refclkin) {
-               val &= ~CFGCHIP2_USB2PHYCLKMUX;
-       } else if (strcmp(parent->name, "pll0_aux_clk") == 0) {
-               val |= CFGCHIP2_USB2PHYCLKMUX;
-       } else {
-               pr_err("Bad parent on USB 2.0 PHY clock\n");
-               return -EINVAL;
-       }
-
-       /* reference frequency also comes from parent clock */
-       val &= ~CFGCHIP2_REFFREQ_MASK;
-       switch (clk_get_rate(parent)) {
-       case 12000000:
-               val |= CFGCHIP2_REFFREQ_12MHZ;
-               break;
-       case 13000000:
-               val |= CFGCHIP2_REFFREQ_13MHZ;
-               break;
-       case 19200000:
-               val |= CFGCHIP2_REFFREQ_19_2MHZ;
-               break;
-       case 20000000:
-               val |= CFGCHIP2_REFFREQ_20MHZ;
-               break;
-       case 24000000:
-               val |= CFGCHIP2_REFFREQ_24MHZ;
-               break;
-       case 26000000:
-               val |= CFGCHIP2_REFFREQ_26MHZ;
-               break;
-       case 38400000:
-               val |= CFGCHIP2_REFFREQ_38_4MHZ;
-               break;
-       case 40000000:
-               val |= CFGCHIP2_REFFREQ_40MHZ;
-               break;
-       case 48000000:
-               val |= CFGCHIP2_REFFREQ_48MHZ;
-               break;
-       default:
-               pr_err("Bad parent clock rate on USB 2.0 PHY clock\n");
-               return -EINVAL;
-       }
-
-       writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
-       return 0;
-}
-
-static struct clk usb20_phy_clk = {
-       .name           = "usb0_clk48",
-       .clk_enable     = usb20_phy_clk_enable,
-       .clk_disable    = usb20_phy_clk_disable,
-       .set_parent     = usb20_phy_clk_set_parent,
-};
-
-static struct clk_lookup usb20_phy_clk_lookup =
-       CLK("da8xx-usb-phy", "usb0_clk48", &usb20_phy_clk);
-
-/**
- * da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock
- *
- * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
- *     or "pll0_aux" if false.
- */
-int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
-{
-       struct clk *parent;
-       int ret;
-
-       usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
-       ret = PTR_ERR_OR_ZERO(usb20_clk);
-       if (ret)
-               return ret;
-
-       parent = clk_get(NULL, use_usb_refclkin ? "usb_refclkin" : "pll0_aux");
-       ret = PTR_ERR_OR_ZERO(parent);
-       if (ret) {
-               clk_put(usb20_clk);
-               return ret;
-       }
-
-       usb20_phy_clk.parent = parent;
-       ret = clk_register(&usb20_phy_clk);
-       if (!ret)
-               clkdev_add(&usb20_phy_clk_lookup);
-
-       clk_put(parent);
-
-       return ret;
-}
-
-static int usb11_phy_clk_set_parent(struct clk *clk, struct clk *parent)
-{
-       u32 val;
-
-       val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
-       /* Set the USB 1.1 PHY clock mux based on the parent clock. */
-       if (parent == &usb20_phy_clk) {
-               val &= ~CFGCHIP2_USB1PHYCLKMUX;
-       } else if (parent == &usb_refclkin) {
-               val |= CFGCHIP2_USB1PHYCLKMUX;
-       } else {
-               pr_err("Bad parent on USB 1.1 PHY clock\n");
-               return -EINVAL;
-       }
-
-       writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
-
-       return 0;
-}
-
-static struct clk usb11_phy_clk = {
-       .name           = "usb1_clk48",
-       .set_parent     = usb11_phy_clk_set_parent,
+static struct platform_device da8xx_usb_phy_clks_device = {
+       .name           = "da830-usb-phy-clks",
+       .id             = -1,
 };
 
-static struct clk_lookup usb11_phy_clk_lookup =
-       CLK("da8xx-usb-phy", "usb1_clk48", &usb11_phy_clk);
-
-/**
- * da8xx_register_usb11_phy_clk - register USB1PHYCLKMUX clock
- *
- * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
- *     or "usb0_clk48" if false.
- */
-int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
+int __init da8xx_register_usb_phy_clocks(void)
 {
-       struct clk *parent;
-       int ret = 0;
-
-       if (use_usb_refclkin)
-               parent = clk_get(NULL, "usb_refclkin");
-       else
-               parent = clk_get(&da8xx_usb_phy.dev, "usb0_clk48");
-       if (IS_ERR(parent))
-               return PTR_ERR(parent);
-
-       usb11_phy_clk.parent = parent;
-       ret = clk_register(&usb11_phy_clk);
-       if (!ret)
-               clkdev_add(&usb11_phy_clk_lookup);
+       struct da8xx_cfgchip_clk_platform_data pdata;
 
-       clk_put(parent);
+       pdata.cfgchip = da8xx_get_cfgchip();
+       da8xx_usb_phy_clks_device.dev.platform_data = &pdata;
 
-       return ret;
+       return platform_device_register(&da8xx_usb_phy_clks_device);
 }
index f4b6c93a7fd07fdc289d486e09c2f331ecfb5d21..865dcc4c3181a1e4540e094baa0ef976d876b0b5 100644 (file)
@@ -190,8 +190,6 @@ static void __init exynos_dt_fixup(void)
 }
 
 DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
-       /* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
-       /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
        .l2c_aux_val    = 0x3c400001,
        .l2c_aux_mask   = 0xc20fffff,
        .smp            = smp_ops(exynos_smp_ops),
index f3384e3a675d63509c90c05a95db3bb5f0c23b67..7ead3acd6fa4d4f14463cb3606222894dbc991c4 100644 (file)
@@ -203,6 +203,7 @@ static int __init exynos_pmu_irq_init(struct device_node *node,
                                          NULL);
        if (!domain) {
                iounmap(pmu_base_addr);
+               pmu_base_addr = NULL;
                return -ENOMEM;
        }
 
index a129aae7260286fcaf77bc110bce3dea71fb679e..909bb24937812028a706fe865de275b228d1f53d 100644 (file)
@@ -148,13 +148,20 @@ static int hi3xxx_hotplug_init(void)
        struct device_node *node;
 
        node = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
-       if (node) {
-               ctrl_base = of_iomap(node, 0);
-               id = HI3620_CTRL;
-               return 0;
+       if (!node) {
+               id = ERROR_CTRL;
+               return -ENOENT;
        }
-       id = ERROR_CTRL;
-       return -ENOENT;
+
+       ctrl_base = of_iomap(node, 0);
+       of_node_put(node);
+       if (!ctrl_base) {
+               id = ERROR_CTRL;
+               return -ENOMEM;
+       }
+
+       id = HI3620_CTRL;
+       return 0;
 }
 
 void hi3xxx_set_cpu(int cpu, bool enable)
@@ -173,11 +180,15 @@ static bool hix5hd2_hotplug_init(void)
        struct device_node *np;
 
        np = of_find_compatible_node(NULL, NULL, "hisilicon,cpuctrl");
-       if (np) {
-               ctrl_base = of_iomap(np, 0);
-               return true;
-       }
-       return false;
+       if (!np)
+               return false;
+
+       ctrl_base = of_iomap(np, 0);
+       of_node_put(np);
+       if (!ctrl_base)
+               return false;
+
+       return true;
 }
 
 void hix5hd2_set_cpu(int cpu, bool enable)
@@ -219,10 +230,10 @@ void hip01_set_cpu(int cpu, bool enable)
 
        if (!ctrl_base) {
                np = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl");
-               if (np)
-                       ctrl_base = of_iomap(np, 0);
-               else
-                       BUG();
+               BUG_ON(!np);
+               ctrl_base = of_iomap(np, 0);
+               of_node_put(np);
+               BUG_ON(!ctrl_base);
        }
 
        if (enable) {
index 6f423238477477c2720d4cb042305016f0676fb9..abc337111eff2e59c63dd898313b45092ba53a7f 100644 (file)
@@ -523,18 +523,6 @@ config SOC_IMX6UL
        help
          This enables support for Freescale i.MX6 UltraLite processor.
 
-config SOC_IMX7D
-       bool "i.MX7 Dual support"
-       select PINCTRL_IMX7D
-       select ARM_GIC
-       select HAVE_ARM_ARCH_TIMER
-       select HAVE_IMX_ANATOP
-       select HAVE_IMX_MMDC
-       select HAVE_IMX_SRC
-       select IMX_GPCV2
-       help
-               This enables support for Freescale i.MX7 Dual processor.
-
 config SOC_LS1021A
        bool "Freescale LS1021A support"
        select ARM_GIC
@@ -549,6 +537,27 @@ comment "Cortex-A/Cortex-M asymmetric multiprocessing platforms"
 
 if ARCH_MULTI_V7 || ARM_SINGLE_ARMV7M
 
+config SOC_IMX7D_CA7
+       bool
+       select ARM_GIC
+       select HAVE_ARM_ARCH_TIMER
+       select HAVE_IMX_ANATOP
+       select HAVE_IMX_MMDC
+       select HAVE_IMX_SRC
+       select IMX_GPCV2
+
+config SOC_IMX7D_CM4
+       bool
+       select ARMV7M_SYSTICK
+
+config SOC_IMX7D
+       bool "i.MX7 Dual support"
+       select PINCTRL_IMX7D
+       select SOC_IMX7D_CA7 if ARCH_MULTI_V7
+       select SOC_IMX7D_CM4 if ARM_SINGLE_ARMV7M
+       help
+               This enables support for Freescale i.MX7 Dual processor.
+
 config SOC_VF610
        bool "Vybrid Family VF610 support"
        select ARM_GIC if ARCH_MULTI_V7
index 2327e3e876d86b6212948e9b0489fbfafd432096..bae179af21f6dc211ea656264d6aa10192de84f6 100644 (file)
@@ -26,7 +26,7 @@ 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
-obj-$(CONFIG_SOC_IMX6SLL) += cpuidle-imx6sl.o
+obj-$(CONFIG_SOC_IMX6SLL) += cpuidle-imx6sx.o
 obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o
 obj-$(CONFIG_SOC_IMX6UL) += cpuidle-imx6sx.o
 endif
@@ -81,7 +81,8 @@ obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o
 obj-$(CONFIG_SOC_IMX6SLL) += mach-imx6sl.o
 obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o
 obj-$(CONFIG_SOC_IMX6UL) += mach-imx6ul.o
-obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o
+obj-$(CONFIG_SOC_IMX7D_CA7) += mach-imx7d.o
+obj-$(CONFIG_SOC_IMX7D_CM4) += mach-imx7d-cm4.o
 
 ifeq ($(CONFIG_SUSPEND),y)
 AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
index c8d68e918b2ff60741e33df67da243b4ceb64ea8..423dd76bb6b812e408f106e2367386820b13a8a4 100644 (file)
@@ -38,7 +38,6 @@ void imx21_soc_init(void);
 void imx27_soc_init(void);
 void imx31_soc_init(void);
 void imx35_soc_init(void);
-void epit_timer_init(void __iomem *base, int irq);
 int mx21_clocks_init(unsigned long lref, unsigned long fref);
 int mx27_clocks_init(unsigned long fref);
 int mx31_clocks_init(unsigned long fref);
@@ -58,10 +57,12 @@ struct device *imx_soc_device_init(void);
 void imx6_enable_rbc(bool enable);
 void imx_gpc_check_dt(void);
 void imx_gpc_set_arm_power_in_lpm(bool power_off);
+void imx_gpc_set_l2_mem_power_in_lpm(bool power_off);
 void imx_gpc_set_arm_power_up_timing(u32 sw2iso, u32 sw);
 void imx_gpc_set_arm_power_down_timing(u32 sw2iso, u32 sw);
 void imx25_pm_init(void);
 void imx27_pm_init(void);
+void imx5_pmu_init(void);
 
 enum mxc_cpu_pwr_mode {
        WAIT_CLOCKED,           /* wfi only */
index 4f2d1c772f8559d789b71ca1f83568148153e466..e210bac18840016223fd29c613cdc711de62dcdf 100644 (file)
@@ -117,3 +117,48 @@ int mx53_revision(void)
        return mx5_cpu_rev;
 }
 EXPORT_SYMBOL(mx53_revision);
+
+#define ARM_GPC                0x4
+#define DBGEN          BIT(16)
+
+/*
+ * This enables the DBGEN bit in ARM_GPC register, which is
+ * required for accessing some performance counter features.
+ * Technically it is only required while perf is used, but to
+ * keep the source code simple we just enable it all the time
+ * when the kernel configuration allows using the feature.
+ */
+void __init imx5_pmu_init(void)
+{
+       void __iomem *tigerp_base;
+       struct device_node *np;
+       u32 gpc;
+
+       if (!IS_ENABLED(CONFIG_ARM_PMU))
+               return;
+
+       np = of_find_compatible_node(NULL, NULL, "arm,cortex-a8-pmu");
+       if (!np)
+               return;
+
+       if (!of_property_read_bool(np, "secure-reg-access"))
+               goto exit;
+
+       of_node_put(np);
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx51-tigerp");
+       if (!np)
+               return;
+
+       tigerp_base = of_iomap(np, 0);
+       if (!tigerp_base)
+               goto exit;
+
+       gpc = readl_relaxed(tigerp_base + ARM_GPC);
+       gpc |= DBGEN;
+       writel_relaxed(gpc, tigerp_base + ARM_GPC);
+       iounmap(tigerp_base);
+exit:
+       of_node_put(np);
+
+}
index 32969f34486a54933dfbed32c91740287269d833..c6b1bf97a6c16e4e1bfcd4237362f5270323189b 100644 (file)
@@ -68,6 +68,7 @@ void __init imx_aips_allow_unprivileged_access(
 
        for_each_compatible_node(np, NULL, compat) {
                aips_base_addr = of_iomap(np, 0);
+               WARN_ON(!aips_base_addr);
                imx_set_aips(aips_base_addr);
        }
 }
index fa8ead145d1716928871e7d419221f4b2759e70b..8d866fb674a85af738422ab0a6fc055a5ee0f191 100644 (file)
@@ -12,7 +12,6 @@
 
 #include "common.h"
 #include "cpuidle.h"
-#include "hardware.h"
 
 static int imx6sl_enter_wait(struct cpuidle_device *dev,
                            struct cpuidle_driver *drv, int index)
@@ -22,11 +21,9 @@ static int imx6sl_enter_wait(struct cpuidle_device *dev,
         * Software workaround for ERR005311, see function
         * description for details.
         */
-       if (cpu_is_imx6sl())
-               imx6sl_set_wait_clk(true);
+       imx6sl_set_wait_clk(true);
        cpu_do_idle();
-       if (cpu_is_imx6sl())
-               imx6sl_set_wait_clk(false);
+       imx6sl_set_wait_clk(false);
        imx6_set_lpm(WAIT_CLOCKED);
 
        return index;
index d0f14b761ff704b5800037cc4f19a585492bac83..243a108a940b46c9c0d9b13d2802beb11f84d2d9 100644 (file)
@@ -103,6 +103,7 @@ int __init imx6sx_cpuidle_init(void)
 {
        imx6_set_int_mem_clk_lpm(true);
        imx6_enable_rbc(false);
+       imx_gpc_set_l2_mem_power_in_lpm(false);
        /*
         * set ARM power up/down timing to the fastest,
         * sw2iso and sw can be set to one 32K cycle = 31us
index de535cb679b36d58d6cb88106656e1e260c490c0..e11159d40fb8166adf43573d211e264ab2f45ca2 100644 (file)
@@ -20,6 +20,7 @@
 #include "common.h"
 #include "hardware.h"
 
+#define GPC_CNTR               0x0
 #define GPC_IMR1               0x008
 #define GPC_PGC_CPU_PDN                0x2a0
 #define GPC_PGC_CPU_PUPSCR     0x2a4
@@ -27,6 +28,8 @@
 #define GPC_PGC_SW2ISO_SHIFT   0x8
 #define GPC_PGC_SW_SHIFT       0x0
 
+#define GPC_CNTR_L2_PGE_SHIFT  22
+
 #define IMR_NUM                        4
 #define GPC_MAX_IRQS           (IMR_NUM * 32)
 
@@ -51,6 +54,17 @@ void imx_gpc_set_arm_power_in_lpm(bool power_off)
        writel_relaxed(power_off, gpc_base + GPC_PGC_CPU_PDN);
 }
 
+void imx_gpc_set_l2_mem_power_in_lpm(bool power_off)
+{
+       u32 val;
+
+       val = readl_relaxed(gpc_base + GPC_CNTR);
+       val &= ~(1 << GPC_CNTR_L2_PGE_SHIFT);
+       if (power_off)
+               val |= 1 << GPC_CNTR_L2_PGE_SHIFT;
+       writel_relaxed(val, gpc_base + GPC_CNTR);
+}
+
 void imx_gpc_pre_suspend(bool arm_power_off)
 {
        void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
index 668d74b72511298c19bcde47924cb654f5362a42..9d9640aaf85857c5b972bc27f8c78e38003ec76f 100644 (file)
@@ -9,35 +9,17 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
-#include <linux/irq.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-
 #include "common.h"
-#include "mx31.h"
 
 static const char * const imx31_dt_board_compat[] __initconst = {
        "fsl,imx31",
        NULL
 };
 
-/* FIXME: replace with DT binding */
-static const struct resource imx31_rnga_res[] __initconst = {
-       DEFINE_RES_MEM(MX31_RNGA_BASE_ADDR, SZ_16K),
-};
-
-static void __init imx31_dt_mach_init(void)
-{
-       platform_device_register_simple("mxc_rnga", -1, imx31_rnga_res,
-                                       ARRAY_SIZE(imx31_rnga_res));
-}
-
 DT_MACHINE_START(IMX31_DT, "Freescale i.MX31 (Device Tree Support)")
        .map_io         = mx31_map_io,
        .init_early     = imx31_init_early,
        .init_irq       = mx31_init_irq,
-       .init_machine   = imx31_dt_mach_init,
        .dt_compat      = imx31_dt_board_compat,
 MACHINE_END
index 3835b6a3423c9ec2fb73d692f9b7f6050e5c0a70..c7169c2f94c4fd8cc018caa790c7b170e778eaf3 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
@@ -48,11 +49,38 @@ static void __init imx51_ipu_mipi_setup(void)
        iounmap(hsc_addr);
 }
 
+static void __init imx51_m4if_setup(void)
+{
+       void __iomem *m4if_base;
+       struct device_node *np;
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx51-m4if");
+       if (!np)
+               return;
+
+       m4if_base = of_iomap(np, 0);
+       if (!m4if_base) {
+               pr_err("Unable to map M4IF registers\n");
+               return;
+       }
+
+       /*
+        * Configure VPU and IPU with higher priorities
+        * in order to avoid artifacts during video playback
+        */
+       writel_relaxed(0x00000203, m4if_base + 0x40);
+       writel_relaxed(0x00000000, m4if_base + 0x44);
+       writel_relaxed(0x00120125, m4if_base + 0x9c);
+       writel_relaxed(0x001901A3, m4if_base + 0x48);
+       iounmap(m4if_base);
+}
+
 static void __init imx51_dt_init(void)
 {
        imx51_ipu_mipi_setup();
        imx_src_init();
-
+       imx51_m4if_setup();
+       imx5_pmu_init();
        imx_aips_allow_unprivileged_access("fsl,imx51-aipstz");
 }
 
index 07c2e8dca494b6b1451b59900e35e00d93c63372..5ec7100737e806269a766b2697eeb2a1f5a4bba4 100644 (file)
@@ -31,7 +31,7 @@ static void __init imx53_init_early(void)
 static void __init imx53_dt_init(void)
 {
        imx_src_init();
-
+       imx5_pmu_init();
        imx_aips_allow_unprivileged_access("fsl,imx53-aipstz");
 }
 
index c7a1ef180dda4e0be51e8365abb99a058da40370..99be4225297a36ea145350b4849b3965545a2731 100644 (file)
@@ -42,7 +42,10 @@ static void __init imx6sl_init_late(void)
        if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ))
                platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0);
 
-       imx6sl_cpuidle_init();
+       if (IS_ENABLED(CONFIG_SOC_IMX6SL) && cpu_is_imx6sl())
+               imx6sl_cpuidle_init();
+       else if (IS_ENABLED(CONFIG_SOC_IMX6SLL))
+               imx6sx_cpuidle_init();
 }
 
 static void __init imx6sl_init_machine(void)
diff --git a/arch/arm/mach-imx/mach-imx7d-cm4.c b/arch/arm/mach-imx/mach-imx7d-cm4.c
new file mode 100644 (file)
index 0000000..0800b58
--- /dev/null
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Pengutronix, Oleksij Rempel <o.rempel@pengutronix.de>
+ */
+
+#include <linux/kernel.h>
+#include <asm/v7m.h>
+#include <asm/mach/arch.h>
+
+static const char * const imx7d_cm4_dt_compat[] __initconst = {
+       "fsl,imx7d-cm4",
+       NULL,
+};
+
+DT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual Cortex-M4 (Device Tree)")
+       .dt_compat = imx7d_cm4_dt_compat,
+       .restart = armv7m_restart,
+MACHINE_END
index 017539dd712bc04c94feff14fef8960c1f9933b8..b08e407d8d96f4f7a61d107ee877a64571a8acaf 100644 (file)
@@ -130,6 +130,13 @@ static const u32 imx6sl_mmdc_io_offset[] __initconst = {
        0x330, 0x334, 0x320,        /* SDCKE0, SDCKE1, RESET */
 };
 
+static const u32 imx6sll_mmdc_io_offset[] __initconst = {
+       0x294, 0x298, 0x29c, 0x2a0, /* DQM0 ~ DQM3 */
+       0x544, 0x54c, 0x554, 0x558, /* GPR_B0DS ~ GPR_B3DS */
+       0x530, 0x540, 0x2ac, 0x52c, /* MODE_CTL, MODE, SDCLK_0, GPR_ADDDS */
+       0x2a4, 0x2a8,               /* SDCKE0, SDCKE1*/
+};
+
 static const u32 imx6sx_mmdc_io_offset[] __initconst = {
        0x2ec, 0x2f0, 0x2f4, 0x2f8, /* DQM0 ~ DQM3 */
        0x60c, 0x610, 0x61c, 0x620, /* GPR_B0DS ~ GPR_B3DS */
@@ -175,6 +182,16 @@ static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
        .mmdc_io_offset = imx6sl_mmdc_io_offset,
 };
 
+static const struct imx6_pm_socdata imx6sll_pm_data __initconst = {
+       .mmdc_compat = "fsl,imx6sll-mmdc",
+       .src_compat = "fsl,imx6sll-src",
+       .iomuxc_compat = "fsl,imx6sll-iomuxc",
+       .gpc_compat = "fsl,imx6sll-gpc",
+       .pl310_compat = "arm,pl310-cache",
+       .mmdc_io_num = ARRAY_SIZE(imx6sll_mmdc_io_offset),
+       .mmdc_io_offset = imx6sll_mmdc_io_offset,
+};
+
 static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
        .mmdc_compat = "fsl,imx6sx-mmdc",
        .src_compat = "fsl,imx6sx-src",
@@ -296,7 +313,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
                if (cpu_is_imx6sl())
                        val |= BM_CLPCR_BYPASS_PMIC_READY;
                if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
-                   cpu_is_imx6ull())
+                   cpu_is_imx6ull() || cpu_is_imx6sll())
                        val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
                else
                        val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
@@ -314,7 +331,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
                if (cpu_is_imx6sl() || cpu_is_imx6sx())
                        val |= BM_CLPCR_BYPASS_PMIC_READY;
                if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
-                   cpu_is_imx6ull())
+                   cpu_is_imx6ull() || cpu_is_imx6sll())
                        val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
                else
                        val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
@@ -631,7 +648,17 @@ void __init imx6dl_pm_init(void)
 
 void __init imx6sl_pm_init(void)
 {
-       imx6_pm_common_init(&imx6sl_pm_data);
+       struct regmap *gpr;
+
+       if (cpu_is_imx6sl()) {
+               imx6_pm_common_init(&imx6sl_pm_data);
+       } else {
+               imx6_pm_common_init(&imx6sll_pm_data);
+               gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
+               if (!IS_ERR(gpr))
+                       regmap_update_bits(gpr, IOMUXC_GPR5,
+                               IMX6SLL_GPR5_AFCG_X_BYPASS_MASK, 0);
+       }
 }
 
 void __init imx6sx_pm_init(void)
index 4ffbbd217e8286e18181fac98487a8860ead6372..c130497dc6cc4710ceaaec9ff6dd96c4b7eb9f69 100644 (file)
@@ -35,6 +35,8 @@
 #define AXP_BOOTROM_BASE 0xfff00000
 #define AXP_BOOTROM_SIZE 0x100000
 
+static struct clk *boot_cpu_clk;
+
 static struct clk *get_cpu_clk(int cpu)
 {
        struct clk *cpu_clk;
@@ -48,30 +50,6 @@ static struct clk *get_cpu_clk(int cpu)
        return cpu_clk;
 }
 
-static void set_secondary_cpu_clock(unsigned int cpu)
-{
-       int thiscpu;
-       unsigned long rate;
-       struct clk *cpu_clk;
-
-       thiscpu = get_cpu();
-
-       cpu_clk = get_cpu_clk(thiscpu);
-       if (!cpu_clk)
-               goto out;
-       clk_prepare_enable(cpu_clk);
-       rate = clk_get_rate(cpu_clk);
-
-       cpu_clk = get_cpu_clk(cpu);
-       if (!cpu_clk)
-               goto out;
-       clk_set_rate(cpu_clk, rate);
-       clk_prepare_enable(cpu_clk);
-
-out:
-       put_cpu();
-}
-
 static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
        int ret, hw_cpu;
@@ -79,7 +57,6 @@ static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle)
        pr_info("Booting CPU %d\n", cpu);
 
        hw_cpu = cpu_logical_map(cpu);
-       set_secondary_cpu_clock(hw_cpu);
        mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_xp_secondary_startup);
 
        /*
@@ -122,6 +99,19 @@ static void __init armada_xp_smp_init_cpus(void)
                panic("Invalid number of CPUs in DT\n");
 }
 
+static int armada_xp_sync_secondary_clk(unsigned int cpu)
+{
+       struct clk *cpu_clk = get_cpu_clk(cpu);
+
+       if (!cpu_clk || !boot_cpu_clk)
+               return 0;
+
+       clk_prepare_enable(cpu_clk);
+       clk_set_rate(cpu_clk, clk_get_rate(boot_cpu_clk));
+
+       return 0;
+}
+
 static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
 {
        struct device_node *node;
@@ -131,6 +121,14 @@ static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
        flush_cache_all();
        set_cpu_coherent();
 
+       boot_cpu_clk = get_cpu_clk(smp_processor_id());
+       if (boot_cpu_clk) {
+               clk_prepare_enable(boot_cpu_clk);
+               cpuhp_setup_state_nocalls(CPUHP_AP_ARM_MVEBU_SYNC_CLOCKS,
+                                         "arm/mvebu/sync_clocks:online",
+                                         armada_xp_sync_secondary_clk, NULL);
+       }
+
        /*
         * In order to boot the secondary CPUs we need to ensure
         * the bootROM is mapped at the correct address.
@@ -223,7 +221,6 @@ static int mv98dx3236_boot_secondary(unsigned int cpu, struct task_struct *idle)
        int ret, hw_cpu;
 
        hw_cpu = cpu_logical_map(cpu);
-       set_secondary_cpu_clock(hw_cpu);
        mv98dx3236_resume_set_cpu_boot_addr(hw_cpu,
                                            armada_xp_secondary_startup);
 
index 27a78c80e5b17352aafc4924d04694217bfa5c15..73d5d72dfc3e520894a85875de94791fac84236d 100644 (file)
@@ -116,8 +116,8 @@ void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr)
                PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
 }
 
-extern unsigned char mvebu_boot_wa_start;
-extern unsigned char mvebu_boot_wa_end;
+extern unsigned char mvebu_boot_wa_start[];
+extern unsigned char mvebu_boot_wa_end[];
 
 /*
  * This function sets up the boot address workaround needed for SMP
@@ -130,7 +130,7 @@ int mvebu_setup_boot_addr_wa(unsigned int crypto_eng_target,
                             phys_addr_t resume_addr_reg)
 {
        void __iomem *sram_virt_base;
-       u32 code_len = &mvebu_boot_wa_end - &mvebu_boot_wa_start;
+       u32 code_len = mvebu_boot_wa_end - mvebu_boot_wa_start;
 
        mvebu_mbus_del_window(BOOTROM_BASE, BOOTROM_SIZE);
        mvebu_mbus_add_window_by_id(crypto_eng_target, crypto_eng_attribute,
index bf608441b35731e13b99fb7012bdc89ba005c168..ddc27638ba2a5e7807b9a904df874c5e913ef812 100644 (file)
  */
 
 #include <linux/linkage.h>
-#include <asm/assembler.h>
+#include <linux/platform_data/ams-delta-fiq.h>
 
+#include <asm/assembler.h>
 #include <mach/board-ams-delta.h>
-#include <mach/ams-delta-fiq.h>
 
+#include "ams-delta-fiq.h"
 #include "iomap.h"
 #include "soc.h"
 
index d7ca9e2b40d274c096333c7488011ac7dcc746db..b0dc7ddf5877d70eeda21df28b331acdf99a4cdb 100644 (file)
  * under the terms of the GNU General Public License version 2 as published by
  * the Free Software Foundation.
  */
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/platform_data/ams-delta-fiq.h>
+#include <linux/platform_device.h>
 
 #include <mach/board-ams-delta.h>
 
 #include <asm/fiq.h>
 
-#include <mach/ams-delta-fiq.h>
+#include "ams-delta-fiq.h"
 
 static struct fiq_handler fh = {
        .name   = "ams-delta-fiq"
@@ -34,20 +37,24 @@ static struct fiq_handler fh = {
  * The FIQ and IRQ isrs can both read and write it.
  * It is structured as a header section several 32bit slots,
  * followed by the circular buffer where the FIQ isr stores
- * keystrokes received from the qwerty keyboard.
- * See ams-delta-fiq.h for details of offsets.
+ * keystrokes received from the qwerty keyboard.  See
+ * <linux/platform_data/ams-delta-fiq.h> for details of offsets.
  */
-unsigned int fiq_buffer[1024];
-EXPORT_SYMBOL(fiq_buffer);
+static unsigned int fiq_buffer[1024];
 
+static struct irq_chip *irq_chip;
+static struct irq_data *irq_data[16];
 static unsigned int irq_counter[16];
 
+static const char *pin_name[16] __initconst = {
+       [AMS_DELTA_GPIO_PIN_KEYBRD_DATA]        = "keybrd_data",
+       [AMS_DELTA_GPIO_PIN_KEYBRD_CLK]         = "keybrd_clk",
+};
+
 static irqreturn_t deferred_fiq(int irq, void *dev_id)
 {
+       struct irq_data *d;
        int gpio, irq_num, fiq_count;
-       struct irq_chip *irq_chip;
-
-       irq_chip = irq_get_chip(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK));
 
        /*
         * For each handled GPIO interrupt, keep calling its interrupt handler
@@ -55,24 +62,21 @@ static irqreturn_t deferred_fiq(int irq, void *dev_id)
         */
        for (gpio = AMS_DELTA_GPIO_PIN_KEYBRD_CLK;
                        gpio <= AMS_DELTA_GPIO_PIN_HOOK_SWITCH; gpio++) {
-               irq_num = gpio_to_irq(gpio);
+               d = irq_data[gpio];
+               irq_num = d->irq;
                fiq_count = fiq_buffer[FIQ_CNT_INT_00 + gpio];
 
                if (irq_counter[gpio] < fiq_count &&
                                gpio != AMS_DELTA_GPIO_PIN_KEYBRD_CLK) {
-                       struct irq_data *d = irq_get_irq_data(irq_num);
-
                        /*
                         * handle_simple_irq() that OMAP GPIO edge
                         * interrupts default to since commit 80ac93c27441
                         * requires interrupt already acked and unmasked.
                         */
-                       if (irq_chip) {
-                               if (irq_chip->irq_ack)
-                                       irq_chip->irq_ack(d);
-                               if (irq_chip->irq_unmask)
-                                       irq_chip->irq_unmask(d);
-                       }
+                       if (irq_chip->irq_ack)
+                               irq_chip->irq_ack(d);
+                       if (irq_chip->irq_unmask)
+                               irq_chip->irq_unmask(d);
                }
                for (; irq_counter[gpio] < fiq_count; irq_counter[gpio]++)
                        generic_handle_irq(irq_num);
@@ -80,14 +84,56 @@ static irqreturn_t deferred_fiq(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-void __init ams_delta_init_fiq(void)
+void __init ams_delta_init_fiq(struct gpio_chip *chip,
+                              struct platform_device *serio)
 {
+       struct gpio_desc *gpiod, *data = NULL, *clk = NULL;
        void *fiqhandler_start;
        unsigned int fiqhandler_length;
        struct pt_regs FIQ_regs;
        unsigned long val, offset;
        int i, retval;
 
+       /* Store irq_chip location for IRQ handler use */
+       irq_chip = chip->irq.chip;
+       if (!irq_chip) {
+               pr_err("%s: GPIO chip %s is missing IRQ function\n", __func__,
+                      chip->label);
+               return;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(irq_data); i++) {
+               gpiod = gpiochip_request_own_desc(chip, i, pin_name[i]);
+               if (IS_ERR(gpiod)) {
+                       pr_err("%s: failed to get GPIO pin %d (%ld)\n",
+                              __func__, i, PTR_ERR(gpiod));
+                       return;
+               }
+               /* Store irq_data location for IRQ handler use */
+               irq_data[i] = irq_get_irq_data(gpiod_to_irq(gpiod));
+
+               /*
+                * FIQ handler takes full control over serio data and clk GPIO
+                * pins.  Initiaize them and keep requested so nobody can
+                * interfere.  Fail if any of those two couldn't be requested.
+                */
+               switch (i) {
+               case AMS_DELTA_GPIO_PIN_KEYBRD_DATA:
+                       data = gpiod;
+                       gpiod_direction_input(data);
+                       break;
+               case AMS_DELTA_GPIO_PIN_KEYBRD_CLK:
+                       clk = gpiod;
+                       gpiod_direction_input(clk);
+                       break;
+               default:
+                       gpiochip_free_own_desc(gpiod);
+                       break;
+               }
+       }
+       if (!data || !clk)
+               goto out_gpio;
+
        fiqhandler_start = &qwerty_fiqin_start;
        fiqhandler_length = &qwerty_fiqin_end - &qwerty_fiqin_start;
        pr_info("Installing fiq handler from %p, length 0x%x\n",
@@ -97,7 +143,7 @@ void __init ams_delta_init_fiq(void)
        if (retval) {
                pr_err("ams_delta_init_fiq(): couldn't claim FIQ, ret=%d\n",
                                retval);
-               return;
+               goto out_gpio;
        }
 
        retval = request_irq(INT_DEFERRED_FIQ, deferred_fiq,
@@ -105,7 +151,7 @@ void __init ams_delta_init_fiq(void)
        if (retval < 0) {
                pr_err("Failed to get deferred_fiq IRQ, ret=%d\n", retval);
                release_fiq(&fh);
-               return;
+               goto out_gpio;
        }
        /*
         * Since no set_type() method is provided by OMAP irq chip,
@@ -155,4 +201,29 @@ void __init ams_delta_init_fiq(void)
        offset = IRQ_ILR0_REG_OFFSET + (INT_GPIO_BANK1 - NR_IRQS_LEGACY) * 0x4;
        val = omap_readl(OMAP_IH1_BASE + offset) | 1;
        omap_writel(val, OMAP_IH1_BASE + offset);
+
+       /* Initialize serio device IRQ resource and platform_data */
+       serio->resource[0].start = gpiod_to_irq(clk);
+       serio->resource[0].end = serio->resource[0].start;
+       serio->dev.platform_data = fiq_buffer;
+
+       /*
+        * Since FIQ handler performs handling of GPIO registers for
+        * "keybrd_clk" IRQ pin, ams_delta_serio driver used to set
+        * handle_simple_irq() as active IRQ handler for that pin to avoid
+        * bad interaction with gpio-omap driver.  This is no longer needed
+        * as handle_simple_irq() is now the default handler for OMAP GPIO
+        * edge interrupts.
+        * This comment replaces the obsolete code which has been removed
+        * from the ams_delta_serio driver and stands here only as a reminder
+        * of that dependency on gpio-omap driver behavior.
+        */
+
+       return;
+
+out_gpio:
+       if (data)
+               gpiochip_free_own_desc(data);
+       if (clk)
+               gpiochip_free_own_desc(clk);
 }
diff --git a/arch/arm/mach-omap1/ams-delta-fiq.h b/arch/arm/mach-omap1/ams-delta-fiq.h
new file mode 100644 (file)
index 0000000..fd76df3
--- /dev/null
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * arch/arm/mach-omap1/ams-delta-fiq.h
+ *
+ * Taken from the original Amstrad modifications to fiq.h
+ *
+ * Copyright (c) 2004 Amstrad Plc
+ * Copyright (c) 2006 Matt Callow
+ * Copyright (c) 2010 Janusz Krzysztofik
+ *
+ * This program is free software; you can 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 __AMS_DELTA_FIQ_H
+#define __AMS_DELTA_FIQ_H
+
+#include <mach/irqs.h>
+
+/*
+ * Interrupt number used for passing control from FIQ to IRQ.
+ * IRQ12, described as reserved, has been selected.
+ */
+#define INT_DEFERRED_FIQ       INT_1510_RES12
+/*
+ * Base address of an interrupt handler that the INT_DEFERRED_FIQ belongs to.
+ */
+#if (INT_DEFERRED_FIQ < IH2_BASE)
+#define DEFERRED_FIQ_IH_BASE   OMAP_IH1_BASE
+#else
+#define DEFERRED_FIQ_IH_BASE   OMAP_IH2_BASE
+#endif
+
+#ifndef __ASSEMBLER__
+extern unsigned char qwerty_fiqin_start, qwerty_fiqin_end;
+
+extern void __init ams_delta_init_fiq(struct gpio_chip *chip,
+                                     struct platform_device *pdev);
+#endif
+
+#endif
index 80f54cb54276fe81b870d7dd9298f39b340e2417..dd28d2614d7fecc13a49bd06a2d437ec2c88c70c 100644 (file)
 #include <mach/mux.h>
 
 #include <mach/hardware.h>
-#include <mach/ams-delta-fiq.h>
 #include "camera.h"
 #include <mach/usb.h>
 
+#include "ams-delta-fiq.h"
 #include "iomap.h"
 #include "common.h"
 
@@ -179,7 +179,10 @@ static struct resource latch1_resources[] = {
        },
 };
 
+#define LATCH1_LABEL   "latch1"
+
 static struct bgpio_pdata latch1_pdata = {
+       .label  = LATCH1_LABEL,
        .base   = LATCH1_GPIO_BASE,
        .ngpio  = LATCH1_NGPIO,
 };
@@ -194,6 +197,15 @@ static struct platform_device latch1_gpio_device = {
        },
 };
 
+#define LATCH1_PIN_LED_CAMERA          0
+#define LATCH1_PIN_LED_ADVERT          1
+#define LATCH1_PIN_LED_MAIL            2
+#define LATCH1_PIN_LED_HANDSFREE       3
+#define LATCH1_PIN_LED_VOICEMAIL       4
+#define LATCH1_PIN_LED_VOICE           5
+#define LATCH1_PIN_DOCKIT1             6
+#define LATCH1_PIN_DOCKIT2             7
+
 static struct resource latch2_resources[] = {
        [0] = {
                .name   = "dat",
@@ -398,38 +410,43 @@ static struct gpiod_lookup_table ams_delta_lcd_gpio_table = {
        },
 };
 
-static const struct gpio_led gpio_leds[] __initconst = {
-       {
+/*
+ * Dynamically allocated GPIO numbers must be obtained fromm GPIO device
+ * before they can be put in the gpio_led table.  Before that happens,
+ * initialize the table with invalid GPIO numbers, not 0.
+ */
+static struct gpio_led gpio_leds[] __initdata = {
+       [LATCH1_PIN_LED_CAMERA] = {
                .name            = "camera",
-               .gpio            = LATCH1_GPIO_BASE + 0,
+               .gpio            = -EINVAL,
                .default_state   = LEDS_GPIO_DEFSTATE_OFF,
 #ifdef CONFIG_LEDS_TRIGGERS
                .default_trigger = "ams_delta_camera",
 #endif
        },
-       {
+       [LATCH1_PIN_LED_ADVERT] = {
                .name            = "advert",
-               .gpio            = LATCH1_GPIO_BASE + 1,
+               .gpio            = -EINVAL,
                .default_state   = LEDS_GPIO_DEFSTATE_OFF,
        },
-       {
+       [LATCH1_PIN_LED_MAIL] = {
                .name            = "email",
-               .gpio            = LATCH1_GPIO_BASE + 2,
+               .gpio            = -EINVAL,
                .default_state   = LEDS_GPIO_DEFSTATE_OFF,
        },
-       {
+       [LATCH1_PIN_LED_HANDSFREE] = {
                .name            = "handsfree",
-               .gpio            = LATCH1_GPIO_BASE + 3,
+               .gpio            = -EINVAL,
                .default_state   = LEDS_GPIO_DEFSTATE_OFF,
        },
-       {
+       [LATCH1_PIN_LED_VOICEMAIL] = {
                .name            = "voicemail",
-               .gpio            = LATCH1_GPIO_BASE + 4,
+               .gpio            = -EINVAL,
                .default_state   = LEDS_GPIO_DEFSTATE_OFF,
        },
-       {
+       [LATCH1_PIN_LED_VOICE] = {
                .name            = "voice",
-               .gpio            = LATCH1_GPIO_BASE + 5,
+               .gpio            = -EINVAL,
                .default_state   = LEDS_GPIO_DEFSTATE_OFF,
        },
 };
@@ -504,16 +521,70 @@ static struct platform_device cx20442_codec_device = {
        .id     = -1,
 };
 
-static struct gpiod_lookup_table ams_delta_serio_gpio_table = {
+static struct resource ams_delta_serio_resources[] = {
+       {
+               .flags  = IORESOURCE_IRQ,
+               /*
+                * Initialize IRQ resource with invalid IRQ number.
+                * It will be replaced with dynamically allocated GPIO IRQ
+                * obtained from GPIO chip as soon as the chip is available.
+                */
+               .start  = -EINVAL,
+               .end    = -EINVAL,
+       },
+};
+
+static struct platform_device ams_delta_serio_device = {
+       .name           = "ams-delta-serio",
+       .id             = PLATFORM_DEVID_NONE,
+       .dev            = {
+               /*
+                * Initialize .platform_data explicitly with NULL to
+                * indicate it is going to be used.  It will be replaced
+                * with FIQ buffer address as soon as FIQ is initialized.
+                */
+               .platform_data = NULL,
+       },
+       .num_resources  = ARRAY_SIZE(ams_delta_serio_resources),
+       .resource       = ams_delta_serio_resources,
+};
+
+static struct regulator_consumer_supply keybrd_pwr_consumers[] = {
+       /*
+        * Initialize supply .dev_name with NULL.  It will be replaced
+        * with serio dev_name() as soon as the serio device is registered.
+        */
+       REGULATOR_SUPPLY("vcc", NULL),
+};
+
+static struct regulator_init_data keybrd_pwr_initdata = {
+       .constraints            = {
+               .valid_ops_mask         = REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(keybrd_pwr_consumers),
+       .consumer_supplies      = keybrd_pwr_consumers,
+};
+
+static struct fixed_voltage_config keybrd_pwr_config = {
+       .supply_name            = "keybrd_pwr",
+       .microvolts             = 5000000,
+       .gpio                   = AMS_DELTA_GPIO_PIN_KEYBRD_PWR,
+       .enable_high            = 1,
+       .init_data              = &keybrd_pwr_initdata,
+};
+
+static struct platform_device keybrd_pwr_device = {
+       .name   = "reg-fixed-voltage",
+       .id     = PLATFORM_DEVID_AUTO,
+       .dev    = {
+               .platform_data  = &keybrd_pwr_config,
+       },
+};
+
+static struct gpiod_lookup_table keybrd_pwr_gpio_table = {
        .table = {
-               GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_KEYBRD_DATA,
-                           "data", 0),
-               GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_KEYBRD_CLK,
-                           "clock", 0),
-               GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_KEYBRD_PWR,
-                           "power", 0),
-               GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_KEYBRD_DATAOUT,
-                           "dataout", 0),
+               GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_KEYBRD_PWR, NULL,
+                           GPIO_ACTIVE_HIGH),
                { },
        },
 };
@@ -524,9 +595,7 @@ static struct platform_device *ams_delta_devices[] __initdata = {
        &ams_delta_kp_device,
        &ams_delta_camera_device,
        &ams_delta_audio_device,
-};
-
-static struct platform_device *late_devices[] __initdata = {
+       &ams_delta_serio_device,
        &ams_delta_nand_device,
        &ams_delta_lcd_device,
        &cx20442_codec_device,
@@ -534,14 +603,55 @@ static struct platform_device *late_devices[] __initdata = {
 
 static struct gpiod_lookup_table *ams_delta_gpio_tables[] __initdata = {
        &ams_delta_audio_gpio_table,
-       &ams_delta_serio_gpio_table,
-};
-
-static struct gpiod_lookup_table *late_gpio_tables[] __initdata = {
+       &keybrd_pwr_gpio_table,
        &ams_delta_lcd_gpio_table,
        &ams_delta_nand_gpio_table,
 };
 
+/*
+ * Some drivers may not use GPIO lookup tables but need to be provided
+ * with GPIO numbers.  The same applies to GPIO based IRQ lines - some
+ * drivers may even not use GPIO layer but expect just IRQ numbers.
+ * We could either define GPIO lookup tables then use them on behalf
+ * of those devices, or we can use GPIO driver level methods for
+ * identification of GPIO and IRQ numbers. For the purpose of the latter,
+ * defina a helper function which identifies GPIO chips by their labels.
+ */
+static int gpiochip_match_by_label(struct gpio_chip *chip, void *data)
+{
+       char *label = data;
+
+       return !strcmp(label, chip->label);
+}
+
+static struct gpiod_hog ams_delta_gpio_hogs[] = {
+       GPIO_HOG(LATCH2_LABEL, LATCH2_PIN_KEYBRD_DATAOUT, "keybrd_dataout",
+                GPIO_ACTIVE_HIGH, GPIOD_OUT_LOW),
+       {},
+};
+
+/*
+ * The purpose of this function is to take care of proper initialization of
+ * devices and data structures which depend on GPIO lines provided by OMAP GPIO
+ * banks but their drivers don't use GPIO lookup tables or GPIO layer at all.
+ * The function may be called as soon as OMAP GPIO devices are probed.
+ * Since that happens at postcore_initcall, it can be called successfully
+ * from init_machine or later.
+ * Dependent devices may be registered from within this function or later.
+ */
+static void __init omap_gpio_deps_init(void)
+{
+       struct gpio_chip *chip;
+
+       chip = gpiochip_find(OMAP_GPIO_LABEL, gpiochip_match_by_label);
+       if (!chip) {
+               pr_err("%s: OMAP GPIO chip not found\n", __func__);
+               return;
+       }
+
+       ams_delta_init_fiq(chip, &ams_delta_serio_device);
+}
+
 static void __init ams_delta_init(void)
 {
        /* mux pins for uarts */
@@ -562,6 +672,9 @@ static void __init ams_delta_init(void)
        omap_cfg_reg(J19_1610_CAM_D6);
        omap_cfg_reg(J18_1610_CAM_D7);
 
+       omap_gpio_deps_init();
+       gpiod_add_hogs(ams_delta_gpio_hogs);
+
        omap_serial_init();
        omap_register_i2c_bus(1, 100, NULL, 0);
 
@@ -571,25 +684,38 @@ static void __init ams_delta_init(void)
        led_trigger_register_simple("ams_delta_camera",
                        &ams_delta_camera_led_trigger);
 #endif
-       gpio_led_register_device(-1, &leds_pdata);
        platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
 
        /*
-        * As soon as devices have been registered, assign their dev_names
-        * to respective GPIO lookup tables before they are added.
+        * As soon as regulator consumers have been registered, assign their
+        * dev_names to consumer supply entries of respective regulators.
+        */
+       keybrd_pwr_consumers[0].dev_name =
+                       dev_name(&ams_delta_serio_device.dev);
+
+       /*
+        * Once consumer supply entries are populated with dev_names,
+        * register regulator devices.  At this stage only the keyboard
+        * power regulator has its consumer supply table fully populated.
+        */
+       platform_device_register(&keybrd_pwr_device);
+
+       /*
+        * As soon as GPIO consumers have been registered, assign
+        * their dev_names to respective GPIO lookup tables.
         */
        ams_delta_audio_gpio_table.dev_id =
                        dev_name(&ams_delta_audio_device.dev);
+       keybrd_pwr_gpio_table.dev_id = dev_name(&keybrd_pwr_device.dev);
+       ams_delta_nand_gpio_table.dev_id = dev_name(&ams_delta_nand_device.dev);
+       ams_delta_lcd_gpio_table.dev_id = dev_name(&ams_delta_lcd_device.dev);
+
        /*
-        * No device name is assigned to GPIO lookup table for serio device
-        * as long as serio driver is not converted to platform device driver.
+        * Once GPIO lookup tables are populated with dev_names, register them.
         */
-
        gpiod_add_lookup_tables(ams_delta_gpio_tables,
                                ARRAY_SIZE(ams_delta_gpio_tables));
 
-       ams_delta_init_fiq();
-
        omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1);
 
        omapfb_set_lcd_config(&ams_delta_lcd_config);
@@ -643,35 +769,84 @@ static struct platform_device ams_delta_modem_device = {
        },
 };
 
-static int __init late_init(void)
+/*
+ * leds-gpio driver doesn't make use of GPIO lookup tables,
+ * it has to be provided with GPIO numbers over platform data
+ * if GPIO descriptor info can't be obtained from device tree.
+ * We could either define GPIO lookup tables and use them on behalf
+ * of the leds-gpio device, or we can use GPIO driver level methods
+ * for identification of GPIO numbers as long as we don't support
+ * device tree.  Let's do the latter.
+ */
+static void __init ams_delta_led_init(struct gpio_chip *chip)
+{
+       struct gpio_desc *gpiod;
+       int i;
+
+       for (i = LATCH1_PIN_LED_CAMERA; i < LATCH1_PIN_DOCKIT1; i++) {
+               gpiod = gpiochip_request_own_desc(chip, i, NULL);
+               if (IS_ERR(gpiod)) {
+                       pr_warn("%s: %s GPIO %d request failed (%ld)\n",
+                               __func__, LATCH1_LABEL, i, PTR_ERR(gpiod));
+                       continue;
+               }
+
+               /* Assign GPIO numbers to LED device. */
+               gpio_leds[i].gpio = desc_to_gpio(gpiod);
+
+               gpiochip_free_own_desc(gpiod);
+       }
+
+       gpio_led_register_device(PLATFORM_DEVID_NONE, &leds_pdata);
+}
+
+/*
+ * The purpose of this function is to take care of assignment of GPIO numbers
+ * to platform devices which depend on GPIO lines provided by Amstrad Delta
+ * latch1 and/or latch2 GPIO devices but don't use GPIO lookup tables.
+ * The function may be called as soon as latch1/latch2 GPIO devices are
+ * initilized.  Since basic-mmio-gpio driver is not registered before
+ * device_initcall, this may happen at erliest during device_initcall_sync.
+ * Dependent devices shouldn't be registered before that, their
+ * registration may be performed from within this function or later.
+ */
+static int __init ams_delta_gpio_init(void)
 {
+       struct gpio_chip *chip;
        int err;
 
        if (!machine_is_ams_delta())
                return -ENODEV;
 
+       chip = gpiochip_find(LATCH1_LABEL, gpiochip_match_by_label);
+       if (!chip)
+               pr_err("%s: latch1 GPIO chip not found\n", __func__);
+       else
+               ams_delta_led_init(chip);
+
        err = gpio_request_array(latch_gpios, ARRAY_SIZE(latch_gpios));
-       if (err) {
+       if (err)
                pr_err("Couldn't take over latch1/latch2 GPIO pins\n");
-               return err;
-       }
 
-       platform_add_devices(late_devices, ARRAY_SIZE(late_devices));
-
-       /*
-        * As soon as devices have been registered, assign their dev_names
-        * to respective GPIO lookup tables before they are added.
-        */
-       ams_delta_lcd_gpio_table.dev_id = dev_name(&ams_delta_lcd_device.dev);
-       ams_delta_nand_gpio_table.dev_id = dev_name(&ams_delta_nand_device.dev);
+       return err;
+}
+device_initcall_sync(ams_delta_gpio_init);
 
-       gpiod_add_lookup_tables(late_gpio_tables, ARRAY_SIZE(late_gpio_tables));
+static int __init modem_nreset_init(void)
+{
+       int err;
 
        err = platform_device_register(&modem_nreset_device);
-       if (err) {
+       if (err)
                pr_err("Couldn't register the modem regulator device\n");
-               return err;
-       }
+
+       return err;
+}
+
+
+static int __init ams_delta_modem_init(void)
+{
+       int err;
 
        omap_cfg_reg(M14_1510_GPIO2);
        ams_delta_modem_ports[0].irq =
@@ -692,7 +867,22 @@ static int __init late_init(void)
 
        err = platform_device_register(&ams_delta_modem_device);
        if (err)
-               goto gpio_free;
+               gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
+
+       return err;
+}
+
+static int __init late_init(void)
+{
+       int err;
+
+       err = modem_nreset_init();
+       if (err)
+               return err;
+
+       err = ams_delta_modem_init();
+       if (err)
+               return err;
 
        /*
         * Once the modem device is registered, the modem_nreset
@@ -708,7 +898,6 @@ static int __init late_init(void)
 
 unregister:
        platform_device_unregister(&ams_delta_modem_device);
-gpio_free:
        gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
        return err;
 }
index ab51f855469798432b6ce0df38532c6327ddf01e..9aeb8ad8c3270cb5761f2a82408f2ba96e9c1a63 100644 (file)
@@ -274,7 +274,7 @@ static struct platform_device h2_kp_device = {
        .resource       = h2_kp_resources,
 };
 
-static struct gpio_led h2_gpio_led_pins[] = {
+static const struct gpio_led h2_gpio_led_pins[] = {
        {
                .name           = "h2:red",
                .default_trigger = "heartbeat",
index ad339f51cc7858324c5504bc30b94ddbdcd5fe6b..2edcd6356f2d635011d55b1e77f04ef44aa1cd13 100644 (file)
@@ -326,7 +326,7 @@ static struct spi_board_info h3_spi_board_info[] __initdata = {
        },
 };
 
-static struct gpio_led h3_gpio_led_pins[] = {
+static const struct gpio_led h3_gpio_led_pins[] = {
        {
                .name           = "h3:red",
                .default_trigger = "heartbeat",
index da8f3fc3180f55c2366ed9f68afb2fe116cf7a75..5733212759d3bb8cb1a76b2be3da6b15cf02e989 100644 (file)
@@ -292,7 +292,7 @@ static struct platform_device herald_gpiokeys_device = {
 };
 
 /* LEDs for the Herald.  These connect to the HTCPLD GPIO device. */
-static struct gpio_led gpio_leds[] = {
+static const struct gpio_led gpio_leds[] = {
        {"dpad",        NULL, HTCPLD_GPIO_LED_DPAD,        0, 0, LEDS_GPIO_DEFSTATE_OFF},
        {"kbd",         NULL, HTCPLD_GPIO_LED_KBD,         0, 0, LEDS_GPIO_DEFSTATE_OFF},
        {"vibrate",     NULL, HTCPLD_GPIO_LED_VIBRATE,     0, 0, LEDS_GPIO_DEFSTATE_OFF},
index 9ffa8d755a599344825b53c6363ac22038d21197..4df15e693b6ef61c0814699f9c9cd23364374c6c 100644 (file)
@@ -167,7 +167,7 @@ static struct platform_device *osk5912_devices[] __initdata = {
        &osk5912_cf_device,
 };
 
-static struct gpio_led tps_leds[] = {
+static const struct gpio_led tps_leds[] = {
        /* NOTE:  D9 and D2 have hardware blink support.
         * Also, D9 requires non-battery power.
         */
@@ -385,7 +385,7 @@ static struct platform_device osk5912_lcd_device = {
        .id             = -1,
 };
 
-static struct gpio_led mistral_gpio_led_pins[] = {
+static const struct gpio_led mistral_gpio_led_pins[] = {
        {
                .name           = "mistral:red",
                .default_trigger = "heartbeat",
diff --git a/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h b/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h
deleted file mode 100644 (file)
index 6dfc3e1..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * arch/arm/mach-omap1/include/ams-delta-fiq.h
- *
- * Taken from the original Amstrad modifications to fiq.h
- *
- * Copyright (c) 2004 Amstrad Plc
- * Copyright (c) 2006 Matt Callow
- * Copyright (c) 2010 Janusz Krzysztofik
- *
- * This program is free software; you can 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 __AMS_DELTA_FIQ_H
-#define __AMS_DELTA_FIQ_H
-
-#include <mach/irqs.h>
-
-/*
- * Interrupt number used for passing control from FIQ to IRQ.
- * IRQ12, described as reserved, has been selected.
- */
-#define INT_DEFERRED_FIQ       INT_1510_RES12
-/*
- * Base address of an interrupt handler that the INT_DEFERRED_FIQ belongs to.
- */
-#if (INT_DEFERRED_FIQ < IH2_BASE)
-#define DEFERRED_FIQ_IH_BASE   OMAP_IH1_BASE
-#else
-#define DEFERRED_FIQ_IH_BASE   OMAP_IH2_BASE
-#endif
-
-/*
- * These are the offsets from the beginning of the fiq_buffer. They are put here
- * since the buffer and header need to be accessed by drivers servicing devices
- * which generate GPIO interrupts - e.g. keyboard, modem, hook switch.
- */
-#define FIQ_MASK                0
-#define FIQ_STATE               1
-#define FIQ_KEYS_CNT            2
-#define FIQ_TAIL_OFFSET                 3
-#define FIQ_HEAD_OFFSET                 4
-#define FIQ_BUF_LEN             5
-#define FIQ_KEY                         6
-#define FIQ_MISSED_KEYS                 7
-#define FIQ_BUFFER_START        8
-#define FIQ_GPIO_INT_MASK       9
-#define FIQ_KEYS_HICNT         10
-#define FIQ_IRQ_PEND           11
-#define FIQ_SIR_CODE_L1                12
-#define IRQ_SIR_CODE_L2                13
-
-#define FIQ_CNT_INT_00         14
-#define FIQ_CNT_INT_KEY                15
-#define FIQ_CNT_INT_MDM                16
-#define FIQ_CNT_INT_03         17
-#define FIQ_CNT_INT_HSW                18
-#define FIQ_CNT_INT_05         19
-#define FIQ_CNT_INT_06         20
-#define FIQ_CNT_INT_07         21
-#define FIQ_CNT_INT_08         22
-#define FIQ_CNT_INT_09         23
-#define FIQ_CNT_INT_10         24
-#define FIQ_CNT_INT_11         25
-#define FIQ_CNT_INT_12         26
-#define FIQ_CNT_INT_13         27
-#define FIQ_CNT_INT_14         28
-#define FIQ_CNT_INT_15         29
-
-#define FIQ_CIRC_BUFF          30      /*Start of circular buffer */
-
-#ifndef __ASSEMBLER__
-extern unsigned int fiq_buffer[];
-extern unsigned char qwerty_fiqin_start, qwerty_fiqin_end;
-
-extern void __init ams_delta_init_fiq(void);
-#endif
-
-#endif
index 2ceffd85dd3d3fbcc4f80ae831713b37d23a83f3..cd65ea4e9c54e633bd66a0178ca3f06ad16e8db9 100644 (file)
@@ -2160,6 +2160,37 @@ static int of_dev_hwmod_lookup(struct device_node *np,
        return -ENODEV;
 }
 
+/**
+ * omap_hwmod_fix_mpu_rt_idx - fix up mpu_rt_idx register offsets
+ *
+ * @oh: struct omap_hwmod *
+ * @np: struct device_node *
+ *
+ * Fix up module register offsets for modules with mpu_rt_idx.
+ * Only needed for cpsw with interconnect target module defined
+ * in device tree while still using legacy hwmod platform data
+ * for rev, sysc and syss registers.
+ *
+ * Can be removed when all cpsw hwmod platform data has been
+ * dropped.
+ */
+static void omap_hwmod_fix_mpu_rt_idx(struct omap_hwmod *oh,
+                                     struct device_node *np,
+                                     struct resource *res)
+{
+       struct device_node *child = NULL;
+       int error;
+
+       child = of_get_next_child(np, child);
+       if (!child)
+               return;
+
+       error = of_address_to_resource(child, oh->mpu_rt_idx, res);
+       if (error)
+               pr_err("%s: error mapping mpu_rt_idx: %i\n",
+                      __func__, error);
+}
+
 /**
  * omap_hwmod_parse_module_range - map module IO range from device tree
  * @oh: struct omap_hwmod *
@@ -2220,7 +2251,13 @@ int omap_hwmod_parse_module_range(struct omap_hwmod *oh,
        size = be32_to_cpup(ranges);
 
        pr_debug("omap_hwmod: %s %s at 0x%llx size 0x%llx\n",
-                oh->name, np->name, base, size);
+                oh ? oh->name : "", np->name, base, size);
+
+       if (oh && oh->mpu_rt_idx) {
+               omap_hwmod_fix_mpu_rt_idx(oh, np, res);
+
+               return 0;
+       }
 
        res->start = base;
        res->end = base + size - 1;
index b68f9c0aff0b594d97af0c004c2525a7072197f0..d5ddba00bb7310bf0120902e2837dbddc4e90713 100644 (file)
@@ -92,11 +92,13 @@ static void omap_rtc_wait_not_busy(struct omap_hwmod *oh)
  */
 void omap_hwmod_rtc_unlock(struct omap_hwmod *oh)
 {
-       local_irq_disable();
+       unsigned long flags;
+
+       local_irq_save(flags);
        omap_rtc_wait_not_busy(oh);
        omap_hwmod_write(OMAP_RTC_KICK0_VALUE, oh, OMAP_RTC_KICK0_REG);
        omap_hwmod_write(OMAP_RTC_KICK1_VALUE, oh, OMAP_RTC_KICK1_REG);
-       local_irq_enable();
+       local_irq_restore(flags);
 }
 
 /**
@@ -110,9 +112,11 @@ void omap_hwmod_rtc_unlock(struct omap_hwmod *oh)
  */
 void omap_hwmod_rtc_lock(struct omap_hwmod *oh)
 {
-       local_irq_disable();
+       unsigned long flags;
+
+       local_irq_save(flags);
        omap_rtc_wait_not_busy(oh);
        omap_hwmod_write(0x0, oh, OMAP_RTC_KICK0_REG);
        omap_hwmod_write(0x0, oh, OMAP_RTC_KICK1_REG);
-       local_irq_enable();
+       local_irq_restore(flags);
 }
index b9846b19e5e2c7b9737085e23c56d83e0d0a6f67..d8ae8a85b14bdc4087ddafbc08894765242cbee5 100644 (file)
@@ -27,6 +27,8 @@ int main(void)
               offsetof(struct am33xx_pm_ro_sram_data, amx3_pm_sram_data_virt));
        DEFINE(AMX3_PM_RO_SRAM_DATA_PHYS_OFFSET,
               offsetof(struct am33xx_pm_ro_sram_data, amx3_pm_sram_data_phys));
+       DEFINE(AMX3_PM_RTC_BASE_VIRT_OFFSET,
+              offsetof(struct am33xx_pm_ro_sram_data, rtc_base_virt));
        DEFINE(AMX3_PM_RO_SRAM_DATA_SIZE,
               sizeof(struct am33xx_pm_ro_sram_data));
 
index acb698d5780f84a74bc21a25129d2bdb41b77e61..5a883920395862ba660fdea4af0ed30999af4593 100644 (file)
@@ -47,11 +47,6 @@ static int pm_dbg_init_done;
 
 static int pm_dbg_init(void);
 
-enum {
-       DEBUG_FILE_COUNTERS = 0,
-       DEBUG_FILE_TIMERS,
-};
-
 static const char pwrdm_state_names[][PWRDM_MAX_PWRSTS] = {
        "OFF",
        "RET",
@@ -141,39 +136,21 @@ static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user)
        return 0;
 }
 
-static int pm_dbg_show_counters(struct seq_file *s, void *unused)
+static int pm_dbg_counters_show(struct seq_file *s, void *unused)
 {
        pwrdm_for_each(pwrdm_dbg_show_counter, s);
        clkdm_for_each(clkdm_dbg_show_counter, s);
 
        return 0;
 }
+DEFINE_SHOW_ATTRIBUTE(pm_dbg_counters);
 
-static int pm_dbg_show_timers(struct seq_file *s, void *unused)
+static int pm_dbg_timers_show(struct seq_file *s, void *unused)
 {
        pwrdm_for_each(pwrdm_dbg_show_timer, s);
        return 0;
 }
-
-static int pm_dbg_open(struct inode *inode, struct file *file)
-{
-       switch ((int)inode->i_private) {
-       case DEBUG_FILE_COUNTERS:
-               return single_open(file, pm_dbg_show_counters,
-                       &inode->i_private);
-       case DEBUG_FILE_TIMERS:
-       default:
-               return single_open(file, pm_dbg_show_timers,
-                       &inode->i_private);
-       }
-}
-
-static const struct file_operations debug_fops = {
-       .open           = pm_dbg_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(pm_dbg_timers);
 
 static int pwrdm_suspend_get(void *data, u64 *val)
 {
@@ -259,10 +236,8 @@ static int __init pm_dbg_init(void)
        if (!d)
                return -EINVAL;
 
-       (void) debugfs_create_file("count", S_IRUGO,
-               d, (void *)DEBUG_FILE_COUNTERS, &debug_fops);
-       (void) debugfs_create_file("time", S_IRUGO,
-               d, (void *)DEBUG_FILE_TIMERS, &debug_fops);
+       (void) debugfs_create_file("count", 0444, d, NULL, &pm_dbg_counters_fops);
+       (void) debugfs_create_file("time", 0444, d, NULL, &pm_dbg_timers_fops);
 
        pwrdm_for_each(pwrdms_setup, (void *)d);
 
index 9b3755a2e2ecdeceb5007f8bed14c1720a64e2da..f4971e4a86b26893578badccb6c0828a4c8821ab 100644 (file)
@@ -26,6 +26,7 @@
 static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm, *mpu_pwrdm;
 static struct clockdomain *gfx_l4ls_clkdm;
 static void __iomem *scu_base;
+static struct omap_hwmod *rtc_oh;
 
 static int __init am43xx_map_scu(void)
 {
@@ -106,12 +107,13 @@ static void amx3_post_suspend_common(void)
                pr_err("PM: GFX domain did not transition: %x\n", status);
 }
 
-static int am33xx_suspend(unsigned int state, int (*fn)(unsigned long))
+static int am33xx_suspend(unsigned int state, int (*fn)(unsigned long),
+                         unsigned long args)
 {
        int ret = 0;
 
        amx3_pre_suspend_common();
-       ret = cpu_suspend(0, fn);
+       ret = cpu_suspend(args, fn);
        amx3_post_suspend_common();
 
        /*
@@ -128,13 +130,14 @@ static int am33xx_suspend(unsigned int state, int (*fn)(unsigned long))
        return ret;
 }
 
-static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long))
+static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long),
+                         unsigned long args)
 {
        int ret = 0;
 
        amx3_pre_suspend_common();
        scu_power_mode(scu_base, SCU_PM_POWEROFF);
-       ret = cpu_suspend(0, fn);
+       ret = cpu_suspend(args, fn);
        scu_power_mode(scu_base, SCU_PM_NORMAL);
        amx3_post_suspend_common();
 
@@ -151,16 +154,25 @@ static struct am33xx_pm_sram_addr *amx3_get_sram_addrs(void)
                return NULL;
 }
 
+void __iomem *am43xx_get_rtc_base_addr(void)
+{
+       rtc_oh = omap_hwmod_lookup("rtc");
+
+       return omap_hwmod_get_mpu_rt_va(rtc_oh);
+}
+
 static struct am33xx_pm_platform_data am33xx_ops = {
        .init = am33xx_suspend_init,
        .soc_suspend = am33xx_suspend,
        .get_sram_addrs = amx3_get_sram_addrs,
+       .get_rtc_base_addr = am43xx_get_rtc_base_addr,
 };
 
 static struct am33xx_pm_platform_data am43xx_ops = {
        .init = am43xx_suspend_init,
        .soc_suspend = am43xx_suspend,
        .get_sram_addrs = amx3_get_sram_addrs,
+       .get_rtc_base_addr = am43xx_get_rtc_base_addr,
 };
 
 static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void)
index 322b3bb868b49766f53ac807674ced65b5b42bc9..47a816468cdb45a2cf55b3751dfd8dd82c1c40c3 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <generated/ti-pm-asm-offsets.h>
 #include <linux/linkage.h>
+#include <linux/platform_data/pm33xx.h>
 #include <linux/ti-emif-sram.h>
 #include <asm/assembler.h>
 #include <asm/memory.h>
 #define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE                   0x0003
 #define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE                    0x0002
 
+/* replicated define because linux/bitops.h cannot be included in assembly */
+#define BIT(nr)                        (1 << (nr))
+
        .arm
        .align 3
 
 ENTRY(am33xx_do_wfi)
        stmfd   sp!, {r4 - r11, lr}     @ save registers on stack
 
+       /* Save wfi_flags arg to data space */
+       mov     r4, r0
+       adr     r3, am33xx_pm_ro_sram_data
+       ldr     r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
+       str     r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
+
+       /* Only flush cache is we know we are losing MPU context */
+       tst     r4, #WFI_FLAG_FLUSH_CACHE
+       beq     cache_skip_flush
+
        /*
         * Flush all data from the L1 and L2 data cache before disabling
         * SCTLR.C bit.
@@ -48,14 +62,33 @@ ENTRY(am33xx_do_wfi)
        ldr     r1, kernel_flush
        blx     r1
 
+       adr     r3, am33xx_pm_ro_sram_data
+       ldr     r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
+       ldr     r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
+
+cache_skip_flush:
+       /* Check if we want self refresh */
+       tst     r4, #WFI_FLAG_SELF_REFRESH
+       beq     emif_skip_enter_sr
+
        adr     r9, am33xx_emif_sram_table
 
        ldr     r3, [r9, #EMIF_PM_ENTER_SR_OFFSET]
        blx     r3
 
+emif_skip_enter_sr:
+       /* Only necessary if PER is losing context */
+       tst     r4, #WFI_FLAG_SAVE_EMIF
+       beq     emif_skip_save
+
        ldr     r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET]
        blx     r3
 
+emif_skip_save:
+       /* Only can disable EMIF if we have entered self refresh */
+       tst     r4, #WFI_FLAG_SELF_REFRESH
+       beq     emif_skip_disable
+
        /* Disable EMIF */
        ldr     r1, virt_emif_clkctrl
        ldr     r2, [r1]
@@ -69,6 +102,10 @@ wait_emif_disable:
        cmp     r2, r3
        bne     wait_emif_disable
 
+emif_skip_disable:
+       tst     r4, #WFI_FLAG_WAKE_M3
+       beq     wkup_m3_skip
+
        /*
         * For the MPU WFI to be registered as an interrupt
         * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set
@@ -79,6 +116,7 @@ wait_emif_disable:
        bic     r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
        str     r2, [r1]
 
+wkup_m3_skip:
        /*
         * Execute an ISB instruction to ensure that all of the
         * CP15 register changes have been committed.
@@ -132,10 +170,18 @@ wait_emif_enable:
        cmp     r2, r3
        bne     wait_emif_enable
 
+       /* Only necessary if PER is losing context */
+       tst     r4, #WFI_FLAG_SELF_REFRESH
+       beq     emif_skip_exit_sr_abt
 
+       adr     r9, am33xx_emif_sram_table
        ldr     r1, [r9, #EMIF_PM_ABORT_SR_OFFSET]
        blx     r1
 
+emif_skip_exit_sr_abt:
+       tst     r4, #WFI_FLAG_FLUSH_CACHE
+       beq     cache_skip_restore
+
        /*
         * Set SCTLR.C bit to allow data cache allocation
         */
@@ -144,6 +190,7 @@ wait_emif_enable:
        mcr     p15, 0, r0, c1, c0, 0
        isb
 
+cache_skip_restore:
        /* Let the suspend code know about the abort */
        mov     r0, #1
        ldmfd   sp!, {r4 - r11, pc}     @ restore regs and return
@@ -181,8 +228,6 @@ ENDPROC(am33xx_resume_from_deep_sleep)
  * Local variables
  */
        .align
-resume_addr:
-       .word   cpu_resume - PAGE_OFFSET + 0x80000000
 kernel_flush:
        .word   v7_flush_dcache_all
 virt_mpu_clkctrl:
@@ -205,6 +250,9 @@ ENTRY(am33xx_pm_sram)
        .word am33xx_emif_sram_table
        .word am33xx_pm_ro_sram_data
 
+resume_addr:
+.word  cpu_resume - PAGE_OFFSET + 0x80000000
+
 .align 3
 ENTRY(am33xx_pm_ro_sram_data)
        .space AMX3_PM_RO_SRAM_DATA_SIZE
index 8903814a6677d327579f9410f9b9b641e23ed97a..5b9343b58fc700de1738601ac091b5990061fb7a 100644 (file)
@@ -9,7 +9,7 @@
 #include <generated/ti-pm-asm-offsets.h>
 #include <linux/linkage.h>
 #include <linux/ti-emif-sram.h>
-
+#include <linux/platform_data/pm33xx.h>
 #include <asm/assembler.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/memory.h>
@@ -22,6 +22,9 @@
 #include "prm33xx.h"
 #include "prcm43xx.h"
 
+/* replicated define because linux/bitops.h cannot be included in assembly */
+#define BIT(nr)                        (1 << (nr))
+
 #define AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED         0x00030000
 #define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE           0x0003
 #define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE            0x0002
                                        AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET)
 #define AM43XX_PRM_EMIF_CTRL_OFFSET                    0x0030
 
+#define RTC_SECONDS_REG                                        0x0
+#define RTC_PMIC_REG                                   0x98
+#define RTC_PMIC_POWER_EN                              BIT(16)
+#define RTC_PMIC_EXT_WAKEUP_STS                                BIT(12)
+#define RTC_PMIC_EXT_WAKEUP_POL                                BIT(4)
+#define RTC_PMIC_EXT_WAKEUP_EN                         BIT(0)
+
        .arm
        .align 3
 
 ENTRY(am43xx_do_wfi)
        stmfd   sp!, {r4 - r11, lr}     @ save registers on stack
 
+       /* Save wfi_flags arg to data space */
+       mov     r4, r0
+       adr     r3, am43xx_pm_ro_sram_data
+       ldr     r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
+       str     r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
+
 #ifdef CONFIG_CACHE_L2X0
        /* Retrieve l2 cache virt address BEFORE we shut off EMIF */
        ldr     r1, get_l2cache_base
@@ -58,6 +74,10 @@ ENTRY(am43xx_do_wfi)
        mov     r8, r0
 #endif
 
+       /* Only flush cache is we know we are losing MPU context */
+       tst     r4, #WFI_FLAG_FLUSH_CACHE
+       beq     cache_skip_flush
+
        /*
         * Flush all data from the L1 and L2 data cache before disabling
         * SCTLR.C bit.
@@ -128,13 +148,47 @@ sync:
        bne     sync
 #endif
 
+       /* Restore wfi_flags */
+       adr     r3, am43xx_pm_ro_sram_data
+       ldr     r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
+       ldr     r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
+
+cache_skip_flush:
+       /*
+        * If we are trying to enter RTC+DDR mode we must perform
+        * a read from the rtc address space to ensure translation
+        * presence in the TLB to avoid page table walk after DDR
+        * is unavailable.
+        */
+       tst     r4, #WFI_FLAG_RTC_ONLY
+       beq     skip_rtc_va_refresh
+
+       adr     r3, am43xx_pm_ro_sram_data
+       ldr     r1, [r3, #AMX3_PM_RTC_BASE_VIRT_OFFSET]
+       ldr     r0, [r1]
+
+skip_rtc_va_refresh:
+       /* Check if we want self refresh */
+       tst     r4, #WFI_FLAG_SELF_REFRESH
+       beq     emif_skip_enter_sr
+
        adr     r9, am43xx_emif_sram_table
 
        ldr     r3, [r9, #EMIF_PM_ENTER_SR_OFFSET]
        blx     r3
 
+emif_skip_enter_sr:
+       /* Only necessary if PER is losing context */
+       tst     r4, #WFI_FLAG_SAVE_EMIF
+       beq     emif_skip_save
+
        ldr     r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET]
-       blx     r3
+       blx     r3
+
+emif_skip_save:
+       /* Only can disable EMIF if we have entered self refresh */
+       tst     r4, #WFI_FLAG_SELF_REFRESH
+       beq     emif_skip_disable
 
        /* Disable EMIF */
        ldr     r1, am43xx_virt_emif_clkctrl
@@ -148,6 +202,38 @@ wait_emif_disable:
        cmp     r2, r3
        bne     wait_emif_disable
 
+emif_skip_disable:
+       tst     r4, #WFI_FLAG_RTC_ONLY
+       beq     skip_rtc_only
+
+       adr     r3, am43xx_pm_ro_sram_data
+       ldr     r1, [r3, #AMX3_PM_RTC_BASE_VIRT_OFFSET]
+
+       ldr     r0, [r1, #RTC_PMIC_REG]
+       orr     r0, r0, #RTC_PMIC_POWER_EN
+       orr     r0, r0, #RTC_PMIC_EXT_WAKEUP_STS
+       orr     r0, r0, #RTC_PMIC_EXT_WAKEUP_EN
+       orr     r0, r0, #RTC_PMIC_EXT_WAKEUP_POL
+       str     r0, [r1, #RTC_PMIC_REG]
+       ldr     r0, [r1, #RTC_PMIC_REG]
+       /* Wait for 2 seconds to lose power */
+       mov     r3, #2
+       ldr     r2, [r1, #RTC_SECONDS_REG]
+rtc_loop:
+       ldr     r0, [r1, #RTC_SECONDS_REG]
+       cmp     r0, r2
+       beq     rtc_loop
+       mov     r2, r0
+       subs    r3, r3, #1
+       bne     rtc_loop
+
+       b       re_enable_emif
+
+skip_rtc_only:
+
+       tst     r4, #WFI_FLAG_WAKE_M3
+       beq     wkup_m3_skip
+
        /*
         * For the MPU WFI to be registered as an interrupt
         * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set
@@ -165,6 +251,7 @@ wait_emif_disable:
        mov     r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP
        str     r2, [r1]
 
+wkup_m3_skip:
        /*
         * Execute a barrier instruction to ensure that all cache,
         * TLB and branch predictor maintenance operations issued
@@ -209,6 +296,7 @@ wait_emif_disable:
        mov     r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
        str     r2, [r1]
 
+re_enable_emif:
        /* Re-enable EMIF */
        ldr     r1, am43xx_virt_emif_clkctrl
        mov     r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
@@ -218,6 +306,9 @@ wait_emif_enable:
        cmp     r2, r3
        bne     wait_emif_enable
 
+       tst     r4, #WFI_FLAG_FLUSH_CACHE
+       beq     cache_skip_restore
+
        /*
         * Set SCTLR.C bit to allow data cache allocation
         */
@@ -226,9 +317,16 @@ wait_emif_enable:
        mcr     p15, 0, r0, c1, c0, 0
        isb
 
-       ldr     r1, [r9, #EMIF_PM_ABORT_SR_OFFSET]
-       blx     r1
+cache_skip_restore:
+       /* Only necessary if PER is losing context */
+       tst     r4, #WFI_FLAG_SELF_REFRESH
+       beq     emif_skip_exit_sr_abt
+
+       adr     r9, am43xx_emif_sram_table
+       ldr     r1, [r9, #EMIF_PM_ABORT_SR_OFFSET]
+       blx     r1
 
+emif_skip_exit_sr_abt:
        /* Let the suspend code know about the abort */
        mov     r0, #1
        ldmfd   sp!, {r4 - r11, pc}     @ restore regs and return
@@ -333,8 +431,6 @@ ENDPROC(am43xx_resume_from_deep_sleep)
  * Local variables
  */
        .align
-resume_addr:
-       .word   cpu_resume - PAGE_OFFSET + 0x80000000
 kernel_flush:
        .word   v7_flush_dcache_all
 ddr_start:
@@ -381,6 +477,8 @@ ENTRY(am43xx_pm_sram)
        .word am43xx_emif_sram_table
        .word am43xx_pm_ro_sram_data
 
+resume_addr:
+       .word   cpu_resume - PAGE_OFFSET + 0x80000000
 .align 3
 
 ENTRY(am43xx_pm_ro_sram_data)
index 5a16ea74e28a00820e6d3b92b0c2c3c73ebaa784..a24783a03827a28cc1544347b0fe98ce150de5ee 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/clkdev.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
 #include <linux/spi/pxa2xx_spi.h>
@@ -477,6 +478,18 @@ struct platform_device pxa_device_ac97 = {
 
 void __init pxa_set_ac97_info(pxa2xx_audio_ops_t *ops)
 {
+       int ret;
+
+       ret = clk_add_alias("ac97_clk", "pxa2xx-ac97:0", "AC97CLK",
+                          &pxa_device_ac97.dev);
+       if (ret)
+               pr_err("PXA AC97 clock1 alias error: %d\n", ret);
+
+       ret = clk_add_alias("ac97_clk", "pxa2xx-ac97:1", "AC97CLK",
+                           &pxa_device_ac97.dev);
+       if (ret)
+               pr_err("PXA AC97 clock2 alias error: %d\n", ret);
+
        pxa_register_device(&pxa_device_ac97, ops);
 }
 
index e2e7f247a6456746f6fb3773c4798c512d3b27e4..b79b757fdd413e5d6754a67d20007b345da7067b 100644 (file)
@@ -54,6 +54,7 @@
 
 #include "devices.h"
 #include "generic.h"
+#include "udc.h"
 
 /* Physical address space information */
 
@@ -594,6 +595,8 @@ static struct platform_device gpio_vbus = {
        },
 };
 
+static struct pxa2xx_udc_mach_info hx4700_udc_info;
+
 /*
  * Touchscreen - TSC2046 connected to SSP2
  */
@@ -891,6 +894,7 @@ static void __init hx4700_init(void)
        gpio_set_value(GPIO71_HX4700_ASIC3_nRESET, 1);
        mdelay(10);
 
+       pxa_set_udc_info(&hx4700_udc_info);
        regulator_has_full_constraints();
 }
 
index 9b6c7ea45a4010555f97b83cfa2655a60cd7c672..04dc78d0809f820dfcc642185cd81a7a88ed271d 100644 (file)
@@ -677,14 +677,12 @@ MIO_SIMPLE_DEV(mioa701_led,         "leds-gpio",      &gpio_led_info)
 MIO_SIMPLE_DEV(pxa2xx_pcm,       "pxa2xx-pcm",     NULL)
 MIO_SIMPLE_DEV(mioa701_sound,    "mioa701-wm9713", NULL)
 MIO_SIMPLE_DEV(mioa701_board,    "mioa701-board",  NULL)
-MIO_SIMPLE_DEV(wm9713_acodec,    "wm9713-codec",   NULL);
 MIO_SIMPLE_DEV(gpio_vbus,        "gpio-vbus",      &gpio_vbus_data);
 
 static struct platform_device *devices[] __initdata = {
        &mioa701_gpio_keys,
        &mioa701_backlight,
        &mioa701_led,
-       &wm9713_acodec,
        &pxa2xx_pcm,
        &mioa701_sound,
        &power_dev,
index d69de312d8d91a432d5652428cdfc3808ff760e6..52e70a5c1281d95b936cd6f4c38704f2432887f8 100644 (file)
@@ -47,16 +47,6 @@ int wm9713_irq;
 int lcd_id;
 int lcd_orientation;
 
-struct platform_device pxa_device_wm9713_audio = {
-       .name           = "wm9713-codec",
-       .id             = -1,
-};
-
-static void __init zylonite_init_wm9713_audio(void)
-{
-       platform_device_register(&pxa_device_wm9713_audio);
-}
-
 static struct resource smc91x_resources[] = {
        [0] = {
                .start  = ZYLONITE_ETH_PHYS + 0x300,
@@ -428,7 +418,6 @@ static void __init zylonite_init(void)
        zylonite_init_nand();
        zylonite_init_leds();
        zylonite_init_ohci();
-       zylonite_init_wm9713_audio();
 }
 
 MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
index fafd3d7f9f8c4b6ff1576c756e65b06666c51c2c..8ca9265220269e4d66517a028485be7d947ebee9 100644 (file)
@@ -17,6 +17,7 @@ config ARCH_ROCKCHIP
        select ARM_GLOBAL_TIMER
        select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
        select ZONE_DMA if ARM_LPAE
+       select PM
        help
          Support for Rockchip's Cortex-A9 Single-to-Quad-Core-SoCs
          containing the RK2928, RK30xx and RK31xx series.
index b6b32724ace8c34b91660613d0fa1e94093f2de7..4ff83f956cfb30a02d97a2b07ba03dc01cc424cb 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #ifndef __ARCH_ARM_MACH_S3C24XX_S3C2412_H
-#define __ARCH_ARM_REGS_S3C24XX_S3C2412_H __FILE__
+#define __ARCH_ARM_MACH_S3C24XX_S3C2412_H __FILE__
 
 #define S3C2412_MEMREG(x)              (S3C24XX_VA_MEMCTRL + (x))
 #define S3C2412_EBIREG(x)              (S3C2412_VA_EBI + (x))
index 0b67254eabb2c4e823fb7f31aca437e1d45979f3..aeb2eed085988bb853685cc0174b192de0b4f054 100644 (file)
@@ -15,6 +15,7 @@ config ARCH_RCAR_GEN1
 
 config ARCH_RCAR_GEN2
        bool
+       select HAVE_ARM_ARCH_TIMER
        select PM
        select PM_GENERIC_DOMAINS
        select RENESAS_IRQC
@@ -58,6 +59,7 @@ config ARCH_R8A73A4
        bool "R-Mobile APE6 (R8A73A40)"
        select ARCH_RMOBILE
        select ARM_ERRATA_798181 if SMP
+       select HAVE_ARM_ARCH_TIMER
        select RENESAS_IRQC
 
 config ARCH_R8A7740
index 1939f521579c6357af51c68d559396a205944422..b33dc59d8698d218bacf6fd1117b9814dd5ade6b 100644 (file)
@@ -11,9 +11,7 @@ obj-$(CONFIG_ARCH_SH73A0)     += setup-sh73a0.o
 obj-$(CONFIG_ARCH_R8A73A4)     += setup-r8a73a4.o
 obj-$(CONFIG_ARCH_R8A7740)     += setup-r8a7740.o
 obj-$(CONFIG_ARCH_R8A7778)     += setup-r8a7778.o
-obj-$(CONFIG_ARCH_R8A7779)     += setup-r8a7779.o pm-r8a7779.o
-obj-$(CONFIG_ARCH_R8A7790)     += setup-r8a7790.o
-obj-$(CONFIG_ARCH_R8A7791)     += setup-r8a7791.o
+obj-$(CONFIG_ARCH_R8A7779)     += setup-r8a7779.o
 obj-$(CONFIG_ARCH_EMEV2)       += setup-emev2.o
 obj-$(CONFIG_ARCH_R7S72100)    += setup-r7s72100.o
 
@@ -23,17 +21,15 @@ cpu-y                               := platsmp.o headsmp.o
 # Shared SoC family objects
 obj-$(CONFIG_ARCH_RCAR_GEN2)   += setup-rcar-gen2.o platsmp-apmu.o $(cpu-y)
 CFLAGS_setup-rcar-gen2.o       += -march=armv7-a
-obj-$(CONFIG_ARCH_RCAR_GEN2)   += headsmp-apmu.o
 obj-$(CONFIG_ARCH_R8A7790)     += regulator-quirk-rcar-gen2.o
 obj-$(CONFIG_ARCH_R8A7791)     += regulator-quirk-rcar-gen2.o
 obj-$(CONFIG_ARCH_R8A7793)     += regulator-quirk-rcar-gen2.o
 
 # SMP objects
 smp-y                          := $(cpu-y)
+smp-$(CONFIG_ARCH_RCAR_GEN2)   += headsmp-apmu.o
 smp-$(CONFIG_ARCH_SH73A0)      += smp-sh73a0.o headsmp-scu.o platsmp-scu.o
 smp-$(CONFIG_ARCH_R8A7779)     += smp-r8a7779.o headsmp-scu.o platsmp-scu.o
-smp-$(CONFIG_ARCH_R8A7790)     += smp-r8a7790.o
-smp-$(CONFIG_ARCH_R8A7791)     += smp-r8a7791.o
 smp-$(CONFIG_ARCH_EMEV2)       += smp-emev2.o headsmp-scu.o platsmp-scu.o
 
 # PM objects
index 2109f123bdfb2e19c3e24e77037b91eb87e4afd5..3ac4b36b5c2bf286992dbf22ec0bd888231002c1 100644 (file)
@@ -15,7 +15,6 @@ extern void shmobile_smp_sleep(void);
 extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn,
                              unsigned long arg);
 extern bool shmobile_smp_cpu_can_disable(unsigned int cpu);
-extern bool shmobile_smp_init_fallback_ops(void);
 extern void shmobile_boot_apmu(void);
 extern void shmobile_boot_scu(void);
 extern void shmobile_smp_scu_prepare_cpus(phys_addr_t scu_base_phys,
index d49ab194766a401fb5642f269f01db39929ef9a5..fabe9cadd12ef0b1d82ed9c3ead65f35943e8a70 100644 (file)
@@ -1,19 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * SMP support for APMU based systems with Cortex A7/A15
  *
  * Copyright (C) 2014  Renesas Electronics Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 
-#ifdef CONFIG_SMP
 ENTRY(shmobile_boot_apmu)
        bl      secure_cntvoff_init
        b       secondary_startup
 ENDPROC(shmobile_boot_apmu)
-#endif
index ba732effc90b019fcf4ba65aa29eb3408d88efba..96330ef256416dce9c3d310dcef6c2ccb06450bc 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * SMP support for SoCs with APMU
  *
  * Copyright (C) 2014  Renesas Electronics Corporation
  * Copyright (C) 2013  Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 #include <linux/cpu_pm.h>
 #include <linux/delay.h>
@@ -23,7 +20,6 @@
 #include <asm/smp_plat.h>
 #include <asm/suspend.h>
 #include "common.h"
-#include "platsmp-apmu.h"
 #include "rcar-gen2.h"
 
 static struct {
@@ -87,6 +83,104 @@ static int __maybe_unused apmu_wrap(int cpu, int (*fn)(void __iomem *p, int cpu)
        return p ? fn(p, apmu_cpus[cpu].bit) : -EINVAL;
 }
 
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_SUSPEND)
+/* nicked from arch/arm/mach-exynos/hotplug.c */
+static inline void cpu_enter_lowpower_a15(void)
+{
+       unsigned int v;
+
+       asm volatile(
+       "       mrc     p15, 0, %0, c1, c0, 0\n"
+       "       bic     %0, %0, %1\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+               : "=&r" (v)
+               : "Ir" (CR_C)
+               : "cc");
+
+       flush_cache_louis();
+
+       asm volatile(
+       /*
+        * Turn off coherency
+        */
+       "       mrc     p15, 0, %0, c1, c0, 1\n"
+       "       bic     %0, %0, %1\n"
+       "       mcr     p15, 0, %0, c1, c0, 1\n"
+               : "=&r" (v)
+               : "Ir" (0x40)
+               : "cc");
+
+       isb();
+       dsb();
+}
+
+static void shmobile_smp_apmu_cpu_shutdown(unsigned int cpu)
+{
+
+       /* Select next sleep mode using the APMU */
+       apmu_wrap(cpu, apmu_power_off);
+
+       /* Do ARM specific CPU shutdown */
+       cpu_enter_lowpower_a15();
+}
+#endif
+
+#if defined(CONFIG_HOTPLUG_CPU)
+static void shmobile_smp_apmu_cpu_die(unsigned int cpu)
+{
+       /* For this particular CPU deregister boot vector */
+       shmobile_smp_hook(cpu, 0, 0);
+
+       /* Shutdown CPU core */
+       shmobile_smp_apmu_cpu_shutdown(cpu);
+
+       /* jump to shared mach-shmobile sleep / reset code */
+       shmobile_smp_sleep();
+}
+
+static int shmobile_smp_apmu_cpu_kill(unsigned int cpu)
+{
+       return apmu_wrap(cpu, apmu_power_off_poll);
+}
+#endif
+
+#if defined(CONFIG_SUSPEND)
+static int shmobile_smp_apmu_do_suspend(unsigned long cpu)
+{
+       shmobile_smp_hook(cpu, __pa_symbol(cpu_resume), 0);
+       shmobile_smp_apmu_cpu_shutdown(cpu);
+       cpu_do_idle(); /* WFI selects Core Standby */
+       return 1;
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+       unsigned int v;
+
+       asm volatile("mrc    p15, 0, %0, c1, c0, 0\n"
+                    "       orr     %0, %0, %1\n"
+                    "       mcr     p15, 0, %0, c1, c0, 0\n"
+                    "       mrc     p15, 0, %0, c1, c0, 1\n"
+                    "       orr     %0, %0, %2\n"
+                    "       mcr     p15, 0, %0, c1, c0, 1\n"
+                    : "=&r" (v)
+                    : "Ir" (CR_C), "Ir" (0x40)
+                    : "cc");
+}
+
+static int shmobile_smp_apmu_enter_suspend(suspend_state_t state)
+{
+       cpu_suspend(smp_processor_id(), shmobile_smp_apmu_do_suspend);
+       cpu_leave_lowpower();
+       return 0;
+}
+
+void __init shmobile_smp_apmu_suspend_init(void)
+{
+       shmobile_suspend_ops.enter = shmobile_smp_apmu_enter_suspend;
+}
+#endif
+
 #ifdef CONFIG_SMP
 static void apmu_init_cpu(struct resource *res, int cpu, int bit)
 {
@@ -106,38 +200,6 @@ static void apmu_init_cpu(struct resource *res, int cpu, int bit)
        writel(x, apmu_cpus[cpu].iomem + DBGRCR_OFFS);
 }
 
-static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit),
-                          struct rcar_apmu_config *apmu_config, int num)
-{
-       int id;
-       int k;
-       int bit, index;
-       bool is_allowed;
-
-       for (k = 0; k < num; k++) {
-               /* only enable the cluster that includes the boot CPU */
-               is_allowed = false;
-               for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) {
-                       id = apmu_config[k].cpus[bit];
-                       if (id >= 0) {
-                               if (id == cpu_logical_map(0))
-                                       is_allowed = true;
-                       }
-               }
-               if (!is_allowed)
-                       continue;
-
-               for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) {
-                       id = apmu_config[k].cpus[bit];
-                       if (id >= 0) {
-                               index = get_logical_index(id);
-                               if (index >= 0)
-                                       fn(&apmu_config[k].iomem, index, bit);
-                       }
-               }
-       }
-}
-
 static const struct of_device_id apmu_ids[] = {
        { .compatible = "renesas,apmu" },
        { /*sentinel*/ }
@@ -194,15 +256,8 @@ static void __init shmobile_smp_apmu_setup_boot(void)
        shmobile_boot_fn_gen2 = shmobile_boot_fn;
 }
 
-void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
-                                          struct rcar_apmu_config *apmu_config,
-                                          int num)
-{
-       shmobile_smp_apmu_setup_boot();
-       apmu_parse_cfg(apmu_init_cpu, apmu_config, num);
-}
-
-int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int shmobile_smp_apmu_boot_secondary(unsigned int cpu,
+                                           struct task_struct *idle)
 {
        /* For this particular CPU register boot vector */
        shmobile_smp_hook(cpu, __pa_symbol(shmobile_boot_apmu), 0);
@@ -229,101 +284,3 @@ static struct smp_operations apmu_smp_ops __initdata = {
 
 CPU_METHOD_OF_DECLARE(shmobile_smp_apmu, "renesas,apmu", &apmu_smp_ops);
 #endif /* CONFIG_SMP */
-
-#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_SUSPEND)
-/* nicked from arch/arm/mach-exynos/hotplug.c */
-static inline void cpu_enter_lowpower_a15(void)
-{
-       unsigned int v;
-
-       asm volatile(
-       "       mrc     p15, 0, %0, c1, c0, 0\n"
-       "       bic     %0, %0, %1\n"
-       "       mcr     p15, 0, %0, c1, c0, 0\n"
-               : "=&r" (v)
-               : "Ir" (CR_C)
-               : "cc");
-
-       flush_cache_louis();
-
-       asm volatile(
-       /*
-        * Turn off coherency
-        */
-       "       mrc     p15, 0, %0, c1, c0, 1\n"
-       "       bic     %0, %0, %1\n"
-       "       mcr     p15, 0, %0, c1, c0, 1\n"
-               : "=&r" (v)
-               : "Ir" (0x40)
-               : "cc");
-
-       isb();
-       dsb();
-}
-
-static void shmobile_smp_apmu_cpu_shutdown(unsigned int cpu)
-{
-
-       /* Select next sleep mode using the APMU */
-       apmu_wrap(cpu, apmu_power_off);
-
-       /* Do ARM specific CPU shutdown */
-       cpu_enter_lowpower_a15();
-}
-
-static inline void cpu_leave_lowpower(void)
-{
-       unsigned int v;
-
-       asm volatile("mrc    p15, 0, %0, c1, c0, 0\n"
-                    "       orr     %0, %0, %1\n"
-                    "       mcr     p15, 0, %0, c1, c0, 0\n"
-                    "       mrc     p15, 0, %0, c1, c0, 1\n"
-                    "       orr     %0, %0, %2\n"
-                    "       mcr     p15, 0, %0, c1, c0, 1\n"
-                    : "=&r" (v)
-                    : "Ir" (CR_C), "Ir" (0x40)
-                    : "cc");
-}
-#endif
-
-#if defined(CONFIG_HOTPLUG_CPU)
-void shmobile_smp_apmu_cpu_die(unsigned int cpu)
-{
-       /* For this particular CPU deregister boot vector */
-       shmobile_smp_hook(cpu, 0, 0);
-
-       /* Shutdown CPU core */
-       shmobile_smp_apmu_cpu_shutdown(cpu);
-
-       /* jump to shared mach-shmobile sleep / reset code */
-       shmobile_smp_sleep();
-}
-
-int shmobile_smp_apmu_cpu_kill(unsigned int cpu)
-{
-       return apmu_wrap(cpu, apmu_power_off_poll);
-}
-#endif
-
-#if defined(CONFIG_SUSPEND)
-static int shmobile_smp_apmu_do_suspend(unsigned long cpu)
-{
-       shmobile_smp_hook(cpu, __pa_symbol(cpu_resume), 0);
-       shmobile_smp_apmu_cpu_shutdown(cpu);
-       cpu_do_idle(); /* WFI selects Core Standby */
-       return 1;
-}
-
-static int shmobile_smp_apmu_enter_suspend(suspend_state_t state)
-{
-       cpu_suspend(smp_processor_id(), shmobile_smp_apmu_do_suspend);
-       cpu_leave_lowpower();
-       return 0;
-}
-
-void __init shmobile_smp_apmu_suspend_init(void)
-{
-       shmobile_suspend_ops.enter = shmobile_smp_apmu_enter_suspend;
-}
-#endif
diff --git a/arch/arm/mach-shmobile/platsmp-apmu.h b/arch/arm/mach-shmobile/platsmp-apmu.h
deleted file mode 100644 (file)
index 76512c9..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * rmobile apmu definition
- *
- * Copyright (C) 2014  Renesas Electronics Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef PLATSMP_APMU_H
-#define PLATSMP_APMU_H
-
-struct rcar_apmu_config {
-       struct resource iomem;
-       int cpus[4];
-};
-
-extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
-                                          struct rcar_apmu_config *apmu_config,
-                                          int num);
-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);
-
-#endif /* PLATSMP_APMU_H */
index 02e21bceb0856bc5ac5c769af3362afab2927c99..b23378f3d7e1726b6f92b3cc8be0ba8264c838f7 100644 (file)
@@ -36,12 +36,3 @@ bool shmobile_smp_cpu_can_disable(unsigned int cpu)
        return true; /* Hotplug of any CPU is supported */
 }
 #endif
-
-bool __init shmobile_smp_init_fallback_ops(void)
-{
-       /* fallback on PSCI/smp_ops if no other DT based method is detected */
-       if (!IS_ENABLED(CONFIG_SMP))
-               return false;
-
-       return platform_can_secondary_boot() ? true : false;
-}
diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c
deleted file mode 100644 (file)
index 5c9a93f..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * r8a7779 Power management support
- *
- * 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/soc/renesas/rcar-sysc.h>
-
-#include <asm/io.h>
-
-#include "r8a7779.h"
-
-/* SYSC */
-#define SYSCIER 0x0c
-#define SYSCIMR 0x10
-
-#if defined(CONFIG_PM) || defined(CONFIG_SMP)
-
-static void __init r8a7779_sysc_init(void)
-{
-       rcar_sysc_init(0xffd85000, 0x0131000e);
-}
-
-#else /* CONFIG_PM || CONFIG_SMP */
-
-static inline void r8a7779_sysc_init(void) {}
-
-#endif /* CONFIG_PM || CONFIG_SMP */
-
-void __init r8a7779_pm_init(void)
-{
-       static int once;
-
-       if (!once++)
-               r8a7779_sysc_init();
-}
index 5a798b406af05be06e170af851e48a32a3a7025b..345af3ebcc3aeeb69fd79ff259f31f17cce007d0 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/smp.h>
-#include <linux/soc/renesas/rcar-sysc.h>
 #include <asm/io.h>
 #include <asm/cputype.h>
 #include "common.h"
@@ -46,23 +45,6 @@ static inline u32 phys_to_sbar(phys_addr_t addr)
        return (addr >> 8) & 0xfffffc00;
 }
 
-/* SYSC */
-#define SYSCIER 0x0c
-#define SYSCIMR 0x10
-
-#if defined(CONFIG_SMP)
-
-static void __init rcar_gen2_sysc_init(u32 syscier)
-{
-       rcar_sysc_init(0xe6180000, syscier);
-}
-
-#else /* CONFIG_SMP */
-
-static inline void rcar_gen2_sysc_init(u32 syscier) {}
-
-#endif /* CONFIG_SMP */
-
 void __init rcar_gen2_pm_init(void)
 {
        void __iomem *p;
@@ -72,7 +54,6 @@ void __init rcar_gen2_pm_init(void)
        bool has_a7 = false;
        bool has_a15 = false;
        struct resource res;
-       u32 syscier = 0;
        int error;
 
        if (once++)
@@ -89,11 +70,6 @@ void __init rcar_gen2_pm_init(void)
                        has_a7 = true;
        }
 
-       if (of_machine_is_compatible("renesas,r8a7790"))
-               syscier = 0x013111ef;
-       else if (of_machine_is_compatible("renesas,r8a7791"))
-               syscier = 0x00111003;
-
        np = of_find_compatible_node(NULL, NULL, "renesas,smp-sram");
        if (!np) {
                /* No smp-sram in DT, fall back to hardcoded address */
@@ -155,6 +131,5 @@ map:
        }
        iounmap(p);
 
-       rcar_gen2_sysc_init(syscier);
        shmobile_smp_apmu_suspend_init();
 }
index 30668aa6acc34647bb5f62407c657ac3debe3e9c..ca9db8fde2f791ccbc6b47c21824358de995a135 100644 (file)
@@ -2,8 +2,6 @@
 #ifndef __ASM_R8A7779_H__
 #define __ASM_R8A7779_H__
 
-extern void r8a7779_pm_init(void);
-
 extern const struct smp_operations r8a7779_smp_ops;
 
 #endif /* __ASM_R8A7779_H__ */
diff --git a/arch/arm/mach-shmobile/r8a7790.h b/arch/arm/mach-shmobile/r8a7790.h
deleted file mode 100644 (file)
index 669c8cd..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_R8A7790_H__
-#define __ASM_R8A7790_H__
-
-extern const struct smp_operations r8a7790_smp_ops;
-
-#endif /* __ASM_R8A7790_H__ */
diff --git a/arch/arm/mach-shmobile/r8a7791.h b/arch/arm/mach-shmobile/r8a7791.h
deleted file mode 100644 (file)
index 8c794aa..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_R8A7791_H__
-#define __ASM_R8A7791_H__
-
-extern const struct smp_operations r8a7791_smp_ops;
-
-#endif /* __ASM_R8A7791_H__ */
index 93f628acfd944fd5b03a012f18951945d5aa44e9..21ebc7678ffddbba07a1ffa3be13eb01b2dec1ed 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * R-Car Generation 2 da9063/da9210 regulator quirk
  *
  * been initialized, but before the i2c slave drivers are initialized.
  *
  * Copyright (C) 2015 Glider bvba
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT 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>
index 3c99aaf65325cd19860968c24e4cf83703e84970..a328d2f526783f59b1144627113109604f27f123 100644 (file)
@@ -1,16 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Emma Mobile EV2 processor support
  *
  * Copyright (C) 2012  Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
index 319ca9508ec63b4f395d4c45cccb1dfe0bba7d0f..14867226f8f46e141fc5cd877fff4ca3d3bc7224 100644 (file)
@@ -1,17 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r7s72100 processor support
  *
  * 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.
  */
 
 #include <linux/kernel.h>
index 20173c4f415ddda4dcb0def623a317214583cab0..23a29a0ea9c96c35fd0c3db3440aefebe0c02603 100644 (file)
@@ -1,17 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a73a4 processor support
  *
  * 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.
  */
 
 #include <linux/init.h>
@@ -26,7 +18,6 @@ static const char *const r8a73a4_boards_compat_dt[] __initconst = {
 };
 
 DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)")
-       .init_early     = shmobile_init_delay,
        .init_late      = shmobile_init_late,
        .dt_compat      = r8a73a4_boards_compat_dt,
 MACHINE_END
index 3849eef0d3a7641820f0dacbd54b838351804dcc..787d039b5a073863c2e655f6ee779c201b2f42d1 100644 (file)
@@ -1,17 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * R8A7740 processor support
  *
  * Copyright (C) 2011  Renesas Solutions Corp.
  * Copyright (C) 2011  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
index 7fa4a0b5f6549287c7db537f36aaabdc48e04093..ce51794f64c7b1dd4a00cbfa5b420251c1fdb581 100644 (file)
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a7778 processor support
  *
  * Copyright (C) 2013  Renesas Solutions Corp.
  * Copyright (C) 2013  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
  * Copyright (C) 2013  Cogent Embedded, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/io.h>
index 0686112f243525b64ba771f31d3e6b93d7b3d9a1..d589326099e01f6dc92cda4c37f5cb267b6ed810 100644 (file)
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * r8a7779 processor support
  *
  * Copyright (C) 2011, 2013  Renesas Solutions Corp.
  * Copyright (C) 2011  Magnus Damm
  * Copyright (C) 2013  Cogent Embedded, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 #include <linux/init.h>
 #include <linux/irq.h>
diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c
deleted file mode 100644 (file)
index 78d3e85..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * r8a7790 processor support
- *
- * 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.
- */
-
-#include <linux/init.h>
-
-#include <asm/mach/arch.h>
-
-#include "common.h"
-#include "r8a7790.h"
-#include "rcar-gen2.h"
-
-static const char * const r8a7790_boards_compat_dt[] __initconst = {
-       "renesas,r8a7790",
-       NULL,
-};
-
-DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)")
-       .smp_init       = smp_init_ops(shmobile_smp_init_fallback_ops),
-       .smp            = smp_ops(r8a7790_smp_ops),
-       .init_early     = shmobile_init_delay,
-       .init_time      = rcar_gen2_timer_init,
-       .init_late      = shmobile_init_late,
-       .reserve        = rcar_gen2_reserve,
-       .dt_compat      = r8a7790_boards_compat_dt,
-MACHINE_END
diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c
deleted file mode 100644 (file)
index 26e2d18..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * r8a7791 processor support
- *
- * Copyright (C) 2013  Renesas Electronics Corporation
- * 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.
- */
-
-#include <linux/init.h>
-
-#include <asm/mach/arch.h>
-
-#include "common.h"
-#include "r8a7791.h"
-#include "rcar-gen2.h"
-
-static const char *const r8a7791_boards_compat_dt[] __initconst = {
-       "renesas,r8a7791",
-       NULL,
-};
-
-DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)")
-       .smp_init       = smp_init_ops(shmobile_smp_init_fallback_ops),
-       .smp            = smp_ops(r8a7791_smp_ops),
-       .init_early     = shmobile_init_delay,
-       .init_time      = rcar_gen2_timer_init,
-       .init_late      = shmobile_init_late,
-       .reserve        = rcar_gen2_reserve,
-       .dt_compat      = r8a7791_boards_compat_dt,
-MACHINE_END
index 88fdc1801d90f9a1ecc7e96516f368bc9c9e898b..013acc97795cbfc48bb99323a3936e1a9de46adc 100644 (file)
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * R-Car Generation 2 support
  *
  * Copyright (C) 2013  Renesas Solutions Corp.
  * Copyright (C) 2013  Magnus Damm
  * Copyright (C) 2014  Ulrich Hecht
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/clk-provider.h>
@@ -67,7 +59,6 @@ static unsigned int __init get_extal_freq(void)
 
 void __init rcar_gen2_timer_init(void)
 {
-#ifdef CONFIG_ARM_ARCH_TIMER
        void __iomem *base;
        u32 freq;
 
@@ -109,7 +100,6 @@ void __init rcar_gen2_timer_init(void)
        }
 
        iounmap(base);
-#endif /* CONFIG_ARM_ARCH_TIMER */
 
        of_clk_init(NULL);
        timer_probe();
@@ -186,10 +176,8 @@ void __init rcar_gen2_reserve(void)
 }
 
 static const char * const rcar_gen2_boards_compat_dt[] __initconst = {
-       /*
-        * R8A7790 and R8A7791 can't be handled here as long as they need SMP
-        * initialization fallback.
-        */
+       "renesas,r8a7790",
+       "renesas,r8a7791",
        "renesas,r8a7792",
        "renesas,r8a7793",
        "renesas,r8a7794",
@@ -197,7 +185,6 @@ static const char * const rcar_gen2_boards_compat_dt[] __initconst = {
 };
 
 DT_MACHINE_START(RCAR_GEN2_DT, "Generic R-Car Gen2 (Flattened Device Tree)")
-       .init_early     = shmobile_init_delay,
        .init_late      = shmobile_init_late,
        .init_time      = rcar_gen2_timer_init,
        .reserve        = rcar_gen2_reserve,
@@ -212,7 +199,6 @@ static const char * const rz_g1_boards_compat_dt[] __initconst = {
 };
 
 DT_MACHINE_START(RZ_G1_DT, "Generic RZ/G1 (Flattened Device Tree)")
-       .init_early     = shmobile_init_delay,
        .init_late      = shmobile_init_late,
        .init_time      = rcar_gen2_timer_init,
        .reserve        = rcar_gen2_reserve,
index a25ff188e403e581352f76a1aaa957f2235a56a7..cc08aa752244764a4dd818a17987137c3a4afd98 100644 (file)
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * sh73a0 processor support
  *
  * Copyright (C) 2010  Takashi Yoshii
  * Copyright (C) 2010  Magnus Damm
  * Copyright (C) 2008  Yoshihiro Shimoda
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
index 3a732199cf5e98c0f5cc625c86c75fb182631513..3853ecea44ca021c533c0168ce38d0889dfe412c 100644 (file)
@@ -1,17 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * SMP support for Emma Mobile EV2
  *
  * Copyright (C) 2012  Renesas Solutions Corp.
  * Copyright (C) 2012  Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
index c6951ee245889b8f79a83018740c0eea910d60dd..0ed73b650c141e589118157777190f42c69570f9 100644 (file)
@@ -1,17 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * SMP support for R-Mobile / SH-Mobile - r8a7779 portion
  *
  * Copyright (C) 2011  Renesas Solutions Corp.
  * Copyright (C) 2011  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.
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
 #define AVECR IOMEM(0xfe700040)
 #define R8A7779_SCU_BASE 0xf0000000
 
-static const struct rcar_sysc_ch r8a7779_ch_cpu1 = {
-       .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
-       .chan_bit = 1, /* ARM1 */
-       .isr_bit = 1, /* ARM1 */
-};
-
-static const struct rcar_sysc_ch r8a7779_ch_cpu2 = {
-       .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
-       .chan_bit = 2, /* ARM2 */
-       .isr_bit = 2, /* ARM2 */
-};
-
-static const struct rcar_sysc_ch r8a7779_ch_cpu3 = {
-       .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
-       .chan_bit = 3, /* ARM3 */
-       .isr_bit = 3, /* ARM3 */
-};
-
-static const struct rcar_sysc_ch * const r8a7779_ch_cpu[4] = {
-       [1] = &r8a7779_ch_cpu1,
-       [2] = &r8a7779_ch_cpu2,
-       [3] = &r8a7779_ch_cpu3,
-};
-
-static int r8a7779_platform_cpu_kill(unsigned int cpu)
+static int r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-       const struct rcar_sysc_ch *ch = NULL;
        int ret = -EIO;
 
        cpu = cpu_logical_map(cpu);
-
-       if (cpu < ARRAY_SIZE(r8a7779_ch_cpu))
-               ch = r8a7779_ch_cpu[cpu];
-
-       if (ch)
-               ret = rcar_sysc_power_down(ch);
-
-       return ret ? ret : 1;
-}
-
-static int r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle)
-{
-       const struct rcar_sysc_ch *ch = NULL;
-       unsigned int lcpu = cpu_logical_map(cpu);
-       int ret;
-
-       if (lcpu < ARRAY_SIZE(r8a7779_ch_cpu))
-               ch = r8a7779_ch_cpu[lcpu];
-
-       if (ch)
-               ret = rcar_sysc_power_up(ch);
-       else
-               ret = -EIO;
+       if (cpu)
+               ret = rcar_sysc_power_up_cpu(cpu);
 
        return ret;
 }
@@ -95,16 +41,20 @@ static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus)
 
        /* setup r8a7779 specific SCU bits */
        shmobile_smp_scu_prepare_cpus(R8A7779_SCU_BASE, max_cpus);
+}
 
-       r8a7779_pm_init();
+#ifdef CONFIG_HOTPLUG_CPU
+static int r8a7779_platform_cpu_kill(unsigned int cpu)
+{
+       int ret = -EIO;
 
-       /* power off secondary CPUs */
-       r8a7779_platform_cpu_kill(1);
-       r8a7779_platform_cpu_kill(2);
-       r8a7779_platform_cpu_kill(3);
+       cpu = cpu_logical_map(cpu);
+       if (cpu)
+               ret = rcar_sysc_power_down_cpu(cpu);
+
+       return ret ? ret : 1;
 }
 
-#ifdef CONFIG_HOTPLUG_CPU
 static int r8a7779_cpu_kill(unsigned int cpu)
 {
        if (shmobile_smp_scu_cpu_kill(cpu))
diff --git a/arch/arm/mach-shmobile/smp-r8a7790.c b/arch/arm/mach-shmobile/smp-r8a7790.c
deleted file mode 100644 (file)
index 28f26d5..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * SMP support for r8a7790
- *
- * Copyright (C) 2012-2013 Renesas Solutions Corp.
- * Copyright (C) 2012 Takashi Yoshii <takashi.yoshii.ze@renesas.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/io.h>
-#include <linux/soc/renesas/rcar-sysc.h>
-
-#include <asm/smp_plat.h>
-
-#include "common.h"
-#include "platsmp-apmu.h"
-#include "rcar-gen2.h"
-#include "r8a7790.h"
-
-static const struct rcar_sysc_ch r8a7790_ca15_scu = {
-       .chan_offs = 0x180, /* PWRSR5 .. PWRER5 */
-       .isr_bit = 12, /* CA15-SCU */
-};
-
-static const struct rcar_sysc_ch r8a7790_ca7_scu = {
-       .chan_offs = 0x100, /* PWRSR3 .. PWRER3 */
-       .isr_bit = 21, /* CA7-SCU */
-};
-
-static struct rcar_apmu_config r8a7790_apmu_config[] = {
-       {
-               .iomem = DEFINE_RES_MEM(0xe6152000, 0x188),
-               .cpus = { 0, 1, 2, 3 },
-       },
-       {
-               .iomem = DEFINE_RES_MEM(0xe6151000, 0x188),
-               .cpus = { 0x100, 0x0101, 0x102, 0x103 },
-       }
-};
-
-static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus)
-{
-       /* let APMU code install data related to shmobile_boot_vector */
-       shmobile_smp_apmu_prepare_cpus(max_cpus,
-                                      r8a7790_apmu_config,
-                                      ARRAY_SIZE(r8a7790_apmu_config));
-
-       /* turn on power to SCU */
-       rcar_gen2_pm_init();
-       rcar_sysc_power_up(&r8a7790_ca15_scu);
-       rcar_sysc_power_up(&r8a7790_ca7_scu);
-}
-
-const struct smp_operations r8a7790_smp_ops __initconst = {
-       .smp_prepare_cpus       = r8a7790_smp_prepare_cpus,
-       .smp_boot_secondary     = shmobile_smp_apmu_boot_secondary,
-#ifdef CONFIG_HOTPLUG_CPU
-       .cpu_can_disable        = shmobile_smp_cpu_can_disable,
-       .cpu_die                = shmobile_smp_apmu_cpu_die,
-       .cpu_kill               = shmobile_smp_apmu_cpu_kill,
-#endif
-};
diff --git a/arch/arm/mach-shmobile/smp-r8a7791.c b/arch/arm/mach-shmobile/smp-r8a7791.c
deleted file mode 100644 (file)
index 2948c22..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * SMP support for r8a7791
- *
- * 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.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/io.h>
-
-#include <asm/smp_plat.h>
-
-#include "common.h"
-#include "platsmp-apmu.h"
-#include "r8a7791.h"
-#include "rcar-gen2.h"
-
-static struct rcar_apmu_config r8a7791_apmu_config[] = {
-       {
-               .iomem = DEFINE_RES_MEM(0xe6152000, 0x188),
-               .cpus = { 0, 1 },
-       }
-};
-
-static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus)
-{
-       /* let APMU code install data related to shmobile_boot_vector */
-       shmobile_smp_apmu_prepare_cpus(max_cpus,
-                                      r8a7791_apmu_config,
-                                      ARRAY_SIZE(r8a7791_apmu_config));
-
-       rcar_gen2_pm_init();
-}
-
-const struct smp_operations r8a7791_smp_ops __initconst = {
-       .smp_prepare_cpus       = r8a7791_smp_prepare_cpus,
-       .smp_boot_secondary     = shmobile_smp_apmu_boot_secondary,
-#ifdef CONFIG_HOTPLUG_CPU
-       .cpu_can_disable        = shmobile_smp_cpu_can_disable,
-       .cpu_die                = shmobile_smp_apmu_cpu_die,
-       .cpu_kill               = shmobile_smp_apmu_cpu_kill,
-#endif
-};
index 6196a638038530481da95f6938bdf8198c56c880..828e8aea037e7d5e8ba1483d272756b389828a70 100644 (file)
@@ -32,14 +32,6 @@ void __init shmobile_init_delay(void)
        for_each_child_of_node(cpus, np) {
                u32 freq;
 
-               if (IS_ENABLED(CONFIG_ARM_ARCH_TIMER) &&
-                   (of_device_is_compatible(np, "arm,cortex-a7") ||
-                    of_device_is_compatible(np, "arm,cortex-a15"))) {
-                       of_node_put(np);
-                       of_node_put(cpus);
-                       return;
-               }
-
                if (!of_property_read_u32(np, "clock-frequency", &freq))
                        max_freq = max(max_freq, freq);
        }
index 779235a9147d0d7c266f17862fe136e4db55deee..e661d2626675128c3e0f0d54e786b63115dd9038 100644 (file)
@@ -9,6 +9,7 @@ config ARCH_UNIPHIER
        select HAVE_ARM_SCU
        select HAVE_ARM_TWD if SMP
        select PINCTRL
+       select RESET_CONTROLLER
        help
          Support for UniPhier SoC family developed by Socionext Inc.
          (formerly, System LSI Business Division of Panasonic Corporation)
diff --git a/arch/arm/mach-uniphier/Makefile b/arch/arm/mach-uniphier/Makefile
deleted file mode 100644 (file)
index e69de29..0000000
index d1329f1ba4e4c322059604f6d81f51585eed00d0..bf992264060ef6300a8d856caafbadbb1ff97126 100644 (file)
@@ -32,7 +32,7 @@ bool is_swbp_insn(uprobe_opcode_t *insn)
 int set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm,
             unsigned long vaddr)
 {
-       return uprobe_write_opcode(mm, vaddr,
+       return uprobe_write_opcode(auprobe, mm, vaddr,
                   __opcode_to_mem_arm(auprobe->bpinsn));
 }
 
index d0a53cc6293a3d3c288ffc1f9809d90fe439cea2..1b1a0e95c7511b9256f1953c00d0ca32994b2160 100644 (file)
@@ -108,6 +108,7 @@ config ARM64
        select HAVE_ARCH_KGDB
        select HAVE_ARCH_MMAP_RND_BITS
        select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
+       select HAVE_ARCH_PREL32_RELOCATIONS
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_STACKLEAK
        select HAVE_ARCH_THREAD_STRUCT_WHITELIST
@@ -762,7 +763,6 @@ config NEED_PER_CPU_EMBED_FIRST_CHUNK
 
 config HOLES_IN_ZONE
        def_bool y
-       depends on NUMA
 
 source kernel/Kconfig.hz
 
index d5aeac351fc3a776ee840f09680f43a864b5307c..393d2b524284e79ab4a344779089432eb4ef31bd 100644 (file)
@@ -71,6 +71,13 @@ config ARCH_EXYNOS
        help
          This enables support for ARMv8 based Samsung Exynos SoC family.
 
+config ARCH_K3
+       bool "Texas Instruments Inc. K3 multicore SoC architecture"
+       select PM_GENERIC_DOMAINS if PM
+       help
+         This enables support for Texas Instruments' K3 multicore SoC
+         architecture.
+
 config ARCH_LAYERSCAPE
        bool "ARMv8 based Freescale Layerscape SoC family"
        select EDAC_SUPPORT
@@ -151,6 +158,7 @@ config ARCH_ROCKCHIP
        select GPIOLIB
        select PINCTRL
        select PINCTRL_ROCKCHIP
+       select PM
        select ROCKCHIP_TIMER
        help
          This enables support for the ARMv8 based Rockchip chipsets,
@@ -261,6 +269,7 @@ config ARCH_UNIPHIER
        bool "Socionext UniPhier SoC Family"
        select ARCH_HAS_RESET_CONTROLLER
        select PINCTRL
+       select RESET_CONTROLLER
        help
          This enables support for Socionext UniPhier SoC family.
 
index efe61a2e4b5e0a0c5dbcb18c39c8de100941cd04..106039d25e2f7a708b81db27d7c95ae82aaa54dc 100644 (file)
@@ -62,14 +62,14 @@ CHECKFLAGS  += -D__AARCH64EB__
 AS             += -EB
 # Prefer the baremetal ELF build target, but not all toolchains include
 # it so fall back to the standard linux version if needed.
-LDFLAGS                += -EB $(call ld-option, -maarch64elfb, -maarch64linuxb)
+KBUILD_LDFLAGS += -EB $(call ld-option, -maarch64elfb, -maarch64linuxb)
 UTS_MACHINE    := aarch64_be
 else
 KBUILD_CPPFLAGS        += -mlittle-endian
 CHECKFLAGS     += -D__AARCH64EL__
 AS             += -EL
 # Same as above, prefer ELF but fall back to linux target if needed.
-LDFLAGS                += -EL $(call ld-option, -maarch64elf, -maarch64linux)
+KBUILD_LDFLAGS += -EL $(call ld-option, -maarch64elf, -maarch64linux)
 UTS_MACHINE    := aarch64
 endif
 
index 3543bc32455339cf22d7ca70f2aef5a3de159cba..4690364d584bf4e6a9bf43e8b8788fb8b1c5f0cf 100644 (file)
@@ -23,5 +23,6 @@ subdir-y += rockchip
 subdir-y += socionext
 subdir-y += sprd
 subdir-y += synaptics
+subdir-y += ti
 subdir-y += xilinx
 subdir-y += zte
index c31f90a494810d2ac9ef89fdd2bb4413ccb7da5e..9ffa7a038791eb26aacd9d02a528fba224f4571c 100644 (file)
@@ -1,9 +1,11 @@
 # SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-amarula-relic.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-bananapi-m64.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-nanopi-a64.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-olinuxino.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-orangepi-win.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-plus.dtb sun50i-a64-pine64.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinebook.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-libretech-all-h3-cc.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts
new file mode 100644 (file)
index 0000000..eac4793
--- /dev/null
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 Amarula Solutions B.V.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+/dts-v1/;
+
+#include "sun50i-a64.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       model = "Amarula A64-Relic";
+       compatible = "amarula,a64-relic", "allwinner,sun50i-a64";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       wifi_pwrseq: wifi-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               clocks = <&rtc 1>;
+               clock-names = "ext_clock";
+               reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* WL-PMU-EN: PL2 */
+       };
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&mmc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       vmmc-supply = <&reg_dcdc1>;
+       /*
+        * Schematic shows both dldo4 and eldo1 connected for vcc-io-wifi, but
+        * dldo4 connection shows DNP(Do Not Populate) and eldo1 connected with
+        * 0Ohm register to vcc-io-wifi so eldo1 is used.
+        */
+       vqmmc-supply = <&reg_eldo1>;
+       mmc-pwrseq = <&wifi_pwrseq>;
+       bus-width = <4>;
+       non-removable;
+       status = "okay";
+
+       brcmf: wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+               interrupt-parent = <&r_pio>;
+               interrupts = <0 3 IRQ_TYPE_LEVEL_LOW>;  /* WL-WAKE-AP: PL3 */
+               interrupt-names = "host-wake";
+       };
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins>;
+       vmmc-supply = <&reg_dcdc1>;
+       bus-width = <8>;
+       non-removable;
+       cap-mmc-hw-reset;
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
+
+&r_rsb {
+       status = "okay";
+
+       axp803: pmic@3a3 {
+               compatible = "x-powers,axp803";
+               reg = <0x3a3>;
+               interrupt-parent = <&r_intc>;
+               interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+               x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */
+       };
+};
+
+#include "axp803.dtsi"
+
+&reg_aldo1 {
+       regulator-always-on;
+       regulator-min-microvolt = <2800000>;
+       regulator-max-microvolt = <2800000>;
+       regulator-name = "avdd-csi";
+};
+
+&reg_aldo2 {
+       regulator-always-on;
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "vcc-pl";
+};
+
+&reg_aldo3 {
+       regulator-always-on;
+       regulator-min-microvolt = <3000000>;
+       regulator-max-microvolt = <3000000>;
+       regulator-name = "vcc-pll-avcc";
+};
+
+&reg_dcdc1 {
+       regulator-always-on;
+       regulator-min-microvolt = <3300000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "vcc-3v3";
+};
+
+&reg_dcdc2 {
+       regulator-always-on;
+       regulator-min-microvolt = <1040000>;
+       regulator-max-microvolt = <1300000>;
+       regulator-name = "vdd-cpux";
+};
+
+/* DCDC3 is polyphased with DCDC2 */
+
+&reg_dcdc5 {
+       regulator-always-on;
+       regulator-min-microvolt = <1500000>;
+       regulator-max-microvolt = <1500000>;
+       regulator-name = "vcc-dram";
+};
+
+&reg_dcdc6 {
+       regulator-always-on;
+       regulator-min-microvolt = <1100000>;
+       regulator-max-microvolt = <1100000>;
+       regulator-name = "vdd-sys";
+};
+
+&reg_dldo1 {
+       regulator-min-microvolt = <3300000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "vcc-hdmi-dsi-sensor";
+};
+
+&reg_dldo2 {
+       regulator-min-microvolt = <3300000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "vcc-mipi";
+};
+
+&reg_dldo3 {
+       regulator-min-microvolt = <2800000>;
+       regulator-max-microvolt = <2800000>;
+       regulator-name = "dovdd-csi";
+};
+
+&reg_dldo4 {
+       regulator-min-microvolt = <3300000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "vcc-wifi-io";
+};
+
+&reg_drivevbus {
+       regulator-name = "usb0-vbus";
+       status = "okay";
+};
+
+&reg_eldo1 {
+       regulator-always-on;
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <1800000>;
+       regulator-name = "cpvdd";
+};
+
+&reg_eldo3 {
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <1800000>;
+       regulator-name = "dvdd-csi";
+};
+
+&reg_fldo1 {
+       regulator-min-microvolt = <1200000>;
+       regulator-max-microvolt = <1200000>;
+       regulator-name = "vcc-1v2-hsic";
+};
+
+/*
+ * The A64 chip cannot work without this regulator off, although
+ * it seems to be only driving the AR100 core.
+ * Maybe we don't still know well about CPUs domain.
+ */
+&reg_fldo2 {
+       regulator-always-on;
+       regulator-min-microvolt = <1100000>;
+       regulator-max-microvolt = <1100000>;
+       regulator-name = "vdd-cpus";
+};
+
+&reg_rtc_ldo {
+       regulator-name = "vcc-rtc";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins_a>;
+       status = "okay";
+};
+
+&usb_otg {
+       dr_mode = "otg";
+       status = "okay";
+};
+
+&usbphy {
+       usb0_id_det-gpios = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */
+       usb0_vbus-supply = <&reg_drivevbus>;
+       status = "okay";
+};
index 0716b144118775df150f19010549a141c18e744f..094cfed13df97aa35e58ec6e06dc86fcbc18767a 100644 (file)
        regulator-name = "vcc-rtc";
 };
 
+&simplefb_hdmi {
+       vcc-hdmi-supply = <&reg_dldo1>;
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_pins_a>;
index e2dce48fa29a096e8d9a155aeec64d9fcb9d685f..98dbff19f5cccd6db3711cbe611f2fe3f0f8128f 100644 (file)
        regulator-name = "vcc-rtc";
 };
 
+&simplefb_hdmi {
+       vcc-hdmi-supply = <&reg_dldo1>;
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_pins_a>;
index 3b3081b10ecbef973219e8830a33d9fd40aa5e5d..3f531393eaee9a8cbae54ad5e1f5fd0e1b3aafbb 100644 (file)
        regulator-name = "vcc-rtc";
 };
 
+&simplefb_hdmi {
+       vcc-hdmi-supply = <&reg_dldo1>;
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_pins_a>;
index bf42690a3361e51f148f343eb1c9b9fa30251b9d..1221764f5719cfe19a97b63c440ff8465e2b5dec 100644 (file)
        regulator-name = "vcc-rtc";
 };
 
+&simplefb_hdmi {
+       vcc-hdmi-supply = <&reg_dldo1>;
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_pins_a>;
index a75825798a7174e9cc85d17171f400f8e3cdcabd..1b9b92e541d2d7348225a38dd49dd45202687356 100644 (file)
        regulator-name = "vcc-rtc";
 };
 
+&simplefb_hdmi {
+       vcc-hdmi-supply = <&reg_dldo1>;
+};
+
 /* On Euler connector */
 &spdif {
        status = "disabled";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
new file mode 100644 (file)
index 0000000..897e60c
--- /dev/null
@@ -0,0 +1,285 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.xyz>
+ * Copyright (C) 2018 Vasily Khoruzhick <anarsoul@gmail.com>
+ *
+ */
+
+/dts-v1/;
+
+#include "sun50i-a64.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+       model = "Pinebook";
+       compatible = "pine64,pinebook", "allwinner,sun50i-a64";
+
+       aliases {
+               serial0 = &uart0;
+               ethernet0 = &rtl8723cs;
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm 0 50000 0>;
+               brightness-levels = <0 5 10 15 20 30 40 55 70 85 100>;
+               default-brightness-level = <2>;
+               enable-gpios = <&pio 3 23 GPIO_ACTIVE_HIGH>; /* PD23 */
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+
+               framebuffer-lcd {
+                       panel-supply = <&reg_dc1sw>;
+                       dvdd25-supply = <&reg_dldo2>;
+                       dvdd12-supply = <&reg_fldo1>;
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+
+               lid_switch {
+                       label = "Lid Switch";
+                       gpios = <&r_pio 0 12 GPIO_ACTIVE_LOW>; /* PL12 */
+                       linux,input-type = <EV_SW>;
+                       linux,code = <SW_LID>;
+                       linux,can-disable;
+                       wakeup-source;
+               };
+       };
+
+       reg_vcc3v3: vcc3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       wifi_pwrseq: wifi_pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
+       };
+};
+
+&ehci0 {
+       phys = <&usbphy 0>;
+       phy-names = "usb";
+       status = "okay";
+};
+
+&ehci1 {
+       status = "okay";
+};
+
+&mmc0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc0_pins>;
+       vmmc-supply = <&reg_dcdc1>;
+       cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
+       cd-inverted;
+       disable-wp;
+       bus-width = <4>;
+       status = "okay";
+};
+
+&mmc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       vmmc-supply = <&reg_dldo4>;
+       vqmmc-supply = <&reg_eldo1>;
+       mmc-pwrseq = <&wifi_pwrseq>;
+       bus-width = <4>;
+       non-removable;
+       status = "okay";
+
+       rtl8723cs: wifi@1 {
+               reg = <1>;
+       };
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins>;
+       vmmc-supply = <&reg_dcdc1>;
+       vqmmc-supply = <&reg_eldo1>;
+       bus-width = <8>;
+       non-removable;
+       cap-mmc-hw-reset;
+       mmc-hs200-1_8v;
+       status = "okay";
+};
+
+&ohci0 {
+       phys = <&usbphy 0>;
+       phy-names = "usb";
+       status = "okay";
+};
+
+&ohci1 {
+       status = "okay";
+};
+
+&pwm {
+       status = "okay";
+};
+
+&r_rsb {
+       status = "okay";
+
+       axp803: pmic@3a3 {
+               compatible = "x-powers,axp803";
+               reg = <0x3a3>;
+               interrupt-parent = <&r_intc>;
+               interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+       };
+};
+
+/* The ANX6345 eDP-bridge is on r_i2c */
+&r_i2c {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&r_i2c_pins_a>;
+       status = "okay";
+};
+
+#include "axp803.dtsi"
+
+&reg_aldo1 {
+       regulator-min-microvolt = <2800000>;
+       regulator-max-microvolt = <2800000>;
+       regulator-name = "vcc-csi";
+};
+
+&reg_aldo2 {
+       regulator-always-on;
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "vcc-pl";
+};
+
+&reg_aldo3 {
+       regulator-always-on;
+       regulator-min-microvolt = <2700000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "vcc-pll-avcc";
+};
+
+&reg_dc1sw {
+       regulator-name = "vcc-lcd";
+};
+
+&reg_dcdc1 {
+       regulator-always-on;
+       regulator-min-microvolt = <3300000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "vcc-3v3";
+};
+
+&reg_dcdc2 {
+       regulator-always-on;
+       regulator-min-microvolt = <1000000>;
+       regulator-max-microvolt = <1300000>;
+       regulator-name = "vdd-cpux";
+};
+
+/* DCDC3 is polyphased with DCDC2 */
+
+&reg_dcdc5 {
+       regulator-always-on;
+       regulator-min-microvolt = <1200000>;
+       regulator-max-microvolt = <1200000>;
+       regulator-name = "vcc-dram";
+};
+
+&reg_dcdc6 {
+       regulator-always-on;
+       regulator-min-microvolt = <1100000>;
+       regulator-max-microvolt = <1100000>;
+       regulator-name = "vdd-sys";
+};
+
+&reg_dldo1 {
+       regulator-min-microvolt = <3300000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "vcc-hdmi";
+};
+
+&reg_dldo2 {
+       regulator-min-microvolt = <2500000>;
+       regulator-max-microvolt = <2500000>;
+       regulator-name = "vcc-edp";
+};
+
+&reg_dldo3 {
+       regulator-min-microvolt = <3300000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "avdd-csi";
+};
+
+&reg_dldo4 {
+       regulator-min-microvolt = <3300000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "vcc-wifi";
+};
+
+&reg_eldo1 {
+       regulator-always-on;
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <1800000>;
+       regulator-name = "cpvdd";
+};
+
+&reg_eldo3 {
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <1800000>;
+       regulator-name = "vdd-1v8-csi";
+};
+
+&reg_fldo1 {
+       regulator-min-microvolt = <1200000>;
+       regulator-max-microvolt = <1200000>;
+       regulator-name = "vcc-1v2-hsic";
+};
+
+&reg_fldo2 {
+       regulator-always-on;
+       regulator-min-microvolt = <1100000>;
+       regulator-max-microvolt = <1100000>;
+       regulator-name = "vdd-cpus";
+};
+
+&reg_ldo_io0 {
+       regulator-min-microvolt = <3300000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "vcc-usb";
+       status = "okay";
+};
+
+&reg_rtc_ldo {
+       regulator-name = "vcc-rtc";
+};
+
+&simplefb_hdmi {
+       vcc-hdmi-supply = <&reg_dldo1>;
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins_a>;
+       status = "okay";
+};
+
+&usb_otg {
+       dr_mode = "host";
+};
+
+&usbphy {
+       usb0_vbus-supply = <&reg_ldo_io0>;
+       usb1_vbus-supply = <&reg_ldo_io0>;
+       status = "okay";
+};
index abe179de35d780cc1d3691394d465817dad30549..c21f2331add60255d0cb97b49319a3e30c22d354 100644 (file)
        regulator-name = "vcc-wifi";
 };
 
+&simplefb_hdmi {
+       vcc-hdmi-supply = <&reg_dldo1>;
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_pins_a>;
index 43418bd881d81e73da7634fa6ff62c11d64b65ef..6723b8695e0bbc4f0f3e8a9c99dae81bf3835142 100644 (file)
@@ -45,6 +45,8 @@
 
 #include "sun50i-a64.dtsi"
 
+#include <dt-bindings/gpio/gpio.h>
+
 &mmc0 {
        pinctrl-names = "default";
        pinctrl-0 = <&mmc0_pins>;
@@ -52,6 +54,7 @@
        non-removable;
        disable-wp;
        bus-width = <4>;
+       cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
        status = "okay";
 };
 
        };
 };
 
+&spi0  {
+       status = "okay";
+
+       flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <40000000>;
+       };
+};
+
 #include "axp803.dtsi"
 
 &reg_aldo2 {
index d9baab3dc96bda014262a99fe44b7af9c2624a7b..81f8e0098699e89ec3f9b56405aa5f1509957ab1 100644 (file)
@@ -38,6 +38,7 @@
                        gpios = <&r_pio 0 8 GPIO_ACTIVE_LOW>; /* PL8 */
                        linux,input-type = <EV_SW>;
                        linux,code = <SW_LID>;
+                       wakeup-source;
                };
        };
 
 &reg_dldo3 {
        regulator-min-microvolt = <1200000>;
        regulator-max-microvolt = <1200000>;
-       regulator-name = "eDP12";
+       regulator-name = "vdd-edp";
 };
 
 &reg_dldo4 {
        regulator-name = "vcc-rtc";
 };
 
+&simplefb_hdmi {
+       vcc-hdmi-supply = <&reg_dldo1>;
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_pins_a>;
index 1b2ef28c42bd1eaf2c37557b2b27d90ff1d86d8c..d3daf90a8715c50b844eb6e6f577aeb2c756991b 100644 (file)
  */
 
 #include <dt-bindings/clock/sun50i-a64-ccu.h>
+#include <dt-bindings/clock/sun8i-de2.h>
 #include <dt-bindings/clock/sun8i-r-ccu.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/reset/sun50i-a64-ccu.h>
+#include <dt-bindings/reset/sun8i-de2.h>
+#include <dt-bindings/reset/sun8i-r-ccu.h>
 
 / {
        interrupt-parent = <&gic>;
                #size-cells = <1>;
                ranges;
 
-/*
- * The pipeline mixer0-lcd0 depends on clock CLK_MIXER0 from DE2 CCU.
- * However there is no support for this clock on A64 yet, so we depend
- * on the upstream clocks here to keep them (and thus CLK_MIXER0) up.
- */
                simplefb_lcd: framebuffer-lcd {
                        compatible = "allwinner,simple-framebuffer",
                                     "simple-framebuffer";
                        allwinner,pipeline = "mixer0-lcd0";
                        clocks = <&ccu CLK_TCON0>,
-                                <&ccu CLK_DE>, <&ccu CLK_BUS_DE>;
+                                <&display_clocks CLK_MIXER0>;
+                       status = "disabled";
+               };
+
+               simplefb_hdmi: framebuffer-hdmi {
+                       compatible = "allwinner,simple-framebuffer",
+                                    "simple-framebuffer";
+                       allwinner,pipeline = "mixer1-lcd1-hdmi";
+                       clocks = <&display_clocks CLK_MIXER1>,
+                                <&ccu CLK_TCON1>, <&ccu CLK_HDMI>;
                        status = "disabled";
                };
        };
                #size-cells = <1>;
                ranges;
 
+               de2@1000000 {
+                       compatible = "allwinner,sun50i-a64-de2";
+                       reg = <0x1000000 0x400000>;
+                       allwinner,sram = <&de2_sram 1>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x1000000 0x400000>;
+
+                       display_clocks: clock@0 {
+                               compatible = "allwinner,sun50i-a64-de2-clk";
+                               reg = <0x0 0x100000>;
+                               clocks = <&ccu CLK_DE>,
+                                        <&ccu CLK_BUS_DE>;
+                               clock-names = "mod",
+                                             "bus";
+                               resets = <&ccu RST_BUS_DE>;
+                               #clock-cells = <1>;
+                               #reset-cells = <1>;
+                       };
+               };
+
                syscon: syscon@1c00000 {
-                       compatible = "allwinner,sun50i-a64-system-controller",
-                               "syscon";
+                       compatible = "allwinner,sun50i-a64-system-control";
                        reg = <0x01c00000 0x1000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       sram_c: sram@18000 {
+                               compatible = "mmio-sram";
+                               reg = <0x00018000 0x28000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x00018000 0x28000>;
+
+                               de2_sram: sram-section@0 {
+                                       compatible = "allwinner,sun50i-a64-sram-c";
+                                       reg = <0x0000 0x28000>;
+                               };
+                       };
                };
 
                dma: dma-controller@1c02000 {
                                bias-pull-up;
                        };
 
+                       pwm_pin: pwm_pin {
+                               pins = "PD22";
+                               function = "pwm";
+                       };
+
                        rmii_pins: rmii_pins {
                                pins = "PD10", "PD11", "PD13", "PD14", "PD17",
                                       "PD18", "PD19", "PD20", "PD22", "PD23";
                        clocks = <&ccu CLK_BUS_EMAC>;
                        clock-names = "stmmaceth";
                        status = "disabled";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
 
                        mdio: mdio {
                                compatible = "snps,dwmac-mdio";
                        #interrupt-cells = <3>;
                };
 
+               pwm: pwm@1c21400 {
+                       compatible = "allwinner,sun50i-a64-pwm",
+                                    "allwinner,sun5i-a13-pwm";
+                       reg = <0x01c21400 0x400>;
+                       clocks = <&osc24M>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pwm_pin>;
+                       #pwm-cells = <3>;
+                       status = "disabled";
+               };
+
                rtc: rtc@1f00000 {
                        compatible = "allwinner,sun6i-a31-rtc";
                        reg = <0x01f00000 0x54>;
                        interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-output-names = "rtc-osc32k", "rtc-osc32k-out";
+                       clocks = <&osc32k>;
+                       #clock-cells = <1>;
                };
 
                r_intc: interrupt-controller@1f00c00 {
                        #reset-cells = <1>;
                };
 
+               r_i2c: i2c@1f02400 {
+                       compatible = "allwinner,sun50i-a64-i2c",
+                                    "allwinner,sun6i-a31-i2c";
+                       reg = <0x01f02400 0x400>;
+                       interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&r_ccu CLK_APB0_I2C>;
+                       resets = <&r_ccu RST_APB0_I2C>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               r_pwm: pwm@1f03800 {
+                       compatible = "allwinner,sun50i-a64-pwm",
+                                    "allwinner,sun5i-a13-pwm";
+                       reg = <0x01f03800 0x400>;
+                       clocks = <&osc24M>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&r_pwm_pin>;
+                       #pwm-cells = <3>;
+                       status = "disabled";
+               };
+
                r_pio: pinctrl@1f02c00 {
                        compatible = "allwinner,sun50i-a64-r-pinctrl";
                        reg = <0x01f02c00 0x400>;
                        interrupt-controller;
                        #interrupt-cells = <3>;
 
+                       r_i2c_pins_a: i2c-a {
+                               pins = "PL8", "PL9";
+                               function = "s_i2c";
+                       };
+
+                       r_pwm_pin: pwm {
+                               pins = "PL10";
+                               function = "s_pwm";
+                       };
+
                        r_rsb_pins: rsb {
                                pins = "PL0", "PL1";
                                function = "s_rsb";
index 98862c7c7258ebb6677bdbb856b707a7b1126a99..3e0d5a9c096d37cdc878d07aadb79cee4009b972 100644 (file)
        status = "okay";
 };
 
+&spi0  {
+       status = "okay";
+
+       flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <40000000>;
+       };
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_pins_a>;
index b6f2d6b2ecaea7afd40ba3da6d27b94ffc8b10fb..48daec7f78ba7cf4e674687fca73ed976c3b5b4b 100644 (file)
        chosen {
                stdout-path = "serial0:115200n8";
        };
+
+       leds {
+               compatible = "gpio-leds";
+
+               heartbeat {
+                       label = "pine-h64:green:heartbeat";
+                       gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */
+               };
+
+               link {
+                       label = "pine-h64:white:link";
+                       gpios = <&r_pio 0 3 GPIO_ACTIVE_HIGH>; /* PL3 */
+               };
+
+               status {
+                       label = "pine-h64:blue:status";
+                       gpios = <&r_pio 0 7 GPIO_ACTIVE_HIGH>; /* PL7 */
+               };
+       };
+};
+
+&mmc0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc0_pins>;
+       vmmc-supply = <&reg_cldo1>;
+       cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
+       bus-width = <4>;
+       status = "okay";
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins>;
+       vmmc-supply = <&reg_cldo1>;
+       vqmmc-supply = <&reg_bldo2>;
+       non-removable;
+       cap-mmc-hw-reset;
+       bus-width = <8>;
+       status = "okay";
 };
 
 &r_i2c {
        status = "okay";
 
+       axp805: pmic@36 {
+               compatible = "x-powers,axp805", "x-powers,axp806";
+               reg = <0x36>;
+               interrupt-parent = <&r_intc>;
+               interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               x-powers,self-working-mode;
+
+               regulators {
+                       reg_aldo1: aldo1 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc-pl";
+                       };
+
+                       reg_aldo2: aldo2 {
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc-ac200";
+                       };
+
+                       reg_aldo3: aldo3 {
+                               /* This regulator is connected with CLDO1 */
+                               regulator-always-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc-3v3-1";
+                       };
+
+                       reg_bldo1: bldo1 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc-bias-pll";
+                       };
+
+                       reg_bldo2: bldo2 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc-efuse-pcie-hdmi-io";
+                       };
+
+                       reg_bldo3: bldo3 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc-dcxoio";
+                       };
+
+                       bldo4 {
+                               /* unused */
+                       };
+
+                       reg_cldo1: cldo1 {
+                               /* This regulator is connected with ALDO3 */
+                               regulator-always-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc-3v3-2";
+                       };
+
+                       reg_cldo2: cldo2 {
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc-wifi-1";
+                       };
+
+                       reg_cldo3: cldo3 {
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc-wifi-2";
+                       };
+
+                       reg_dcdca: dcdca {
+                               regulator-always-on;
+                               regulator-min-microvolt = <810000>;
+                               regulator-max-microvolt = <1080000>;
+                               regulator-name = "vdd-cpu";
+                       };
+
+                       reg_dcdcc: dcdcc {
+                               regulator-min-microvolt = <810000>;
+                               regulator-max-microvolt = <1080000>;
+                               regulator-name = "vdd-gpu";
+                       };
+
+                       reg_dcdcd: dcdcd {
+                               regulator-always-on;
+                               regulator-min-microvolt = <960000>;
+                               regulator-max-microvolt = <960000>;
+                               regulator-name = "vdd-sys";
+                       };
+
+                       reg_dcdce: dcdce {
+                               regulator-always-on;
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-name = "vcc-dram";
+                       };
+
+                       sw {
+                               /* unused */
+                       };
+               };
+       };
+
        pcf8563: rtc@51 {
                compatible = "nxp,pcf8563";
                reg = <0x51>;
index c72da8cd9ef5881eceedcf8390fbcda620c5cac9..cfa5fffcf62b437c60a9fde4b601767ecc7548b3 100644 (file)
@@ -5,7 +5,9 @@
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/sun50i-h6-ccu.h>
+#include <dt-bindings/clock/sun50i-h6-r-ccu.h>
 #include <dt-bindings/reset/sun50i-h6-ccu.h>
+#include <dt-bindings/reset/sun50i-h6-r-ccu.h>
 
 / {
        interrupt-parent = <&gic>;
                        interrupt-controller;
                        #interrupt-cells = <3>;
 
+                       mmc0_pins: mmc0-pins {
+                               pins = "PF0", "PF1", "PF2", "PF3",
+                                      "PF4", "PF5";
+                               function = "mmc0";
+                               drive-strength = <30>;
+                               bias-pull-up;
+                       };
+
+                       mmc2_pins: mmc2-pins {
+                               pins = "PC1", "PC4", "PC5", "PC6",
+                                      "PC7", "PC8", "PC9", "PC10",
+                                      "PC11", "PC12", "PC13", "PC14";
+                               function = "mmc2";
+                               drive-strength = <30>;
+                               bias-pull-up;
+                       };
+
                        uart0_ph_pins: uart0-ph {
                                pins = "PH0", "PH1";
                                function = "uart0";
                        };
                };
 
+               mmc0: mmc@4020000 {
+                       compatible = "allwinner,sun50i-h6-mmc",
+                                    "allwinner,sun50i-a64-mmc";
+                       reg = <0x04020000 0x1000>;
+                       clocks = <&ccu CLK_BUS_MMC0>, <&ccu CLK_MMC0>;
+                       clock-names = "ahb", "mmc";
+                       resets = <&ccu RST_BUS_MMC0>;
+                       reset-names = "ahb";
+                       interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               mmc1: mmc@4021000 {
+                       compatible = "allwinner,sun50i-h6-mmc",
+                                    "allwinner,sun50i-a64-mmc";
+                       reg = <0x04021000 0x1000>;
+                       clocks = <&ccu CLK_BUS_MMC1>, <&ccu CLK_MMC1>;
+                       clock-names = "ahb", "mmc";
+                       resets = <&ccu RST_BUS_MMC1>;
+                       reset-names = "ahb";
+                       interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               mmc2: mmc@4022000 {
+                       compatible = "allwinner,sun50i-h6-emmc",
+                                    "allwinner,sun50i-a64-emmc";
+                       reg = <0x04022000 0x1000>;
+                       clocks = <&ccu CLK_BUS_MMC2>, <&ccu CLK_MMC2>;
+                       clock-names = "ahb", "mmc";
+                       resets = <&ccu RST_BUS_MMC2>;
+                       reset-names = "ahb";
+                       interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
                uart0: serial@5000000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x05000000 0x400>;
                        reg = <0x07022000 0x400>;
                        interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&r_ccu 2>, <&osc24M>, <&osc32k>;
+                       clocks = <&r_ccu CLK_R_APB1>, <&osc24M>, <&osc32k>;
                        clock-names = "apb", "hosc", "losc";
                        gpio-controller;
                        #gpio-cells = <3>;
                        compatible = "allwinner,sun6i-a31-i2c";
                        reg = <0x07081400 0x400>;
                        interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&r_ccu 8>;
-                       resets = <&r_ccu 4>;
+                       clocks = <&r_ccu CLK_R_APB2_I2C>;
+                       resets = <&r_ccu RST_R_APB2_I2C>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&r_i2c_pins>;
                        status = "disabled";
index 67dac595dc72ebdeffcd5b6bffd50d115cce8cbc..d033da401c268a79290708569a3ba92566657edd 100644 (file)
                                #clock-cells = <0>;
                                compatible = "fixed-clock";
                        };
+
+                       qspi_clk: qspi-clk {
+                               #clock-cells = <0>;
+                               compatible = "fixed-clock";
+                               clock-frequency = <200000000>;
+                       };
                };
 
                gmac0: ethernet@ff800000 {
                        interrupts = <0 90 4>;
                        interrupt-names = "macirq";
                        mac-address = [00 00 00 00 00 00];
-                       resets = <&rst EMAC0_RESET>;
-                       reset-names = "stmmaceth";
+                       resets = <&rst EMAC0_RESET>, <&rst EMAC0_OCP_RESET>;
+                       reset-names = "stmmaceth", "stmmaceth-ocp";
                        clocks = <&clkmgr STRATIX10_EMAC0_CLK>;
                        clock-names = "stmmaceth";
                        status = "disabled";
                        interrupts = <0 91 4>;
                        interrupt-names = "macirq";
                        mac-address = [00 00 00 00 00 00];
-                       resets = <&rst EMAC1_RESET>;
-                       reset-names = "stmmaceth";
+                       resets = <&rst EMAC1_RESET>, <&rst EMAC1_OCP_RESET>;
+                       reset-names = "stmmaceth", "stmmaceth-ocp";
                        clocks = <&clkmgr STRATIX10_EMAC1_CLK>;
                        clock-names = "stmmaceth";
                        status = "disabled";
                        interrupts = <0 92 4>;
                        interrupt-names = "macirq";
                        mac-address = [00 00 00 00 00 00];
-                       resets = <&rst EMAC2_RESET>;
-                       reset-names = "stmmaceth";
+                       resets = <&rst EMAC2_RESET>, <&rst EMAC2_OCP_RESET>;
+                       reset-names = "stmmaceth", "stmmaceth-ocp";
                        clocks = <&clkmgr STRATIX10_EMAC2_CLK>;
                        clock-names = "stmmaceth";
                        status = "disabled";
                        resets = <&rst SPIM0_RESET>;
                        reg-io-width = <4>;
                        num-cs = <4>;
+                       clocks = <&clkmgr STRATIX10_L4_MAIN_CLK>;
                        status = "disabled";
                };
 
                        resets = <&rst SPIM1_RESET>;
                        reg-io-width = <4>;
                        num-cs = <4>;
+                       clocks = <&clkmgr STRATIX10_L4_MAIN_CLK>;
                        status = "disabled";
                };
 
                        phy-names = "usb2-phy";
                        resets = <&rst USB0_RESET>, <&rst USB0_OCP_RESET>;
                        reset-names = "dwc2", "dwc2-ecc";
+                       clocks = <&clkmgr STRATIX10_USB_CLK>;
                        status = "disabled";
                };
 
                        phy-names = "usb2-phy";
                        resets = <&rst USB1_RESET>, <&rst USB1_OCP_RESET>;
                        reset-names = "dwc2", "dwc2-ecc";
+                       clocks = <&clkmgr STRATIX10_USB_CLK>;
                        status = "disabled";
                };
 
                        reg = <0xffd00200 0x100>;
                        interrupts = <0 117 4>;
                        resets = <&rst WATCHDOG0_RESET>;
+                       clocks = <&clkmgr STRATIX10_L4_SYS_FREE_CLK>;
                        status = "disabled";
                };
 
                        reg = <0xffd00300 0x100>;
                        interrupts = <0 118 4>;
                        resets = <&rst WATCHDOG1_RESET>;
+                       clocks = <&clkmgr STRATIX10_L4_SYS_FREE_CLK>;
                        status = "disabled";
                };
 
                        reg = <0xffd00400 0x100>;
                        interrupts = <0 125 4>;
                        resets = <&rst WATCHDOG2_RESET>;
+                       clocks = <&clkmgr STRATIX10_L4_SYS_FREE_CLK>;
                        status = "disabled";
                };
 
                        reg = <0xffd00500 0x100>;
                        interrupts = <0 126 4>;
                        resets = <&rst WATCHDOG3_RESET>;
+                       clocks = <&clkmgr STRATIX10_L4_SYS_FREE_CLK>;
                        status = "disabled";
                };
 
                                interrupts = <16 4>, <48 4>;
                        };
                };
+
+               qspi: spi@ff8d2000 {
+                       compatible = "cdns,qspi-nor";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0xff8d2000 0x100>,
+                             <0xff900000 0x100000>;
+                       interrupts = <0 3 4>;
+                       cdns,fifo-depth = <128>;
+                       cdns,fifo-width = <4>;
+                       cdns,trigger-address = <0x00000000>;
+                       clocks = <&qspi_clk>;
+
+                       status = "disabled";
+               };
        };
 };
index f9b1ef12db4859daeb551bc04ddc6bf9e961f09a..6edc4fa9fd42683e12f1de2eb4ac3d9732255e44 100644 (file)
                reg = <0x68>;
        };
 };
+
+&qspi {
+       flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "n25q00a";
+               reg = <0>;
+               spi-max-frequency = <50000000>;
+
+               m25p,fast-read;
+               cdns,page-size = <256>;
+               cdns,block-size = <16>;
+               cdns,read-delay = <1>;
+               cdns,tshsl-ns = <50>;
+               cdns,tsd2d-ns = <50>;
+               cdns,tchsh-ns = <4>;
+               cdns,tslch-ns = <4>;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       qspi_boot: partition@0 {
+                               label = "Boot and fpga data";
+                               reg = <0x0 0x4000000>;
+                       };
+
+                       qspi_rootfs: partition@4000000 {
+                               label = "Root Filesystem - JFFS2";
+                               reg = <0x4000000 0x4000000>;
+                       };
+               };
+       };
+};
index 34dd0e9b5cbbc102e38880bacc85575544854090..a97c0e2d7bc64b687277eeb87a550c3dd0f85ee4 100644 (file)
@@ -17,6 +17,9 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-nexbox-a95x.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905x-p212.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p230.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p231.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s805x-p241.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905w-p281.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905w-tx3-mini.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-khadas-vim2.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-nexbox-a1.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-q200.dtb
index dff9b15eb3c0b63a70c65070c465305c35985dee..d5c01427a5ca08cc9543acbfed8d22ecfdec4297 100644 (file)
@@ -6,21 +6,75 @@
 /dts-v1/;
 
 #include "meson-axg.dtsi"
+#include <dt-bindings/input/input.h>
 
 / {
        compatible = "amlogic,s400", "amlogic,a113d", "amlogic,meson-axg";
        model = "Amlogic Meson AXG S400 Development Board";
 
+       adc_keys {
+               compatible = "adc-keys";
+               io-channels = <&saradc 0>;
+               io-channel-names = "buttons";
+               keyup-threshold-microvolt = <1800000>;
+
+               button-next {
+                       label = "Next";
+                       linux,code = <KEY_NEXT>;
+                       press-threshold-microvolt = <1116000>; /* 62% */
+               };
+
+               button-prev {
+                       label = "Previous";
+                       linux,code = <KEY_PREVIOUS>;
+                       press-threshold-microvolt = <900000>; /* 50% */
+               };
+
+               button-wifi {
+                       label = "Wifi";
+                       linux,code = <KEY_WLAN>;
+                       press-threshold-microvolt = <684000>; /* 38% */
+               };
+
+               button-up {
+                       label = "Volume Up";
+                       linux,code = <KEY_VOLUMEUP>;
+                       press-threshold-microvolt = <468000>; /* 26% */
+               };
+
+               button-down {
+                       label = "Volume Down";
+                       linux,code = <KEY_VOLUMEDOWN>;
+                       press-threshold-microvolt = <252000>; /* 14% */
+               };
+
+               button-voice {
+                       label = "Voice";
+                       linux,code = <KEY_VOICECOMMAND>;
+                       press-threshold-microvolt = <0>; /* 0% */
+               };
+       };
+
        aliases {
                serial0 = &uart_AO;
                serial1 = &uart_A;
        };
 
+       main_12v: regulator-main_12v {
+               compatible = "regulator-fixed";
+               regulator-name = "12V";
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+               regulator-always-on;
+       };
+
        vddio_boot: regulator-vddio_boot {
                compatible = "regulator-fixed";
                regulator-name = "VDDIO_BOOT";
                regulator-min-microvolt = <1800000>;
                regulator-max-microvolt = <1800000>;
+               vin-supply = <&vddao_3v3>;
+               regulator-always-on;
        };
 
        vddao_3v3: regulator-vddao_3v3 {
@@ -28,6 +82,8 @@
                regulator-name = "VDDAO_3V3";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
+               vin-supply = <&main_12v>;
+               regulator-always-on;
        };
 
        vddio_ao18: regulator-vddio_ao18 {
@@ -35,6 +91,8 @@
                regulator-name = "VDDIO_AO18";
                regulator-min-microvolt = <1800000>;
                regulator-max-microvolt = <1800000>;
+               vin-supply = <&vddao_3v3>;
+               regulator-always-on;
        };
 
        vcc_3v3: regulator-vcc_3v3 {
                regulator-name = "VCC_3V3";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
+               vin-supply = <&vddao_3v3>;
+               regulator-always-on;
+       };
+
+       vcc_5v: regulator-vcc_5v {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&main_12v>;
+
+               gpio = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       usb_pwr: regulator-usb_pwr {
+               compatible = "regulator-fixed";
+               regulator-name = "USB_PWR";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc_5v>;
+
+               gpio = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
        };
 
        emmc_pwrseq: emmc-pwrseq {
                clock-frequency = <32768>;
                pwms = <&pwm_ab 0 30518 0>; /* PWM_A at 32.768KHz */
        };
+
+       speaker-leds {
+               compatible = "gpio-leds";
+
+               aled1 {
+                       label = "speaker:aled1";
+                       gpios = <&gpio_speaker 7 0>;
+               };
+
+               aled2 {
+                       label = "speaker:aled2";
+                       gpios = <&gpio_speaker 6 0>;
+               };
+
+               aled3 {
+                       label = "speaker:aled3";
+                       gpios = <&gpio_speaker 5 0>;
+               };
+
+               aled4 {
+                       label = "speaker:aled4";
+                       gpios = <&gpio_speaker 4 0>;
+               };
+
+               aled5 {
+                       label = "speaker:aled5";
+                       gpios = <&gpio_speaker 3 0>;
+               };
+
+               aled6 {
+                       label = "speaker:aled6";
+                       gpios = <&gpio_speaker 2 0>;
+               };
+       };
+
+       linein: audio-codec@0 {
+               #sound-dai-cells = <0>;
+               compatible = "everest,es7241";
+               VDDA-supply = <&vcc_3v3>;
+               VDDP-supply = <&vcc_3v3>;
+               VDDD-supply = <&vcc_3v3>;
+               status = "okay";
+               sound-name-prefix = "Linein";
+       };
+
+       lineout: audio-codec@1 {
+               #sound-dai-cells = <0>;
+               compatible = "everest,es7154";
+               VDD-supply = <&vcc_3v3>;
+               PVDD-supply = <&vcc_5v>;
+               status = "okay";
+               sound-name-prefix = "Lineout";
+       };
+
+       spdif_dit: audio-codec@2 {
+               #sound-dai-cells = <0>;
+               compatible = "linux,spdif-dit";
+               status = "okay";
+               sound-name-prefix = "DIT";
+       };
 };
 
 &ethmac {
        status = "okay";
        pinctrl-0 = <&i2c1_z_pins>;
        pinctrl-names = "default";
+
+       speaker_amp1: audio-codec@1b {
+               compatible = "ti,tas5707";
+               reg = <0x1b>;
+               reset-gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_LOW>;
+               #sound-dai-cells = <0>;
+               AVDD-supply = <&vcc_3v3>;
+               DVDD-supply = <&vcc_3v3>;
+               PVDD_A-supply = <&main_12v>;
+               PVDD_B-supply = <&main_12v>;
+               PVDD_C-supply = <&main_12v>;
+               PVDD_D-supply = <&main_12v>;
+       };
 };
 
 &i2c_AO {
        status = "okay";
        pinctrl-0 = <&i2c_ao_sck_10_pins>, <&i2c_ao_sda_11_pins>;
        pinctrl-names = "default";
+
+       gpio_speaker: gpio-controller@1f {
+               compatible = "nxp,pca9557";
+               reg = <0x1f>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               vcc-supply = <&vddao_3v3>;
+       };
 };
 
 &pwm_ab {
                compatible = "brcm,bcm4329-fmac";
        };
 };
+
+&saradc {
+       status = "okay";
+       vref-supply = <&vddio_ao18>;
+};
index 67d7115e4effbde75173aa4a4c07ae890b3183c5..c518130e5ce730e8267456cee4a6062d4527b772 100644 (file)
@@ -6,6 +6,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/axg-audio-clkc.h>
 #include <dt-bindings/clock/axg-clkc.h>
 #include <dt-bindings/clock/axg-aoclkc.h>
 #include <dt-bindings/gpio/meson-axg-gpio.h>
                method = "smc";
        };
 
+       tdmif_a: audio-controller@0 {
+               compatible = "amlogic,axg-tdm-iface";
+               #sound-dai-cells = <0>;
+               sound-name-prefix = "TDM_A";
+               clocks = <&clkc_audio AUD_CLKID_MST_A_MCLK>,
+                        <&clkc_audio AUD_CLKID_MST_A_SCLK>,
+                        <&clkc_audio AUD_CLKID_MST_A_LRCLK>;
+               clock-names = "mclk", "sclk", "lrclk";
+               status = "disabled";
+       };
+
+       tdmif_b: audio-controller@1 {
+               compatible = "amlogic,axg-tdm-iface";
+               #sound-dai-cells = <0>;
+               sound-name-prefix = "TDM_B";
+               clocks = <&clkc_audio AUD_CLKID_MST_B_MCLK>,
+                        <&clkc_audio AUD_CLKID_MST_B_SCLK>,
+                        <&clkc_audio AUD_CLKID_MST_B_LRCLK>;
+               clock-names = "mclk", "sclk", "lrclk";
+               status = "disabled";
+       };
+
+       tdmif_c: audio-controller@2 {
+               compatible = "amlogic,axg-tdm-iface";
+               #sound-dai-cells = <0>;
+               sound-name-prefix = "TDM_C";
+               clocks = <&clkc_audio AUD_CLKID_MST_C_MCLK>,
+                        <&clkc_audio AUD_CLKID_MST_C_SCLK>,
+                        <&clkc_audio AUD_CLKID_MST_C_LRCLK>;
+               clock-names = "mclk", "sclk", "lrclk";
+               status = "disabled";
+       };
+
        timer {
                compatible = "arm,armv8-timer";
                interrupts = <GIC_PPI 13
                        };
                };
 
+               audio: bus@ff642000 {
+                       compatible = "simple-bus";
+                       reg = <0x0 0xff642000 0x0 0x2000>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x0 0x0 0x0 0xff642000 0x0 0x2000>;
+
+                       clkc_audio: clock-controller@0 {
+                               compatible = "amlogic,axg-audio-clkc";
+                               reg = <0x0 0x0 0x0 0xb4>;
+                               #clock-cells = <1>;
+
+                               clocks = <&clkc CLKID_AUDIO>,
+                                        <&clkc CLKID_MPLL0>,
+                                        <&clkc CLKID_MPLL1>,
+                                        <&clkc CLKID_MPLL2>,
+                                        <&clkc CLKID_MPLL3>,
+                                        <&clkc CLKID_HIFI_PLL>,
+                                        <&clkc CLKID_FCLK_DIV3>,
+                                        <&clkc CLKID_FCLK_DIV4>,
+                                        <&clkc CLKID_GP0_PLL>;
+                               clock-names = "pclk",
+                                             "mst_in0",
+                                             "mst_in1",
+                                             "mst_in2",
+                                             "mst_in3",
+                                             "mst_in4",
+                                             "mst_in5",
+                                             "mst_in6",
+                                             "mst_in7";
+
+                               resets = <&reset RESET_AUDIO>;
+                       };
+
+                       arb: reset-controller@280 {
+                               compatible = "amlogic,meson-axg-audio-arb";
+                               reg = <0x0 0x280 0x0 0x4>;
+                               #reset-cells = <1>;
+                               clocks = <&clkc_audio AUD_CLKID_DDR_ARB>;
+                       };
+
+                       tdmin_a: audio-controller@300 {
+                               compatible = "amlogic,axg-tdmin";
+                               reg = <0x0 0x300 0x0 0x40>;
+                               sound-name-prefix = "TDMIN_A";
+                               clocks = <&clkc_audio AUD_CLKID_TDMIN_A>,
+                                        <&clkc_audio AUD_CLKID_TDMIN_A_SCLK>,
+                                        <&clkc_audio AUD_CLKID_TDMIN_A_SCLK_SEL>,
+                                        <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>,
+                                        <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>;
+                               clock-names = "pclk", "sclk", "sclk_sel",
+                                             "lrclk", "lrclk_sel";
+                               status = "disabled";
+                       };
+
+                       tdmin_b: audio-controller@340 {
+                               compatible = "amlogic,axg-tdmin";
+                               reg = <0x0 0x340 0x0 0x40>;
+                               sound-name-prefix = "TDMIN_B";
+                               clocks = <&clkc_audio AUD_CLKID_TDMIN_B>,
+                                        <&clkc_audio AUD_CLKID_TDMIN_B_SCLK>,
+                                        <&clkc_audio AUD_CLKID_TDMIN_B_SCLK_SEL>,
+                                        <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>,
+                                        <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>;
+                               clock-names = "pclk", "sclk", "sclk_sel",
+                                             "lrclk", "lrclk_sel";
+                               status = "disabled";
+                       };
+
+                       tdmin_c: audio-controller@380 {
+                               compatible = "amlogic,axg-tdmin";
+                               reg = <0x0 0x380 0x0 0x40>;
+                               sound-name-prefix = "TDMIN_C";
+                               clocks = <&clkc_audio AUD_CLKID_TDMIN_C>,
+                                        <&clkc_audio AUD_CLKID_TDMIN_C_SCLK>,
+                                        <&clkc_audio AUD_CLKID_TDMIN_C_SCLK_SEL>,
+                                        <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>,
+                                        <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>;
+                               clock-names = "pclk", "sclk", "sclk_sel",
+                                             "lrclk", "lrclk_sel";
+                               status = "disabled";
+                       };
+
+                       tdmin_lb: audio-controller@3c0 {
+                               compatible = "amlogic,axg-tdmin";
+                               reg = <0x0 0x3c0 0x0 0x40>;
+                               sound-name-prefix = "TDMIN_LB";
+                               clocks = <&clkc_audio AUD_CLKID_TDMIN_LB>,
+                                        <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK>,
+                                        <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK_SEL>,
+                                        <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>,
+                                        <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>;
+                               clock-names = "pclk", "sclk", "sclk_sel",
+                                             "lrclk", "lrclk_sel";
+                               status = "disabled";
+                       };
+
+                       spdifout: audio-controller@480 {
+                               compatible = "amlogic,axg-spdifout";
+                               reg = <0x0 0x480 0x0 0x50>;
+                               #sound-dai-cells = <0>;
+                               sound-name-prefix = "SPDIFOUT";
+                               clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
+                                        <&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
+                               clock-names = "pclk", "mclk";
+                               status = "disabled";
+                       };
+
+                       tdmout_a: audio-controller@500 {
+                               compatible = "amlogic,axg-tdmout";
+                               reg = <0x0 0x500 0x0 0x40>;
+                               sound-name-prefix = "TDMOUT_A";
+                               clocks = <&clkc_audio AUD_CLKID_TDMOUT_A>,
+                                        <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK>,
+                                        <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK_SEL>,
+                                        <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>,
+                                        <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>;
+                               clock-names = "pclk", "sclk", "sclk_sel",
+                                             "lrclk", "lrclk_sel";
+                               status = "disabled";
+                       };
+
+                       tdmout_b: audio-controller@540 {
+                               compatible = "amlogic,axg-tdmout";
+                               reg = <0x0 0x540 0x0 0x40>;
+                               sound-name-prefix = "TDMOUT_B";
+                               clocks = <&clkc_audio AUD_CLKID_TDMOUT_B>,
+                                        <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK>,
+                                        <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK_SEL>,
+                                        <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>,
+                                        <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>;
+                               clock-names = "pclk", "sclk", "sclk_sel",
+                                             "lrclk", "lrclk_sel";
+                               status = "disabled";
+                       };
+
+                       tdmout_c: audio-controller@580 {
+                               compatible = "amlogic,axg-tdmout";
+                               reg = <0x0 0x580 0x0 0x40>;
+                               sound-name-prefix = "TDMOUT_C";
+                               clocks = <&clkc_audio AUD_CLKID_TDMOUT_C>,
+                                        <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK>,
+                                        <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK_SEL>,
+                                        <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>,
+                                        <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>;
+                               clock-names = "pclk", "sclk", "sclk_sel",
+                                             "lrclk", "lrclk_sel";
+                               status = "disabled";
+                       };
+               };
+
                cbus: bus@ffd00000 {
                        compatible = "simple-bus";
                        reg = <0x0 0xffd00000 0x0 0x25000>;
                                        };
                                };
 
+                               pdm_dclk_a14_pins: pdm_dclk_a14 {
+                                       mux {
+                                               groups = "pdm_dclk_a14";
+                                               function = "pdm";
+                                       };
+                               };
+
+                               pdm_dclk_a19_pins: pdm_dclk_a19 {
+                                       mux {
+                                               groups = "pdm_dclk_a19";
+                                               function = "pdm";
+                                       };
+                               };
+
+                               pdm_din0_pins: pdm_din0 {
+                                       mux {
+                                               groups = "pdm_din0";
+                                               function = "pdm";
+                                       };
+                               };
+
+                               pdm_din1_pins: pdm_din1 {
+                                       mux {
+                                               groups = "pdm_din1";
+                                               function = "pdm";
+                                       };
+                               };
+
+                               pdm_din2_pins: pdm_din2 {
+                                       mux {
+                                               groups = "pdm_din2";
+                                               function = "pdm";
+                                       };
+                               };
+
+                               pdm_din3_pins: pdm_din3 {
+                                       mux {
+                                               groups = "pdm_din3";
+                                               function = "pdm";
+                                       };
+                               };
+
                                pwm_a_a_pins: pwm_a_a {
                                        mux {
                                                groups = "pwm_a_a";
                                        };
                                };
 
+                               spdif_in_z_pins: spdif_in_z {
+                                       mux {
+                                               groups = "spdif_in_z";
+                                               function = "spdif_in";
+                                       };
+                               };
+
+                               spdif_in_a1_pins: spdif_in_a1 {
+                                       mux {
+                                               groups = "spdif_in_a1";
+                                               function = "spdif_in";
+                                       };
+                               };
+
+                               spdif_in_a7_pins: spdif_in_a7 {
+                                       mux {
+                                               groups = "spdif_in_a7";
+                                               function = "spdif_in";
+                                       };
+                               };
+
+                               spdif_in_a19_pins: spdif_in_a19 {
+                                       mux {
+                                               groups = "spdif_in_a19";
+                                               function = "spdif_in";
+                                       };
+                               };
+
+                               spdif_in_a20_pins: spdif_in_a20 {
+                                       mux {
+                                               groups = "spdif_in_a20";
+                                               function = "spdif_in";
+                                       };
+                               };
+
+                               spdif_out_z_pins: spdif_out_z {
+                                       mux {
+                                               groups = "spdif_out_z";
+                                               function = "spdif_out";
+                                       };
+                               };
+
+                               spdif_out_a1_pins: spdif_out_a1 {
+                                       mux {
+                                               groups = "spdif_out_a1";
+                                               function = "spdif_out";
+                                       };
+                               };
+
+                               spdif_out_a11_pins: spdif_out_a11 {
+                                       mux {
+                                               groups = "spdif_out_a11";
+                                               function = "spdif_out";
+                                       };
+                               };
+
+                               spdif_out_a19_pins: spdif_out_a19 {
+                                       mux {
+                                               groups = "spdif_out_a19";
+                                               function = "spdif_out";
+                                       };
+                               };
+
+                               spdif_out_a20_pins: spdif_out_a20 {
+                                       mux {
+                                               groups = "spdif_out_a20";
+                                               function = "spdif_out";
+                                       };
+                               };
+
                                spi0_pins: spi0 {
                                        mux {
                                                groups = "spi0_miso",
                                interrupts = <GIC_SPI 196 IRQ_TYPE_EDGE_RISING>;
                                status = "disabled";
                        };
+
+                       saradc: adc@9000 {
+                               compatible = "amlogic,meson-axg-saradc",
+                                       "amlogic,meson-saradc";
+                               reg = <0x0 0x9000 0x0 0x38>;
+                               #io-channel-cells = <1>;
+                               interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&xtal>,
+                                       <&clkc_AO CLKID_AO_SAR_ADC>,
+                                       <&clkc_AO CLKID_AO_SAR_ADC_CLK>,
+                                       <&clkc_AO CLKID_AO_SAR_ADC_SEL>;
+                               clock-names = "clkin", "core", "adc_clk", "adc_sel";
+                               status = "disabled";
+                       };
                };
        };
 };
index 88e712ea757a238152c06f932dfecfeb5b36b843..765247bc4f2477e423a32d4c0efa7d83b0b3a4e9 100644 (file)
                regulator-always-on;
        };
 
+       vddio_ao18: regulator-vddio_ao18 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDIO_AO18";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+
        vddio_boot: regulator-vddio_boot {
                compatible = "regulator-fixed";
                regulator-name = "VDDIO_BOOT";
        clock-names = "clkin0";
 };
 
+&saradc {
+       status = "okay";
+       vref-supply = <&vddio_ao18>;
+};
+
 /* Wireless SDIO Module */
 &sd_emmc_a {
        status = "okay";
 
        vmmc-supply = <&vddao_3v3>;
        vqmmc-supply = <&vddio_boot>;
-
-       brcmf: wifi@1 {
-               reg = <1>;
-               compatible = "brcm,bcm4329-fmac";
-       };
 };
 
 /* SD card */
index 7d5709c37e9558cb6437864926ceae993a3e55f3..cbe99bd4e06d2c43934a23848bbe788ee69e0390 100644 (file)
                compatible = "mmc-pwrseq-emmc";
                reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
        };
+
+       /* CVBS is available on CON1 pin 36, disabled by default */
+       cvbs-connector {
+               compatible = "composite-video-connector";
+               status = "disabled";
+
+               port {
+                       cvbs_connector_in: endpoint {
+                               remote-endpoint = <&cvbs_vdac_out>;
+                       };
+               };
+       };
+
+       hdmi-connector {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_connector_in: endpoint {
+                               remote-endpoint = <&hdmi_tx_tmds_out>;
+                       };
+               };
+       };
+};
+
+&cec_AO {
+       status = "okay";
+       pinctrl-0 = <&ao_cec_pins>;
+       pinctrl-names = "default";
+       hdmi-phandle = <&hdmi_tx>;
+};
+
+&cvbs_vdac_port {
+       cvbs_vdac_out: endpoint {
+               remote-endpoint = <&cvbs_connector_in>;
+       };
 };
 
 &ethmac {
        };
 };
 
+&hdmi_tx {
+       status = "okay";
+       pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
+       pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+       hdmi_tx_tmds_out: endpoint {
+               remote-endpoint = <&hdmi_connector_in>;
+       };
+};
+
 &ir {
        status = "okay";
        pinctrl-0 = <&remote_input_ao_pins>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts
new file mode 100644 (file)
index 0000000..70433e0
--- /dev/null
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+
+#include "meson-gxl-s905x.dtsi"
+
+/ {
+       compatible = "amlogic,p241", "amlogic,s805x", "amlogic,meson-gxl";
+       model = "Amlogic Meson GXL (S805X) P241 Development Board";
+
+       aliases {
+               serial0 = &uart_AO;
+               serial1 = &uart_A;
+               ethernet0 = &ethmac;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       cvbs-connector {
+               compatible = "composite-video-connector";
+
+               port {
+                       cvbs_connector_in: endpoint {
+                               remote-endpoint = <&cvbs_vdac_out>;
+                       };
+               };
+       };
+
+       emmc_pwrseq: emmc-pwrseq {
+               compatible = "mmc-pwrseq-emmc";
+               reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+       };
+
+       hdmi-connector {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_connector_in: endpoint {
+                               remote-endpoint = <&hdmi_tx_tmds_out>;
+                       };
+               };
+       };
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x0 0x0 0x0 0x20000000>;
+       };
+
+       vddio_boot: regulator-vddio_boot {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDIO_BOOT";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+
+       vddao_3v3: regulator-vddao_3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDAO_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       vddio_ao18: regulator-vddio_ao18 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDIO_AO18";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+
+       vcc_3v3: regulator-vcc_3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       emmc_pwrseq: emmc-pwrseq {
+               compatible = "mmc-pwrseq-emmc";
+               reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+       };
+
+       wifi32k: wifi32k {
+               compatible = "pwm-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+               pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+       };
+
+       sdio_pwrseq: sdio-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+               clocks = <&wifi32k>;
+               clock-names = "ext_clock";
+       };
+};
+
+&cec_AO {
+       status = "okay";
+       pinctrl-0 = <&ao_cec_pins>;
+       pinctrl-names = "default";
+       hdmi-phandle = <&hdmi_tx>;
+};
+
+&cvbs_vdac_port {
+       cvbs_vdac_out: endpoint {
+               remote-endpoint = <&cvbs_connector_in>;
+       };
+};
+
+&ethmac {
+       status = "okay";
+};
+
+&internal_phy {
+       pinctrl-0 = <&eth_link_led_pins>, <&eth_act_led_pins>;
+       pinctrl-names = "default";
+};
+
+&ir {
+       status = "okay";
+       pinctrl-0 = <&remote_input_ao_pins>;
+       pinctrl-names = "default";
+};
+
+&hdmi_tx {
+       status = "okay";
+       pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
+       pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+       hdmi_tx_tmds_out: endpoint {
+               remote-endpoint = <&hdmi_connector_in>;
+       };
+};
+
+&saradc {
+       status = "okay";
+       vref-supply = <&vddio_ao18>;
+};
+
+/* Wireless SDIO Module */
+&sd_emmc_a {
+       status = "okay";
+       pinctrl-0 = <&sdio_pins>;
+       pinctrl-1 = <&sdio_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       bus-width = <4>;
+       cap-sd-highspeed;
+       max-frequency = <100000000>;
+
+       non-removable;
+       disable-wp;
+
+       mmc-pwrseq = <&sdio_pwrseq>;
+
+       vmmc-supply = <&vddao_3v3>;
+       vqmmc-supply = <&vddio_boot>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+       status = "okay";
+       pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+       pinctrl-1 = <&emmc_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
+
+       bus-width = <8>;
+       cap-mmc-highspeed;
+       max-frequency = <200000000>;
+       non-removable;
+       disable-wp;
+       mmc-ddr-1_8v;
+       mmc-hs200-1_8v;
+
+       mmc-pwrseq = <&emmc_pwrseq>;
+       vmmc-supply = <&vcc_3v3>;
+       vqmmc-supply = <&vddio_boot>;
+};
+
+&pwm_ef {
+       status = "okay";
+       pinctrl-0 = <&pwm_e_pins>;
+       pinctrl-names = "default";
+       clocks = <&clkc CLKID_FCLK_DIV4>;
+       clock-names = "clkin0";
+};
+
+/* This is connected to the Bluetooth module: */
+&uart_A {
+       status = "okay";
+       pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+       pinctrl-names = "default";
+       uart-has-rtscts;
+};
+
+&uart_AO {
+       status = "okay";
+       pinctrl-0 = <&uart_ao_a_pins>;
+       pinctrl-names = "default";
+};
+
+&usb0 {
+       status = "okay";
+};
index a9f9bb90a877d36ec9d7aec9f7b792282ac6af7a..15014faa2ab2517ddd63e12d675bccf775c14b3e 100644 (file)
                };
        };
 
-       vddio_ao18: regulator-vddio_ao18 {
-               compatible = "regulator-fixed";
-               regulator-name = "VDDIO_AO18";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <1800000>;
-       };
-
        hdmi-connector {
                compatible = "hdmi-connector";
                type = "a";
        };
 };
 
-&saradc {
-       status = "okay";
-       vref-supply = <&vddio_ao18>;
+&sd_emmc_a {
+       brcmf: wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+       };
 };
index 80a231476b80997c3d1801bda9c5e9c43dbca428..92c425d0259cc66021ae480e84738ee778fe930f 100644 (file)
        phy-mode = "rmii";
        phy-handle = <&internal_phy>;
 };
+
+&sd_emmc_a {
+       brcmf: wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+       };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-p281.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-p281.dts
new file mode 100644 (file)
index 0000000..6509c49
--- /dev/null
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Martin Blumenstingl <martin.blumenstingl@googlemail.com>.
+ * Based on meson-gxl-s905d-p231.dts:
+ * - Copyright (c) 2016 Endless Computers, Inc.
+ *   Author: Carlo Caione <carlo@endlessm.com>
+ */
+
+/dts-v1/;
+
+#include "meson-gxl-s905x.dtsi"
+#include "meson-gx-p23x-q20x.dtsi"
+
+/ {
+       compatible = "amlogic,p281", "amlogic,s905w", "amlogic,meson-gxl";
+       model = "Amlogic Meson GXL (S905W) P281 Development Board";
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x0 0x0 0x0 0x40000000>;
+       };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts
new file mode 100644 (file)
index 0000000..789c819
--- /dev/null
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Martin Blumenstingl <martin.blumenstingl@googlemail.com>.
+ * Based on meson-gxl-s905d-p231.dts:
+ * - Copyright (c) 2016 Endless Computers, Inc.
+ *   Author: Carlo Caione <carlo@endlessm.com>
+ */
+
+/dts-v1/;
+
+#include "meson-gxl-s905x.dtsi"
+#include "meson-gx-p23x-q20x.dtsi"
+
+/ {
+       compatible = "oranth,tx3-mini", "amlogic,s905w", "amlogic,meson-gxl";
+       model = "Oranth Tanix TX3 Mini";
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x0 0x0 0x0 0x40000000>; /* 1 GiB or 2 GiB */
+       };
+};
index 0868da476e41ff1a81aa40be378a13737c2a2c4a..313f88f8759e1d5f9ea7ad9e6b0b777a82a7cccb 100644 (file)
        #cooling-cells = <2>;
 };
 
+&cpu1 {
+       #cooling-cells = <2>;
+};
+
+&cpu2 {
+       #cooling-cells = <2>;
+};
+
+&cpu3 {
+       #cooling-cells = <2>;
+};
+
 &cpu4 {
        #cooling-cells = <2>;
 };
 
+&cpu5 {
+       #cooling-cells = <2>;
+};
+
+&cpu6 {
+       #cooling-cells = <2>;
+};
+
+&cpu7 {
+       #cooling-cells = <2>;
+};
+
 &ethmac {
        pinctrl-0 = <&eth_pins>;
        pinctrl-names = "default";
index 101417298a1dd726f8986c99d5b229dc38d770c9..73d656e4aadeae9be4346de49de06aa49a91ee2e 100644 (file)
                        gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>;
                };
        };
-
-       vddio_ao18: regulator-vddio_ao18 {
-               compatible = "regulator-fixed";
-               regulator-name = "VDDIO_AO18";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <1800000>;
-       };
 };
 
 /* Q200 has exclusive choice between internal or external PHY */
@@ -79,7 +72,9 @@
        };
 };
 
-&saradc {
-       status = "okay";
-       vref-supply = <&vddio_ao18>;
+&sd_emmc_a {
+       brcmf: wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+       };
 };
index 8d132b17514a85229ddaeb117b4e1c73b86de68c..d02b80d77378664309ce664e623e5256ba62aa89 100644 (file)
        phy-mode = "rmii";
        phy-handle = <&internal_phy>;
 };
+
+&sd_emmc_a {
+       brcmf: wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+       };
+};
index 2c5db03f226c60b595dad62e136e32ca4d769702..b2b7ced633cf6cc6ed5b52332ed8ef31e2eae0be 100644 (file)
@@ -63,7 +63,7 @@
                };
 
                idle-states {
-                       entry-method = "arm,psci";
+                       entry-method = "psci";
 
                        CPU_SLEEP_0: cpu-sleep-0 {
                                compatible = "arm,idle-state";
index c51950f4a1b66b4088331a8741edf38bfd6eec22..ab77adb4f3c20d46902bda9d96d2c77651a02b3a 100644 (file)
@@ -63,7 +63,7 @@
                };
 
                idle-states {
-                       entry-method = "arm,psci";
+                       entry-method = "psci";
 
                        CPU_SLEEP_0: cpu-sleep-0 {
                                compatible = "arm,idle-state";
index 2b2bf39c30ef68c1347f01457bb0818516fe2d43..1fb5c5a0f32e38876e25561d39548dfe700dde34 100644 (file)
@@ -62,7 +62,7 @@
                };
 
                idle-states {
-                       entry-method = "arm,psci";
+                       entry-method = "psci";
 
                        CPU_SLEEP_0: cpu-sleep-0 {
                                compatible = "arm,idle-state";
index c4d06cffcb119d8119c80e3fa233656b32a143a3..20c7d0aa6cb78435fadad908509117539f5a96d0 100644 (file)
@@ -1,3 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_ARCH_BCM_IPROC) += bcm958742k.dtb
 dtb-$(CONFIG_ARCH_BCM_IPROC) += bcm958742t.dtb
+
+dtb-$(CONFIG_ARCH_BCM_IPROC) += bcm958802a802x.dtb
index 8862ec907fd8e9564aa9d8e5ed4aba173f6a2623..bc299c3d90683b02e168b9c06cbfd0b26c66ee2f 100644 (file)
  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "stingray.dtsi"
+#include "stingray-board-base.dtsi"
 
 / {
-       chosen {
-               stdout-path = "serial0:115200n8";
-       };
-
-       aliases {
-               serial0 = &uart1;
-               serial1 = &uart0;
-               serial2 = &uart2;
-               serial3 = &uart3;
-       };
-
        sdio0_vddo_ctrl_reg: sdio0_vddo_ctrl {
                compatible = "regulator-gpio";
                regulator-name = "sdio0_vddo_ctrl_reg";
        };
 };
 
-&memory { /* Default DRAM banks */
-       reg = <0x00000000 0x80000000 0x0 0x80000000>, /* 2G @ 2G */
-             <0x00000008 0x80000000 0x1 0x80000000>; /* 6G @ 34G */
-};
-
 &sata0 {
        status = "okay";
 };
        status = "okay";
 };
 
-&mdio_mux_iproc {
-       mdio@10 {
-               gphy0: eth-phy@10 {
-                       reg = <0x10>;
-               };
-       };
-};
-
-&uart1 {
-       status = "okay";
-};
-
 &pwm {
        status = "okay";
 };
 };
 
 &enet {
-       phy-mode = "rgmii-id";
-       phy-handle = <&gphy0>;
        status = "okay";
 };
 
 
 &sdio0 {
        vqmmc-supply = <&sdio0_vddo_ctrl_reg>;
-       non-removable;
-       full-pwr-cycle;
        status = "okay";
 };
 
 &sdio1 {
        vqmmc-supply = <&sdio1_vddo_ctrl_reg>;
-       full-pwr-cycle;
        status = "okay";
 };
diff --git a/arch/arm64/boot/dts/broadcom/stingray/bcm958802a802x.dts b/arch/arm64/boot/dts/broadcom/stingray/bcm958802a802x.dts
new file mode 100644 (file)
index 0000000..a41facd
--- /dev/null
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: (GPL-2.0 or BSD-3-Clause)
+/*
+ *Copyright(c) 2018 Broadcom
+ */
+
+/dts-v1/;
+
+#include "stingray-board-base.dtsi"
+
+/ {
+       compatible = "brcm,bcm958802a802x", "brcm,stingray";
+       model = "Stingray PS225xx (BCM958802A802x)";
+};
+
+&enet {
+       status = "disabled";
+};
+
+&sdio0 {
+       no-1-8-v;
+       status = "okay";
+};
+
+&uart0 {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray-board-base.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray-board-base.dtsi
new file mode 100644 (file)
index 0000000..82a2471
--- /dev/null
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: (GPL-2.0 or BSD-3-Clause)
+/*
+ *  Copyright(c) 2016-2018 Broadcom
+ */
+
+#include "stingray.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       aliases {
+               serial0 = &uart1;
+               serial1 = &uart0;
+               serial2 = &uart2;
+               serial3 = &uart3;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&memory { /* Default DRAM banks */
+       reg = <0x00000000 0x80000000 0x0 0x80000000>, /* 2G @ 2G */
+             <0x00000008 0x80000000 0x1 0x80000000>; /* 6G @ 34G */
+};
+
+&enet {
+       phy-mode = "rgmii-id";
+       phy-handle = <&gphy0>;
+};
+
+&uart1 {
+       status = "okay";
+};
+
+&sdio0 {
+       non-removable;
+       full-pwr-cycle;
+};
+
+&sdio1 {
+       full-pwr-cycle;
+};
+
+&mdio_mux_iproc {
+       mdio@10 {
+               gphy0: eth-phy@10 {
+                       reg = <0x10>;
+               };
+       };
+};
index 3a4d4524b5ed24e7d09797b52885d928ab7deb2e..10a106aca22983cbd9dec61c1f809b11633fac82 100644 (file)
                        reg = <0x0001d104 0x32>,
                              <0x0001c854 0x4>;
                        clocks = <&osc>;
-                       clock-output-names = "genpll0", "clk_125", "clk_scr",
+                       clock-output-names = "genpll0", "clk_125m", "clk_scr",
                                             "clk_250", "clk_pcie_axi",
                                             "clk_paxc_axi_x2",
                                             "clk_paxc_axi";
                };
 
+               genpll2: genpll2@1d1ac {
+                       #clock-cells = <1>;
+                       compatible = "brcm,sr-genpll2";
+                       reg = <0x0001d1ac 0x32>,
+                             <0x0001c854 0x4>;
+                       clocks = <&osc>;
+                       clock-output-names = "genpll2", "clk_nic",
+                                            "clk_ts_500_ref", "clk_125_nitro",
+                                            "clk_chimp", "clk_nic_flash",
+                                            "clk_fs";
+               };
+
                genpll3: genpll3@1d1e0 {
                        #clock-cells = <1>;
                        compatible = "brcm,sr-genpll3";
@@ -75,8 +87,8 @@
                              <0x0001c854 0x4>;
                        clocks = <&osc>;
                        clock-output-names = "genpll4", "clk_ccn",
-                                            "clk_tpiu_pll", "noc_clk",
-                                            "pll_chclk_fs4",
+                                            "clk_tpiu_pll", "clk_noc",
+                                            "clk_chclk_fs4",
                                             "clk_bridge_fscpu";
                };
 
@@ -86,8 +98,8 @@
                        reg = <0x0001d248 0x32>,
                              <0x0001c870 0x4>;
                        clocks = <&osc>;
-                       clock-output-names = "genpll5", "fs4_hf_clk",
-                                            "crypto_ae_clk", "raid_ae_clk";
+                       clock-output-names = "genpll5", "clk_fs4_hf",
+                                            "clk_crypto_ae", "clk_raid_ae";
                };
 
                lcpll0: lcpll0@1d0c4 {
                        reg = <0x0001d138 0x3c>,
                              <0x0001c870 0x4>;
                        clocks = <&osc>;
-                       clock-output-names = "lcpll1", "clk_wanpn",
+                       clock-output-names = "lcpll1", "clk_wan",
                                             "clk_usb_ref",
-                                            "timesync_evt_clk";
+                                            "clk_crmu_ts";
                };
 
                hsls_clk: hsls_clk {
diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray-pcie.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray-pcie.dtsi
new file mode 100644 (file)
index 0000000..33a472a
--- /dev/null
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: (GPL-2.0 or BSD-3-Clause)
+/*
+ *Copyright(c) 2018 Broadcom
+ */
+
+pcie8: pcie@60400000 {
+       compatible = "brcm,iproc-pcie-paxc-v2";
+       reg = <0 0x60400000 0 0x1000>;
+       linux,pci-domain = <8>;
+
+       bus-range = <0x0 0x1>;
+
+       #address-cells = <3>;
+       #size-cells = <2>;
+       device_type = "pci";
+       ranges = <0x83000000 0 0x10000000 0 0x10000000 0 0x20000000>;
+
+       dma-coherent;
+
+       msi-map = <0x100 &gic_its 0x2000 0x1>, /* PF0 */
+                 <0x108 &gic_its 0x2040 0x8>, /* PF0-VF0-7 */
+                 <0x101 &gic_its 0x2080 0x1>, /* PF1 */
+                 <0x110 &gic_its 0x20c8 0x8>, /* PF1-VF8-15 */
+                 <0x102 &gic_its 0x2100 0x1>, /* PF2 */
+                 <0x118 &gic_its 0x2150 0x8>, /* PF2-VF16-23 */
+                 <0x103 &gic_its 0x2180 0x1>, /* PF3 */
+                 <0x120 &gic_its 0x21d8 0x8>, /* PF3-VF24-31 */
+                 <0x104 &gic_its 0x2200 0x1>, /* PF4 */
+                 <0x128 &gic_its 0x2260 0x8>, /* PF4-VF32-39 */
+                 <0x105 &gic_its 0x2280 0x1>, /* PF5 */
+                 <0x130 &gic_its 0x22e8 0x8>, /* PF5-VF40-47 */
+                 <0x106 &gic_its 0x2300 0x1>, /* PF6 */
+                 <0x138 &gic_its 0x2370 0x8>, /* PF6-VF48-55 */
+                 <0x107 &gic_its 0x2380 0x1>, /* PF7 */
+                 <0x140 &gic_its 0x23f8 0x8>; /* PF7-VF56-63 */
+
+       phys = <&pcie_phy 8>;
+       phy-names = "pcie-phy";
+};
+
+pcie-ss {
+       compatible = "simple-bus";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       ranges = <0x0 0x0 0x40000000 0x800>;
+
+       pcie_phy: phy@0 {
+               compatible = "brcm,sr-pcie-phy";
+               reg = <0x0 0x200>;
+               brcm,sr-cdru = <&cdru>;
+               brcm,sr-mhb = <&mhb>;
+               #phy-cells = <1>;
+       };
+};
index a70e8ddbd66f5b836fa5e51e369d7829b0ec0501..e283480bfc7e5d50701b7d62bde1b9b3e53ee5a5 100644 (file)
                             <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
        };
 
+       mhb: syscon@60401000 {
+               compatible = "brcm,sr-mhb", "syscon";
+               reg = <0 0x60401000 0 0x38c>;
+       };
+
        scr {
                compatible = "simple-bus";
                #address-cells = <1>;
 
                #include "stingray-clock.dtsi"
 
+               otp: otp@1c400 {
+                       compatible = "brcm,ocotp-v2";
+                       reg = <0x0001c400 0x68>;
+                       brcm,ocotp-size = <2048>;
+                       status = "okay";
+               };
+
+               cdru: syscon@1d000 {
+                       compatible = "brcm,sr-cdru", "syscon";
+                       reg = <0x0001d000 0x400>;
+               };
+
                gpio_crmu: gpio@24800 {
                        compatible = "brcm,iproc-gpio";
                        reg = <0x00024800 0x4c>;
 
        #include "stingray-fs4.dtsi"
        #include "stingray-sata.dtsi"
+       #include "stingray-pcie.dtsi"
 
        hsls {
                compatible = "simple-bus";
                        interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&hsls_25m_div2_clk>, <&hsls_div4_clk>;
                        clock-names = "wdogclk", "apb_pclk";
+                       timeout-sec = <60>;
                };
 
                gpio_hsls: gpio@d0000 {
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tmu-g3d-sensor-conf.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tmu-g3d-sensor-conf.dtsi
deleted file mode 100644 (file)
index f080357..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Device tree sources for Exynos5433 TMU sensor configuration
- *
- * Copyright (c) 2016 Jonghwa Lee <jonghwa3.lee@samsung.com>
- */
-
-#include <dt-bindings/thermal/thermal_exynos.h>
-
-#thermal-sensor-cells = <0>;
-samsung,tmu_gain = <8>;
-samsung,tmu_reference_voltage = <23>;
-samsung,tmu_noise_cancel_mode = <4>;
-samsung,tmu_efuse_value = <75>;
-samsung,tmu_min_efuse_value = <40>;
-samsung,tmu_max_efuse_value = <150>;
-samsung,tmu_first_point_trim = <25>;
-samsung,tmu_second_point_trim = <85>;
-samsung,tmu_default_temp_offset = <50>;
-samsung,tmu_mux_addr = <6>;
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tmu-sensor-conf.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tmu-sensor-conf.dtsi
deleted file mode 100644 (file)
index cccae66..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Device tree sources for Exynos5433 TMU sensor configuration
- *
- * Copyright (c) 2016 Chanwoo Choi <cw00.choi@samsung.com>
- */
-
-#include <dt-bindings/thermal/thermal_exynos.h>
-
-#thermal-sensor-cells = <0>;
-samsung,tmu_gain = <8>;
-samsung,tmu_reference_voltage = <16>;
-samsung,tmu_noise_cancel_mode = <4>;
-samsung,tmu_efuse_value = <75>;
-samsung,tmu_min_efuse_value = <40>;
-samsung,tmu_max_efuse_value = <150>;
-samsung,tmu_first_point_trim = <25>;
-samsung,tmu_second_point_trim = <85>;
-samsung,tmu_default_temp_offset = <50>;
index 038c99792ccb33f94fa2191687102946e3ebe265..2131f12364cb23906047495bbfae29e5084c3420 100644 (file)
                        clocks = <&cmu_peris CLK_PCLK_TMU0_APBIF>,
                                <&cmu_peris CLK_SCLK_TMU0>;
                        clock-names = "tmu_apbif", "tmu_sclk";
-                       #include "exynos5433-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                        status = "disabled";
                };
 
                        clocks = <&cmu_peris CLK_PCLK_TMU0_APBIF>,
                                <&cmu_peris CLK_SCLK_TMU0>;
                        clock-names = "tmu_apbif", "tmu_sclk";
-                       #include "exynos5433-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                        status = "disabled";
                };
 
                        clocks = <&cmu_peris CLK_PCLK_TMU1_APBIF>,
                                <&cmu_peris CLK_SCLK_TMU1>;
                        clock-names = "tmu_apbif", "tmu_sclk";
-                       #include "exynos5433-tmu-g3d-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                        status = "disabled";
                };
 
                        clocks = <&cmu_peris CLK_PCLK_TMU1_APBIF>,
                                <&cmu_peris CLK_SCLK_TMU1>;
                        clock-names = "tmu_apbif", "tmu_sclk";
-                       #include "exynos5433-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                        status = "disabled";
                };
 
                        clocks = <&cmu_peris CLK_PCLK_TMU1_APBIF>,
                                <&cmu_peris CLK_SCLK_TMU1>;
                        clock-names = "tmu_apbif", "tmu_sclk";
-                       #include "exynos5433-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                        status = "disabled";
                };
 
                        power-domains = <&pd_gscl>;
                };
 
-               sysmmu_scaler_0: sysmmu@0x15040000 {
+               sysmmu_scaler_0: sysmmu@15040000 {
                        compatible = "samsung,exynos-sysmmu";
                        reg = <0x15040000 0x1000>;
                        interrupts = <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>;
                        power-domains = <&pd_mscl>;
                };
 
-               sysmmu_scaler_1: sysmmu@0x15050000 {
+               sysmmu_scaler_1: sysmmu@15050000 {
                        compatible = "samsung,exynos-sysmmu";
                        reg = <0x15050000 0x1000>;
                        interrupts = <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm64/boot/dts/exynos/exynos7-tmu-sensor-conf.dtsi b/arch/arm64/boot/dts/exynos/exynos7-tmu-sensor-conf.dtsi
deleted file mode 100644 (file)
index 4849471..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Device tree sources for Exynos7 TMU sensor configuration
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- */
-
-#include <dt-bindings/thermal/thermal_exynos.h>
-
-#thermal-sensor-cells = <0>;
-samsung,tmu_gain = <9>;
-samsung,tmu_reference_voltage = <17>;
-samsung,tmu_noise_cancel_mode = <4>;
-samsung,tmu_efuse_value = <75>;
-samsung,tmu_min_efuse_value = <15>;
-samsung,tmu_max_efuse_value = <100>;
-samsung,tmu_first_point_trim = <25>;
-samsung,tmu_second_point_trim = <85>;
-samsung,tmu_default_temp_offset = <50>;
-samsung,tmu_cal_type = <TYPE_ONE_POINT_TRIMMING>;
index 93a84338938a65cc1a594f3de37fa3bcfe48b9e5..75ad724c487ec863c3e409a09cb6cb70fddb5f66 100644 (file)
                        clocks = <&clock_peris PCLK_TMU>,
                                 <&clock_peris SCLK_TMU>;
                        clock-names = "tmu_apbif", "tmu_sclk";
-                       #include "exynos7-tmu-sensor-conf.dtsi"
+                       #thermal-sensor-cells = <0>;
                };
 
                thermal-zones {
index 7286b1ebfd7acc155c2ed9f75f1c70fa08ab5147..f90c040fd5e8e1d063c4ff658dc664f241459c8e 100644 (file)
@@ -1,45 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Freescale LS1012A Freedom Board.
  *
  * Copyright 2016 Freescale Semiconductor, Inc.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 /dts-v1/;
 
index cdc4aee75227aadb147dea1797e2c0b47c94a6f6..2fb1cb1f7d8f82e34c6da6a16299120f5979d534 100644 (file)
@@ -1,45 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Freescale LS1012A QDS Board.
  *
  * Copyright 2016 Freescale Semiconductor, Inc.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 /dts-v1/;
 
index c1a119effa6156603d52df2e5d952541c6faef0d..5edb1e137a52cf1b5fdfe50695541e20fff8c25f 100644 (file)
@@ -1,45 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Freescale LS1012A RDB Board.
  *
  * Copyright 2016 Freescale Semiconductor, Inc.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 /dts-v1/;
 
index 205f0f4c5df0a5b6b9fe1480d97be09930f38e00..68ac78c4564dc74cdfd0f40697c1b599bee72add 100644 (file)
@@ -1,45 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Freescale Layerscape-1012A family SoC.
  *
  * Copyright 2016 Freescale Semiconductor, Inc.
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -79,7 +43,7 @@
                 * PSCI node is not added default, U-boot will add missing
                 * parts if it determines to use PSCI.
                 */
-               entry-method = "arm,psci";
+               entry-method = "psci";
 
                CPU_PH20: cpu-ph20 {
                        compatible = "arm,idle-state";
index 169e171407a631cef269be07a5836dcfabb3aae9..6082ae02213642878e5a659c51fc6fe7fd506df2 100644 (file)
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
  * QorIQ FMan v3 device tree nodes for ls1043
  *
  * Copyright 2015-2016 Freescale Semiconductor Inc.
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
  */
 
 &soc {
index 6341281485cfe5ed87bd124a2c60ed5f456e9c95..c7b8d2c009cd5a286c26f7f385f9bdf170f3c849 100644 (file)
@@ -1,47 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Freescale Layerscape-1043A family SoC.
  *
  * Copyright 2014-2015 Freescale Semiconductor, Inc.
  *
  * Mingkai Hu <Mingkai.hu@freescale.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 3dc0c8e9663d435a00c938efbf11385c63c9db09..7b01ba8d3b7e193ef861fd44d34fb6a30e3bafe6 100644 (file)
@@ -1,47 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Freescale Layerscape-1043A family SoC.
  *
  * Copyright 2014-2015 Freescale Semiconductor, Inc.
  *
  * Mingkai Hu <Mingkai.hu@freescale.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 1109f22bda5e5aa1cc8335cd532174a37342e057..7881e3d81a9aba6134fc66a7d35e6d02daa4009a 100644 (file)
@@ -1,47 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Freescale Layerscape-1043A family SoC.
  *
  * Copyright 2014-2015 Freescale Semiconductor, Inc.
  *
  * Mingkai Hu <Mingkai.hu@freescale.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/thermal/thermal.h>
@@ -80,8 +43,8 @@
                        reg = <0x0>;
                        clocks = <&clockgen 1 0>;
                        next-level-cache = <&l2>;
-                       #cooling-cells = <2>;
                        cpu-idle-states = <&CPU_PH20>;
+                       #cooling-cells = <2>;
                };
 
                cpu1: cpu@1 {
@@ -91,6 +54,7 @@
                        clocks = <&clockgen 1 0>;
                        next-level-cache = <&l2>;
                        cpu-idle-states = <&CPU_PH20>;
+                       #cooling-cells = <2>;
                };
 
                cpu2: cpu@2 {
                        clocks = <&clockgen 1 0>;
                        next-level-cache = <&l2>;
                        cpu-idle-states = <&CPU_PH20>;
+                       #cooling-cells = <2>;
                };
 
                cpu3: cpu@3 {
                        clocks = <&clockgen 1 0>;
                        next-level-cache = <&l2>;
                        cpu-idle-states = <&CPU_PH20>;
+                       #cooling-cells = <2>;
                };
 
                l2: l2-cache {
                 * PSCI node is not added default, U-boot will add missing
                 * parts if it determines to use PSCI.
                 */
-               entry-method = "arm,psci";
+               entry-method = "psci";
 
                CPU_PH20: cpu-ph20 {
                        compatible = "arm,idle-state";
index f5017dba0f17f97343b98410eee65bcfb84cc35f..d6caaea57d904bb56340691a7317931a23df6932 100644 (file)
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
  * QorIQ FMan v3 device tree nodes for ls1046
  *
  * Copyright 2015-2016 Freescale Semiconductor Inc.
  *
- * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
  */
 
 &soc {
index 434383bade0edc50df2b9176ae37e1961b7fc90b..e69306e6b0b180af5c8f9f69af82abdb6b367e37 100644 (file)
@@ -1,47 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Freescale Layerscape-1046A family SoC.
  *
  * Copyright 2016 Freescale Semiconductor, Inc.
  *
  * Shaohui Xie <Shaohui.Xie@nxp.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 5dc2782e2a58e785c8ec0263d2f2faafe9c07987..440e111651d53d9bba85763f0a04cde2796022b3 100644 (file)
@@ -1,47 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Freescale Layerscape-1046A family SoC.
  *
  * Copyright 2016 Freescale Semiconductor, Inc.
  *
  * Mingkai Hu <mingkai.hu@nxp.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 136ebfa9b3332018f24dce132d6acc6b6b5c5326..ef83786b8b905d57852ad6637bd2d4dfb5683c43 100644 (file)
@@ -1,47 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Freescale Layerscape-1046A family SoC.
  *
  * Copyright 2016 Freescale Semiconductor, Inc.
  *
  * Mingkai Hu <mingkai.hu@nxp.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -87,6 +50,7 @@
                        clocks = <&clockgen 1 0>;
                        next-level-cache = <&l2>;
                        cpu-idle-states = <&CPU_PH20>;
+                       #cooling-cells = <2>;
                };
 
                cpu2: cpu@2 {
@@ -96,6 +60,7 @@
                        clocks = <&clockgen 1 0>;
                        next-level-cache = <&l2>;
                        cpu-idle-states = <&CPU_PH20>;
+                       #cooling-cells = <2>;
                };
 
                cpu3: cpu@3 {
                        clocks = <&clockgen 1 0>;
                        next-level-cache = <&l2>;
                        cpu-idle-states = <&CPU_PH20>;
+                       #cooling-cells = <2>;
                };
 
                l2: l2-cache {
                 * PSCI node is not added default, U-boot will add missing
                 * parts if it determines to use PSCI.
                 */
-               entry-method = "arm,psci";
+               entry-method = "psci";
 
                CPU_PH20: cpu-ph20 {
                        compatible = "arm,idle-state";
index 30128051d0c02ea3da6b61dc0b352a0216955eed..6f48d21b97c0450386ff3c1503e384faa0625e23 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for NXP LS1088A QDS Board.
  *
@@ -5,43 +6,6 @@
  *
  * Harninder Rai <harninder.rai@nxp.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 4f17601b919cf8e50fbd6925993b35a7ee989848..8e925df6c01c048b92add464297de5b1529a3482 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for NXP LS1088A RDB Board.
  *
@@ -5,43 +6,6 @@
  *
  * Harninder Rai <harninder.rai@nxp.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 1c6556bcfddf83375de077c69a00625aa05f2403..a07f612ab56b7be9453b80dd50023f1ded9569b9 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for NXP Layerscape-1088A family SoC.
  *
@@ -5,43 +6,6 @@
  *
  * Harninder Rai <harninder.rai@nxp.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/thermal/thermal.h>
@@ -76,6 +40,7 @@
                        reg = <0x1>;
                        clocks = <&clockgen 1 0>;
                        cpu-idle-states = <&CPU_PH20>;
+                       #cooling-cells = <2>;
                };
 
                cpu2: cpu@2 {
@@ -84,6 +49,7 @@
                        reg = <0x2>;
                        clocks = <&clockgen 1 0>;
                        cpu-idle-states = <&CPU_PH20>;
+                       #cooling-cells = <2>;
                };
 
                cpu3: cpu@3 {
@@ -92,6 +58,7 @@
                        reg = <0x3>;
                        clocks = <&clockgen 1 0>;
                        cpu-idle-states = <&CPU_PH20>;
+                       #cooling-cells = <2>;
                };
 
                cpu4: cpu@100 {
                        reg = <0x101>;
                        clocks = <&clockgen 1 1>;
                        cpu-idle-states = <&CPU_PH20>;
+                       #cooling-cells = <2>;
                };
 
                cpu6: cpu@102 {
                        reg = <0x102>;
                        clocks = <&clockgen 1 1>;
                        cpu-idle-states = <&CPU_PH20>;
+                       #cooling-cells = <2>;
                };
 
                cpu7: cpu@103 {
                        reg = <0x103>;
                        clocks = <&clockgen 1 1>;
                        cpu-idle-states = <&CPU_PH20>;
+                       #cooling-cells = <2>;
                };
 
                CPU_PH20: cpu-ph20 {
index 3c99608b9b45d25b0b2f03ccb0bf4b69cfd3c9de..f6c3ee78ace06c494466223e236988212c25e866 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Freescale LS2080a QDS Board.
  *
@@ -7,43 +8,6 @@
  * Abhimanyu Saini <abhimanyu.saini@nxp.com>
  * Bhupesh Sharma <bhupesh.sharma@freescale.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index a4e7de9f70d8553a05a567589bdf0be6098a674c..44894356059ce0f0f405331220536ab6e8e55d88 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Freescale LS2080a RDB Board.
  *
@@ -7,43 +8,6 @@
  * Abhimanyu Saini <abhimanyu.saini@nxp.com>
  * Bhupesh Sharma <bhupesh.sharma@freescale.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index fbbb73e571c06f0db11909372958fa3ba0a6d334..5517305039a4230263aa3ed8d528934bafe430b1 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Freescale LS2080a software Simulator model
  *
@@ -5,43 +6,6 @@
  *
  * Bhupesh Sharma <bhupesh.sharma@freescale.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 8d739301e7b8acbb34951d2b843553bcc101f1e8..f9c1d30cf4a7df64d7e877d6be18fa156d16faa6 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Freescale Layerscape-2080A family SoC.
  *
@@ -6,43 +7,6 @@
  * Abhimanyu Saini <abhimanyu.saini@nxp.com>
  * Bhupesh Sharma <bhupesh.sharma@freescale.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "fsl-ls208xa.dtsi"
@@ -65,6 +29,7 @@
                clocks = <&clockgen 1 0>;
                cpu-idle-states = <&CPU_PW20>;
                next-level-cache = <&cluster0_l2>;
+               #cooling-cells = <2>;
        };
 
        cpu2: cpu@100 {
@@ -84,6 +49,7 @@
                clocks = <&clockgen 1 1>;
                cpu-idle-states = <&CPU_PW20>;
                next-level-cache = <&cluster1_l2>;
+               #cooling-cells = <2>;
        };
 
        cpu4: cpu@200 {
                clocks = <&clockgen 1 2>;
                cpu-idle-states = <&CPU_PW20>;
                next-level-cache = <&cluster2_l2>;
+               #cooling-cells = <2>;
        };
 
        cpu6: cpu@300 {
                clocks = <&clockgen 1 3>;
                cpu-idle-states = <&CPU_PW20>;
                next-level-cache = <&cluster3_l2>;
+               #cooling-cells = <2>;
        };
 
        cluster0_l2: l2-cache0 {
index eaee5b1c3a448ac95952b6548c6a2d5ac5ddfc26..7c17b1bd4529a0f411565e561da918eb950951a4 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Freescale LS2088A QDS Board.
  *
@@ -6,43 +7,6 @@
  *
  * Abhimanyu Saini <abhimanyu.saini@nxp.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index c411442cac62cb2e1309a9759d5959050d247659..f6b4d75a258bed0d3852c9c85ba6dcb72be9452a 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Freescale LS2088A RDB Board.
  *
@@ -6,43 +7,6 @@
  *
  * Abhimanyu Saini <abhimanyu.saini@nxp.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 0884e1a7790111b0b55d535da3bc6081327f493e..7c882da3f6b0e176b9af449705c699322cdf4e0b 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Freescale Layerscape-2088A family SoC.
  *
@@ -6,43 +7,6 @@
  *
  * Abhimanyu Saini <abhimanyu.saini@nxp.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "fsl-ls208xa.dtsi"
@@ -65,6 +29,7 @@
                clocks = <&clockgen 1 0>;
                cpu-idle-states = <&CPU_PW20>;
                next-level-cache = <&cluster0_l2>;
+               #cooling-cells = <2>;
        };
 
        cpu2: cpu@100 {
@@ -84,6 +49,7 @@
                clocks = <&clockgen 1 1>;
                cpu-idle-states = <&CPU_PW20>;
                next-level-cache = <&cluster1_l2>;
+               #cooling-cells = <2>;
        };
 
        cpu4: cpu@200 {
                clocks = <&clockgen 1 2>;
                cpu-idle-states = <&CPU_PW20>;
                next-level-cache = <&cluster2_l2>;
+               #cooling-cells = <2>;
        };
 
        cpu6: cpu@300 {
                clocks = <&clockgen 1 3>;
                cpu-idle-states = <&CPU_PW20>;
                next-level-cache = <&cluster3_l2>;
+               #cooling-cells = <2>;
        };
 
        cluster0_l2: l2-cache0 {
index 1de618801c736a0ebaa753ab4dfce8c27b3e370d..c11f52e7ae9aa67701297688a8b71edd2fb33d7e 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Freescale LS2080A QDS Board.
  *
@@ -6,43 +7,6 @@
  *
  * Abhimanyu Saini <abhimanyu.saini@nxp.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 &esdhc {
index 061647bd97b8a6246d94b41d0c64027769036a02..6fd7f63085c9be6b066ea4a485c19835088df909 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree file for Freescale LS2080A RDB Board.
  *
@@ -6,43 +7,6 @@
  *
  * Abhimanyu Saini <abhimanyu.saini@nxp.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 &esdhc {
index 137ef4dfc3e9f1d4667833ea690d7c0d3386f961..8cb78dd9967281d06c1cd10c4a55b0bebe337e6e 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Device Tree Include file for Freescale Layerscape-2080A family SoC.
  *
@@ -6,43 +7,6 @@
  *
  * Abhimanyu Saini <abhimanyu.saini@nxp.com>
  *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPLv2 or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/thermal/thermal.h>
index ae15307f6e8bf5d679f02dfe4a523df5b93511af..ff1aba5fae7f829122c3ce42d4df616e15f434c7 100644 (file)
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
  * QorIQ BMan Portals device tree
  *
  * Copyright 2011-2016 Freescale Semiconductor Inc.
  *
- * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
  */
 
 &bportals {
index ecdffe731b98b260ecd22cdf78575fa8d2e82c38..dbd2fc3ba790ee8d82c89a37b80bfef5b3246554 100644 (file)
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
  * QorIQ FMan v3 10g port #0 device tree
  *
  * Copyright 2012-2015 Freescale Semiconductor Inc.
  *
- * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
  */
 
 fman@1a00000 {
index a7f6af56b6a5a7e75e6aec21384ad7500e7022de..6fc5d256005715d8394030c06b5fab6950cf1938 100644 (file)
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
  * QorIQ FMan v3 10g port #1 device tree
  *
  * Copyright 2012-2015 Freescale Semiconductor Inc.
  *
- * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
  */
 
 fman@1a00000 {
index d600786719fb2d8f958f7de8dd9e8bf8ad15997e..4e02276fcf993f718b23eef7663395d32e40d4e2 100644 (file)
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
  * QorIQ FMan v3 1g port #0 device tree
  *
  * Copyright 2012-2015 Freescale Semiconductor Inc.
  *
- * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
  */
 
 fman@1a00000 {
index 3c0b76d43043f0f7b388bfda67fce315c87b9a8c..0312fa43fa777aae684da3f880d04c60bec2e232 100644 (file)
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
  * QorIQ FMan v3 1g port #1 device tree
  *
  * Copyright 2012-2015 Freescale Semiconductor Inc.
  *
- * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
  */
 
 fman@1a00000 {
index 89633afca26ac21218ba76db2eeac05fa564d265..af2df07971dd9bea91a30e95715dc2b652965877 100644 (file)
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
  * QorIQ FMan v3 1g port #2 device tree
  *
  * Copyright 2012-2015 Freescale Semiconductor Inc.
  *
- * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
  */
 
 fman@1a00000 {
index 87c2b705b1f96b6a3003d09a260a39c862bffedf..4ac98dc8b227932ab27f29535c02c90e2ccccd62 100644 (file)
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
  * QorIQ FMan v3 1g port #3 device tree
  *
  * Copyright 2012-2015 Freescale Semiconductor Inc.
  *
- * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
  */
 
 fman@1a00000 {
index 8f4d74b96b678b486dd598ff5a1963ae14e41b54..bd932d8b0160ba136b398197c2abc41980d6be47 100644 (file)
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
  * QorIQ FMan v3 1g port #4 device tree
  *
  * Copyright 2012-2015 Freescale Semiconductor Inc.
  *
- * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
  */
 
 fman@1a00000 {
index d534f770f7295ba7cd39f4ea4be35ca09d2254f2..7de1c5203f3e20019d8028521b917b71d19db163 100644 (file)
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
  * QorIQ FMan v3 1g port #5 device tree
  *
  * Copyright 2012-2015 Freescale Semiconductor Inc.
  *
- * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
  */
 
 fman@1a00000 {
index 4664c33e0763e942ed07ecf37ab20a47057d1858..263b972a6d1e9f2772ec36a4855647cde24c0316 100644 (file)
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
  * QorIQ FMan v3 device tree
  *
  * Copyright 2012-2015 Freescale Semiconductor Inc.
  *
- * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
  */
 
 fman0: fman@1a00000 {
index 6a93a4a9be0e8ac62c91f61d57895cd4f90892a5..e3bec08b110d280552c9e34964ce668fd29eba0a 100644 (file)
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
  * QorIQ QMan Portals device tree
  *
  * Copyright 2011-2016 Freescale Semiconductor Inc.
  *
- * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
  */
 
 &qportals {
index 68c5a6c819aef2c3fbe8b59aac695cfb0c3a3a77..c98bcbc8dfba33386f5cf7d66fcc8a6c9480d817 100644 (file)
 };
 
 &dwmmc1 {
+       bus-width = <0x4>;
+       cap-sd-highspeed;
+       sd-uhs-sdr12;
+       sd-uhs-sdr25;
+       sd-uhs-sdr50;
+       sd-uhs-sdr104;
+       disable-wp;
+       cd-inverted;
+       cd-gpios = <&gpio25 3 0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sd_pmx_func
+                    &sd_clk_cfg_func
+                    &sd_cfg_func>;
        vmmc-supply = <&ldo16>;
        vqmmc-supply = <&ldo9>;
        status = "okay";
 };
 
 &dwmmc2 { /* WIFI */
+       bus-width = <0x4>;
+       non-removable;
        broken-cd;
+       cap-power-off-card;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdio_pmx_func
+                    &sdio_clk_cfg_func
+                    &sdio_cfg_func>;
        /* WL_EN */
        vmmc-supply = <&wlan_en>;
-       ti,non-removable;
-       non-removable;
-       cap-power-off-card;
-       keep-power-in-suspend;
-       #address-cells = <0x1>;
-       #size-cells = <0x0>;
        status = "ok";
 
        wlcore: wlcore@2 {
index 851190a719ea9de4d0dbc663721a915ca92516fa..f432b0a88c65dc6bb961572eea1399a33557d35c 100644 (file)
@@ -61,7 +61,7 @@
                        reg = <0x0 0x0>;
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
-                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_0>;
+                       cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
                        capacity-dmips-mhz = <592>;
                        clocks = <&stub_clock HI3660_CLK_STUB_CLUSTER0>;
                        operating-points-v2 = <&cluster0_opp>;
@@ -75,7 +75,7 @@
                        reg = <0x0 0x1>;
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
-                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_0>;
+                       cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
                        capacity-dmips-mhz = <592>;
                        clocks = <&stub_clock HI3660_CLK_STUB_CLUSTER0>;
                        operating-points-v2 = <&cluster0_opp>;
@@ -87,7 +87,7 @@
                        reg = <0x0 0x2>;
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
-                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_0>;
+                       cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
                        capacity-dmips-mhz = <592>;
                        clocks = <&stub_clock HI3660_CLK_STUB_CLUSTER0>;
                        operating-points-v2 = <&cluster0_opp>;
@@ -99,7 +99,7 @@
                        reg = <0x0 0x3>;
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
-                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_0>;
+                       cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
                        capacity-dmips-mhz = <592>;
                        clocks = <&stub_clock HI3660_CLK_STUB_CLUSTER0>;
                        operating-points-v2 = <&cluster0_opp>;
                        reg = <0x0 0x100>;
                        enable-method = "psci";
                        next-level-cache = <&A73_L2>;
-                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_1>;
+                       cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_1>;
                        capacity-dmips-mhz = <1024>;
                        clocks = <&stub_clock HI3660_CLK_STUB_CLUSTER1>;
                        operating-points-v2 = <&cluster1_opp>;
                        reg = <0x0 0x101>;
                        enable-method = "psci";
                        next-level-cache = <&A73_L2>;
-                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_1>;
+                       cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_1>;
                        capacity-dmips-mhz = <1024>;
                        clocks = <&stub_clock HI3660_CLK_STUB_CLUSTER1>;
                        operating-points-v2 = <&cluster1_opp>;
                        reg = <0x0 0x102>;
                        enable-method = "psci";
                        next-level-cache = <&A73_L2>;
-                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_1>;
+                       cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_1>;
                        capacity-dmips-mhz = <1024>;
                        clocks = <&stub_clock HI3660_CLK_STUB_CLUSTER1>;
                        operating-points-v2 = <&cluster1_opp>;
                        reg = <0x0 0x103>;
                        enable-method = "psci";
                        next-level-cache = <&A73_L2>;
-                       cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_1>;
+                       cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_1>;
                        capacity-dmips-mhz = <1024>;
                        clocks = <&stub_clock HI3660_CLK_STUB_CLUSTER1>;
                        operating-points-v2 = <&cluster1_opp>;
                idle-states {
                        entry-method = "psci";
 
-                       CPU_SLEEP: cpu-sleep {
+                       CPU_SLEEP_0: cpu-sleep-0 {
                                compatible = "arm,idle-state";
                                local-timer-stop;
                                arm,psci-suspend-param = <0x0010000>;
-                               entry-latency-us = <40>;
-                               exit-latency-us = <70>;
-                               min-residency-us = <3000>;
+                               entry-latency-us = <400>;
+                               exit-latency-us = <650>;
+                               min-residency-us = <1500>;
                        };
-
                        CLUSTER_SLEEP_0: cluster-sleep-0 {
                                compatible = "arm,idle-state";
                                local-timer-stop;
                                arm,psci-suspend-param = <0x1010000>;
                                entry-latency-us = <500>;
-                               exit-latency-us = <5000>;
-                               min-residency-us = <20000>;
+                               exit-latency-us = <1600>;
+                               min-residency-us = <3500>;
+                       };
+
+
+                       CPU_SLEEP_1: cpu-sleep-1 {
+                               compatible = "arm,idle-state";
+                               local-timer-stop;
+                               arm,psci-suspend-param = <0x0010000>;
+                               entry-latency-us = <400>;
+                               exit-latency-us = <550>;
+                               min-residency-us = <1500>;
                        };
 
                        CLUSTER_SLEEP_1: cluster-sleep-1 {
                                compatible = "arm,idle-state";
                                local-timer-stop;
                                arm,psci-suspend-param = <0x1010000>;
-                               entry-latency-us = <1000>;
-                               exit-latency-us = <5000>;
-                               min-residency-us = <20000>;
+                               entry-latency-us = <800>;
+                               exit-latency-us = <2900>;
+                               min-residency-us = <3500>;
                        };
                };
 
 
                /* SD */
                dwmmc1: dwmmc1@ff37f000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       cd-inverted;
                        compatible = "hisilicon,hi3660-dw-mshc";
-                       bus-width = <0x4>;
-                       disable-wp;
-                       cap-sd-highspeed;
-                       supports-highspeed;
-                       card-detect-delay = <200>;
                        reg = <0x0 0xff37f000 0x0 0x1000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
                        interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&crg_ctrl HI3660_CLK_GATE_SD>,
                                <&crg_ctrl HI3660_HCLK_GATE_SD>;
                        clock-frequency = <3200000>;
                        resets = <&crg_rst 0x94 18>;
                        reset-names = "reset";
-                       cd-gpios = <&gpio25 3 0>;
                        hisilicon,peripheral-syscon = <&sctrl>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&sd_pmx_func
-                                    &sd_clk_cfg_func
-                                    &sd_cfg_func>;
-                       sd-uhs-sdr12;
-                       sd-uhs-sdr25;
-                       sd-uhs-sdr50;
-                       sd-uhs-sdr104;
+                       card-detect-delay = <200>;
                        status = "disabled";
-
-                       slot@0 {
-                               reg = <0x0>;
-                               bus-width = <4>;
-                               disable-wp;
-                       };
                };
 
                /* SDIO */
                dwmmc2: dwmmc2@ff3ff000 {
                        compatible = "hisilicon,hi3660-dw-mshc";
                        reg = <0x0 0xff3ff000 0x0 0x1000>;
+                       #address-cells = <0x1>;
+                       #size-cells = <0x0>;
                        interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&crg_ctrl HI3660_CLK_GATE_SDIO0>,
                                 <&crg_ctrl HI3660_HCLK_GATE_SDIO0>;
                        resets = <&crg_rst 0x94 20>;
                        reset-names = "reset";
                        card-detect-delay = <200>;
-                       supports-highspeed;
-                       keep-power-in-suspend;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&sdio_pmx_func
-                                    &sdio_clk_cfg_func
-                                    &sdio_cfg_func>;
                        status = "disabled";
                };
 
index 7f12624f6c8e8c6af0a3900f3e7d703a969c6c0e..f4964bee6a1a9b7b7e0ab2063f3c2987253c9096 100644 (file)
                        bus-width = <0x4>;
                        non-removable;
                        cap-power-off-card;
-                       keep-power-in-suspend;
                        vmmc-supply = <&reg_vdd_3v3>;
                        mmc-pwrseq = <&wl1835_pwrseq>;
 
index 586b281cd5312d711e115eb3fe4734b125e476d3..247024df714fce9ab1d85ee4dc73a5bec948f99c 100644 (file)
@@ -88,8 +88,8 @@
                        next-level-cache = <&CLUSTER0_L2>;
                        clocks = <&stub_clock 0>;
                        operating-points-v2 = <&cpu_opp_table>;
-                       #cooling-cells = <2>; /* min followed by max */
                        cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+                       #cooling-cells = <2>; /* min followed by max */
                        dynamic-power-coefficient = <311>;
                };
 
                        next-level-cache = <&CLUSTER0_L2>;
                        operating-points-v2 = <&cpu_opp_table>;
                        cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+                       #cooling-cells = <2>; /* min followed by max */
+                       dynamic-power-coefficient = <311>;
                };
 
                cpu2: cpu@2 {
                        next-level-cache = <&CLUSTER0_L2>;
                        operating-points-v2 = <&cpu_opp_table>;
                        cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+                       #cooling-cells = <2>; /* min followed by max */
+                       dynamic-power-coefficient = <311>;
                };
 
                cpu3: cpu@3 {
                        next-level-cache = <&CLUSTER0_L2>;
                        operating-points-v2 = <&cpu_opp_table>;
                        cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+                       #cooling-cells = <2>; /* min followed by max */
+                       dynamic-power-coefficient = <311>;
                };
 
                cpu4: cpu@100 {
                        next-level-cache = <&CLUSTER1_L2>;
                        operating-points-v2 = <&cpu_opp_table>;
                        cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+                       #cooling-cells = <2>; /* min followed by max */
+                       dynamic-power-coefficient = <311>;
                };
 
                cpu5: cpu@101 {
                        next-level-cache = <&CLUSTER1_L2>;
                        operating-points-v2 = <&cpu_opp_table>;
                        cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+                       #cooling-cells = <2>; /* min followed by max */
+                       dynamic-power-coefficient = <311>;
                };
 
                cpu6: cpu@102 {
                        next-level-cache = <&CLUSTER1_L2>;
                        operating-points-v2 = <&cpu_opp_table>;
                        cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+                       #cooling-cells = <2>; /* min followed by max */
+                       dynamic-power-coefficient = <311>;
                };
 
                cpu7: cpu@103 {
                        next-level-cache = <&CLUSTER1_L2>;
                        operating-points-v2 = <&cpu_opp_table>;
                        cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+                       #cooling-cells = <2>; /* min followed by max */
+                       dynamic-power-coefficient = <311>;
                };
 
                CLUSTER0_L2: l2-cache0 {
index 3353252d78a0a93bd65b693f0516b38abe86fc75..d9531e242eb4c859545dad19d4bbb6c12e1c3a66 100644 (file)
                serial1 = &uart1;
        };
 
+       reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               /*
+                * The PSCI firmware region depicted below is the default one
+                * and should be updated by the bootloader.
+                */
+               psci-area@4000000 {
+                       reg = <0 0x4000000 0 0x200000>;
+                       no-map;
+               };
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                                status = "disabled";
                        };
 
+                       avs: avs@11500 {
+                               compatible = "marvell,armada-3700-avs",
+                                            "syscon";
+                               reg = <0x11500 0x40>;
+                       };
+
                        uart0: serial@12000 {
                                compatible = "marvell,armada-3700-uart";
                                reg = <0x12000 0x200>;
                        };
 
                        crypto: crypto@90000 {
-                               compatible = "inside-secure,safexcel-eip97";
+                               compatible = "inside-secure,safexcel-eip97ies";
                                reg = <0x90000 0x20000>;
                                interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
index a66958ff4de6e493e6c2a6eaf62c546389d99397..56fa448609094beffda8eb4e47b9ee4dbc224506 100644 (file)
@@ -91,7 +91,7 @@
        };
 
        sfp_eth3: sfp-eth3 {
-               /* CON3,4 - CPS lane 5 */
+               /* CON13,14 - CPS lane 5 */
                compatible = "sff,sfp";
                i2c-bus = <&sfp_1g_i2c>;
                los-gpio = <&cp0_gpio2 22 GPIO_ACTIVE_HIGH>;
index 1c6ff8197a88b1f890fed5b592b9358986942145..840c8454d03e3e81770a718e8e6aa17f53298ec6 100644 (file)
                };
 
                CP110_LABEL(crypto): crypto@800000 {
-                       compatible = "inside-secure,safexcel-eip197";
+                       compatible = "inside-secure,safexcel-eip197b";
                        reg = <0x800000 0x200000>;
                        interrupts = <ICU_GRP_NSR 87 IRQ_TYPE_LEVEL_HIGH>,
                                <ICU_GRP_NSR 88 IRQ_TYPE_LEVEL_HIGH>,
index ac17f60f998c58ed21a7c134dffae9436752b553..5b7fd6ad96e424b2ba4b656b388968ff3e3c7d72 100644 (file)
@@ -3,5 +3,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt2712-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6755-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb
index 6d8532af834688d96e1bdb7394c3d2821da393e4..75cc0f7cc088869f219d66da2fad2592acd5153e 100644 (file)
                };
 
                idle-states {
-                       entry-method = "arm,psci";
+                       entry-method = "psci";
 
                        CPU_SLEEP_0: cpu-sleep-0 {
                                compatible = "arm,idle-state";
diff --git a/arch/arm64/boot/dts/mediatek/mt6797-x20-dev.dts b/arch/arm64/boot/dts/mediatek/mt6797-x20-dev.dts
new file mode 100644 (file)
index 0000000..742938a
--- /dev/null
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for MediaTek X20 Development Board
+ *
+ * Copyright (C) 2018, Linaro Ltd.
+ *
+ */
+
+/dts-v1/;
+
+#include "mt6797.dtsi"
+
+/ {
+       model = "Mediatek X20 Development Board";
+       compatible = "archermind,mt6797-x20-dev", "mediatek,mt6797";
+
+       aliases {
+               serial0 = &uart1;
+       };
+
+       memory@40000000 {
+               device_type = "memory";
+               reg = <0 0x40000000 0 0x80000000>;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&uart1 {
+       status = "okay";
+};
index b7837642c33a8b6aae187b8c6df2dc71c9994edb..a747b7bf132d1dafe8ff4d6b5ebcaaa5b7021f1e 100644 (file)
@@ -18,7 +18,7 @@
        compatible = "mediatek,mt7622-rfb1", "mediatek,mt7622";
 
        chosen {
-               bootargs = "console=ttyS0,115200n1 swiotlb=512";
+               bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512";
        };
 
        cpus {
@@ -34,7 +34,7 @@
        };
 
        gpio-keys {
-               compatible = "gpio-keys-polled";
+               compatible = "gpio-keys";
                poll-interval = <100>;
 
                factory {
index 9213c966c2242ee6c8a14d270ffeb4712533f54f..de2c47bdbe6468698ca6c2548b5a08b6386c7b93 100644 (file)
@@ -89,6 +89,7 @@
                                 <&apmixedsys CLK_APMIXED_MAIN_CORE_EN>;
                        clock-names = "cpu", "intermediate";
                        operating-points-v2 = <&cpu_opp_table>;
+                       #cooling-cells = <2>;
                        enable-method = "psci";
                        clock-frequency = <1300000000>;
                };
 
        pio: pinctrl@10211000 {
                compatible = "mediatek,mt7622-pinctrl";
-               reg = <0 0x10211000 0 0x1000>;
+               reg = <0 0x10211000 0 0x1000>,
+                     <0 0x10005000 0 0x1000>;
+               reg-names = "base", "eint";
                gpio-controller;
                #gpio-cells = <2>;
+               gpio-ranges = <&pio 0 0 103>;
+               interrupt-controller;
+               interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-parent = <&gic>;
+               #interrupt-cells = <2>;
        };
 
        watchdog: watchdog@10212000 {
                reg = <0 0x11002000 0 0x400>;
                interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
                clocks = <&topckgen CLK_TOP_UART_SEL>,
-                        <&pericfg CLK_PERI_UART1_PD>;
+                        <&pericfg CLK_PERI_UART0_PD>;
                clock-names = "baud", "bus";
                status = "disabled";
        };
index 94597e33c8065eb4b12ee805885988991d43e42c..abd2f15a544b24f7f411456389897f7b4a52a47b 100644 (file)
                        reg = <0x001>;
                        enable-method = "psci";
                        cpu-idle-states = <&CPU_SLEEP_0>;
+                       #cooling-cells = <2>;
                        clocks = <&infracfg CLK_INFRA_CA53SEL>,
                                 <&apmixedsys CLK_APMIXED_MAINPLL>;
                        clock-names = "cpu", "intermediate";
                        reg = <0x101>;
                        enable-method = "psci";
                        cpu-idle-states = <&CPU_SLEEP_0>;
+                       #cooling-cells = <2>;
                        clocks = <&infracfg CLK_INFRA_CA57SEL>,
                                 <&apmixedsys CLK_APMIXED_MAINPLL>;
                        clock-names = "cpu", "intermediate";
index ecb034177fc2c2bd070df72e56f120f08f7829aa..57d3f00464cea6605559adb79fbac78aff3d7e9d 100644 (file)
        };
 
        cbb {
+               ethernet@2490000 {
+                       status = "okay";
+
+                       phy-reset-gpios = <&gpio TEGRA194_MAIN_GPIO(G, 5) GPIO_ACTIVE_LOW>;
+                       phy-handle = <&phy>;
+                       phy-mode = "rgmii";
+
+                       mdio {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               phy: phy@0 {
+                                       compatible = "ethernet-phy-ieee802.3-c22";
+                                       reg = <0x0>;
+                                       interrupt-parent = <&gpio>;
+                                       interrupts = <TEGRA194_MAIN_GPIO(G, 4) IRQ_TYPE_LEVEL_LOW>;
+                               };
+                       };
+               };
+
                serial@3110000 {
                        status = "okay";
                };
 
                /* SDMMC1 (SD/MMC) */
                sdhci@3400000 {
-/*
                        cd-gpios = <&gpio TEGRA194_MAIN_GPIO(A, 0) GPIO_ACTIVE_LOW>;
-*/
                };
 
                /* SDMMC4 (eMMC) */
index 6322ef265c2ffa6464ca221afa58b1305dc69440..a4dfcd19b9e88965187cd24e23116103b0f7e652 100644 (file)
                #size-cells = <1>;
                ranges = <0x0 0x0 0x0 0x40000000>;
 
+               gpio: gpio@2200000 {
+                       compatible = "nvidia,tegra194-gpio";
+                       reg-names = "security", "gpio";
+                       reg = <0x2200000 0x10000>,
+                             <0x2210000 0x10000>;
+                       interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 296 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+               };
+
+               ethernet@2490000 {
+                       compatible = "nvidia,tegra186-eqos",
+                                    "snps,dwc-qos-ethernet-4.10";
+                       reg = <0x02490000 0x10000>;
+                       interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&bpmp TEGRA194_CLK_AXI_CBB>,
+                                <&bpmp TEGRA194_CLK_EQOS_AXI>,
+                                <&bpmp TEGRA194_CLK_EQOS_RX>,
+                                <&bpmp TEGRA194_CLK_EQOS_TX>,
+                                <&bpmp TEGRA194_CLK_EQOS_PTP_REF>;
+                       clock-names = "master_bus", "slave_bus", "rx", "tx", "ptp_ref";
+                       resets = <&bpmp TEGRA194_RESET_EQOS>;
+                       reset-names = "eqos";
+                       status = "disabled";
+
+                       snps,write-requests = <1>;
+                       snps,read-requests = <3>;
+                       snps,burst-map = <0x7>;
+                       snps,txpbl = <16>;
+                       snps,rxpbl = <8>;
+               };
+
                uarta: serial@3100000 {
                        compatible = "nvidia,tegra194-uart", "nvidia,tegra20-uart";
                        reg = <0x03100000 0x40>;
                };
        };
 
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       compatible = "nvidia,tegra194-carmel", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x10000>;
+                       enable-method = "psci";
+               };
+
+               cpu@1 {
+                       compatible = "nvidia,tegra194-carmel", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x10001>;
+                       enable-method = "psci";
+               };
+
+               cpu@2 {
+                       compatible = "nvidia,tegra194-carmel", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x100>;
+                       enable-method = "psci";
+               };
+
+               cpu@3 {
+                       compatible = "nvidia,tegra194-carmel", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x101>;
+                       enable-method = "psci";
+               };
+
+               cpu@4 {
+                       compatible = "nvidia,tegra194-carmel", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x200>;
+                       enable-method = "psci";
+               };
+
+               cpu@5 {
+                       compatible = "nvidia,tegra194-carmel", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x201>;
+                       enable-method = "psci";
+               };
+
+               cpu@6 {
+                       compatible = "nvidia,tegra194-carmel", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x10300>;
+                       enable-method = "psci";
+               };
+
+               cpu@7 {
+                       compatible = "nvidia,tegra194-carmel", "arm,armv8";
+                       device_type = "cpu";
+                       reg = <0x10301>;
+                       enable-method = "psci";
+               };
+       };
+
+       psci {
+               compatible = "arm,psci-1.0";
+               status = "okay";
+               method = "smc";
+       };
+
        timer {
                compatible = "arm,armv8-timer";
                interrupts = <GIC_PPI 13
index 9ff848792712d60236435c1542b060d4c85494f2..78ce3979ef096fd1dc3059c9d8e9e9f44ca56ba9 100644 (file)
                        led@6 {
                                label = "apq8016-sbc:blue:bt";
                                gpios = <&pm8916_mpps 3 GPIO_ACTIVE_HIGH>;
-                               linux,default-trigger = "bt";
+                               linux,default-trigger = "bluetooth-power";
                                default-state = "off";
                        };
                };
index 4d5ef01f43a331c456eddf1a324f1e1d450bcea5..0ef90c6554a9885260c41dff9bbb6b627dc6ddac 100644 (file)
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/gpio/gpio.h>
 
+/*
+ * GPIO name legend: proper name = the GPIO line is used as GPIO
+ *         NC      = not connected (pin out but not routed from the chip to
+ *                   anything the board)
+ *         "[PER]" = pin is muxed for [peripheral] (not GPIO)
+ *         LSEC    = Low Speed External Connector
+ *         P HSEC  = Primary High Speed External Connector
+ *         S HSEC  = Secondary High Speed External Connector
+ *         J14     = Camera Connector
+ *         TP      = Test Points
+ *
+ * Line names are taken from the schematic "DragonBoard 820c",
+ * drawing no: LM25-P2751-1
+ *
+ * For the lines routed to the external connectors the
+ * lines are named after the 96Boards CE Specification 1.0,
+ * Appendix "Expansion Connector Signal Description".
+ *
+ * When the 96Board naming of a line and the schematic name of
+ * the same line are in conflict, the 96Board specification
+ * takes precedence, which means that the external UART on the
+ * LSEC is named UART0 while the schematic and SoC names this
+ * UART3. This is only for the informational lines i.e. "[FOO]",
+ * the GPIO named lines "GPIO-A" thru "GPIO-L" are the only
+ * ones actually used for GPIO.
+ */
+
 / {
        aliases {
                serial0 = &blsp2_uart1;
                        status = "okay";
                };
 
+               pinctrl@1010000 {
+                       gpio-line-names =
+                               "[SPI0_DOUT]", /* GPIO_0, BLSP1_SPI_MOSI, LSEC pin 14 */
+                               "[SPI0_DIN]", /* GPIO_1, BLSP1_SPI_MISO, LSEC pin 10 */
+                               "[SPI0_CS]", /* GPIO_2, BLSP1_SPI_CS_N, LSEC pin 12 */
+                               "[SPI0_SCLK]", /* GPIO_3, BLSP1_SPI_CLK, LSEC pin 8 */
+                               "[UART1_TxD]", /* GPIO_4, BLSP8_UART_TX, LSEC pin 11 */
+                               "[UART1_RxD]", /* GPIO_5, BLSP8_UART_RX, LSEC pin 13 */
+                               "[I2C1_SDA]", /* GPIO_6, BLSP8_I2C_SDA, LSEC pin 21 */
+                               "[I2C1_SCL]", /* GPIO_7, BLSP8_I2C_SCL, LSEC pin 19 */
+                               "GPIO-H", /* GPIO_8, LCD0_RESET_N, LSEC pin 30 */
+                               "TP93", /* GPIO_9 */
+                               "GPIO-G", /* GPIO_10, MDP_VSYNC_P, LSEC pin 29 */
+                               "[MDP_VSYNC_S]", /* GPIO_11, S HSEC pin 55 */
+                               "NC", /* GPIO_12 */
+                               "[CSI0_MCLK]", /* GPIO_13, CAM_MCLK0, P HSEC pin 15 */
+                               "[CAM_MCLK1]", /* GPIO_14, J14 pin 11 */
+                               "[CSI1_MCLK]", /* GPIO_15, CAM_MCLK2, P HSEC pin 17 */
+                               "TP99", /* GPIO_16 */
+                               "[I2C2_SDA]", /* GPIO_17, CCI_I2C_SDA0, P HSEC pin 34 */
+                               "[I2C2_SCL]", /* GPIO_18, CCI_I2C_SCL0, P HSEC pin 32 */
+                               "[CCI_I2C_SDA1]", /* GPIO_19, S HSEC pin 38 */
+                               "[CCI_I2C_SCL1]", /* GPIO_20, S HSEC pin 36 */
+                               "FLASH_STROBE_EN", /* GPIO_21, S HSEC pin 5 */
+                               "FLASH_STROBE_TRIG", /* GPIO_22, S HSEC pin 1 */
+                               "GPIO-K", /* GPIO_23, CAM2_RST_N, LSEC pin 33 */
+                               "GPIO-D", /* GPIO_24, LSEC pin 26 */
+                               "GPIO-I", /* GPIO_25, CAM0_RST_N, LSEC pin 31 */
+                               "GPIO-J", /* GPIO_26, CAM0_STANDBY_N, LSEC pin 32 */
+                               "BLSP6_I2C_SDA", /* GPIO_27 */
+                               "BLSP6_I2C_SCL", /* GPIO_28 */
+                               "GPIO-B", /* GPIO_29, TS0_RESET_N, LSEC pin 24 */
+                               "GPIO30", /* GPIO_30, S HSEC pin 4 */
+                               "HDMI_CEC", /* GPIO_31 */
+                               "HDMI_DDC_CLOCK", /* GPIO_32 */
+                               "HDMI_DDC_DATA", /* GPIO_33 */
+                               "HDMI_HOT_PLUG_DETECT", /* GPIO_34 */
+                               "PCIE0_RST_N", /* GPIO_35 */
+                               "PCIE0_CLKREQ_N", /* GPIO_36 */
+                               "PCIE0_WAKE", /* GPIO_37 */
+                               "SD_CARD_DET_N", /* GPIO_38 */
+                               "TSIF1_SYNC", /* GPIO_39, S HSEC pin 48 */
+                               "W_DISABLE_N", /* GPIO_40 */
+                               "[BLSP9_UART_TX]", /* GPIO_41 */
+                               "[BLSP9_UART_RX]", /* GPIO_42 */
+                               "[BLSP2_UART_CTS_N]", /* GPIO_43 */
+                               "[BLSP2_UART_RFR_N]", /* GPIO_44 */
+                               "[BLSP3_UART_TX]", /* GPIO_45 */
+                               "[BLSP3_UART_RX]", /* GPIO_46 */
+                               "[I2C0_SDA]", /* GPIO_47, LS_I2C0_SDA, LSEC pin 17 */
+                               "[I2C0_SCL]", /* GPIO_48, LS_I2C0_SCL, LSEC pin 15 */
+                               "[UART0_TxD]", /* GPIO_49, BLSP9_UART_TX, LSEC pin 5 */
+                               "[UART0_RxD]", /* GPIO_50, BLSP9_UART_RX, LSEC pin 7 */
+                               "[UART0_CTS]", /* GPIO_51, BLSP9_UART_CTS_N, LSEC pin 3 */
+                               "[UART0_RTS]", /* GPIO_52, BLSP9_UART_RFR_N, LSEC pin 9 */
+                               "[CODEC_INT1_N]", /* GPIO_53 */
+                               "[CODEC_INT2_N]", /* GPIO_54 */
+                               "[BLSP7_I2C_SDA]", /* GPIO_55 */
+                               "[BLSP7_I2C_SCL]", /* GPIO_56 */
+                               "MI2S_MCLK", /* GPIO_57, S HSEC pin 3 */
+                               "[PCM_CLK]", /* GPIO_58, QUA_MI2S_SCK, LSEC pin 18 */
+                               "[PCM_FS]", /* GPIO_59, QUA_MI2S_WS, LSEC pin 16 */
+                               "[PCM_DO]", /* GPIO_60, QUA_MI2S_DATA0, LSEC pin 20 */
+                               "[PCM_DI]", /* GPIO_61, QUA_MI2S_DATA1, LSEC pin 22 */
+                               "GPIO-E", /* GPIO_62, LSEC pin 27 */
+                               "TP87", /* GPIO_63 */
+                               "[CODEC_RST_N]", /* GPIO_64 */
+                               "[PCM1_CLK]", /* GPIO_65 */
+                               "[PCM1_SYNC]", /* GPIO_66 */
+                               "[PCM1_DIN]", /* GPIO_67 */
+                               "[PCM1_DOUT]", /* GPIO_68 */
+                               "AUDIO_REF_CLK", /* GPIO_69 */
+                               "SLIMBUS_CLK", /* GPIO_70 */
+                               "SLIMBUS_DATA0", /* GPIO_71 */
+                               "SLIMBUS_DATA1", /* GPIO_72 */
+                               "NC", /* GPIO_73 */
+                               "NC", /* GPIO_74 */
+                               "NC", /* GPIO_75 */
+                               "NC", /* GPIO_76 */
+                               "TP94", /* GPIO_77 */
+                               "NC", /* GPIO_78 */
+                               "TP95", /* GPIO_79 */
+                               "GPIO-A", /* GPIO_80, MEMS_RESET_N, LSEC pin 23 */
+                               "TP88", /* GPIO_81 */
+                               "TP89", /* GPIO_82 */
+                               "TP90", /* GPIO_83 */
+                               "TP91", /* GPIO_84 */
+                               "[SD_DAT0]", /* GPIO_85, BLSP12_SPI_MOSI, P HSEC pin 1 */
+                               "[SD_CMD]", /* GPIO_86, BLSP12_SPI_MISO, P HSEC pin 11 */
+                               "[SD_DAT3]", /* GPIO_87, BLSP12_SPI_CS_N, P HSEC pin 7 */
+                               "[SD_SCLK]", /* GPIO_88, BLSP12_SPI_CLK, P HSEC pin 9 */
+                               "TSIF1_CLK", /* GPIO_89, S HSEC pin 42 */
+                               "TSIF1_EN", /* GPIO_90, S HSEC pin 46 */
+                               "TSIF1_DATA", /* GPIO_91, S HSEC pin 44 */
+                               "NC", /* GPIO_92 */
+                               "TSIF2_CLK", /* GPIO_93, S HSEC pin 52 */
+                               "TSIF2_EN", /* GPIO_94, S HSEC pin 56 */
+                               "TSIF2_DATA", /* GPIO_95, S HSEC pin 54 */
+                               "TSIF2_SYNC", /* GPIO_96, S HSEC pin 58 */
+                               "NC", /* GPIO_97 */
+                               "CAM1_STANDBY_N", /* GPIO_98 */
+                               "NC", /* GPIO_99 */
+                               "NC", /* GPIO_100 */
+                               "[LCD1_RESET_N]", /* GPIO_101, S HSEC pin 51 */
+                               "BOOT_CONFIG1", /* GPIO_102 */
+                               "USB_HUB_RESET", /* GPIO_103 */
+                               "CAM1_RST_N", /* GPIO_104 */
+                               "NC", /* GPIO_105 */
+                               "NC", /* GPIO_106 */
+                               "NC", /* GPIO_107 */
+                               "NC", /* GPIO_108 */
+                               "NC", /* GPIO_109 */
+                               "NC", /* GPIO_110 */
+                               "NC", /* GPIO_111 */
+                               "NC", /* GPIO_112 */
+                               "PMI8994_BUA", /* GPIO_113 */
+                               "PCIE2_RST_N", /* GPIO_114 */
+                               "PCIE2_CLKREQ_N", /* GPIO_115 */
+                               "PCIE2_WAKE", /* GPIO_116 */
+                               "SSC_IRQ_0", /* GPIO_117 */
+                               "SSC_IRQ_1", /* GPIO_118 */
+                               "SSC_IRQ_2", /* GPIO_119 */
+                               "NC", /* GPIO_120 */
+                               "GPIO121", /* GPIO_121, S HSEC pin 2 */
+                               "NC", /* GPIO_122 */
+                               "SSC_IRQ_6", /* GPIO_123 */
+                               "SSC_IRQ_7", /* GPIO_124 */
+                               "GPIO-C", /* GPIO_125, TS_INT0, LSEC pin 25 */
+                               "BOOT_CONFIG5", /* GPIO_126 */
+                               "NC", /* GPIO_127 */
+                               "NC", /* GPIO_128 */
+                               "BOOT_CONFIG7", /* GPIO_129 */
+                               "PCIE1_RST_N", /* GPIO_130 */
+                               "PCIE1_CLKREQ_N", /* GPIO_131 */
+                               "PCIE1_WAKE", /* GPIO_132 */
+                               "GPIO-L", /* GPIO_133, CAM2_STANDBY_N, LSEC pin 34 */
+                               "NC", /* GPIO_134 */
+                               "NC", /* GPIO_135 */
+                               "BOOT_CONFIG8", /* GPIO_136 */
+                               "NC", /* GPIO_137 */
+                               "NC", /* GPIO_138 */
+                               "GPS_SSBI2", /* GPIO_139 */
+                               "GPS_SSBI1", /* GPIO_140 */
+                               "NC", /* GPIO_141 */
+                               "NC", /* GPIO_142 */
+                               "NC", /* GPIO_143 */
+                               "BOOT_CONFIG6", /* GPIO_144 */
+                               "NC", /* GPIO_145 */
+                               "NC", /* GPIO_146 */
+                               "NC", /* GPIO_147 */
+                               "NC", /* GPIO_148 */
+                               "NC"; /* GPIO_149 */
+               };
+
+               qcom,spmi@400f000 {
+                       pmic@0 {
+                               gpios@c000 {
+                                       gpio-line-names =
+                                               "NC",
+                                               "KEY_VOLP_N",
+                                               "NC",
+                                               "BL1_PWM",
+                                               "GPIO-F", /* BL0_PWM, LSEC pin 28 */
+                                               "BL1_EN",
+                                               "NC",
+                                               "WLAN_EN",
+                                               "NC",
+                                               "NC",
+                                               "NC",
+                                               "NC",
+                                               "NC",
+                                               "NC",
+                                               "DIVCLK1",
+                                               "DIVCLK2",
+                                               "DIVCLK3",
+                                               "DIVCLK4",
+                                               "BT_EN",
+                                               "PMIC_SLB",
+                                               "PMIC_BUA",
+                                               "USB_VBUS_DET";
+                               };
+
+                               mpps@a000 {
+                                       gpio-line-names =
+                                               "VDDPX_BIAS",
+                                               "WIFI_LED",
+                                               "NC",
+                                               "BT_LED",
+                                               "PM_MPP05",
+                                               "PM_MPP06",
+                                               "PM_MPP07",
+                                               "NC";
+                               };
+                       };
+
+                       pmic@2 {
+                               gpios@c000 {
+                                       gpio-line-names =
+                                               "NC",
+                                               "SPKR_AMP_EN1",
+                                               "SPKR_AMP_EN2",
+                                               "TP61",
+                                               "NC",
+                                               "USB2_VBUS_DET",
+                                               "NC",
+                                               "NC",
+                                               "NC",
+                                               "NC";
+                               };
+                       };
+               };
+
                phy@34000 {
                        status = "okay";
                };
index c2625d15a8c08f535e6f00f5c8228212c4d7ec5f..7b32b8990d62fb22acdbbf287929162fb826f480 100644 (file)
                        clocks = <&gcc GCC_MDSS_AHB_CLK>,
                                 <&gcc GCC_MDSS_AXI_CLK>,
                                 <&gcc GCC_MDSS_VSYNC_CLK>;
-                       clock-names = "iface_clk",
-                                     "bus_clk",
-                                     "vsync_clk";
+                       clock-names = "iface",
+                                     "bus",
+                                     "vsync";
 
                        interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>;
 
                                         <&gcc GCC_MDSS_AXI_CLK>,
                                         <&gcc GCC_MDSS_MDP_CLK>,
                                         <&gcc GCC_MDSS_VSYNC_CLK>;
-                               clock-names = "iface_clk",
-                                             "bus_clk",
-                                             "core_clk",
-                                             "vsync_clk";
+                               clock-names = "iface",
+                                             "bus",
+                                             "core",
+                                             "vsync";
 
                                iommus = <&apps_iommu 4>;
 
                                         <&gcc GCC_MDSS_BYTE0_CLK>,
                                         <&gcc GCC_MDSS_PCLK0_CLK>,
                                         <&gcc GCC_MDSS_ESC0_CLK>;
-                               clock-names = "mdp_core_clk",
-                                             "iface_clk",
-                                             "bus_clk",
-                                             "byte_clk",
-                                             "pixel_clk",
-                                             "core_clk";
+                               clock-names = "mdp_core",
+                                             "iface",
+                                             "bus",
+                                             "byte",
+                                             "pixel",
+                                             "core";
                                phys = <&dsi_phy0>;
                                phy-names = "dsi-phy";
 
                                #phy-cells = <0>;
 
                                clocks = <&gcc GCC_MDSS_AHB_CLK>;
-                               clock-names = "iface_clk";
+                               clock-names = "iface";
                        };
                };
 
index 8c7f9ca25b5340f51be48abca6e435f5a6293f7e..cd3865e7a270b97e1913c779fa7ad3448d3e5660 100644 (file)
                        reg = <0x740000 0x20000>;
                };
 
+               tsens0: thermal-sensor@4a9000 {
+                       compatible = "qcom,msm8996-tsens";
+                       reg = <0x4a9000 0x1000>, /* TM */
+                             <0x4a8000 0x1000>; /* SROT */
+                       #qcom,sensors = <13>;
+                       #thermal-sensor-cells = <1>;
+               };
+
+               tsens1: thermal-sensor@4ad000 {
+                       compatible = "qcom,msm8996-tsens";
+                       reg = <0x4ad000 0x1000>, /* TM */
+                             <0x4ac000 0x1000>; /* SROT */
+                       #qcom,sensors = <8>;
+                       #thermal-sensor-cells = <1>;
+               };
+
                tcsr: syscon@7a0000 {
                        compatible = "qcom,tcsr-msm8996", "syscon";
                        reg = <0x7a0000 0x18000>;
                        status = "disabled";
                };
 
-               tsens0: thermal-sensor@4a8000 {
-                       compatible = "qcom,msm8996-tsens";
-                       reg = <0x4a8000 0x2000>;
-                       #thermal-sensor-cells = <1>;
-               };
-
                blsp2_uart1: serial@75b0000 {
                        compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
                        reg = <0x75b0000 0x1000>;
diff --git a/arch/arm64/boot/dts/qcom/pm8005.dtsi b/arch/arm64/boot/dts/qcom/pm8005.dtsi
new file mode 100644 (file)
index 0000000..4d5aca3
--- /dev/null
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/* Copyright 2018 Google LLC. */
+
+#include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+&spmi_bus {
+       pm8005_lsid0: pmic@4 {
+               compatible = "qcom,pm8005", "qcom,spmi-pmic";
+               reg = <0x4 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               pm8005_gpio: gpios@c000 {
+                       compatible = "qcom,pm8005-gpio", "qcom,spmi-gpio";
+                       reg = <0xc000>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupts = <0 0xc0 0 IRQ_TYPE_NONE>,
+                                    <0 0xc1 0 IRQ_TYPE_NONE>,
+                                    <0 0xc2 0 IRQ_TYPE_NONE>,
+                                    <0 0xc3 0 IRQ_TYPE_NONE>;
+               };
+
+       };
+
+       pm8005_lsid1: pmic@5 {
+               compatible = "qcom,pm8005", "qcom,spmi-pmic";
+               reg = <0x5 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+};
diff --git a/arch/arm64/boot/dts/qcom/pm8998.dtsi b/arch/arm64/boot/dts/qcom/pm8998.dtsi
new file mode 100644 (file)
index 0000000..92bed1e
--- /dev/null
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/* Copyright 2018 Google LLC. */
+
+#include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+&spmi_bus {
+       pm8998_lsid0: pmic@0 {
+               compatible = "qcom,pm8998", "qcom,spmi-pmic";
+               reg = <0x0 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               pm8998_gpio: gpios@c000 {
+                       compatible = "qcom,pm8998-gpio", "qcom,spmi-gpio";
+                       reg = <0xc000>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupts = <0 0xc0 0 IRQ_TYPE_NONE>,
+                                    <0 0xc1 0 IRQ_TYPE_NONE>,
+                                    <0 0xc2 0 IRQ_TYPE_NONE>,
+                                    <0 0xc3 0 IRQ_TYPE_NONE>,
+                                    <0 0xc4 0 IRQ_TYPE_NONE>,
+                                    <0 0xc5 0 IRQ_TYPE_NONE>,
+                                    <0 0xc6 0 IRQ_TYPE_NONE>,
+                                    <0 0xc7 0 IRQ_TYPE_NONE>,
+                                    <0 0xc8 0 IRQ_TYPE_NONE>,
+                                    <0 0xc9 0 IRQ_TYPE_NONE>,
+                                    <0 0xca 0 IRQ_TYPE_NONE>,
+                                    <0 0xcb 0 IRQ_TYPE_NONE>,
+                                    <0 0xcc 0 IRQ_TYPE_NONE>,
+                                    <0 0xcd 0 IRQ_TYPE_NONE>,
+                                    <0 0xce 0 IRQ_TYPE_NONE>,
+                                    <0 0xcf 0 IRQ_TYPE_NONE>,
+                                    <0 0xd0 0 IRQ_TYPE_NONE>,
+                                    <0 0xd1 0 IRQ_TYPE_NONE>,
+                                    <0 0xd2 0 IRQ_TYPE_NONE>,
+                                    <0 0xd3 0 IRQ_TYPE_NONE>,
+                                    <0 0xd4 0 IRQ_TYPE_NONE>,
+                                    <0 0xd5 0 IRQ_TYPE_NONE>,
+                                    <0 0xd6 0 IRQ_TYPE_NONE>,
+                                    <0 0xd7 0 IRQ_TYPE_NONE>,
+                                    <0 0xd8 0 IRQ_TYPE_NONE>,
+                                    <0 0xd9 0 IRQ_TYPE_NONE>;
+               };
+
+       };
+
+       pm8998_lsid1: pmic@1 {
+               compatible = "qcom,pm8998", "qcom,spmi-pmic";
+               reg = <0x1 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+};
index 979ab49913f1c825612114ac62b6538ef31471d7..6d651f314193724e024d099a2f7a9ae32fc26f5f 100644 (file)
 / {
        model = "Qualcomm Technologies, Inc. SDM845 MTP";
        compatible = "qcom,sdm845-mtp";
+
+       aliases {
+               serial0 = &uart9;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&i2c10 {
+       status = "okay";
+       clock-frequency = <400000>;
+};
+
+&qupv3_id_1 {
+       status = "okay";
+};
+
+&uart9 {
+       status = "okay";
+};
+
+/* PINCTRL - additions to nodes defined in sdm845.dtsi */
+
+&qup_i2c10_default {
+       pinconf {
+               pins = "gpio55", "gpio56";
+               drive-strength = <2>;
+               bias-disable;
+       };
+};
+
+&qup_uart9_default {
+       pinconf-tx {
+               pins = "gpio4";
+               drive-strength = <2>;
+               bias-disable;
+       };
+
+       pinconf-rx {
+               pins = "gpio5";
+               drive-strength = <2>;
+               bias-pull-up;
+       };
 };
index cdaabeb3c9950ec69cd62322bd487f7530d7edec..0c9a2aa6a1b5235fa5307784045d6e14ac036435 100644 (file)
@@ -5,7 +5,10 @@
  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
  */
 
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/qcom,rpmh-rsc.h>
 
 / {
        interrupt-parent = <&intc>;
        #address-cells = <2>;
        #size-cells = <2>;
 
+       aliases {
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
+               i2c3 = &i2c3;
+               i2c4 = &i2c4;
+               i2c5 = &i2c5;
+               i2c6 = &i2c6;
+               i2c7 = &i2c7;
+               i2c8 = &i2c8;
+               i2c9 = &i2c9;
+               i2c10 = &i2c10;
+               i2c11 = &i2c11;
+               i2c12 = &i2c12;
+               i2c13 = &i2c13;
+               i2c14 = &i2c14;
+               i2c15 = &i2c15;
+               spi0 = &spi0;
+               spi1 = &spi1;
+               spi2 = &spi2;
+               spi3 = &spi3;
+               spi4 = &spi4;
+               spi5 = &spi5;
+               spi6 = &spi6;
+               spi7 = &spi7;
+               spi8 = &spi8;
+               spi9 = &spi9;
+               spi10 = &spi10;
+               spi11 = &spi11;
+               spi12 = &spi12;
+               spi13 = &spi13;
+               spi14 = &spi14;
+               spi15 = &spi15;
+       };
+
        chosen { };
 
        memory@80000000 {
                };
        };
 
+       pmu {
+               compatible = "arm,armv8-pmuv3";
+               interrupts = <GIC_PPI 5 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
        timer {
                compatible = "arm,armv8-timer";
                interrupts = <GIC_PPI 1 IRQ_TYPE_LEVEL_LOW>,
                        #power-domain-cells = <1>;
                };
 
+               qupv3_id_0: geniqup@8c0000 {
+                       compatible = "qcom,geni-se-qup";
+                       reg = <0x8c0000 0x6000>;
+                       clock-names = "m-ahb", "s-ahb";
+                       clocks = <&gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>,
+                                <&gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+                       status = "disabled";
+
+                       i2c0: i2c@880000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0x880000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c0_default>;
+                               interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi0: spi@880000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0x880000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi0_default>;
+                               interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@884000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0x884000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c1_default>;
+                               interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi1: spi@884000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0x884000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi1_default>;
+                               interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c2: i2c@888000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0x888000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c2_default>;
+                               interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi2: spi@888000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0x888000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi2_default>;
+                               interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c3: i2c@88c000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0x88c000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c3_default>;
+                               interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi3: spi@88c000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0x88c000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi3_default>;
+                               interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c4: i2c@890000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0x890000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S4_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c4_default>;
+                               interrupts = <GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi4: spi@890000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0x890000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S4_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi4_default>;
+                               interrupts = <GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c5: i2c@894000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0x894000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c5_default>;
+                               interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi5: spi@894000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0x894000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi5_default>;
+                               interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c6: i2c@898000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0x898000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S6_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c6_default>;
+                               interrupts = <GIC_SPI 607 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi6: spi@898000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0x898000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S6_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi6_default>;
+                               interrupts = <GIC_SPI 607 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c7: i2c@89c000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0x89c000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S7_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c7_default>;
+                               interrupts = <GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi7: spi@89c000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0x89c000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S7_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi7_default>;
+                               interrupts = <GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+               };
+
+               qupv3_id_1: geniqup@ac0000 {
+                       compatible = "qcom,geni-se-qup";
+                       reg = <0xac0000 0x6000>;
+                       clock-names = "m-ahb", "s-ahb";
+                       clocks = <&gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>,
+                                <&gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+                       status = "disabled";
+
+                       i2c8: i2c@a80000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0xa80000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c8_default>;
+                               interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi8: spi@a80000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0xa80000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi8_default>;
+                               interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c9: i2c@a84000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0xa84000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c9_default>;
+                               interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi9: spi@a84000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0xa84000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi9_default>;
+                               interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       uart9: serial@a84000 {
+                               compatible = "qcom,geni-debug-uart";
+                               reg = <0xa84000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_uart9_default>;
+                               interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+
+                       i2c10: i2c@a88000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0xa88000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c10_default>;
+                               interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi10: spi@a88000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0xa88000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi10_default>;
+                               interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c11: i2c@a8c000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0xa8c000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c11_default>;
+                               interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi11: spi@a8c000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0xa8c000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi11_default>;
+                               interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c12: i2c@a90000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0xa90000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c12_default>;
+                               interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi12: spi@a90000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0xa90000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi12_default>;
+                               interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c13: i2c@a94000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0xa94000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c13_default>;
+                               interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi13: spi@a94000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0xa94000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi13_default>;
+                               interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c14: i2c@a98000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0xa98000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c14_default>;
+                               interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi14: spi@a98000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0xa98000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi14_default>;
+                               interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2c15: i2c@a9c000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0xa9c000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S7_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c15_default>;
+                               interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi15: spi@a9c000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0xa9c000 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S7_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi15_default>;
+                               interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+               };
+
                tcsr_mutex_regs: syscon@1f40000 {
                        compatible = "syscon";
                        reg = <0x1f40000 0x40000>;
                        #gpio-cells = <2>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
+
+                       qup_i2c0_default: qup-i2c0-default {
+                               pinmux {
+                                       pins = "gpio0", "gpio1";
+                                       function = "qup0";
+                               };
+                       };
+
+                       qup_i2c1_default: qup-i2c1-default {
+                               pinmux {
+                                       pins = "gpio17", "gpio18";
+                                       function = "qup1";
+                               };
+                       };
+
+                       qup_i2c2_default: qup-i2c2-default {
+                               pinmux {
+                                       pins = "gpio27", "gpio28";
+                                       function = "qup2";
+                               };
+                       };
+
+                       qup_i2c3_default: qup-i2c3-default {
+                               pinmux {
+                                       pins = "gpio41", "gpio42";
+                                       function = "qup3";
+                               };
+                       };
+
+                       qup_i2c4_default: qup-i2c4-default {
+                               pinmux {
+                                       pins = "gpio89", "gpio90";
+                                       function = "qup4";
+                               };
+                       };
+
+                       qup_i2c5_default: qup-i2c5-default {
+                               pinmux {
+                                       pins = "gpio85", "gpio86";
+                                       function = "qup5";
+                               };
+                       };
+
+                       qup_i2c6_default: qup-i2c6-default {
+                               pinmux {
+                                       pins = "gpio45", "gpio46";
+                                       function = "qup6";
+                               };
+                       };
+
+                       qup_i2c7_default: qup-i2c7-default {
+                               pinmux {
+                                       pins = "gpio93", "gpio94";
+                                       function = "qup7";
+                               };
+                       };
+
+                       qup_i2c8_default: qup-i2c8-default {
+                               pinmux {
+                                       pins = "gpio65", "gpio66";
+                                       function = "qup8";
+                               };
+                       };
+
+                       qup_i2c9_default: qup-i2c9-default {
+                               pinmux {
+                                       pins = "gpio6", "gpio7";
+                                       function = "qup9";
+                               };
+                       };
+
+                       qup_i2c10_default: qup-i2c10-default {
+                               pinmux {
+                                       pins = "gpio55", "gpio56";
+                                       function = "qup10";
+                               };
+                       };
+
+                       qup_i2c11_default: qup-i2c11-default {
+                               pinmux {
+                                       pins = "gpio31", "gpio32";
+                                       function = "qup11";
+                               };
+                       };
+
+                       qup_i2c12_default: qup-i2c12-default {
+                               pinmux {
+                                       pins = "gpio49", "gpio50";
+                                       function = "qup12";
+                               };
+                       };
+
+                       qup_i2c13_default: qup-i2c13-default {
+                               pinmux {
+                                       pins = "gpio105", "gpio106";
+                                       function = "qup13";
+                               };
+                       };
+
+                       qup_i2c14_default: qup-i2c14-default {
+                               pinmux {
+                                       pins = "gpio33", "gpio34";
+                                       function = "qup14";
+                               };
+                       };
+
+                       qup_i2c15_default: qup-i2c15-default {
+                               pinmux {
+                                       pins = "gpio81", "gpio82";
+                                       function = "qup15";
+                               };
+                       };
+
+                       qup_spi0_default: qup-spi0-default {
+                               pinmux {
+                                       pins = "gpio0", "gpio1",
+                                              "gpio2", "gpio3";
+                                       function = "qup0";
+                               };
+                       };
+
+                       qup_spi1_default: qup-spi1-default {
+                               pinmux {
+                                       pins = "gpio17", "gpio18",
+                                              "gpio19", "gpio20";
+                                       function = "qup1";
+                               };
+                       };
+
+                       qup_spi2_default: qup-spi2-default {
+                               pinmux {
+                                       pins = "gpio27", "gpio28",
+                                              "gpio29", "gpio30";
+                                       function = "qup2";
+                               };
+                       };
+
+                       qup_spi3_default: qup-spi3-default {
+                               pinmux {
+                                       pins = "gpio41", "gpio42",
+                                              "gpio43", "gpio44";
+                                       function = "qup3";
+                               };
+                       };
+
+                       qup_spi4_default: qup-spi4-default {
+                               pinmux {
+                                       pins = "gpio89", "gpio90",
+                                              "gpio91", "gpio92";
+                                       function = "qup4";
+                               };
+                       };
+
+                       qup_spi5_default: qup-spi5-default {
+                               pinmux {
+                                       pins = "gpio85", "gpio86",
+                                              "gpio87", "gpio88";
+                                       function = "qup5";
+                               };
+                       };
+
+                       qup_spi6_default: qup-spi6-default {
+                               pinmux {
+                                       pins = "gpio45", "gpio46",
+                                              "gpio47", "gpio48";
+                                       function = "qup6";
+                               };
+                       };
+
+                       qup_spi7_default: qup-spi7-default {
+                               pinmux {
+                                       pins = "gpio93", "gpio94",
+                                              "gpio95", "gpio96";
+                                       function = "qup7";
+                               };
+                       };
+
+                       qup_spi8_default: qup-spi8-default {
+                               pinmux {
+                                       pins = "gpio65", "gpio66",
+                                              "gpio67", "gpio68";
+                                       function = "qup8";
+                               };
+                       };
+
+                       qup_spi9_default: qup-spi9-default {
+                               pinmux {
+                                       pins = "gpio6", "gpio7",
+                                              "gpio4", "gpio5";
+                                       function = "qup9";
+                               };
+                       };
+
+                       qup_spi10_default: qup-spi10-default {
+                               pinmux {
+                                       pins = "gpio55", "gpio56",
+                                              "gpio53", "gpio54";
+                                       function = "qup10";
+                               };
+                       };
+
+                       qup_spi11_default: qup-spi11-default {
+                               pinmux {
+                                       pins = "gpio31", "gpio32",
+                                              "gpio33", "gpio34";
+                                       function = "qup11";
+                               };
+                       };
+
+                       qup_spi12_default: qup-spi12-default {
+                               pinmux {
+                                       pins = "gpio49", "gpio50",
+                                              "gpio51", "gpio52";
+                                       function = "qup12";
+                               };
+                       };
+
+                       qup_spi13_default: qup-spi13-default {
+                               pinmux {
+                                       pins = "gpio105", "gpio106",
+                                              "gpio107", "gpio108";
+                                       function = "qup13";
+                               };
+                       };
+
+                       qup_spi14_default: qup-spi14-default {
+                               pinmux {
+                                       pins = "gpio33", "gpio34",
+                                              "gpio31", "gpio32";
+                                       function = "qup14";
+                               };
+                       };
+
+                       qup_spi15_default: qup-spi15-default {
+                               pinmux {
+                                       pins = "gpio81", "gpio82",
+                                              "gpio83", "gpio84";
+                                       function = "qup15";
+                               };
+                       };
+
+                       qup_uart9_default: qup-uart9-default {
+                               pinmux {
+                                       pins = "gpio4", "gpio5";
+                                       function = "qup9";
+                               };
+                       };
+               };
+
+               tsens0: thermal-sensor@c263000 {
+                       compatible = "qcom,sdm845-tsens", "qcom,tsens-v2";
+                       reg = <0xc263000 0x1ff>, /* TM */
+                             <0xc222000 0x1ff>; /* SROT */
+                       #qcom,sensors = <13>;
+                       #thermal-sensor-cells = <1>;
+               };
+
+               tsens1: thermal-sensor@c265000 {
+                       compatible = "qcom,sdm845-tsens", "qcom,tsens-v2";
+                       reg = <0xc265000 0x1ff>, /* TM */
+                             <0xc223000 0x1ff>; /* SROT */
+                       #qcom,sensors = <8>;
+                       #thermal-sensor-cells = <1>;
                };
 
                spmi_bus: spmi@c440000 {
                        #mbox-cells = <1>;
                };
 
+               apps_rsc: rsc@179c0000 {
+                       label = "apps_rsc";
+                       compatible = "qcom,rpmh-rsc";
+                       reg = <0x179c0000 0x10000>,
+                             <0x179d0000 0x10000>,
+                             <0x179e0000 0x10000>;
+                       reg-names = "drv-0", "drv-1", "drv-2";
+                       interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+                       qcom,tcs-offset = <0xd00>;
+                       qcom,drv-id = <2>;
+                       qcom,tcs-config = <ACTIVE_TCS  2>,
+                                         <SLEEP_TCS   3>,
+                                         <WAKE_TCS    3>,
+                                         <CONTROL_TCS 1>;
+
+                       rpmhcc: clock-controller {
+                               compatible = "qcom,sdm845-rpmh-clk";
+                               #clock-cells = <1>;
+                       };
+               };
+
                intc: interrupt-controller@17a00000 {
                        compatible = "arm,gic-v3";
                        #address-cells = <1>;
index 009cb1cb0dde53e2e307d4a64c75eaca8971a417..2f24dfc45617baf6c6f35e963c2d77490f476ea9 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the H3ULCB Kingfisher board
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
  * Copyright (C) 2017 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include "r8a7795-es1-h3ulcb.dts"
index dd4f9b6a42546defb7b1161ce4e589c25f739d5c..598b98168559e0e4d83b045cf700ccca69f8335b 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the H3ULCB (R-Car Starter Kit Premier) board
  *
  * Copyright (C) 2016 Renesas Electronics Corp.
  * Copyright (C) 2016 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /dts-v1/;
index 3f46345a46447fce1ae323b1f632330a4af4a5a3..6b5fa91f1d5d33d38a80a8d39ffb0f5baf92d764 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Salvator-X board with R-Car H3 ES1.x
  *
  * Copyright (C) 2015 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /dts-v1/;
index e19dcd6cb76793d77bfbb91b01560b84fd6c283d..7b2fbaec9aef8d71fb1b9fbb04f0f8b1630b0bab 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the r8a7795 ES1.x SoC
  *
  * Copyright (C) 2015 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include "r8a7795.dtsi"
@@ -80,7 +77,7 @@
 
        vspd3: vsp@fea38000 {
                compatible = "renesas,vsp2";
-               reg = <0 0xfea38000 0 0x8000>;
+               reg = <0 0xfea38000 0 0x5000>;
                interrupts = <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cpg CPG_MOD 620>;
                power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
index 4403227c0f97bed01aedfdbf9617b62639bdcfda..80791ed27539bf8fc967972e3d5ebb933d8d5e1e 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the H3ULCB Kingfisher board
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
  * Copyright (C) 2017 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include "r8a7795-h3ulcb.dts"
index 0afe777973dec8b7e8fa41b1d521652ba450914a..df50bf46406e6e904f31541e1767a1dfe8b4b25a 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the H3ULCB (R-Car Starter Kit Premier) board
  *
  * Copyright (C) 2016 Renesas Electronics Corp.
  * Copyright (C) 2016 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /dts-v1/;
index 0efbef5ea9b7871d3b67065f92e83464f9bf4bc0..446822f5751c77e8a78fe599c8f818a7db8d51f5 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Salvator-X board with R-Car H3 ES2.0
  *
  * Copyright (C) 2015 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /dts-v1/;
index e231b5a7cbabe48a5921354dac31349a1b359e55..8ded64d0a4d56a82b7368b94dcaf285f4cb72e9c 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Salvator-X 2nd version board with R-Car H3 ES2.0
  *
  * Copyright (C) 2015-2017 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /dts-v1/;
index d842940b2f439d3500a79b1a7d924ee9e13f02da..fb9d08ad7659da7938b8cffecba6b41ada7b07dc 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the r8a7795 SoC
  *
  * Copyright (C) 2015 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include <dt-bindings/clock/r8a7795-cpg-mssr.h>
                #size-cells = <2>;
                ranges;
 
-               wdt0: watchdog@e6020000 {
+               rwdt: watchdog@e6020000 {
                        compatible = "renesas,r8a7795-wdt", "renesas,rcar-gen3-wdt";
                        reg = <0 0xe6020000 0 0x0c>;
                        clocks = <&cpg CPG_MOD 402>;
                        status = "disabled";
                };
 
+               arm_cc630p: crypto@e6601000 {
+                       compatible = "arm,cryptocell-630p-ree";
+                       interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+                       reg = <0x0 0xe6601000 0 0x1000>;
+                       clocks = <&cpg CPG_MOD 229>;
+                       resets = <&cpg 229>;
+                       power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+               };
+
                i2c3: i2c@e66d0000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
 
                vspd0: vsp@fea20000 {
                        compatible = "renesas,vsp2";
-                       reg = <0 0xfea20000 0 0x8000>;
+                       reg = <0 0xfea20000 0 0x5000>;
                        interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 623>;
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 
                vspd1: vsp@fea28000 {
                        compatible = "renesas,vsp2";
-                       reg = <0 0xfea28000 0 0x8000>;
+                       reg = <0 0xfea28000 0 0x5000>;
                        interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 622>;
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
 
                vspd2: vsp@fea30000 {
                        compatible = "renesas,vsp2";
-                       reg = <0 0xfea30000 0 0x8000>;
+                       reg = <0 0xfea30000 0 0x5000>;
                        interrupts = <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 621>;
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
index de2390f009e70de65b38643039f674ec02940da2..2df50eb11f165aaccefa4d2cb5f6d51c7de38788 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the M3ULCB Kingfisher board
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
  * Copyright (C) 2017 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include "r8a7796-m3ulcb.dts"
index daee1f1a3f68951b4a7615305d219bd4fa990469..cbd8acbf537e634ab461bd03c9459203440bfbd0 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the M3ULCB (R-Car Starter Kit Pro) board
  *
  * Copyright (C) 2016 Renesas Electronics Corp.
  * Copyright (C) 2016 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /dts-v1/;
index 90cca09b9a5e9cee8350bb95adb8a5b910652ffc..052d72acc862b83c659f0056deeb9fe720d875a6 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Salvator-X board with R-Car M3-W
  *
  * Copyright (C) 2016 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /dts-v1/;
index ddf35d4cd5e56f9d26ccbc0a1477421d6987dda7..8860be65342e4f388efeedb812907401ff0e9c35 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Salvator-X 2nd version board with R-Car M3-W
  *
  * Copyright (C) 2015-2017 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /dts-v1/;
index 7c25be6b5af3eea8cd6978b43e69409c8c5c078e..cbd35c00b4af6e2bde98edc29b67a2fedb4a323d 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the r8a7796 SoC
  *
- * Copyright (C) 2016 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
+ * Copyright (C) 2016-2017 Renesas Electronics Corp.
  */
 
 #include <dt-bindings/clock/r8a7796-cpg-mssr.h>
                #size-cells = <2>;
                ranges;
 
-               wdt0: watchdog@e6020000 {
+               rwdt: watchdog@e6020000 {
                        compatible = "renesas,r8a7796-wdt",
                                     "renesas,rcar-gen3-wdt";
                        reg = <0 0xe6020000 0 0x0c>;
                };
 
                pciec0: pcie@fe000000 {
+                       compatible = "renesas,pcie-r8a7796",
+                                    "renesas,pcie-rcar-gen3";
                        reg = <0 0xfe000000 0 0x80000>;
-                       /* placeholder */
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       bus-range = <0x00 0xff>;
+                       device_type = "pci";
+                       ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000
+                               0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000
+                               0x02000000 0 0x30000000 0 0x30000000 0 0x08000000
+                               0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
+                       /* Map all possible DDR as inbound ranges */
+                       dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>;
+                       interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0>;
+                       interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
+                       clock-names = "pcie", "pcie_bus";
+                       power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+                       resets = <&cpg 319>;
+                       status = "disabled";
                };
 
                pciec1: pcie@ee800000 {
+                       compatible = "renesas,pcie-r8a7796",
+                                    "renesas,pcie-rcar-gen3";
                        reg = <0 0xee800000 0 0x80000>;
-                       /* placeholder */
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       bus-range = <0x00 0xff>;
+                       device_type = "pci";
+                       ranges = <0x01000000 0 0x00000000 0 0xee900000 0 0x00100000
+                               0x02000000 0 0xeea00000 0 0xeea00000 0 0x00200000
+                               0x02000000 0 0xc0000000 0 0xc0000000 0 0x08000000
+                               0x42000000 0 0xc8000000 0 0xc8000000 0 0x08000000>;
+                       /* Map all possible DDR as inbound ranges */
+                       dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>;
+                       interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0>;
+                       interrupt-map = <0 0 0 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 318>, <&pcie_bus_clk>;
+                       clock-names = "pcie", "pcie_bus";
+                       power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+                       resets = <&cpg 318>;
+                       status = "disabled";
                };
 
                imr-lx4@fe860000 {
 
                vspd0: vsp@fea20000 {
                        compatible = "renesas,vsp2";
-                       reg = <0 0xfea20000 0 0x8000>;
+                       reg = <0 0xfea20000 0 0x5000>;
                        interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 623>;
                        power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
 
                vspd1: vsp@fea28000 {
                        compatible = "renesas,vsp2";
-                       reg = <0 0xfea28000 0 0x8000>;
+                       reg = <0 0xfea28000 0 0x5000>;
                        interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 622>;
                        power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
 
                vspd2: vsp@fea30000 {
                        compatible = "renesas,vsp2";
-                       reg = <0 0xfea30000 0 0x8000>;
+                       reg = <0 0xfea30000 0 0x5000>;
                        interrupts = <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 621>;
                        power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
index 486aecacb22abcf237e4739b988c7a31f6257d62..0cd44461a0bd218b830309f1e9b9f61509084492 100644 (file)
                #size-cells = <2>;
                ranges;
 
-               wdt0: watchdog@e6020000 {
+               rwdt: watchdog@e6020000 {
+                       compatible = "renesas,r8a77965-wdt",
+                                    "renesas,rcar-gen3-wdt";
                        reg = <0 0xe6020000 0 0x0c>;
-                       /* placeholder */
+                       clocks = <&cpg CPG_MOD 402>;
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       resets = <&cpg 402>;
+                       status = "disabled";
                };
 
                gpio0: gpio@e6050000 {
                        status = "disabled";
                };
 
+               hscif0: serial@e6540000 {
+                       compatible = "renesas,hscif-r8a77965",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe6540000 0 0x60>;
+                       interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 520>,
+                                <&cpg CPG_CORE R8A77965_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x31>, <&dmac1 0x30>,
+                              <&dmac2 0x31>, <&dmac2 0x30>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       resets = <&cpg 520>;
+                       status = "disabled";
+               };
+
+               hscif1: serial@e6550000 {
+                       compatible = "renesas,hscif-r8a77965",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe6550000 0 0x60>;
+                       interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 519>,
+                                <&cpg CPG_CORE R8A77965_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x33>, <&dmac1 0x32>,
+                              <&dmac2 0x33>, <&dmac2 0x32>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       resets = <&cpg 519>;
+                       status = "disabled";
+               };
+
+               hscif2: serial@e6560000 {
+                       compatible = "renesas,hscif-r8a77965",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe6560000 0 0x60>;
+                       interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 518>,
+                                <&cpg CPG_CORE R8A77965_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x35>, <&dmac1 0x34>,
+                              <&dmac2 0x35>, <&dmac2 0x34>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       resets = <&cpg 518>;
+                       status = "disabled";
+               };
+
+               hscif3: serial@e66a0000 {
+                       compatible = "renesas,hscif-r8a77965",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe66a0000 0 0x60>;
+                       interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 517>,
+                                <&cpg CPG_CORE R8A77965_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac0 0x37>, <&dmac0 0x36>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       resets = <&cpg 517>;
+                       status = "disabled";
+               };
+
+               hscif4: serial@e66b0000 {
+                       compatible = "renesas,hscif-r8a77965",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe66b0000 0 0x60>;
+                       interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 516>,
+                                <&cpg CPG_CORE R8A77965_CLK_S3D1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac0 0x39>, <&dmac0 0x38>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       resets = <&cpg 516>;
+                       status = "disabled";
+               };
+
                hsusb: usb@e6590000 {
                        compatible = "renesas,usbhs-r8a7796",
                                     "renesas,rcar-gen3-usbhs";
                        dma-channels = <16>;
                };
 
+               ipmmu_ds0: mmu@e6740000 {
+                       compatible = "renesas,ipmmu-r8a77965";
+                       reg = <0 0xe6740000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 0>;
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_ds1: mmu@e7740000 {
+                       compatible = "renesas,ipmmu-r8a77965";
+                       reg = <0 0xe7740000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 1>;
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_hc: mmu@e6570000 {
+                       compatible = "renesas,ipmmu-r8a77965";
+                       reg = <0 0xe6570000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 2>;
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_ir: mmu@ff8b0000 {
+                       compatible = "renesas,ipmmu-r8a77965";
+                       reg = <0 0xff8b0000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 3>;
+                       power-domains = <&sysc R8A77965_PD_A3IR>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_mm: mmu@e67b0000 {
+                       compatible = "renesas,ipmmu-r8a77965";
+                       reg = <0 0xe67b0000 0 0x1000>;
+                       interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_mp: mmu@ec670000 {
+                       compatible = "renesas,ipmmu-r8a77965";
+                       reg = <0 0xec670000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 4>;
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_pv0: mmu@fd800000 {
+                       compatible = "renesas,ipmmu-r8a77965";
+                       reg = <0 0xfd800000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 6>;
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_rt: mmu@ffc80000 {
+                       compatible = "renesas,ipmmu-r8a77965";
+                       reg = <0 0xffc80000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 10>;
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vc0: mmu@fe6b0000 {
+                       compatible = "renesas,ipmmu-r8a77965";
+                       reg = <0 0xfe6b0000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 12>;
+                       power-domains = <&sysc R8A77965_PD_A3VC>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vi0: mmu@febd0000 {
+                       compatible = "renesas,ipmmu-r8a77965";
+                       reg = <0 0xfebd0000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 14>;
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vp0: mmu@fe990000 {
+                       compatible = "renesas,ipmmu-r8a77965";
+                       reg = <0 0xfe990000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 16>;
+                       power-domains = <&sysc R8A77965_PD_A3VP>;
+                       #iommu-cells = <1>;
+               };
+
                avb: ethernet@e6800000 {
                        compatible = "renesas,etheravb-r8a77965",
                                     "renesas,etheravb-rcar-gen3";
                        reg = <0 0xe6e60000 0 64>;
                        interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 207>,
-                                <&cpg CPG_CORE 20>,
+                                <&cpg CPG_CORE R8A77965_CLK_S3D1>,
                                 <&scif_clk>;
                        clock-names = "fck", "brg_int", "scif_clk";
                        dmas = <&dmac1 0x51>, <&dmac1 0x50>,
                        reg = <0 0xe6e68000 0 64>;
                        interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 206>,
-                                <&cpg CPG_CORE 20>,
+                                <&cpg CPG_CORE R8A77965_CLK_S3D1>,
                                 <&scif_clk>;
                        clock-names = "fck", "brg_int", "scif_clk";
                        dmas = <&dmac1 0x53>, <&dmac1 0x52>,
                        reg = <0 0xe6e88000 0 64>;
                        interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 310>,
-                                <&cpg CPG_CORE 20>,
+                                <&cpg CPG_CORE R8A77965_CLK_S3D1>,
                                 <&scif_clk>;
                        clock-names = "fck", "brg_int", "scif_clk";
                        power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
                        reg = <0 0xe6c50000 0 64>;
                        interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 204>,
-                                <&cpg CPG_CORE 20>,
+                                <&cpg CPG_CORE R8A77965_CLK_S3D1>,
                                 <&scif_clk>;
                        clock-names = "fck", "brg_int", "scif_clk";
                        dmas = <&dmac0 0x57>, <&dmac0 0x56>;
                        reg = <0 0xe6c40000 0 64>;
                        interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 203>,
-                                <&cpg CPG_CORE 20>,
+                                <&cpg CPG_CORE R8A77965_CLK_S3D1>,
                                 <&scif_clk>;
                        clock-names = "fck", "brg_int", "scif_clk";
                        dmas = <&dmac0 0x59>, <&dmac0 0x58>;
                        reg = <0 0xe6f30000 0 64>;
                        interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 202>,
-                                <&cpg CPG_CORE 20>,
+                                <&cpg CPG_CORE R8A77965_CLK_S3D1>,
                                 <&scif_clk>;
                        clock-names = "fck", "brg_int", "scif_clk";
                        dmas = <&dmac1 0x5b>, <&dmac1 0x5a>,
                                port@0 {
                                        reg = <0>;
                                };
+                               port@1 {
+                                       reg = <1>;
+                               };
                        };
                };
 
                };
 
                pciec0: pcie@fe000000 {
+                       compatible = "renesas,pcie-r8a77965",
+                                    "renesas,pcie-rcar-gen3";
                        reg = <0 0xfe000000 0 0x80000>;
-                       /* placeholder */
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       bus-range = <0x00 0xff>;
+                       device_type = "pci";
+                       ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000
+                               0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000
+                               0x02000000 0 0x30000000 0 0x30000000 0 0x08000000
+                               0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
+                       /* Map all possible DDR as inbound ranges */
+                       dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>;
+                       interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0>;
+                       interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
+                       clock-names = "pcie", "pcie_bus";
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       resets = <&cpg 319>;
+                       status = "disabled";
                };
 
                pciec1: pcie@ee800000 {
+                       compatible = "renesas,pcie-r8a77965",
+                                    "renesas,pcie-rcar-gen3";
                        reg = <0 0xee800000 0 0x80000>;
-                       /* placeholder */
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       bus-range = <0x00 0xff>;
+                       device_type = "pci";
+                       ranges = <0x01000000 0 0x00000000 0 0xee900000 0 0x00100000
+                               0x02000000 0 0xeea00000 0 0xeea00000 0 0x00200000
+                               0x02000000 0 0xc0000000 0 0xc0000000 0 0x08000000
+                               0x42000000 0 0xc8000000 0 0xc8000000 0 0x08000000>;
+                       /* Map all possible DDR as inbound ranges */
+                       dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>;
+                       interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0>;
+                       interrupt-map = <0 0 0 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 318>, <&pcie_bus_clk>;
+                       clock-names = "pcie", "pcie_bus";
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       resets = <&cpg 318>;
+                       status = "disabled";
                };
 
                fcpf0: fcp@fe950000 {
 
                vspd0: vsp@fea20000 {
                        compatible = "renesas,vsp2";
-                       reg = <0 0xfea20000 0 0x8000>;
+                       reg = <0 0xfea20000 0 0x5000>;
                        interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 623>;
                        power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
 
                vspd1: vsp@fea28000 {
                        compatible = "renesas,vsp2";
-                       reg = <0 0xfea28000 0 0x8000>;
+                       reg = <0 0xfea28000 0 0x5000>;
                        interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 622>;
                        power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
index 21f9cf5c6e84ea7072a07b8a4dbd015656e0c154..b6d53321576b602d2ca371433b4fadeb17818393 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Eagle board
  *
  * Copyright (C) 2016-2017 Renesas Electronics Corp.
  * Copyright (C) 2017 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /dts-v1/;
index 9fce031a596f4060ab8d2408938f6f3859ec2409..8eac8ca6550b81f4922cafbe33174de16f3cca98 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the V3M Starter Kit board
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
  * Copyright (C) 2017 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /dts-v1/;
index 98a2317a16c470bb46aff506f0bb7ee9a7d47f4c..954168858fed95e7c8a34d41629540087eaeae87 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the r8a77970 SoC
  *
  * Copyright (C) 2016-2017 Renesas Electronics Corp.
  * Copyright (C) 2017 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include <dt-bindings/clock/r8a77970-cpg-mssr.h>
 
                vspd0: vsp@fea20000 {
                        compatible = "renesas,vsp2";
-                       reg = <0 0xfea20000 0 0x8000>;
+                       reg = <0 0xfea20000 0 0x5000>;
                        interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 623>;
                        power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
index 0b93a7d765859a1feb539350d7790cc7d5a0b918..9f25c407dfd711741d14e2b19521c60097ad5006 100644 (file)
@@ -59,6 +59,8 @@
        phy0: ethernet-phy@0 {
                rxc-skew-ps = <1500>;
                reg = <0>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
        };
 };
 
        clock-frequency = <32768>;
 };
 
+&i2c0 {
+       pinctrl-0 = <&i2c0_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+       clock-frequency = <400000>;
+
+       io_expander0: gpio@20 {
+               compatible = "onnn,pca9654";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       io_expander1: gpio@21 {
+               compatible = "onnn,pca9654";
+               reg = <0x21>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+};
+
 &mmc0 {
        pinctrl-0 = <&mmc_pins>;
        pinctrl-1 = <&mmc_pins_uhs>;
                function = "canfd0";
        };
 
+       i2c0_pins: i2c0 {
+               groups = "i2c0";
+               function = "i2c0";
+       };
+
        mmc_pins: mmc {
                groups = "mmc_data8", "mmc_ctrl", "mmc_ds";
                function = "mmc";
index c9680994555d48343c7bafd82cfed3684f9e67fc..9dac42f8f80435c91e19fad0121e1e56df6855e1 100644 (file)
@@ -15,6 +15,7 @@
 
        aliases {
                serial0 = &scif0;
+               ethernet0 = &gether;
        };
 
        chosen {
        clock-frequency = <32768>;
 };
 
+&gether {
+       pinctrl-0 = <&gether_pins>;
+       pinctrl-names = "default";
+
+       phy-mode = "rgmii";
+       phy-handle = <&phy0>;
+       renesas,no-ether-link;
+       status = "okay";
+
+       phy0: ethernet-phy@0 {
+               reg = <0>;
+               interrupt-parent = <&gpio4>;
+               interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
+       };
+};
+
 &pfc {
+       gether_pins: gether {
+               groups = "gether_mdio_a", "gether_rgmii",
+                        "gether_txcrefclk", "gether_txcrefclk_mega";
+               function = "gether";
+       };
+
        scif0_pins: scif0 {
                groups = "scif0_data";
                function = "scif0";
index 4c40f9f0ebc9ea7f93981a60b491b8144c63ce4f..b8c9a56562f249bb084a9002f7332fc4f43dad5d 100644 (file)
        #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>;
                        enable-method = "psci";
                };
 
+               a53_1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <1>;
+                       clocks = <&cpg CPG_CORE R8A77980_CLK_Z2>;
+                       power-domains = <&sysc R8A77980_PD_CA53_CPU1>;
+                       next-level-cache = <&L2_CA53>;
+                       enable-method = "psci";
+               };
+
+               a53_2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <2>;
+                       clocks = <&cpg CPG_CORE R8A77980_CLK_Z2>;
+                       power-domains = <&sysc R8A77980_PD_CA53_CPU2>;
+                       next-level-cache = <&L2_CA53>;
+                       enable-method = "psci";
+               };
+
+               a53_3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <3>;
+                       clocks = <&cpg CPG_CORE R8A77980_CLK_Z2>;
+                       power-domains = <&sysc R8A77980_PD_CA53_CPU3>;
+                       next-level-cache = <&L2_CA53>;
+                       enable-method = "psci";
+               };
+
                L2_CA53: cache-controller {
                        compatible = "cache";
                        power-domains = <&sysc R8A77980_PD_CA53_SCU>;
                #size-cells = <2>;
                ranges;
 
+               gpio0: gpio@e6050000 {
+                       compatible = "renesas,gpio-r8a77980",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6050000 0 0x50>;
+                       interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 0 22>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 912>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 912>;
+               };
+
+               gpio1: gpio@e6051000 {
+                       compatible = "renesas,gpio-r8a77980",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6051000 0 0x50>;
+                       interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 32 28>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 911>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 911>;
+               };
+
+               gpio2: gpio@e6052000 {
+                       compatible = "renesas,gpio-r8a77980",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6052000 0 0x50>;
+                       interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 64 30>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 910>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 910>;
+               };
+
+               gpio3: gpio@e6053000 {
+                       compatible = "renesas,gpio-r8a77980",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6053000 0 0x50>;
+                       interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 96 17>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 909>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 909>;
+               };
+
+               gpio4: gpio@e6054000 {
+                       compatible = "renesas,gpio-r8a77980",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6054000 0 0x50>;
+                       interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 128 25>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 908>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 908>;
+               };
+
+               gpio5: gpio@e6055000 {
+                       compatible = "renesas,gpio-r8a77980",
+                                    "renesas,rcar-gen3-gpio";
+                       reg = <0 0xe6055000 0 0x50>;
+                       interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       gpio-ranges = <&pfc 0 160 15>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       clocks = <&cpg CPG_MOD 907>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 907>;
+               };
+
                pfc: pin-controller@e6060000 {
                        compatible = "renesas,pfc-r8a77980";
                        reg = <0 0xe6060000 0 0x50c>;
                        #power-domain-cells = <1>;
                };
 
+               intc_ex: interrupt-controller@e61c0000 {
+                       compatible = "renesas,intc-ex-r8a77980", "renesas,irqc";
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       reg = <0 0xe61c0000 0 0x200>;
+                       interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH
+                                     GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 407>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 407>;
+               };
+
+               i2c0: i2c@e6500000 {
+                       compatible = "renesas,i2c-r8a77980",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe6500000 0 0x40>;
+                       interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 931>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 931>;
+                       dmas = <&dmac1 0x91>, <&dmac1 0x90>,
+                              <&dmac2 0x91>, <&dmac2 0x90>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       i2c-scl-internal-delay-ns = <6>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c1: i2c@e6508000 {
+                       compatible = "renesas,i2c-r8a77980",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe6508000 0 0x40>;
+                       interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 930>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 930>;
+                       dmas = <&dmac1 0x93>, <&dmac1 0x92>,
+                              <&dmac2 0x93>, <&dmac2 0x92>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       i2c-scl-internal-delay-ns = <6>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c2: i2c@e6510000 {
+                       compatible = "renesas,i2c-r8a77980",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe6510000 0 0x40>;
+                       interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 929>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 929>;
+                       dmas = <&dmac1 0x95>, <&dmac1 0x94>,
+                              <&dmac2 0x95>, <&dmac2 0x94>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       i2c-scl-internal-delay-ns = <6>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c3: i2c@e66d0000 {
+                       compatible = "renesas,i2c-r8a77980",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe66d0000 0 0x40>;
+                       interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 928>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 928>;
+                       i2c-scl-internal-delay-ns = <6>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c4: i2c@e66d8000 {
+                       compatible = "renesas,i2c-r8a77980",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe66d8000 0 0x40>;
+                       interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 927>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 927>;
+                       i2c-scl-internal-delay-ns = <6>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c5: i2c@e66e0000 {
+                       compatible = "renesas,i2c-r8a77980",
+                                    "renesas,rcar-gen3-i2c";
+                       reg = <0 0xe66e0000 0 0x40>;
+                       interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 919>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 919>;
+                       dmas = <&dmac1 0x9b>, <&dmac1 0x9a>,
+                              <&dmac2 0x9b>, <&dmac2 0x9a>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       i2c-scl-internal-delay-ns = <6>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
                hscif0: serial@e6540000 {
                        compatible = "renesas,hscif-r8a77980",
                                     "renesas,rcar-gen3-hscif",
                        };
                };
 
+               ipmmu_ds1: mmu@e7740000 {
+                       compatible = "renesas,ipmmu-r8a77980";
+                       reg = <0 0xe7740000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 0>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vip0: mmu@e7b00000 {
+                       compatible = "renesas,ipmmu-r8a77980";
+                       reg = <0 0xe7b00000 0 0x1000>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vip1: mmu@e7960000 {
+                       compatible = "renesas,ipmmu-r8a77980";
+                       reg = <0 0xe7960000 0 0x1000>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_ir: mmu@ff8b0000 {
+                       compatible = "renesas,ipmmu-r8a77980";
+                       reg = <0 0xff8b0000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 3>;
+                       power-domains = <&sysc R8A77980_PD_A3IR>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_mm: mmu@e67b0000 {
+                       compatible = "renesas,ipmmu-r8a77980";
+                       reg = <0 0xe67b0000 0 0x1000>;
+                       interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_rt: mmu@ffc80000 {
+                       compatible = "renesas,ipmmu-r8a77980";
+                       reg = <0 0xffc80000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 10>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vc0: mmu@fe6b0000 {
+                       compatible = "renesas,ipmmu-r8a77980";
+                       reg = <0 0xfe6b0000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 12>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vi0: mmu@febd0000 {
+                       compatible = "renesas,ipmmu-r8a77980";
+                       reg = <0 0xfebd0000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 14>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
                avb: ethernet@e6800000 {
                        compatible = "renesas,etheravb-r8a77980",
                                     "renesas,etheravb-rcar-gen3";
                        dma-channels = <16>;
                };
 
+               gether: ethernet@e7400000 {
+                       compatible = "renesas,gether-r8a77980";
+                       reg = <0 0xe7400000 0 0x1000>;
+                       interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 813>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 813>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
                mmc0: mmc@ee140000 {
                        compatible = "renesas,sdhi-r8a77980",
                                     "renesas,rcar-gen3-sdhi";
                              <0x0 0xf1020000 0 0x20000>,
                              <0x0 0xf1040000 0 0x20000>,
                              <0x0 0xf1060000 0 0x20000>;
-                       interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(1) |
+                       interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
                                      IRQ_TYPE_LEVEL_HIGH)>;
                        clocks = <&cpg CPG_MOD 408>;
                        clock-names = "clk";
                        resets = <&cpg 408>;
                };
 
+               vspd0: vsp@fea20000 {
+                       compatible = "renesas,vsp2";
+                       reg = <0 0xfea20000 0 0x5000>;
+                       interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 623>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 623>;
+                       renesas,fcp = <&fcpvd0>;
+               };
+
+               fcpvd0: fcp@fea27000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfea27000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 603>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 603>;
+               };
+
+               du: display@feb00000 {
+                       compatible = "renesas,du-r8a77980",
+                                    "renesas,du-r8a77970";
+                       reg = <0 0xfeb00000 0 0x80000>;
+                       interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 724>;
+                       clock-names = "du.0";
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 724>;
+                       vsps = <&vspd0>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       du_out_rgb: endpoint {
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       du_out_lvds0: endpoint {
+                                               remote-endpoint = <&lvds0_in>;
+                                       };
+                               };
+                       };
+               };
+
+               lvds0: lvds-encoder@feb90000 {
+                       compatible = "renesas,r8a77980-lvds";
+                       reg = <0 0xfeb90000 0 0x14>;
+                       clocks = <&cpg CPG_MOD 727>;
+                       power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+                       resets = <&cpg 727>;
+                       status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       lvds0_in: endpoint {
+                                               remote-endpoint =
+                                                       <&du_out_lvds0>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       lvds0_out: endpoint {
+                                       };
+                               };
+                       };
+               };
+
                prr: chipid@fff00044 {
                        compatible = "renesas,prr";
                        reg = <0 0xfff00044 0 4>;
 
        timer {
                compatible = "arm,armv8-timer";
-               interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) |
+               interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
                                       IRQ_TYPE_LEVEL_LOW)>,
-                                     <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) |
+                                     <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) |
                                       IRQ_TYPE_LEVEL_LOW)>,
-                                     <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) |
+                                     <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
                                       IRQ_TYPE_LEVEL_LOW)>,
-                                     <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) |
+                                     <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
                                       IRQ_TYPE_LEVEL_LOW)>;
        };
 };
index 7a09d0524f9b06633a014231a20938b01a1ca58f..2bc3a4884b0031f713391f046dabc2712f54f0aa 100644 (file)
        };
 };
 
+&ehci0 {
+       status = "okay";
+};
+
 &extal_clk {
        clock-frequency = <48000000>;
 };
 
+&ohci0 {
+       status = "okay";
+};
+
 &pfc {
        avb_pins: avb {
                mux {
                        function = "avb";
                };
        };
+
+       usb0_pins: usb {
+               groups = "usb0_b";
+               function = "usb0";
+       };
+
+       usb30_pins: usb30 {
+               groups = "usb30";
+               function = "usb30";
+       };
+};
+
+&rwdt {
+       timeout-sec = <60>;
+       status = "okay";
 };
 
 &scif2 {
        status = "okay";
 };
+
+&usb2_phy0 {
+       pinctrl-0 = <&usb0_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
+
+&xhci0 {
+       pinctrl-0 = <&usb30_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
index be4f519711a1b029458dbcde96cf994af234b5b5..ae89260baad9fd4d3ad1ec6dbef9c6a7bf1e118f 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <dt-bindings/clock/renesas-cpg-mssr.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/r8a77990-sysc.h>
 
 / {
        compatible = "renesas,r8a77990";
                #address-cells = <1>;
                #size-cells = <0>;
 
-               /* 1 core only at this point */
                a53_0: cpu@0 {
                        compatible = "arm,cortex-a53", "arm,armv8";
-                       reg = <0x0>;
+                       reg = <0>;
                        device_type = "cpu";
                        power-domains = <&sysc 5>;
                        next-level-cache = <&L2_CA53>;
                        enable-method = "psci";
                };
 
+               a53_1: cpu@1 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <1>;
+                       device_type = "cpu";
+                       power-domains = <&sysc 6>;
+                       next-level-cache = <&L2_CA53>;
+                       enable-method = "psci";
+               };
+
                L2_CA53: cache-controller-0 {
                        compatible = "cache";
                        power-domains = <&sysc 21>;
@@ -44,8 +53,9 @@
 
        pmu_a53 {
                compatible = "arm,cortex-a53-pmu";
-               interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
-               interrupt-affinity = <&a53_0>;
+               interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+                                     <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&a53_0>, <&a53_1>;
        };
 
        psci {
                #size-cells = <2>;
                ranges;
 
+               rwdt: watchdog@e6020000 {
+                       compatible = "renesas,r8a77990-wdt",
+                                    "renesas,rcar-gen3-wdt";
+                       reg = <0 0xe6020000 0 0x0c>;
+                       clocks = <&cpg CPG_MOD 402>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 402>;
+                       status = "disabled";
+               };
+
                gpio0: gpio@e6050000 {
                        compatible = "renesas,gpio-r8a77990",
                                     "renesas,rcar-gen3-gpio";
                        #power-domain-cells = <1>;
                };
 
+               ipmmu_ds0: mmu@e6740000 {
+                       compatible = "renesas,ipmmu-r8a77990";
+                       reg = <0 0xe6740000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 0>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_ds1: mmu@e7740000 {
+                       compatible = "renesas,ipmmu-r8a77990";
+                       reg = <0 0xe7740000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 1>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_hc: mmu@e6570000 {
+                       compatible = "renesas,ipmmu-r8a77990";
+                       reg = <0 0xe6570000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 2>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_mm: mmu@e67b0000 {
+                       compatible = "renesas,ipmmu-r8a77990";
+                       reg = <0 0xe67b0000 0 0x1000>;
+                       interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_mp: mmu@ec670000 {
+                       compatible = "renesas,ipmmu-r8a77990";
+                       reg = <0 0xec670000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 4>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_pv0: mmu@fd800000 {
+                       compatible = "renesas,ipmmu-r8a77990";
+                       reg = <0 0xfd800000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 6>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_rt: mmu@ffc80000 {
+                       compatible = "renesas,ipmmu-r8a77990";
+                       reg = <0 0xffc80000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 10>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vc0: mmu@fe6b0000 {
+                       compatible = "renesas,ipmmu-r8a77990";
+                       reg = <0 0xfe6b0000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 12>;
+                       power-domains = <&sysc R8A77990_PD_A3VC>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vi0: mmu@febd0000 {
+                       compatible = "renesas,ipmmu-r8a77990";
+                       reg = <0 0xfebd0000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 14>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vp0: mmu@fe990000 {
+                       compatible = "renesas,ipmmu-r8a77990";
+                       reg = <0 0xfe990000 0 0x1000>;
+                       renesas,ipmmu-main = <&ipmmu_mm 16>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
                avb: ethernet@e6800000 {
                        compatible = "renesas,etheravb-r8a77990",
                                     "renesas,etheravb-rcar-gen3";
-                       reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
+                       reg = <0 0xe6800000 0 0x800>;
                        interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
                        status = "disabled";
                };
 
+               xhci0: usb@ee000000 {
+                       compatible = "renesas,xhci-r8a77990",
+                                    "renesas,rcar-gen3-xhci";
+                       reg = <0 0xee000000 0 0xc00>;
+                       interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 328>;
+                       power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
+                       resets = <&cpg 328>;
+                       status = "disabled";
+               };
+
+               ohci0: usb@ee080000 {
+                       compatible = "generic-ohci";
+                       reg = <0 0xee080000 0 0x100>;
+                       interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 703>;
+                       phys = <&usb2_phy0>;
+                       phy-names = "usb";
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 703>;
+                       status = "disabled";
+               };
+
+               ehci0: usb@ee080100 {
+                       compatible = "generic-ehci";
+                       reg = <0 0xee080100 0 0x100>;
+                       interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 703>;
+                       phys = <&usb2_phy0>;
+                       phy-names = "usb";
+                       companion = <&ohci0>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 703>;
+                       status = "disabled";
+               };
+
+               usb2_phy0: usb-phy@ee080200 {
+                       compatible = "renesas,usb2-phy-r8a77990",
+                                    "renesas,rcar-gen3-usb2-phy";
+                       reg = <0 0xee080200 0 0x700>;
+                       interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 703>;
+                       power-domains = <&sysc 32>;
+                       resets = <&cpg 703>;
+                       #phy-cells = <0>;
+                       status = "disabled";
+               };
+
                gic: interrupt-controller@f1010000 {
                        compatible = "arm,gic-400";
                        #interrupt-cells = <3>;
                              <0x0 0xf1040000 0 0x20000>,
                              <0x0 0xf1060000 0 0x20000>;
                        interrupts = <GIC_PPI 9
-                                       (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
+                                       (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
                        clocks = <&cpg CPG_MOD 408>;
                        clock-names = "clk";
                        power-domains = <&sysc 32>;
 
        timer {
                compatible = "arm,armv8-timer";
-               interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
-                                     <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
-                                     <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
-                                     <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
+               interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                                     <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                                     <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                                     <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
        };
 };
index 9d73de8bc94d387398bba01791b2d2888f6dd969..a8e8f2669d4c53ae7492dc489107d3fbac30eebe 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Draak board
  *
  * Copyright (C) 2016 Renesas Electronics Corp.
  * Copyright (C) 2017 Glider bvba
- *
- * 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/;
                };
        };
 
+       composite-in {
+               compatible = "composite-video-connector";
+
+               port {
+                       composite_con_in: endpoint {
+                               remote-endpoint = <&adv7180_in>;
+                       };
+               };
+       };
+
+       hdmi-in {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_con_in: endpoint {
+                               remote-endpoint = <&adv7612_in>;
+                       };
+               };
+       };
+
        memory@48000000 {
                device_type = "memory";
                /* first 128MB is reserved for secure area. */
                regulator-boot-on;
                regulator-always-on;
        };
+
+       x12_clk: x12 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <74250000>;
+       };
 };
 
 &extal_clk {
                groups = "usb0";
                function = "usb0";
        };
+
+       vin4_pins_cvbs: vin4 {
+               groups = "vin4_data8", "vin4_sync", "vin4_clk";
+               function = "vin4";
+       };
 };
 
 &i2c0 {
                reg = <0x50>;
                pagesize = <8>;
        };
+
+       composite-in@20 {
+               compatible = "adi,adv7180cp";
+               reg = <0x20>;
+
+               port {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               adv7180_in: endpoint {
+                                       remote-endpoint = <&composite_con_in>;
+                               };
+                       };
+
+                       port@3 {
+                               reg = <3>;
+
+                               /*
+                                * The VIN4 video input path is shared between
+                                * CVBS and HDMI inputs through SW[49-53]
+                                * switches.
+                                *
+                                * CVBS is the default selection, link it to
+                                * VIN4 here.
+                                */
+                               adv7180_out: endpoint {
+                                       remote-endpoint = <&vin4_in>;
+                               };
+                       };
+               };
+
+       };
+
+       hdmi-decoder@4c {
+               compatible = "adi,adv7612";
+               reg = <0x4c>;
+               default-input = <0>;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+
+                               adv7612_in: endpoint {
+                                       remote-endpoint = <&hdmi_con_in>;
+                               };
+                       };
+
+                       port@2 {
+                               reg = <2>;
+
+                               /*
+                                * The VIN4 video input path is shared between
+                                * CVBS and HDMI inputs through SW[49-53]
+                                * switches.
+                                *
+                                * CVBS is the default selection, leave HDMI
+                                * not connected here.
+                                */
+                               adv7612_out: endpoint {
+                                       pclk-sample = <0>;
+                                       hsync-active = <0>;
+                                       vsync-active = <0>;
+                               };
+                       };
+               };
+       };
 };
 
 &i2c1 {
        pinctrl-names = "default";
        status = "okay";
 
+       clocks = <&cpg CPG_MOD 724>,
+                <&cpg CPG_MOD 723>,
+                <&x12_clk>;
+       clock-names = "du.0", "du.1", "dclkin.0";
+
        ports {
                port@0 {
                        endpoint {
        timeout-sec = <60>;
        status = "okay";
 };
+
+&vin4 {
+       pinctrl-0 = <&vin4_pins_cvbs>;
+       pinctrl-names = "default";
+
+       status = "okay";
+
+       ports {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               port@0 {
+                       reg = <0>;
+
+                       vin4_in: endpoint {
+                               remote-endpoint = <&adv7180_out>;
+                       };
+               };
+       };
+};
index 2506f46293e8a6fc676b87f54bf1540653451a55..fe77bc43c4474d1579502652b5c88c469c3201b6 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the r8a77995 SoC
  *
  * Copyright (C) 2016 Renesas Electronics Corp.
  * Copyright (C) 2017 Glider bvba
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include <dt-bindings/clock/r8a77995-cpg-mssr.h>
@@ -88,8 +85,7 @@
 
                gpio0: gpio@e6050000 {
                        compatible = "renesas,gpio-r8a77995",
-                                    "renesas,rcar-gen3-gpio",
-                                    "renesas,gpio-rcar";
+                                    "renesas,rcar-gen3-gpio";
                        reg = <0 0xe6050000 0 0x50>;
                        interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
                        #gpio-cells = <2>;
 
                gpio1: gpio@e6051000 {
                        compatible = "renesas,gpio-r8a77995",
-                                    "renesas,rcar-gen3-gpio",
-                                    "renesas,gpio-rcar";
+                                    "renesas,rcar-gen3-gpio";
                        reg = <0 0xe6051000 0 0x50>;
                        interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
                        #gpio-cells = <2>;
 
                gpio2: gpio@e6052000 {
                        compatible = "renesas,gpio-r8a77995",
-                                    "renesas,rcar-gen3-gpio",
-                                    "renesas,gpio-rcar";
+                                    "renesas,rcar-gen3-gpio";
                        reg = <0 0xe6052000 0 0x50>;
                        interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
                        #gpio-cells = <2>;
 
                gpio3: gpio@e6053000 {
                        compatible = "renesas,gpio-r8a77995",
-                                    "renesas,rcar-gen3-gpio",
-                                    "renesas,gpio-rcar";
+                                    "renesas,rcar-gen3-gpio";
                        reg = <0 0xe6053000 0 0x50>;
                        interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
                        #gpio-cells = <2>;
 
                gpio4: gpio@e6054000 {
                        compatible = "renesas,gpio-r8a77995",
-                                    "renesas,rcar-gen3-gpio",
-                                    "renesas,gpio-rcar";
+                                    "renesas,rcar-gen3-gpio";
                        reg = <0 0xe6054000 0 0x50>;
                        interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
                        #gpio-cells = <2>;
 
                gpio5: gpio@e6055000 {
                        compatible = "renesas,gpio-r8a77995",
-                                    "renesas,rcar-gen3-gpio",
-                                    "renesas,gpio-rcar";
+                                    "renesas,rcar-gen3-gpio";
                        reg = <0 0xe6055000 0 0x50>;
                        interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
                        #gpio-cells = <2>;
 
                gpio6: gpio@e6055400 {
                        compatible = "renesas,gpio-r8a77995",
-                                    "renesas,rcar-gen3-gpio",
-                                    "renesas,gpio-rcar";
+                                    "renesas,rcar-gen3-gpio";
                        reg = <0 0xe6055400 0 0x50>;
                        interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
                        #gpio-cells = <2>;
                        #power-domain-cells = <1>;
                };
 
+               thermal: thermal@e6190000 {
+                       compatible = "renesas,thermal-r8a77995";
+                       reg = <0 0xe6190000 0 0x10>, <0 0xe6190100 0 0x38>;
+                       interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 522>;
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       resets = <&cpg 522>;
+                       #thermal-sensor-cells = <0>;
+               };
+
                intc_ex: interrupt-controller@e61c0000 {
                        compatible = "renesas,intc-ex-r8a77995", "renesas,irqc";
                        #interrupt-cells = <2>;
                        resets = <&cpg 407>;
                };
 
+               hscif0: serial@e6540000 {
+                       compatible = "renesas,hscif-r8a77995",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe6540000 0 0x60>;
+                       interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 520>,
+                                <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x31>, <&dmac1 0x30>,
+                              <&dmac2 0x31>, <&dmac2 0x30>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       resets = <&cpg 520>;
+                       status = "disabled";
+               };
+
+               hscif3: serial@e66a0000 {
+                       compatible = "renesas,hscif-r8a77995",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe66a0000 0 0x60>;
+                       interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 517>,
+                                <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac0 0x37>, <&dmac0 0x36>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       resets = <&cpg 517>;
+                       status = "disabled";
+               };
+
                i2c0: i2c@e6500000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        compatible = "renesas,ipmmu-r8a77995";
                        reg = <0 0xe6740000 0 0x1000>;
                        renesas,ipmmu-main = <&ipmmu_mm 0>;
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
                        #iommu-cells = <1>;
                };
 
                        compatible = "renesas,ipmmu-r8a77995";
                        reg = <0 0xe7740000 0 0x1000>;
                        renesas,ipmmu-main = <&ipmmu_mm 1>;
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
                        #iommu-cells = <1>;
                };
 
                        compatible = "renesas,ipmmu-r8a77995";
                        reg = <0 0xe6570000 0 0x1000>;
                        renesas,ipmmu-main = <&ipmmu_mm 2>;
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
                        #iommu-cells = <1>;
                };
 
                        reg = <0 0xe67b0000 0 0x1000>;
                        interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
                        #iommu-cells = <1>;
                };
 
                        compatible = "renesas,ipmmu-r8a77995";
                        reg = <0 0xec670000 0 0x1000>;
                        renesas,ipmmu-main = <&ipmmu_mm 4>;
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
                        #iommu-cells = <1>;
                };
 
                        compatible = "renesas,ipmmu-r8a77995";
                        reg = <0 0xfd800000 0 0x1000>;
                        renesas,ipmmu-main = <&ipmmu_mm 6>;
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
                        #iommu-cells = <1>;
                };
 
                        compatible = "renesas,ipmmu-r8a77995";
                        reg = <0 0xffc80000 0 0x1000>;
                        renesas,ipmmu-main = <&ipmmu_mm 10>;
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
                        #iommu-cells = <1>;
                };
 
                        compatible = "renesas,ipmmu-r8a77995";
                        reg = <0 0xfe6b0000 0 0x1000>;
                        renesas,ipmmu-main = <&ipmmu_mm 12>;
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
                        #iommu-cells = <1>;
                };
 
                        compatible = "renesas,ipmmu-r8a77995";
                        reg = <0 0xfebd0000 0 0x1000>;
                        renesas,ipmmu-main = <&ipmmu_mm 14>;
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
                        #iommu-cells = <1>;
                };
 
                        compatible = "renesas,ipmmu-r8a77995";
                        reg = <0 0xfe990000 0 0x1000>;
                        renesas,ipmmu-main = <&ipmmu_mm 16>;
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
                        #iommu-cells = <1>;
                };
 
                        status = "disabled";
                };
 
+               scif0: serial@e6e60000 {
+                       compatible = "renesas,scif-r8a77995",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6e60000 0 64>;
+                       interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 207>,
+                                <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x51>, <&dmac1 0x50>,
+                              <&dmac2 0x51>, <&dmac2 0x50>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       resets = <&cpg 207>;
+                       status = "disabled";
+               };
+
+               scif1: serial@e6e68000 {
+                       compatible = "renesas,scif-r8a77995",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6e68000 0 64>;
+                       interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 206>,
+                                <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x53>, <&dmac1 0x52>,
+                              <&dmac2 0x53>, <&dmac2 0x52>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       resets = <&cpg 206>;
+                       status = "disabled";
+               };
+
                scif2: serial@e6e88000 {
                        compatible = "renesas,scif-r8a77995",
                                     "renesas,rcar-gen3-scif", "renesas,scif";
                        status = "disabled";
                };
 
+               scif3: serial@e6c50000 {
+                       compatible = "renesas,scif-r8a77995",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6c50000 0 64>;
+                       interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 204>,
+                                <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac0 0x57>, <&dmac0 0x56>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       resets = <&cpg 204>;
+                       status = "disabled";
+               };
+
+               scif4: serial@e6c40000 {
+                       compatible = "renesas,scif-r8a77995",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6c40000 0 64>;
+                       interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 203>,
+                                <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac0 0x59>, <&dmac0 0x58>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       resets = <&cpg 203>;
+                       status = "disabled";
+               };
+
+               scif5: serial@e6f30000 {
+                       compatible = "renesas,scif-r8a77995",
+                                    "renesas,rcar-gen3-scif", "renesas,scif";
+                       reg = <0 0xe6f30000 0 64>;
+                       interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 202>,
+                                <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x5b>, <&dmac1 0x5a>,
+                              <&dmac2 0x5b>, <&dmac2 0x5a>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       resets = <&cpg 202>;
+                       status = "disabled";
+               };
+
+               msiof0: spi@e6e90000 {
+                       compatible = "renesas,msiof-r8a77995",
+                                    "renesas,rcar-gen3-msiof";
+                       reg = <0 0xe6e90000 0 0x64>;
+                       interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 211>;
+                       dmas = <&dmac1 0x41>, <&dmac1 0x40>,
+                              <&dmac2 0x41>, <&dmac2 0x40>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       resets = <&cpg 211>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof1: spi@e6ea0000 {
+                       compatible = "renesas,msiof-r8a77995",
+                                    "renesas,rcar-gen3-msiof";
+                       reg = <0 0xe6ea0000 0 0x64>;
+                       interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 210>;
+                       dmas = <&dmac1 0x43>, <&dmac1 0x42>,
+                              <&dmac2 0x43>, <&dmac2 0x42>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       resets = <&cpg 210>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof2: spi@e6c00000 {
+                       compatible = "renesas,msiof-r8a77995",
+                                    "renesas,rcar-gen3-msiof";
+                       reg = <0 0xe6c00000 0 0x64>;
+                       interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 209>;
+                       dmas = <&dmac0 0x45>, <&dmac0 0x44>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       resets = <&cpg 209>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof3: spi@e6c10000 {
+                       compatible = "renesas,msiof-r8a77995",
+                                    "renesas,rcar-gen3-msiof";
+                       reg = <0 0xe6c10000 0 0x64>;
+                       interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 208>;
+                       dmas = <&dmac0 0x47>, <&dmac0 0x46>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       resets = <&cpg 208>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
                vin4: video@e6ef4000 {
                        compatible = "renesas,vin-r8a77995";
                        reg = <0 0xe6ef4000 0 0x1000>;
 
                vspd0: vsp@fea20000 {
                        compatible = "renesas,vsp2";
-                       reg = <0 0xfea20000 0 0x8000>;
+                       reg = <0 0xfea20000 0 0x5000>;
                        interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 623>;
                        power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
 
                vspd1: vsp@fea28000 {
                        compatible = "renesas,vsp2";
-                       reg = <0 0xfea28000 0 0x8000>;
+                       reg = <0 0xfea28000 0 0x5000>;
                        interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 622>;
                        power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
                };
        };
 
+       thermal-zones {
+               cpu_thermal: cpu-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+                       thermal-sensors = <&thermal>;
+
+                       trips {
+                               cpu-crit {
+                                       temperature = <120000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps {
+                       };
+               };
+       };
+
        timer {
                compatible = "arm,armv8-timer";
                interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
index 9256fbaaab7f32976633eb2d7bf9a62afdb771b1..7d3d866a006352ac196b52002c9c9ce8899f5208 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for common parts of Salvator-X board variants
  *
  * Copyright (C) 2015-2016 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 /*
@@ -36,7 +33,7 @@
 / {
        aliases {
                serial0 = &scif2;
-               serial1 = &scif1;
+               serial1 = &hscif1;
                ethernet0 = &avb;
        };
 
        clock-frequency = <32768>;
 };
 
+&hscif1 {
+       pinctrl-0 = <&hscif1_pins>;
+       pinctrl-names = "default";
+
+       uart-has-rtscts;
+       /* Please only enable hscif1 or scif1 */
+       status = "okay";
+};
+
 &hsusb {
        dr_mode = "otg";
        status = "okay";
                        };
                };
 
-               port@10 {
+               port@a {
                        reg = <10>;
 
                        adv7482_txa: endpoint {
                        };
                };
 
-               port@11 {
+               port@b {
                        reg = <11>;
 
                        adv7482_txb: endpoint {
                function = "du";
        };
 
+       hscif1_pins: hscif1 {
+               groups = "hscif1_data_a", "hscif1_ctrl_a";
+               function = "hscif1";
+       };
+
        i2c2_pins: i2c2 {
                groups = "i2c2_a";
                function = "i2c2";
        };
 
        sdhi2_pins: sd2 {
-               groups = "sdhi2_data8", "sdhi2_ctrl";
+               groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
                function = "sdhi2";
                power-source = <3300>;
        };
 
        sdhi2_pins_uhs: sd2_uhs {
-               groups = "sdhi2_data8", "sdhi2_ctrl";
+               groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
                function = "sdhi2";
                power-source = <1800>;
        };
        pinctrl-names = "default";
 
        uart-has-rtscts;
-       status = "okay";
+       /* Please only enable hscif1 or scif1 */
+       /* status = "okay"; */
 };
 
 &scif2 {
        status = "okay";
 };
 
-&wdt0 {
+&rwdt {
        timeout-sec = <60>;
        status = "okay";
 };
index 468868c8ed9fae67e6bb078a78740aca7302a1cf..ddee50e64632d92874bb9d2b9c98433380b58d81 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Salvator-X board
  *
  * Copyright (C) 2015-2016 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include "salvator-common.dtsi"
@@ -20,6 +17,8 @@
 };
 
 &i2c4 {
+       clock-frequency = <400000>;
+
        versaclock5: clock-generator@6a {
                compatible = "idt,5p49v5923";
                reg = <0x6a>;
index bf4d200fb54635eaa448688af444045145a18a96..717d42758cbc4b399e6dc9b4af0333a62fdda5ca 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Salvator-X 2nd version board
  *
  * Copyright (C) 2015-2017 Renesas Electronics Corp.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include "salvator-common.dtsi"
@@ -20,6 +17,8 @@
 };
 
 &i2c4 {
+       clock-frequency = <400000>;
+
        versaclock6: clock-generator@6a {
                compatible = "idt,5p49v6901";
                reg = <0x6a>;
index a4e715cbde87e1a0274a32d88068381923d18853..8bf3091a899c81ce9234ab05cfcb8aa9542700d7 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the Kingfisher (ULCB extension) board
  *
  * Copyright (C) 2017 Renesas Electronics Corp.
  * Copyright (C) 2017 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 / {
index 0edb16e6b3728149ecd4ef2cbb56f8be904aa403..0ead552d7eae9678cda710c897b84b3f45964c13 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree Source for the R-Car Gen3 ULCB board
  *
  * Copyright (C) 2016 Renesas Electronics Corp.
  * Copyright (C) 2016 Cogent Embedded, Inc.
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2.  This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
  */
 
 #include <dt-bindings/gpio/gpio.h>
        };
 
        sdhi2_pins: sd2 {
-               groups = "sdhi2_data8", "sdhi2_ctrl";
+               groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
                function = "sdhi2";
                power-source = <3300>;
        };
 
        sdhi2_pins_uhs: sd2_uhs {
-               groups = "sdhi2_data8", "sdhi2_ctrl";
+               groups = "sdhi2_data8", "sdhi2_ctrl", "sdhi2_ds";
                function = "sdhi2";
                power-source = <1800>;
        };
        status = "okay";
 };
 
-&wdt0 {
+&rwdt {
        timeout-sec = <60>;
        status = "okay";
 };
index 48a83f882947c1cdd1ada3ab0a8abf2f1f5fe87c..b0092d95b574dcc0256f9f5e244e07b4ff794c38 100644 (file)
@@ -9,7 +9,9 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-orion-r68-meta.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-px5-evb.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-r88.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-evb.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-ficus.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-firefly.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-bob.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire.dtb
index 3d551e3e6c23a5f9eaa58c45d9db5a59eafec79e..8302d86d35c4a77704dfb9d3b3f3209c124b7b89 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 28257724a56e74b79b83c69a76bea0da4e0fd9ed..5272e887a434ec46d52afdffaf76164ad182cdaa 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 PINE64
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index b8e9da15e00c5b16ff444f681466d5454184f040..3f5a2944300fe2441f87ec1ac144d771f2cddbfe 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/clock/rk3328-cru.h>
@@ -89,6 +52,7 @@
                        compatible = "arm,cortex-a53", "arm,armv8";
                        reg = <0x0 0x1>;
                        clocks = <&cru ARMCLK>;
+                       #cooling-cells = <2>;
                        dynamic-power-coefficient = <120>;
                        enable-method = "psci";
                        next-level-cache = <&l2>;
                        compatible = "arm,cortex-a53", "arm,armv8";
                        reg = <0x0 0x2>;
                        clocks = <&cru ARMCLK>;
+                       #cooling-cells = <2>;
                        dynamic-power-coefficient = <120>;
                        enable-method = "psci";
                        next-level-cache = <&l2>;
                        compatible = "arm,cortex-a53", "arm,armv8";
                        reg = <0x0 0x3>;
                        clocks = <&cru ARMCLK>;
+                       #cooling-cells = <2>;
                        dynamic-power-coefficient = <120>;
                        enable-method = "psci";
                        next-level-cache = <&l2>;
                reg = <0x0 0xff120000 0x0 0x100>;
                interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
-               clock-names = "sclk_uart", "pclk_uart";
+               clock-names = "baudclk", "apb_pclk";
                dmas = <&dmac 4>, <&dmac 5>;
                dma-names = "tx", "rx";
                pinctrl-names = "default";
index 8a5275f0539b676f44aeaa9722b1b23e396d02e6..160f2c7e9559c678c330368ae8c8360376ed5c97 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2015 Caesar Wang <wxt@rock-chips.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index a37220a9387c325a1caf7e2c735ee5c776af4982..4de089149c504940b94c4cc450eb0710d54d9a80 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2015 Caesar Wang <wxt@rock-chips.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/input/input.h>
index 5e4d3a7015f52de883c2a43ce38da7f5c5421993..6b9b1ac1994c3512c07b6ab28b20d88a3538de71 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Andreas Färber
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index d3f6c8e0d206d0fcf28ade6612499fec212dcc6a..96147d93dd1da3b4b43066d763ac47ae80150d8d 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Matthias Brugger <mbrugger@suse.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 13a9e22f5d2d2caa3604a4315be98879ba069bbd..fc1bf078a41f6bd4b6e5ac76c85f01642d7d89a4 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index b3510d56517a63a39506e3434ce7969cc708a2d7..7452bedf1a7e18be83e589084250a92d83c1ba6b 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2015 Heiko Stuebner <heiko@sntech.de>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index ad91ced786494afdb9428ea9c83adaf8e6f56e71..9c24de1ba43c56b70d0a29d063ec78324a764340 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2015 Heiko Stuebner <heiko@sntech.de>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/clock/rk3368-cru.h>
                        compatible = "arm,cortex-a53", "arm,armv8";
                        reg = <0x0 0x0>;
                        enable-method = "psci";
-
                        #cooling-cells = <2>; /* min followed by max */
                };
 
                        compatible = "arm,cortex-a53", "arm,armv8";
                        reg = <0x0 0x1>;
                        enable-method = "psci";
+                       #cooling-cells = <2>; /* min followed by max */
                };
 
                cpu_l2: cpu@2 {
                        compatible = "arm,cortex-a53", "arm,armv8";
                        reg = <0x0 0x2>;
                        enable-method = "psci";
+                       #cooling-cells = <2>; /* min followed by max */
                };
 
                cpu_l3: cpu@3 {
                        compatible = "arm,cortex-a53", "arm,armv8";
                        reg = <0x0 0x3>;
                        enable-method = "psci";
+                       #cooling-cells = <2>; /* min followed by max */
                };
 
                cpu_b0: cpu@100 {
                        compatible = "arm,cortex-a53", "arm,armv8";
                        reg = <0x0 0x100>;
                        enable-method = "psci";
-
                        #cooling-cells = <2>; /* min followed by max */
                };
 
                        compatible = "arm,cortex-a53", "arm,armv8";
                        reg = <0x0 0x101>;
                        enable-method = "psci";
+                       #cooling-cells = <2>; /* min followed by max */
                };
 
                cpu_b2: cpu@102 {
                        compatible = "arm,cortex-a53", "arm,armv8";
                        reg = <0x0 0x102>;
                        enable-method = "psci";
+                       #cooling-cells = <2>; /* min followed by max */
                };
 
                cpu_b3: cpu@103 {
                        compatible = "arm,cortex-a53", "arm,armv8";
                        reg = <0x0 0x103>;
                        enable-method = "psci";
+                       #cooling-cells = <2>; /* min followed by max */
                };
        };
 
index 56533c344ef2caa5d237e61aff438caf068d96e3..959ddc3c7df52bde81d64a9bbf924c397d44c9f7 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-ficus.dts b/arch/arm64/boot/dts/rockchip/rk3399-ficus.dts
new file mode 100644 (file)
index 0000000..8978d92
--- /dev/null
@@ -0,0 +1,599 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Collabora Ltd.
+ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd.
+ *
+ * Schematics available at https://dl.vamrs.com/products/ficus/docs/hw
+ */
+
+/dts-v1/;
+#include "rk3399.dtsi"
+#include "rk3399-opp.dtsi"
+
+/ {
+       model = "96boards RK3399 Ficus";
+       compatible = "vamrs,ficus", "rockchip,rk3399";
+
+       chosen {
+               stdout-path = "serial2:1500000n8";
+       };
+
+       clkin_gmac: external-gmac-clock {
+               compatible = "fixed-clock";
+               clock-frequency = <125000000>;
+               clock-output-names = "clkin_gmac";
+               #clock-cells = <0>;
+       };
+
+       vcc1v8_s0: vcc1v8-s0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc1v8_s0";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+       };
+
+       vcc_sys: vcc-sys {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_sys";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
+
+       vcc3v3_sys: vcc3v3-sys {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3_sys";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vcc3v3_pcie: vcc3v3-pcie-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio1 24 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pcie_drv>;
+               regulator-boot-on;
+               regulator-name = "vcc3v3_pcie";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vcc3v3_sys>;
+       };
+
+       vcc5v0_host: vcc5v0-host-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio4 27 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&host_vbus_drv>;
+               regulator-name = "vcc5v0_host";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vdd_log: vdd-log {
+               compatible = "pwm-regulator";
+               pwms = <&pwm2 0 25000 0>;
+               regulator-name = "vdd_log";
+               regulator-min-microvolt = <800000>;
+               regulator-max-microvolt = <1400000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+};
+
+&cpu_l0 {
+       cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l1 {
+       cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l2 {
+       cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l3 {
+       cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_b0 {
+       cpu-supply = <&vdd_cpu_b>;
+};
+
+&cpu_b1 {
+       cpu-supply = <&vdd_cpu_b>;
+};
+
+&emmc_phy {
+       status = "okay";
+};
+
+&gmac {
+       assigned-clocks = <&cru SCLK_RMII_SRC>;
+       assigned-clock-parents = <&clkin_gmac>;
+       clock_in_out = "input";
+       phy-supply = <&vcc3v3_sys>;
+       phy-mode = "rgmii";
+       pinctrl-names = "default";
+       pinctrl-0 = <&rgmii_pins>;
+       snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
+       snps,reset-active-low;
+       snps,reset-delays-us = <0 10000 50000>;
+       tx_delay = <0x28>;
+       rx_delay = <0x11>;
+       status = "okay";
+};
+
+&hdmi {
+       ddc-i2c-bus = <&i2c3>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&hdmi_cec>;
+       status = "okay";
+};
+
+&i2c0 {
+       clock-frequency = <400000>;
+       i2c-scl-rising-time-ns = <168>;
+       i2c-scl-falling-time-ns = <4>;
+       status = "okay";
+
+       vdd_cpu_b: regulator@40 {
+               compatible = "silergy,syr827";
+               reg = <0x40>;
+               fcs,suspend-voltage-selector = <1>;
+               regulator-name = "vdd_cpu_b";
+               regulator-min-microvolt = <712500>;
+               regulator-max-microvolt = <1500000>;
+               regulator-ramp-delay = <1000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc_sys>;
+               status = "okay";
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       vdd_gpu: regulator@41 {
+               compatible = "silergy,syr828";
+               reg = <0x41>;
+               fcs,suspend-voltage-selector = <1>;
+               regulator-name = "vdd_gpu";
+               regulator-min-microvolt = <712500>;
+               regulator-max-microvolt = <1500000>;
+               regulator-ramp-delay = <1000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc_sys>;
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       rk808: pmic@1b {
+               compatible = "rockchip,rk808";
+               reg = <0x1b>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_int_l>;
+               rockchip,system-power-controller;
+               wakeup-source;
+               #clock-cells = <1>;
+               clock-output-names = "xin32k", "rk808-clkout2";
+
+               vcc1-supply = <&vcc_sys>;
+               vcc2-supply = <&vcc_sys>;
+               vcc3-supply = <&vcc_sys>;
+               vcc4-supply = <&vcc_sys>;
+               vcc6-supply = <&vcc_sys>;
+               vcc7-supply = <&vcc_sys>;
+               vcc8-supply = <&vcc3v3_sys>;
+               vcc9-supply = <&vcc_sys>;
+               vcc10-supply = <&vcc_sys>;
+               vcc11-supply = <&vcc_sys>;
+               vcc12-supply = <&vcc3v3_sys>;
+               vddio-supply = <&vcc_1v8>;
+
+               regulators {
+                       vdd_center: DCDC_REG1 {
+                               regulator-name = "vdd_center";
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_cpu_l: DCDC_REG2 {
+                               regulator-name = "vdd_cpu_l";
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_ddr: DCDC_REG3 {
+                               regulator-name = "vcc_ddr";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc_1v8: DCDC_REG4 {
+                               regulator-name = "vcc_1v8";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcc1v8_dvp: LDO_REG1 {
+                               regulator-name = "vcc1v8_dvp";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcca1v8_hdmi: LDO_REG2 {
+                               regulator-name = "vcca1v8_hdmi";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcca_1v8: LDO_REG3 {
+                               regulator-name = "vcca_1v8";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcc_sd: LDO_REG4 {
+                               regulator-name = "vcc_sd";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vcc3v0_sd: LDO_REG5 {
+                               regulator-name = "vcc3v0_sd";
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3000000>;
+                               };
+                       };
+
+                       vcc_1v5: LDO_REG6 {
+                               regulator-name = "vcc_1v5";
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1500000>;
+                               };
+                       };
+
+                       vcca0v9_hdmi: LDO_REG7 {
+                               regulator-name = "vcca0v9_hdmi";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <900000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <900000>;
+                               };
+                       };
+
+                       vcc_3v0: LDO_REG8 {
+                               regulator-name = "vcc_3v0";
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3000000>;
+                               };
+                       };
+
+                       vcc3v3_s3: SWITCH_REG1 {
+                               regulator-name = "vcc3v3_s3";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc3v3_s0: SWITCH_REG2 {
+                               regulator-name = "vcc3v3_s0";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+               };
+       };
+};
+
+&i2c1 {
+       status = "okay";
+};
+
+&i2c2 {
+       status = "okay";
+};
+
+&i2c3 {
+       status = "okay";
+};
+
+&i2c4 {
+       status = "okay";
+};
+
+&io_domains {
+       bt656-supply = <&vcc1v8_s0>; /* bt656_gpio2ab_ms */
+       audio-supply = <&vcc1v8_s0>; /* audio_gpio3d4a_ms */
+       sdmmc-supply = <&vcc_sd>; /* sdmmc_gpio4b_ms */
+       gpio1830-supply = <&vcc_3v0>; /* gpio1833_gpio4cd_ms */
+       status = "okay";
+};
+
+&pcie_phy {
+       status = "okay";
+};
+
+&pcie0 {
+       ep-gpios = <&gpio4 RK_PD4 GPIO_ACTIVE_HIGH>;
+       num-lanes = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie_clkreqn_cpm>;
+       vpcie3v3-supply = <&vcc3v3_pcie>;
+       status = "okay";
+};
+
+&pmu_io_domains {
+       pmu1830-supply = <&vcc_1v8>;
+       status = "okay";
+};
+
+&pinctrl {
+       gmac {
+               rgmii_sleep_pins: rgmii-sleep-pins {
+                       rockchip,pins =
+                               <3 15 RK_FUNC_GPIO &pcfg_output_low>;
+               };
+       };
+
+       sdmmc {
+               sdmmc_bus1: sdmmc-bus1 {
+                       rockchip,pins =
+                               <4 8 RK_FUNC_1 &pcfg_pull_up_8ma>;
+               };
+
+               sdmmc_bus4: sdmmc-bus4 {
+                       rockchip,pins =
+                               <4 8 RK_FUNC_1 &pcfg_pull_up_8ma>,
+                               <4 9 RK_FUNC_1 &pcfg_pull_up_8ma>,
+                               <4 10 RK_FUNC_1 &pcfg_pull_up_8ma>,
+                               <4 11 RK_FUNC_1 &pcfg_pull_up_8ma>;
+               };
+
+               sdmmc_clk: sdmmc-clk {
+                       rockchip,pins =
+                               <4 12 RK_FUNC_1 &pcfg_pull_none_18ma>;
+               };
+
+               sdmmc_cmd: sdmmc-cmd {
+                       rockchip,pins =
+                               <4 13 RK_FUNC_1 &pcfg_pull_up_8ma>;
+               };
+       };
+
+       pcie {
+               pcie_drv: pcie-drv {
+                       rockchip,pins =
+                               <1 24 RK_FUNC_GPIO &pcfg_pull_none>;
+                       };
+       };
+
+       pmic {
+               pmic_int_l: pmic-int-l {
+                       rockchip,pins =
+                               <1 21 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+
+               vsel1_gpio: vsel1-gpio {
+                       rockchip,pins =
+                               <1 17 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+
+               vsel2_gpio: vsel2-gpio {
+                       rockchip,pins =
+                               <1 14 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+       };
+
+       usb2 {
+               host_vbus_drv: host-vbus-drv {
+                       rockchip,pins =
+                               <4 27 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&pwm2 {
+       status = "okay";
+};
+
+&pwm3 {
+       status = "okay";
+};
+
+&sdhci {
+       bus-width = <8>;
+       mmc-hs400-1_8v;
+       mmc-hs400-enhanced-strobe;
+       non-removable;
+       status = "okay";
+};
+
+&sdmmc {
+       bus-width = <4>;
+       cap-mmc-highspeed;
+       cap-sd-highspeed;
+       clock-frequency = <100000000>;
+       clock-freq-min-max = <100000 100000000>;
+       disable-wp;
+       sd-uhs-sdr104;
+       vqmmc-supply = <&vcc_sd>;
+       card-detect-delay = <800>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
+       status = "okay";
+};
+
+&tcphy0 {
+       status = "okay";
+};
+
+&tcphy1 {
+       status = "okay";
+};
+
+&u2phy0 {
+       status = "okay";
+};
+
+&u2phy1 {
+       status = "okay";
+};
+
+&u2phy0_host {
+       phy-supply = <&vcc5v0_host>;
+       status = "okay";
+};
+
+&u2phy1_host {
+       phy-supply = <&vcc5v0_host>;
+       status = "okay";
+};
+
+&u2phy0_otg {
+       status = "okay";
+};
+
+&u2phy1_otg {
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_xfer &uart0_cts>;
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&usb_host0_ehci {
+       status = "okay";
+};
+
+&usb_host0_ohci {
+       status = "okay";
+};
+
+&usb_host1_ehci {
+       status = "okay";
+};
+
+&usb_host1_ohci {
+       status = "okay";
+};
+
+&usbdrd3_0 {
+       status = "okay";
+};
+
+&usbdrd_dwc3_0 {
+       status = "okay";
+       dr_mode = "host";
+};
+
+&usbdrd3_1 {
+       status = "okay";
+};
+
+&usbdrd_dwc3_1 {
+       status = "okay";
+       dr_mode = "host";
+};
+
+&vopb {
+       status = "okay";
+};
+
+&vopb_mmu {
+       status = "okay";
+};
+
+&vopl {
+       status = "okay";
+};
+
+&vopl_mmu {
+       status = "okay";
+};
index 2a352763c8489be969fa361ed0543d3163437d56..38336ab57cc46046988500ac54496a7c97bc0c4f 100644 (file)
@@ -1,46 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
+#include <dt-bindings/input/linux-event-codes.h>
 #include <dt-bindings/pwm/pwm.h>
 #include "rk3399.dtsi"
 #include "rk3399-opp.dtsi"
                regulator-max-microvolt = <12000000>;
        };
 
+       gpio-keys {
+               compatible = "gpio-keys";
+               autorepeat;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwrbtn>;
+
+               power {
+                       debounce-interval = <100>;
+                       gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
+                       label = "GPIO Key Power";
+                       linux,code = <KEY_POWER>;
+                       wakeup-source;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&work_led_gpio>, <&diy_led_gpio>;
+
+               work-led {
+                       label = "work";
+                       default-state = "on";
+                       gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>;
+               };
+
+               diy-led {
+                       label = "diy";
+                       default-state = "off";
+                       gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
        rt5640-sound {
                compatible = "simple-audio-card";
                simple-audio-card,name = "rockchip,rt5640-codec";
 &i2s0 {
        rockchip,playback-channels = <8>;
        rockchip,capture-channels = <8>;
-       #sound-dai-cells = <0>;
        status = "okay";
 };
 
 &i2s1 {
        rockchip,playback-channels = <2>;
        rockchip,capture-channels = <2>;
-       #sound-dai-cells = <0>;
        status = "okay";
 };
 
 &i2s2 {
-       #sound-dai-cells = <0>;
        status = "okay";
 };
 
                        rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };
+
+       leds {
+               work_led_gpio: work_led-gpio {
+                       rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               diy_led_gpio: diy_led-gpio {
+                       rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
 };
 
 &pwm0 {
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts b/arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts
new file mode 100644 (file)
index 0000000..1ee0dc0
--- /dev/null
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Gru-Bob Rev 4+ board device tree source
+ *
+ * Copyright 2018 Google, Inc
+ */
+
+/dts-v1/;
+#include "rk3399-gru-chromebook.dtsi"
+
+/ {
+       model = "Google Bob";
+       compatible = "google,bob-rev13", "google,bob-rev12",
+                    "google,bob-rev11", "google,bob-rev10",
+                    "google,bob-rev9", "google,bob-rev8",
+                    "google,bob-rev7", "google,bob-rev6",
+                    "google,bob-rev5", "google,bob-rev4",
+                    "google,bob", "google,gru", "rockchip,rk3399";
+
+       edp_panel: edp-panel {
+               compatible = "boe,nv101wxmn51", "simple-panel";
+               backlight = <&backlight>;
+               power-supply = <&pp3300_disp>;
+
+               ports {
+                       panel_in_edp: endpoint {
+                               remote-endpoint = <&edp_out_panel>;
+                       };
+               };
+       };
+};
+
+&ap_i2c_ts {
+       touchscreen: touchscreen@10 {
+               compatible = "elan,ekth3500";
+               reg = <0x10>;
+               interrupt-parent = <&gpio3>;
+               interrupts = <13 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&touch_int_l &touch_reset_l>;
+               reset-gpios = <&gpio4 26 GPIO_ACTIVE_LOW>;
+       };
+};
+
+&ap_i2c_tp {
+       trackpad: trackpad@15 {
+               compatible = "elan,ekth3000";
+               reg = <0x15>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&trackpad_int_l>;
+               wakeup-source;
+       };
+};
+
+&backlight {
+       pwms = <&cros_ec_pwm 0>;
+};
+
+&cpu_alert0 {
+       temperature = <65000>;
+};
+
+&cpu_alert1 {
+       temperature = <70000>;
+};
+
+&spi0 {
+       status = "okay";
+};
+
+&pinctrl {
+       tpm {
+               h1_int_od_l: h1-int-od-l {
+                       rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi
new file mode 100644 (file)
index 0000000..ff81dfd
--- /dev/null
@@ -0,0 +1,397 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Gru-Chromebook shared properties
+ *
+ * Copyright 2018 Google, Inc
+ */
+
+#include "rk3399-gru.dtsi"
+
+/ {
+       pp900_ap: pp900-ap {
+               compatible = "regulator-fixed";
+               regulator-name = "pp900_ap";
+
+               /* EC turns on w/ pp900_ap_en; always on for AP */
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <900000>;
+               regulator-max-microvolt = <900000>;
+
+               vin-supply = <&ppvar_sys>;
+       };
+
+       /* EC turns on w/ pp900_usb_en */
+       pp900_usb: pp900-ap {
+       };
+
+       /* EC turns on w/ pp900_pcie_en */
+       pp900_pcie: pp900-ap {
+       };
+
+       pp3000: pp3000 {
+               compatible = "regulator-fixed";
+               regulator-name = "pp3000";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pp3000_en>;
+
+               enable-active-high;
+               gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <3000000>;
+               regulator-max-microvolt = <3000000>;
+
+               vin-supply = <&ppvar_sys>;
+       };
+
+       ppvar_centerlogic_pwm: ppvar-centerlogic-pwm {
+               compatible = "pwm-regulator";
+               regulator-name = "ppvar_centerlogic_pwm";
+
+               pwms = <&pwm3 0 3337 0>;
+               pwm-supply = <&ppvar_sys>;
+               pwm-dutycycle-range = <100 0>;
+               pwm-dutycycle-unit = <100>;
+
+               /* EC turns on w/ ppvar_centerlogic_en; always on for AP */
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <799434>;
+               regulator-max-microvolt = <1049925>;
+       };
+
+       ppvar_centerlogic: ppvar-centerlogic {
+               compatible = "vctrl-regulator";
+               regulator-name = "ppvar_centerlogic";
+
+               regulator-min-microvolt = <799434>;
+               regulator-max-microvolt = <1049925>;
+
+               ctrl-supply = <&ppvar_centerlogic_pwm>;
+               ctrl-voltage-range = <799434 1049925>;
+
+               regulator-settling-time-up-us = <378>;
+               min-slew-down-rate = <225>;
+               ovp-threshold-percent = <16>;
+       };
+
+       /* Schematics call this PPVAR even though it's fixed */
+       ppvar_logic: ppvar-logic {
+               compatible = "regulator-fixed";
+               regulator-name = "ppvar_logic";
+
+               /* EC turns on w/ ppvar_logic_en; always on for AP */
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <900000>;
+               regulator-max-microvolt = <900000>;
+
+               vin-supply = <&ppvar_sys>;
+       };
+
+       pp1800_audio: pp1800-audio {
+               compatible = "regulator-fixed";
+               regulator-name = "pp1800_audio";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pp1800_audio_en>;
+
+               enable-active-high;
+               gpio = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+
+               regulator-always-on;
+               regulator-boot-on;
+
+               vin-supply = <&pp1800>;
+       };
+
+       /* gpio is shared with pp3300_wifi_bt */
+       pp1800_pcie: pp1800-pcie {
+               compatible = "regulator-fixed";
+               regulator-name = "pp1800_pcie";
+               pinctrl-names = "default";
+               pinctrl-0 = <&wlan_module_pd_l>;
+
+               enable-active-high;
+               gpio = <&gpio0 4 GPIO_ACTIVE_HIGH>;
+
+               /*
+                * Need to wait 1ms + ramp-up time before we can power on WiFi.
+                * This has been approximated as 8ms total.
+                */
+               regulator-enable-ramp-delay = <8000>;
+
+               vin-supply = <&pp1800>;
+       };
+
+       /* Always on; plain and simple */
+       pp3000_ap: pp3000_emmc: pp3000 {
+       };
+
+       pp1500_ap_io: pp1500-ap-io {
+               compatible = "regulator-fixed";
+               regulator-name = "pp1500_ap_io";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pp1500_en>;
+
+               enable-active-high;
+               gpio = <&gpio0 10 GPIO_ACTIVE_HIGH>;
+
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <1500000>;
+               regulator-max-microvolt = <1500000>;
+
+               vin-supply = <&pp1800>;
+       };
+
+       pp3300_disp: pp3300-disp {
+               compatible = "regulator-fixed";
+               regulator-name = "pp3300_disp";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pp3300_disp_en>;
+
+               enable-active-high;
+               gpio = <&gpio4 27 GPIO_ACTIVE_HIGH>;
+
+               startup-delay-us = <2000>;
+               vin-supply = <&pp3300>;
+       };
+
+       /* EC turns on w/ pp3300_usb_en_l */
+       pp3300_usb: pp3300 {
+       };
+
+       /* gpio is shared with pp1800_pcie and pinctrl is set there */
+       pp3300_wifi_bt: pp3300-wifi-bt {
+               compatible = "regulator-fixed";
+               regulator-name = "pp3300_wifi_bt";
+
+               enable-active-high;
+               gpio = <&gpio0 4 GPIO_ACTIVE_HIGH>;
+
+               vin-supply = <&pp3300>;
+       };
+
+       /*
+        * This is a bit of a hack. The WiFi module should be reset at least
+        * 1ms after its regulators have ramped up (max rampup time is ~7ms).
+        * With some stretching of the imagination, we can call the 1.8V
+        * regulator a supply.
+        */
+       wlan_pd_n: wlan-pd-n {
+               compatible = "regulator-fixed";
+               regulator-name = "wlan_pd_n";
+               pinctrl-names = "default";
+               pinctrl-0 = <&wlan_module_reset_l>;
+
+               enable-active-high;
+               gpio = <&gpio1 11 GPIO_ACTIVE_HIGH>;
+
+               vin-supply = <&pp1800_pcie>;
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               brightness-levels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+                                    17 18 19 20 21 22 23 24 25 26 27 28 29 30
+                                    31 32 33 34 35 36 37 38 39 40 41 42 43 44
+                                    45 46 47 48 49 50 51 52 53 54 55 56 57 58
+                                    59 60 61 62 63 64 65 66 67 68 69 70 71 72
+                                    73 74 75 76 77 78 79 80 81 82 83 84 85 86
+                                    87 88 89 90 91 92 93 94 95 96 97 98 99 100>;
+               default-brightness-level = <51>;
+               enable-gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
+               power-supply = <&pp3300_disp>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&bl_en>;
+               pwm-delay-us = <10000>;
+       };
+};
+
+&ppvar_bigcpu {
+       min-slew-down-rate = <225>;
+       ovp-threshold-percent = <16>;
+};
+
+&ppvar_litcpu {
+       min-slew-down-rate = <225>;
+       ovp-threshold-percent = <16>;
+};
+
+&ppvar_gpu {
+       min-slew-down-rate = <225>;
+       ovp-threshold-percent = <16>;
+};
+
+&cdn_dp {
+       extcon = <&usbc_extcon0>, <&usbc_extcon1>;
+};
+
+&edp {
+       status = "okay";
+
+       ports {
+               edp_out: port@1 {
+                       reg = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       edp_out_panel: endpoint@0 {
+                               reg = <0>;
+                               remote-endpoint = <&panel_in_edp>;
+                       };
+               };
+       };
+};
+
+ap_i2c_mic: &i2c1 {
+       status = "okay";
+
+       clock-frequency = <400000>;
+
+       /* These are relatively safe rise/fall times */
+       i2c-scl-falling-time-ns = <50>;
+       i2c-scl-rising-time-ns = <300>;
+
+       headsetcodec: rt5514@57 {
+               compatible = "realtek,rt5514";
+               reg = <0x57>;
+               realtek,dmic-init-delay-ms = <20>;
+       };
+};
+
+ap_i2c_tp: &i2c5 {
+       status = "okay";
+
+       clock-frequency = <400000>;
+
+       /* These are relatively safe rise/fall times */
+       i2c-scl-falling-time-ns = <50>;
+       i2c-scl-rising-time-ns = <300>;
+
+       /*
+        * Note strange pullup enable.  Apparently this avoids leakage but
+        * still allows us to get nice 4.7K pullups for high speed i2c
+        * transfers.  Basically we want the pullup on whenever the ap is
+        * alive, so the "en" pin just gets set to output high.
+        */
+       pinctrl-0 = <&i2c5_xfer &ap_i2c_tp_pu_en>;
+};
+
+&cros_ec {
+       cros_ec_pwm: ec-pwm {
+               compatible = "google,cros-ec-pwm";
+               #pwm-cells = <1>;
+       };
+
+       usbc_extcon1: extcon@1 {
+               compatible = "google,extcon-usbc-cros-ec";
+               google,usb-port-id = <1>;
+
+               #extcon-cells = <0>;
+       };
+};
+
+&sound {
+       rockchip,codec = <&max98357a &headsetcodec
+                         &codec &wacky_spi_audio &cdn_dp>;
+};
+
+&spi2 {
+       wacky_spi_audio: spi2@0 {
+               compatible = "realtek,rt5514";
+               reg = <0>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&mic_int>;
+               /* May run faster once verified. */
+               spi-max-frequency = <10000000>;
+               wakeup-source;
+       };
+};
+
+&pci_rootport {
+       mvl_wifi: wifi@0,0 {
+               compatible = "pci1b4b,2b42";
+               reg = <0x83010000 0x0 0x00000000 0x0 0x00100000
+                      0x83010000 0x0 0x00100000 0x0 0x00100000>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&wlan_host_wake_l>;
+               wakeup-source;
+       };
+};
+
+&tcphy1 {
+       status = "okay";
+       extcon = <&usbc_extcon1>;
+};
+
+&u2phy1 {
+       status = "okay";
+};
+
+&usb_host0_ehci {
+       status = "okay";
+};
+
+&usb_host1_ehci {
+       status = "okay";
+};
+
+&usb_host1_ohci {
+       status = "okay";
+};
+
+&usbdrd3_1 {
+       status = "okay";
+       extcon = <&usbc_extcon1>;
+};
+
+&usbdrd_dwc3_1 {
+       status = "okay";
+       dr_mode = "host";
+};
+
+&pinctrl {
+       discrete-regulators {
+               pp1500_en: pp1500-en {
+                       rockchip,pins = <RK_GPIO0 10 RK_FUNC_GPIO
+                                        &pcfg_pull_none>;
+               };
+
+               pp1800_audio_en: pp1800-audio-en {
+                       rockchip,pins = <RK_GPIO0 2 RK_FUNC_GPIO
+                                        &pcfg_pull_down>;
+               };
+
+               pp3000_en: pp3000-en {
+                       rockchip,pins = <RK_GPIO0 12 RK_FUNC_GPIO
+                                        &pcfg_pull_none>;
+               };
+
+               pp3300_disp_en: pp3300-disp-en {
+                       rockchip,pins = <RK_GPIO4 27 RK_FUNC_GPIO
+                                        &pcfg_pull_none>;
+               };
+
+               wlan_module_pd_l: wlan-module-pd-l {
+                       rockchip,pins = <RK_GPIO0 4 RK_FUNC_GPIO
+                                        &pcfg_pull_down>;
+               };
+       };
+};
+
+&wifi {
+       wifi_perst_l: wifi-perst-l {
+               rockchip,pins = <2 27 RK_FUNC_GPIO &pcfg_pull_none>;
+       };
+
+       wlan_host_wake_l: wlan-host-wake-l {
+               rockchip,pins = <0 8 RK_FUNC_GPIO &pcfg_pull_none>;
+       };
+};
index 82179125bfb7c78fcb0d3bc0beef209d1dbaf871..2cc7c47d6a85d79312a519dd0a0c02964f9223ff 100644 (file)
@@ -1,49 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Google Gru-Kevin Rev 6+ board device tree source
  *
  * Copyright 2016-2017 Google, Inc
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
-#include "rk3399-gru.dtsi"
+#include "rk3399-gru-chromebook.dtsi"
 #include <dt-bindings/input/linux-event-codes.h>
 
 /*
                vin-supply = <&pp3300>;
        };
 
-       backlight: backlight {
-               compatible = "pwm-backlight";
-               pwms = <&cros_ec_pwm 1>;
-               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 = <51>;
-               enable-gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
-               power-supply = <&pp3300_disp>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&bl_en>;
-               pwm-delay-us = <10000>;
-       };
-
        edp_panel: edp-panel {
                compatible = "sharp,lq123p1jx31", "simple-panel";
                backlight = <&backlight>;
        };
 };
 
+&backlight {
+       pwms = <&cros_ec_pwm 1>;
+};
+
 &gpio_keys {
        pinctrl-names = "default";
        pinctrl-0 = <&bt_host_wake_l>, <&cpu1_pen_eject>;
@@ -280,23 +229,6 @@ ap_i2c_dig: &i2c2 {
        };
 };
 
-&edp {
-       status = "okay";
-
-       ports {
-               edp_out: port@1 {
-                       reg = <1>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       edp_out_panel: endpoint@0 {
-                               reg = <0>;
-                               remote-endpoint = <&panel_in_edp>;
-                       };
-               };
-       };
-};
-
 &ppvar_bigcpu_pwm {
        regulator-min-microvolt = <798674>;
        regulator-max-microvolt = <1302172>;
@@ -374,10 +306,4 @@ ap_i2c_dig: &i2c2 {
                        rockchip,pins = <0 13 RK_FUNC_GPIO &pcfg_pull_up>;
                };
        };
-
-       wifi {
-               wlan_host_wake_l: wlan-host-wake-l {
-                       rockchip,pins = <0 8 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
 };
index f49bfab75dd031640126b7c9ea50dd0c89b0a4fc..ca07f60322003eadba12af80ece20ee278efa2f4 100644 (file)
@@ -1,45 +1,8 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Google Gru (and derivatives) board device tree source
  *
  * Copyright 2016-2017 Google, Inc
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *  Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/input/input.h>
                regulator-boot-on;
        };
 
-       pp900_ap: pp900-ap {
-               compatible = "regulator-fixed";
-               regulator-name = "pp900_ap";
-
-               /* EC turns on w/ pp900_ap_en; always on for AP */
-               regulator-always-on;
-               regulator-boot-on;
-               regulator-min-microvolt = <900000>;
-               regulator-max-microvolt = <900000>;
-
-               vin-supply = <&ppvar_sys>;
-       };
-
        pp1200_lpddr: pp1200-lpddr {
                compatible = "regulator-fixed";
                regulator-name = "pp1200_lpddr";
                vin-supply = <&ppvar_sys>;
        };
 
-       pp3000: pp3000 {
-               compatible = "regulator-fixed";
-               regulator-name = "pp3000";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pp3000_en>;
-
-               enable-active-high;
-               gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>;
-
-               regulator-always-on;
-               regulator-boot-on;
-               regulator-min-microvolt = <3000000>;
-               regulator-max-microvolt = <3000000>;
-
-               vin-supply = <&ppvar_sys>;
-       };
-
        pp3300: pp3300 {
                compatible = "regulator-fixed";
                regulator-name = "pp3300";
                ctrl-voltage-range = <800107 1302232>;
 
                regulator-settling-time-up-us = <322>;
-               min-slew-down-rate = <225>;
-               ovp-threshold-percent = <16>;
        };
 
        ppvar_litcpu_pwm: ppvar-litcpu-pwm {
                ctrl-voltage-range = <797743 1307837>;
 
                regulator-settling-time-up-us = <384>;
-               min-slew-down-rate = <225>;
-               ovp-threshold-percent = <16>;
        };
 
        ppvar_gpu_pwm: ppvar-gpu-pwm {
                ctrl-voltage-range = <786384 1217747>;
 
                regulator-settling-time-up-us = <390>;
-               min-slew-down-rate = <225>;
-               ovp-threshold-percent = <16>;
-       };
-
-       ppvar_centerlogic_pwm: ppvar-centerlogic-pwm {
-               compatible = "pwm-regulator";
-               regulator-name = "ppvar_centerlogic_pwm";
-
-               pwms = <&pwm3 0 3337 0>;
-               pwm-supply = <&ppvar_sys>;
-               pwm-dutycycle-range = <100 0>;
-               pwm-dutycycle-unit = <100>;
-
-               /* EC turns on w/ ppvar_centerlogic_en; always on for AP */
-               regulator-always-on;
-               regulator-boot-on;
-               regulator-min-microvolt = <799434>;
-               regulator-max-microvolt = <1049925>;
-       };
-
-       ppvar_centerlogic: ppvar-centerlogic {
-               compatible = "vctrl-regulator";
-               regulator-name = "ppvar_centerlogic";
-
-               regulator-min-microvolt = <799434>;
-               regulator-max-microvolt = <1049925>;
-
-               ctrl-supply = <&ppvar_centerlogic_pwm>;
-               ctrl-voltage-range = <799434 1049925>;
-
-               regulator-settling-time-up-us = <378>;
-               min-slew-down-rate = <225>;
-               ovp-threshold-percent = <16>;
-       };
-
-       /* Schematics call this PPVAR even though it's fixed */
-       ppvar_logic: ppvar-logic {
-               compatible = "regulator-fixed";
-               regulator-name = "ppvar_logic";
-
-               /* EC turns on w/ ppvar_logic_en; always on for AP */
-               regulator-always-on;
-               regulator-boot-on;
-               regulator-min-microvolt = <900000>;
-               regulator-max-microvolt = <900000>;
-
-               vin-supply = <&ppvar_sys>;
        };
 
        /* EC turns on w/ pp900_ddrpll_en */
        pp900_ddrpll: pp900-ap {
        };
 
-       /* EC turns on w/ pp900_pcie_en */
-       pp900_pcie: pp900-ap {
-       };
-
        /* EC turns on w/ pp900_pll_en */
        pp900_pll: pp900-ap {
        };
        pp900_pmu: pp900-ap {
        };
 
-       /* EC turns on w/ pp900_usb_en */
-       pp900_usb: pp900-ap {
-       };
-
        /* EC turns on w/ pp1800_s0_en_l */
        pp1800_ap_io: pp1800_emmc: pp1800_nfc: pp1800_s0: pp1800 {
        };
        pp1800_usb: pp1800 {
        };
 
-       pp1500_ap_io: pp1500-ap-io {
-               compatible = "regulator-fixed";
-               regulator-name = "pp1500_ap_io";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pp1500_en>;
-
-               enable-active-high;
-               gpio = <&gpio0 10 GPIO_ACTIVE_HIGH>;
-
-               regulator-always-on;
-               regulator-boot-on;
-               regulator-min-microvolt = <1500000>;
-               regulator-max-microvolt = <1500000>;
-
-               vin-supply = <&pp1800>;
-       };
-
-       pp1800_audio: pp1800-audio {
-               compatible = "regulator-fixed";
-               regulator-name = "pp1800_audio";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pp1800_audio_en>;
-
-               enable-active-high;
-               gpio = <&gpio0 2 GPIO_ACTIVE_HIGH>;
-
-               regulator-always-on;
-               regulator-boot-on;
-
-               vin-supply = <&pp1800>;
-       };
-
-       /* gpio is shared with pp3300_wifi_bt */
-       pp1800_pcie: pp1800-pcie {
-               compatible = "regulator-fixed";
-               regulator-name = "pp1800_pcie";
-               pinctrl-names = "default";
-               pinctrl-0 = <&wlan_module_pd_l>;
-
-               enable-active-high;
-               gpio = <&gpio0 4 GPIO_ACTIVE_HIGH>;
-
-               /*
-                * Need to wait 1ms + ramp-up time before we can power on WiFi.
-                * This has been approximated as 8ms total.
-                */
-               regulator-enable-ramp-delay = <8000>;
-
-               vin-supply = <&pp1800>;
-       };
-
-       /*
-        * This is a bit of a hack. The WiFi module should be reset at least
-        * 1ms after its regulators have ramped up (max rampup time is ~7ms).
-        * With some stretching of the imagination, we can call the 1.8V
-        * regulator a supply.
-        */
-       wlan_pd_n: wlan-pd-n {
-               compatible = "regulator-fixed";
-               regulator-name = "wlan_pd_n";
-               pinctrl-names = "default";
-               pinctrl-0 = <&wlan_module_reset_l>;
-
-               enable-active-high;
-               gpio = <&gpio1 11 GPIO_ACTIVE_HIGH>;
-
-               vin-supply = <&pp1800_pcie>;
-       };
-
-       /* Always on; plain and simple */
-       pp3000_ap: pp3000_emmc: pp3000 {
-       };
-
        pp3000_sd_slot: pp3000-sd-slot {
                compatible = "regulator-fixed";
                regulator-name = "pp3000_sd_slot";
        pp3300_trackpad: pp3300-trackpad {
        };
 
-       /* EC turns on w/ pp3300_usb_en_l */
-       pp3300_usb: pp3300 {
-       };
-
-       pp3300_disp: pp3300-disp {
-               compatible = "regulator-fixed";
-               regulator-name = "pp3300_disp";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pp3300_disp_en>;
-
-               enable-active-high;
-               gpio = <&gpio4 27 GPIO_ACTIVE_HIGH>;
-
-               startup-delay-us = <2000>;
-               vin-supply = <&pp3300>;
-       };
-
-       /* gpio is shared with pp1800_pcie and pinctrl is set there */
-       pp3300_wifi_bt: pp3300-wifi-bt {
-               compatible = "regulator-fixed";
-               regulator-name = "pp3300_wifi_bt";
-
-               enable-active-high;
-               gpio = <&gpio0 4 GPIO_ACTIVE_HIGH>;
-
-               vin-supply = <&pp3300>;
-       };
-
        /* EC turns on w/ usb_a_en */
        pp5000_usb_a_vbus: pp5000 {
        };
                pinctrl-names = "default";
                pinctrl-0 = <&bt_host_wake_l>;
 
-               wake-on-bt {
+               wake_on_bt: wake-on-bt {
                        label = "Wake-on-Bluetooth";
                        gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
                        linux,code = <KEY_WAKEUP>;
                status = "okay";
        };
 
-       sound {
+       sound: sound {
                compatible = "rockchip,rk3399-gru-sound";
                rockchip,cpu = <&i2s0 &i2s2>;
-               rockchip,codec = <&max98357a &headsetcodec
-                                 &codec &wacky_spi_audio &cdn_dp>;
        };
 };
 
 &cdn_dp {
        status = "okay";
-       extcon = <&usbc_extcon0>, <&usbc_extcon1>;
 };
 
 /*
        status = "okay";
 };
 
-ap_i2c_mic: &i2c1 {
-       status = "okay";
-
-       clock-frequency = <400000>;
-
-       /* These are relatively safe rise/fall times */
-       i2c-scl-falling-time-ns = <50>;
-       i2c-scl-rising-time-ns = <300>;
-
-       headsetcodec: rt5514@57 {
-               compatible = "realtek,rt5514";
-               reg = <0x57>;
-               realtek,dmic-init-delay-ms = <20>;
-       };
-};
-
 ap_i2c_ts: &i2c3 {
        status = "okay";
 
@@ -639,24 +393,6 @@ ap_i2c_ts: &i2c3 {
        i2c-scl-rising-time-ns = <300>;
 };
 
-ap_i2c_tp: &i2c5 {
-       status = "okay";
-
-       clock-frequency = <400000>;
-
-       /* These are relatively safe rise/fall times */
-       i2c-scl-falling-time-ns = <50>;
-       i2c-scl-rising-time-ns = <300>;
-
-       /*
-        * Note strange pullup enable.  Apparently this avoids leakage but
-        * still allows us to get nice 4.7K pullups for high speed i2c
-        * transfers.  Basically we want the pullup on whenever the ap is
-        * alive, so the "en" pin just gets set to output high.
-        */
-       pinctrl-0 = <&i2c5_xfer &ap_i2c_tp_pu_en>;
-};
-
 ap_i2c_audio: &i2c8 {
        status = "okay";
 
@@ -730,17 +466,6 @@ ap_i2c_audio: &i2c8 {
                #address-cells = <3>;
                #size-cells = <2>;
                ranges;
-
-               mvl_wifi: wifi@0,0 {
-                       compatible = "pci1b4b,2b42";
-                       reg = <0x83010000 0x0 0x00000000 0x0 0x00100000
-                              0x83010000 0x0 0x00100000 0x0 0x00100000>;
-                       interrupt-parent = <&gpio0>;
-                       interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&wlan_host_wake_l>;
-                       wakeup-source;
-               };
        };
 };
 
@@ -830,18 +555,6 @@ ap_i2c_audio: &i2c8 {
 
 &spi2 {
        status = "okay";
-
-       wacky_spi_audio: spi2@0 {
-               compatible = "realtek,rt5514";
-               reg = <0>;
-               interrupt-parent = <&gpio1>;
-               interrupts = <13 IRQ_TYPE_LEVEL_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&mic_int>;
-               /* May run faster once verified. */
-               spi-max-frequency = <10000000>;
-               wakeup-source;
-       };
 };
 
 &spi5 {
@@ -863,24 +576,12 @@ ap_i2c_audio: &i2c8 {
                        #size-cells = <0>;
                };
 
-               cros_ec_pwm: ec-pwm {
-                       compatible = "google,cros-ec-pwm";
-                       #pwm-cells = <1>;
-               };
-
                usbc_extcon0: extcon@0 {
                        compatible = "google,extcon-usbc-cros-ec";
                        google,usb-port-id = <0>;
 
                        #extcon-cells = <0>;
                };
-
-               usbc_extcon1: extcon@1 {
-                       compatible = "google,extcon-usbc-cros-ec";
-                       google,usb-port-id = <1>;
-
-                       #extcon-cells = <0>;
-               };
        };
 };
 
@@ -896,19 +597,10 @@ ap_i2c_audio: &i2c8 {
        extcon = <&usbc_extcon0>;
 };
 
-&tcphy1 {
-       status = "okay";
-       extcon = <&usbc_extcon1>;
-};
-
 &u2phy0 {
        status = "okay";
 };
 
-&u2phy1 {
-       status = "okay";
-};
-
 &u2phy0_host {
        status = "okay";
 };
@@ -929,22 +621,10 @@ ap_i2c_audio: &i2c8 {
        status = "okay";
 };
 
-&usb_host0_ehci {
-       status = "okay";
-};
-
 &usb_host0_ohci {
        status = "okay";
 };
 
-&usb_host1_ehci {
-       status = "okay";
-};
-
-&usb_host1_ohci {
-       status = "okay";
-};
-
 &usbdrd3_0 {
        status = "okay";
        extcon = <&usbc_extcon0>;
@@ -955,16 +635,6 @@ ap_i2c_audio: &i2c8 {
        dr_mode = "host";
 };
 
-&usbdrd3_1 {
-       status = "okay";
-       extcon = <&usbc_extcon1>;
-};
-
-&usbdrd_dwc3_1 {
-       status = "okay";
-       dr_mode = "host";
-};
-
 &vopb {
        status = "okay";
 };
@@ -1023,26 +693,6 @@ ap_i2c_audio: &i2c8 {
        };
 
        discrete-regulators {
-               pp1500_en: pp1500-en {
-                       rockchip,pins = <RK_GPIO0 10 RK_FUNC_GPIO
-                                        &pcfg_pull_none>;
-               };
-
-               pp1800_audio_en: pp1800-audio-en {
-                       rockchip,pins = <RK_GPIO0 2 RK_FUNC_GPIO
-                                        &pcfg_pull_down>;
-               };
-
-               pp3300_disp_en: pp3300-disp-en {
-                       rockchip,pins = <RK_GPIO4 27 RK_FUNC_GPIO
-                                        &pcfg_pull_none>;
-               };
-
-               pp3000_en: pp3000-en {
-                       rockchip,pins = <RK_GPIO0 12 RK_FUNC_GPIO
-                                        &pcfg_pull_none>;
-               };
-
                sd_io_pwr_en: sd-io-pwr-en {
                        rockchip,pins = <RK_GPIO2 2 RK_FUNC_GPIO
                                         &pcfg_pull_none>;
@@ -1057,11 +707,6 @@ ap_i2c_audio: &i2c8 {
                        rockchip,pins = <RK_GPIO4 29 RK_FUNC_GPIO
                                         &pcfg_pull_none>;
                };
-
-               wlan_module_pd_l: wlan-module-pd-l {
-                       rockchip,pins = <RK_GPIO0 4 RK_FUNC_GPIO
-                                        &pcfg_pull_down>;
-               };
        };
 
        codec {
@@ -1168,11 +813,7 @@ ap_i2c_audio: &i2c8 {
                };
        };
 
-       wifi {
-               wifi_perst_l: wifi-perst-l {
-                       rockchip,pins = <2 27 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-
+       wifi: wifi {
                wlan_module_reset_l: wlan-module-reset-l {
                        rockchip,pins = <1 11 RK_FUNC_GPIO &pcfg_pull_none>;
                };
index d8a120f945c803ee91e4fdd5a7afa3a8b68ed28a..69cc9b05baa572344d78d8176ebe895652f4a9af 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016-2017 Fuzhou Rockchip Electronics Co., Ltd
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 / {
index 81617bcf252272313163f9dc48ef35c077981559..d6f1095abb0409cde225636319bcd340ab861cf5 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016-2017 Fuzhou Rockchip Electronics Co., Ltd
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 / {
index e0afdd8b62bd1887c106069ec987c7de30e72a87..e0d64f862322e507798c4fd5d590963164da4c4e 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
index 14a0f19986390a7593cd3be04b23b0c7de1e493d..0130b9f98c9deefca654794f941e7dec85e655c0 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/pwm/pwm.h>
        pinctrl-0 = <&i2s0_2ch_bus>;
        rockchip,playback-channels = <2>;
        rockchip,capture-channels = <2>;
-       #sound-dai-cells = <0>;
        status = "okay";
 };
 
index ad7548d3b93d50f073f0e93015a9dd107535413d..fef2c06089993c38a76096df356fdf1406fa34f1 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 /dts-v1/;
 &i2s0 {
        rockchip,playback-channels = <8>;
        rockchip,capture-channels = <8>;
-       #sound-dai-cells = <0>;
        status = "okay";
 };
 
 &spdif {
        i2c-scl-rising-time-ns = <450>;
        i2c-scl-falling-time-ns = <15>;
-       #sound-dai-cells = <0>;
        status = "okay";
 };
index 941b627094d7f2dadcb61459fc7250dfef5634d7..36b60791c156d2ace112850571418d0410f81bd7 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include "dt-bindings/pwm/pwm.h"
        status = "okay";
 };
 
+&hdmi_sound {
+       status = "okay";
+};
+
 &i2c0 {
        clock-frequency = <400000>;
        i2c-scl-rising-time-ns = <168>;
 };
 
 &i2s2 {
-       #sound-dai-cells = <0>;
        status = "okay";
 };
 
index e0040b648f4330909066b23fe2129e36435603d6..c88e603396f610615e4070bc8af62dfa9d389b0b 100644 (file)
@@ -1,43 +1,6 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
  * Copyright (c) 2016 Fuzhou Rockchip Electronics Co., Ltd
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #include <dt-bindings/clock/rk3399-cru.h>
                        compatible = "arm,cortex-a53", "arm,armv8";
                        reg = <0x0 0x0>;
                        enable-method = "psci";
-                       #cooling-cells = <2>; /* min followed by max */
                        clocks = <&cru ARMCLKL>;
+                       #cooling-cells = <2>; /* min followed by max */
                        dynamic-power-coefficient = <100>;
                };
 
                        reg = <0x0 0x1>;
                        enable-method = "psci";
                        clocks = <&cru ARMCLKL>;
+                       #cooling-cells = <2>; /* min followed by max */
                        dynamic-power-coefficient = <100>;
                };
 
                        reg = <0x0 0x2>;
                        enable-method = "psci";
                        clocks = <&cru ARMCLKL>;
+                       #cooling-cells = <2>; /* min followed by max */
                        dynamic-power-coefficient = <100>;
                };
 
                        reg = <0x0 0x3>;
                        enable-method = "psci";
                        clocks = <&cru ARMCLKL>;
+                       #cooling-cells = <2>; /* min followed by max */
                        dynamic-power-coefficient = <100>;
                };
 
                        compatible = "arm,cortex-a72", "arm,armv8";
                        reg = <0x0 0x100>;
                        enable-method = "psci";
-                       #cooling-cells = <2>; /* min followed by max */
                        clocks = <&cru ARMCLKB>;
+                       #cooling-cells = <2>; /* min followed by max */
                        dynamic-power-coefficient = <436>;
                };
 
                        reg = <0x0 0x101>;
                        enable-method = "psci";
                        clocks = <&cru ARMCLKB>;
+                       #cooling-cells = <2>; /* min followed by max */
                        dynamic-power-coefficient = <436>;
                };
        };
                         <&cru SRST_P_UPHY0_TCPHY>;
                reset-names = "uphy", "uphy-pipe", "uphy-tcphy";
                rockchip,grf = <&grf>;
-               rockchip,typec-conn-dir = <0xe580 0 16>;
-               rockchip,usb3tousb2-en = <0xe580 3 19>;
-               rockchip,external-psm = <0xe588 14 30>;
-               rockchip,pipe-status = <0xe5c0 0 0>;
                status = "disabled";
 
                tcphy0_dp: dp-port {
                         <&cru SRST_P_UPHY1_TCPHY>;
                reset-names = "uphy", "uphy-pipe", "uphy-tcphy";
                rockchip,grf = <&grf>;
-               rockchip,typec-conn-dir = <0xe58c 0 16>;
-               rockchip,usb3tousb2-en = <0xe58c 3 19>;
-               rockchip,external-psm = <0xe594 14 30>;
-               rockchip,pipe-status = <0xe5c0 16 16>;
                status = "disabled";
 
                tcphy1_dp: dp-port {
                pinctrl-names = "default";
                pinctrl-0 = <&spdif_bus>;
                power-domains = <&power RK3399_PD_SDIOAUDIO>;
+               #sound-dai-cells = <0>;
                status = "disabled";
        };
 
                pinctrl-names = "default";
                pinctrl-0 = <&i2s0_8ch_bus>;
                power-domains = <&power RK3399_PD_SDIOAUDIO>;
+               #sound-dai-cells = <0>;
                status = "disabled";
        };
 
                pinctrl-names = "default";
                pinctrl-0 = <&i2s1_2ch_bus>;
                power-domains = <&power RK3399_PD_SDIOAUDIO>;
+               #sound-dai-cells = <0>;
                status = "disabled";
        };
 
                clock-names = "i2s_clk", "i2s_hclk";
                clocks = <&cru SCLK_I2S2_8CH>, <&cru HCLK_I2S2_8CH>;
                power-domains = <&power RK3399_PD_SDIOAUDIO>;
+               #sound-dai-cells = <0>;
                status = "disabled";
        };
 
                status = "disabled";
        };
 
+       hdmi_sound: hdmi-sound {
+               compatible = "simple-audio-card";
+               simple-audio-card,format = "i2s";
+               simple-audio-card,mclk-fs = <256>;
+               simple-audio-card,name = "hdmi-sound";
+               status = "disabled";
+
+               simple-audio-card,cpu {
+                       sound-dai = <&i2s2>;
+               };
+               simple-audio-card,codec {
+                       sound-dai = <&hdmi>;
+               };
+       };
+
        hdmi: hdmi@ff940000 {
                compatible = "rockchip,rk3399-dw-hdmi";
                reg = <0x0 0xff940000 0x0 0x20000>;
                power-domains = <&power RK3399_PD_HDCP>;
                reg-io-width = <4>;
                rockchip,grf = <&grf>;
+               #sound-dai-cells = <0>;
                status = "disabled";
 
                ports {
                        drive-strength = <12>;
                };
 
+               pcfg_pull_none_13ma: pcfg-pull-none-13ma {
+                       bias-disable;
+                       drive-strength = <13>;
+               };
+
+               pcfg_pull_none_18ma: pcfg-pull-none-18ma {
+                       bias-disable;
+                       drive-strength = <18>;
+               };
+
+               pcfg_pull_none_20ma: pcfg-pull-none-20ma {
+                       bias-disable;
+                       drive-strength = <20>;
+               };
+
+               pcfg_pull_up_2ma: pcfg-pull-up-2ma {
+                       bias-pull-up;
+                       drive-strength = <2>;
+               };
+
                pcfg_pull_up_8ma: pcfg-pull-up-8ma {
                        bias-pull-up;
                        drive-strength = <8>;
                };
 
+               pcfg_pull_up_18ma: pcfg-pull-up-18ma {
+                       bias-pull-up;
+                       drive-strength = <18>;
+               };
+
+               pcfg_pull_up_20ma: pcfg-pull-up-20ma {
+                       bias-pull-up;
+                       drive-strength = <20>;
+               };
+
                pcfg_pull_down_4ma: pcfg-pull-down-4ma {
                        bias-pull-down;
                        drive-strength = <4>;
                };
 
-               pcfg_pull_up_2ma: pcfg-pull-up-2ma {
-                       bias-pull-up;
-                       drive-strength = <2>;
+               pcfg_pull_down_8ma: pcfg-pull-down-8ma {
+                       bias-pull-down;
+                       drive-strength = <8>;
                };
 
                pcfg_pull_down_12ma: pcfg-pull-down-12ma {
                        drive-strength = <12>;
                };
 
-               pcfg_pull_none_13ma: pcfg-pull-none-13ma {
-                       bias-disable;
-                       drive-strength = <13>;
+               pcfg_pull_down_18ma: pcfg-pull-down-18ma {
+                       bias-pull-down;
+                       drive-strength = <18>;
+               };
+
+               pcfg_pull_down_20ma: pcfg-pull-down-20ma {
+                       bias-pull-down;
+                       drive-strength = <20>;
+               };
+
+               pcfg_output_high: pcfg-output-high {
+                       output-high;
+               };
+
+               pcfg_output_low: pcfg-output-low {
+                       output-low;
                };
 
                clock {
                pwm0 {
                        pwm0_pin: pwm0-pin {
                                rockchip,pins =
-                                       <4 18 RK_FUNC_1 &pcfg_pull_none>;
+                                       <4 RK_PC2 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       pwm0_pin_pull_down: pwm0-pin-pull-down {
+                               rockchip,pins =
+                                       <4 RK_PC2 RK_FUNC_1 &pcfg_pull_down>;
                        };
 
                        vop0_pwm_pin: vop0-pwm-pin {
                                rockchip,pins =
-                                       <4 18 RK_FUNC_2 &pcfg_pull_none>;
+                                       <4 RK_PC2 RK_FUNC_2 &pcfg_pull_none>;
+                       };
+
+                       vop1_pwm_pin: vop1-pwm-pin {
+                               rockchip,pins =
+                                       <4 RK_PC2 RK_FUNC_3 &pcfg_pull_none>;
                        };
                };
 
                pwm1 {
                        pwm1_pin: pwm1-pin {
                                rockchip,pins =
-                                       <4 22 RK_FUNC_1 &pcfg_pull_none>;
+                                       <4 RK_PC6 RK_FUNC_1 &pcfg_pull_none>;
                        };
 
-                       vop1_pwm_pin: vop1-pwm-pin {
+                       pwm1_pin_pull_down: pwm1-pin-pull-down {
                                rockchip,pins =
-                                       <4 18 RK_FUNC_3 &pcfg_pull_none>;
+                                       <4 RK_PC6 RK_FUNC_1 &pcfg_pull_down>;
                        };
                };
 
                pwm2 {
                        pwm2_pin: pwm2-pin {
                                rockchip,pins =
-                                       <1 19 RK_FUNC_1 &pcfg_pull_none>;
+                                       <1 RK_PC3 RK_FUNC_1 &pcfg_pull_none>;
+                       };
+
+                       pwm2_pin_pull_down: pwm2-pin-pull-down {
+                               rockchip,pins =
+                                       <1 RK_PC3 RK_FUNC_1 &pcfg_pull_down>;
                        };
                };
 
                pwm3a {
                        pwm3a_pin: pwm3a-pin {
                                rockchip,pins =
-                                       <0 6 RK_FUNC_1 &pcfg_pull_none>;
+                                       <0 RK_PA6 RK_FUNC_1 &pcfg_pull_none>;
                        };
                };
 
                pwm3b {
                        pwm3b_pin: pwm3b-pin {
                                rockchip,pins =
-                                       <1 14 RK_FUNC_1 &pcfg_pull_none>;
+                                       <1 RK_PB6 RK_FUNC_1 &pcfg_pull_none>;
                        };
                };
 
index ae3b5adf32dfe4a31125880e3a8fa49877c83923..7968d524351b3e83ce227784164cf690f5daa158 100644 (file)
@@ -60,6 +60,7 @@
                        &i2s_port4
                        &spdif_port0
                        &comp_spdif_port0>;
+               hp-det-gpio = <&gpio UNIPHIER_GPIO_IRQ(0) GPIO_ACTIVE_LOW>;
        };
 
        spdif-out {
index 7919233c9ce27e3c86dc8dffce13a97e00112c64..1a5e7c24b90160a4b05ea237705a17415adb630f 100644 (file)
@@ -60,6 +60,7 @@
                        &i2s_port4
                        &spdif_port0
                        &comp_spdif_port0>;
+               hp-det-gpio = <&gpio UNIPHIER_GPIO_IRQ(0) GPIO_ACTIVE_LOW>;
        };
 
        spdif-out {
index 0298bd0d0e1a9751dcc9731496ddea4387aa1356..caf112629caad635b0948e23c8aa67941cf6161d 100644 (file)
@@ -58,6 +58,7 @@
                        clocks = <&sys_clk 32>;
                        enable-method = "psci";
                        operating-points-v2 = <&cluster0_opp>;
+                       #cooling-cells = <2>;
                };
 
                cpu2: cpu@100 {
@@ -77,6 +78,7 @@
                        clocks = <&sys_clk 33>;
                        enable-method = "psci";
                        operating-points-v2 = <&cluster1_opp>;
+                       #cooling-cells = <2>;
                };
        };
 
index 98d3b4fdb9adc9d71f5b747c4dd16c6c5d4639fa..82bd642d770b9fcc9976ddbf63375679ca512f62 100644 (file)
                #address-cells = <1>;
                #size-cells = <0>;
 
+               led-controller@200 {
+                       compatible = "sprd,sc27xx-bltc", "sprd,sc2731-bltc";
+                       reg = <0x200>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       led@0 {
+                               label = "red";
+                               reg = <0x0>;
+                       };
+
+                       led@1 {
+                               label = "green";
+                               reg = <0x1>;
+                       };
+
+                       led@2 {
+                               label = "blue";
+                               reg = <0x2>;
+                       };
+               };
+
                rtc@280 {
                        compatible = "sprd,sc27xx-rtc", "sprd,sc2731-rtc";
                        reg = <0x280>;
                        #interrupt-cells = <2>;
                };
 
+               efuse@380 {
+                       compatible = "sprd,sc27xx-efuse", "sprd,sc2731-efuse";
+                       reg = <0x380>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       hwlocks = <&hwlock 12>;
+               };
+
+               pmic_adc: adc@480 {
+                       compatible = "sprd,sc27xx-adc", "sprd,sc2731-adc";
+                       reg = <0x480>;
+                       interrupt-parent = <&sc2731_pmic>;
+                       interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+                       #io-channel-cells = <1>;
+                       hwlocks = <&hwlock 4>;
+               };
+
+               vibrator@ec8 {
+                       compatible = "sprd,sc27xx-vibrator", "sprd,sc2731-vibrator";
+                       reg = <0xec8>;
+               };
+
                regulators {
                        compatible = "sprd,sc27xx-regulator";
 
index 3f5160d2f1307b0db5076d3dc2844fffc544489f..48f5928ed45c5d68cb179a89e01f6e793116ad76 100644 (file)
        };
 
        idle-states{
-               entry-method = "arm,psci";
+               entry-method = "psci";
 
                CORE_PD: core_pd {
                        compatible = "arm,idle-state";
index e9db9108f3c0648e4245e84e9c0ddf6ffb4f152b..eb6be5675f79e683ee1d00ca77233df771f8b53a 100644 (file)
                                clocks = <&ext_32k>;
                        };
 
+                       timer@40050020 {
+                               compatible = "sprd,sc9860-suspend-timer";
+                               reg = <0 0x40050020 0 0x20>;
+                               clocks = <&ext_32k>;
+                       };
+
                        hwlock: hwspinlock@40500000 {
                                compatible = "sprd,hwspinlock-r3p0";
                                reg = <0 0x40500000 0 0x1000>;
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
new file mode 100644 (file)
index 0000000..63e619d
--- /dev/null
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Make file to build device tree binaries for boards based on
+# Texas Instruments Inc processors
+#
+# Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
+#
+
+dtb-$(CONFIG_ARCH_K3_AM6_SOC) += k3-am654-base-board.dtb
diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
new file mode 100644 (file)
index 0000000..2409344
--- /dev/null
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for AM6 SoC Family Main Domain peripherals
+ *
+ * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+&cbass_main {
+       gic500: interrupt-controller@1800000 {
+               compatible = "arm,gic-v3";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+               #interrupt-cells = <3>;
+               interrupt-controller;
+               reg = <0x01800000 0x10000>,     /* GICD */
+                     <0x01880000 0x90000>;     /* GICR */
+               /*
+                * vcpumntirq:
+                * virtual CPU interface maintenance interrupt
+                */
+               interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+
+               gic_its: gic-its@18200000 {
+                       compatible = "arm,gic-v3-its";
+                       reg = <0x01820000 0x10000>;
+                       msi-controller;
+                       #msi-cells = <1>;
+               };
+       };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am65.dtsi b/arch/arm64/boot/dts/ti/k3-am65.dtsi
new file mode 100644 (file)
index 0000000..cede1fa
--- /dev/null
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for AM6 SoC Family
+ *
+ * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+       model = "Texas Instruments K3 AM654 SoC";
+       compatible = "ti,am654";
+       interrupt-parent = <&gic500>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       chosen { };
+
+       firmware {
+               optee {
+                       compatible = "linaro,optee-tz";
+                       method = "smc";
+               };
+
+               psci: psci {
+                       compatible = "arm,psci-1.0";
+                       method = "smc";
+               };
+       };
+
+       a53_timer0: timer-cl0-cpu0 {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, /* cntpsirq */
+                            <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, /* cntpnsirq */
+                            <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, /* cntvirq */
+                            <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; /* cnthpirq */
+       };
+
+       pmu: pmu {
+               compatible = "arm,armv8-pmuv3";
+               /* Recommendation from GIC500 TRM Table A.3 */
+               interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
+       cbass_main: interconnect@100000 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x00100000 0x00 0x00100000 0x00020000>, /* ctrl mmr */
+                        <0x00600000 0x00 0x00600000 0x00001100>, /* GPIO */
+                        <0x00900000 0x00 0x00900000 0x00012000>, /* serdes */
+                        <0x01000000 0x00 0x01000000 0x0af02400>, /* Most peripherals */
+                        <0x30800000 0x00 0x30800000 0x0bc00000>, /* MAIN NAVSS */
+                        /* MCUSS Range */
+                        <0x28380000 0x00 0x28380000 0x03880000>,
+                        <0x40200000 0x00 0x40200000 0x00900100>,
+                        <0x42040000 0x00 0x42040000 0x03ac2400>,
+                        <0x45100000 0x00 0x45100000 0x00c24000>,
+                        <0x46000000 0x00 0x46000000 0x00200000>,
+                        <0x47000000 0x00 0x47000000 0x00068400>;
+
+               cbass_mcu: interconnect@28380000 {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x28380000 0x28380000 0x03880000>, /* MCU NAVSS*/
+                                <0x40200000 0x40200000 0x00900100>, /* First peripheral window */
+                                <0x42040000 0x42040000 0x03ac2400>, /* WKUP */
+                                <0x45100000 0x45100000 0x00c24000>, /* MMRs, remaining NAVSS */
+                                <0x46000000 0x46000000 0x00200000>, /* CPSW */
+                                <0x47000000 0x47000000 0x00068400>; /* OSPI space 1 */
+
+                       cbass_wakeup: interconnect@42040000 {
+                               compatible = "simple-bus";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               /* WKUP  Basic peripherals */
+                               ranges = <0x42040000 0x42040000 0x03ac2400>;
+                       };
+               };
+       };
+};
+
+/* Now include the peripherals for each bus segments */
+#include "k3-am65-main.dtsi"
diff --git a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
new file mode 100644 (file)
index 0000000..af6956f
--- /dev/null
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+
+#include "k3-am654.dtsi"
+
+/ {
+       compatible =  "ti,am654-evm", "ti,am654";
+       model = "Texas Instruments AM654 Base Board";
+
+       chosen {
+               stdout-path = "serial2:115200n8";
+               bootargs = "earlycon=ns16550a,mmio32,0x02800000";
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               /* 4G RAM */
+               reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+                     <0x00000008 0x80000000 0x00000000 0x80000000>;
+       };
+
+       reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+               secure_ddr: secure_ddr@9e800000 {
+                       reg = <0 0x9e800000 0 0x01800000>; /* for OP-TEE */
+                       alignment = <0x1000>;
+                       no-map;
+               };
+       };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am654.dtsi b/arch/arm64/boot/dts/ti/k3-am654.dtsi
new file mode 100644 (file)
index 0000000..2affa6f
--- /dev/null
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for AM6 SoC family in Quad core configuration
+ *
+ * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#include "k3-am65.dtsi"
+
+/ {
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               cpu-map {
+                       cluster0: cluster0 {
+                               core0 {
+                                       cpu = <&cpu0>;
+                               };
+
+                               core1 {
+                                       cpu = <&cpu1>;
+                               };
+                       };
+
+                       cluster1: cluster1 {
+                               core0 {
+                                       cpu = <&cpu2>;
+                               };
+
+                               core1 {
+                                       cpu = <&cpu3>;
+                               };
+                       };
+               };
+
+               cpu0: cpu@0 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0x000>;
+                       device_type = "cpu";
+                       enable-method = "psci";
+                       i-cache-size = <0x8000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <128>;
+                       next-level-cache = <&L2_0>;
+               };
+
+               cpu1: cpu@1 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0x001>;
+                       device_type = "cpu";
+                       enable-method = "psci";
+                       i-cache-size = <0x8000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <128>;
+                       next-level-cache = <&L2_0>;
+               };
+
+               cpu2: cpu@100 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0x100>;
+                       device_type = "cpu";
+                       enable-method = "psci";
+                       i-cache-size = <0x8000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <128>;
+                       next-level-cache = <&L2_1>;
+               };
+
+               cpu3: cpu@101 {
+                       compatible = "arm,cortex-a53", "arm,armv8";
+                       reg = <0x101>;
+                       device_type = "cpu";
+                       enable-method = "psci";
+                       i-cache-size = <0x8000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <128>;
+                       next-level-cache = <&L2_1>;
+               };
+       };
+
+       L2_0: l2-cache0 {
+               compatible = "cache";
+               cache-level = <2>;
+               cache-size = <0x80000>;
+               cache-line-size = <64>;
+               cache-sets = <512>;
+               next-level-cache = <&msmc_l3>;
+       };
+
+       L2_1: l2-cache1 {
+               compatible = "cache";
+               cache-level = <2>;
+               cache-size = <0x80000>;
+               cache-line-size = <64>;
+               cache-sets = <512>;
+               next-level-cache = <&msmc_l3>;
+       };
+
+       msmc_l3: l3-cache0 {
+               compatible = "cache";
+               cache-level = <3>;
+       };
+};
index c2a0c00272e2651c11bd7d3bc1a287abf0489752..60f5443f3ef40b388c0894f327ca0da2a23086b9 100644 (file)
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
-dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-ep108.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += avnet-ultra96-rev1.dtb
 dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zc1232-revA.dtb
 dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zc1254-revA.dtb
 dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zc1275-revA.dtb
diff --git a/arch/arm64/boot/dts/xilinx/avnet-ultra96-rev1.dts b/arch/arm64/boot/dts/xilinx/avnet-ultra96-rev1.dts
new file mode 100644 (file)
index 0000000..88aa06f
--- /dev/null
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Avnet Ultra96 rev1
+ *
+ * (C) Copyright 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+/dts-v1/;
+
+#include "zynqmp-zcu100-revC.dts"
+
+/ {
+       model = "Avnet Ultra96 Rev1";
+       compatible = "avnet,ultra96-rev1", "avnet,ultra96",
+                    "xlnx,zynqmp-zcu100-revC", "xlnx,zynqmp-zcu100",
+                    "xlnx,zynqmp";
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi
deleted file mode 100644 (file)
index 9f5eedb..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * clock specification for Xilinx ZynqMP ep108 development board
- *
- * (C) Copyright 2015, Xilinx, Inc.
- *
- * Michal Simek <michal.simek@xilinx.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.
- */
-
-/ {
-       misc_clk: misc_clk {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <25000000>;
-       };
-
-       i2c_clk: i2c_clk {
-               compatible = "fixed-clock";
-               #clock-cells = <0x0>;
-               clock-frequency = <111111111>;
-       };
-
-       sata_clk: sata_clk {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <75000000>;
-       };
-
-       clk100: clk100 {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <100000000>;
-       };
-
-       clk600: clk600 {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <600000000>;
-       };
-};
-
-&can0 {
-       clocks = <&misc_clk &misc_clk>;
-};
-
-&can1 {
-       clocks = <&misc_clk &misc_clk>;
-};
-
-&fpd_dma_chan1 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan2 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan3 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan4 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan5 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan6 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan7 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan8 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&gem0 {
-       clocks = <&misc_clk>, <&misc_clk>, <&misc_clk>;
-};
-
-&gpio {
-       clocks = <&misc_clk>;
-};
-
-&i2c0 {
-       clocks = <&i2c_clk>;
-};
-
-&i2c1 {
-       clocks = <&i2c_clk>;
-};
-
-&sata {
-       clocks = <&sata_clk>;
-};
-
-&sdhci0 {
-       clocks = <&misc_clk>, <&misc_clk>;
-};
-
-&sdhci1 {
-       clocks = <&misc_clk>, <&misc_clk>;
-};
-
-&spi0 {
-       clocks = <&misc_clk &misc_clk>;
-};
-
-&spi1 {
-       clocks = <&misc_clk &misc_clk>;
-};
-
-&uart0 {
-       clocks = <&misc_clk &misc_clk>;
-};
-
-&usb0 {
-       clocks = <&misc_clk>, <&misc_clk>;
-};
-
-&usb1 {
-       clocks = <&misc_clk>, <&misc_clk>;
-};
-
-&watchdog0 {
-       clocks= <&misc_clk>;
-};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts
deleted file mode 100644 (file)
index 4b06849..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * dts file for Xilinx ZynqMP ep108 development board
- *
- * (C) Copyright 2014 - 2015, Xilinx, Inc.
- *
- * Michal Simek <michal.simek@xilinx.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 "zynqmp.dtsi"
-#include "zynqmp-ep108-clk.dtsi"
-
-/ {
-       model = "ZynqMP EP108";
-
-       aliases {
-               mmc0 = &sdhci0;
-               mmc1 = &sdhci1;
-               serial0 = &uart0;
-       };
-
-       chosen {
-               stdout-path = "serial0:115200n8";
-       };
-
-       memory@0 {
-               device_type = "memory";
-               reg = <0x0 0x0 0x0 0x40000000>;
-       };
-};
-
-&can0 {
-       status = "okay";
-};
-
-&can1 {
-       status = "okay";
-};
-
-&gem0 {
-       status = "okay";
-       phy-handle = <&phy0>;
-       phy-mode = "rgmii-id";
-       phy0: phy@0 {
-               reg = <0>;
-               max-speed = <100>;
-       };
-};
-
-&gpio {
-       status = "okay";
-};
-
-&i2c0 {
-       status = "okay";
-       clock-frequency = <400000>;
-       eeprom@54 {
-               compatible = "atmel,24c64";
-               reg = <0x54>;
-       };
-};
-
-&i2c1 {
-       status = "okay";
-       clock-frequency = <400000>;
-       eeprom@55 {
-               compatible = "atmel,24c64";
-               reg = <0x55>;
-       };
-};
-
-&sata {
-       status = "okay";
-       ceva,broken-gen2;
-       /* SATA Phy OOB timing settings */
-       ceva,p0-cominit-params = /bits/ 8 <0x0F 0x25 0x18 0x29>;
-       ceva,p0-comwake-params = /bits/ 8 <0x04 0x0B 0x08 0x0F>;
-       ceva,p0-burst-params = /bits/ 8 <0x0A 0x08 0x4A 0x06>;
-       ceva,p0-retry-params = /bits/ 16 <0x0216 0x7F06>;
-       ceva,p1-cominit-params = /bits/ 8 <0x0F 0x25 0x18 0x29>;
-       ceva,p1-comwake-params = /bits/ 8 <0x04 0x0B 0x08 0x0F>;
-       ceva,p1-burst-params = /bits/ 8 <0x0A 0x08 0x4A 0x06>;
-       ceva,p1-retry-params = /bits/ 16 <0x0216 0x7F06>;
-};
-
-&sdhci0 {
-       status = "okay";
-       bus-width = <8>;
-};
-
-&sdhci1 {
-       status = "okay";
-};
-
-&spi0 {
-       status = "okay";
-       num-cs = <1>;
-       spi0_flash0: spi0_flash0@0 {
-               compatible = "m25p80";
-               #address-cells = <1>;
-               #size-cells = <1>;
-               spi-max-frequency = <50000000>;
-               reg = <0>;
-
-               spi0_flash0@0 {
-                       label = "spi0_flash0";
-                       reg = <0x0 0x100000>;
-               };
-       };
-};
-
-&spi1 {
-       status = "okay";
-       num-cs = <1>;
-       spi1_flash0: spi1_flash0@0 {
-               compatible = "m25p80";
-               #address-cells = <1>;
-               #size-cells = <1>;
-               spi-max-frequency = <50000000>;
-               reg = <0>;
-
-               spi1_flash0@0 {
-                       label = "spi1_flash0";
-                       reg = <0x0 0x100000>;
-               };
-       };
-};
-
-&uart0 {
-       status = "okay";
-};
-
-&usb0 {
-       status = "okay";
-       dr_mode = "peripheral";
-       maximum-speed = "high-speed";
-};
-
-&usb1 {
-       status = "okay";
-       dr_mode = "host";
-       maximum-speed = "high-speed";
-};
-
-&watchdog0 {
-       status = "okay";
-};
index 3e862a9faf26dff4b08737b7367c20dff18e3c46..eb5e8bddb610adf4d1781d6b4646eef6c1bef657 100644 (file)
@@ -44,8 +44,6 @@
 
        gpio-keys {
                compatible = "gpio-keys";
-               #address-cells = <1>;
-               #size-cells = <0>;
                autorepeat;
                sw4 {
                        label = "sw4";
                        gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
                        default-state = "on";
                };
-
-               bt_power {
-                       label = "bt_power";
-                       gpios = <&gpio 8 GPIO_ACTIVE_HIGH>;
-                       default-state = "on";
-               };
        };
 
        wmmcsdio_fixed: fixedregulator-mmcsdio {
 
 &uart0 {
        status = "okay";
+       bluetooth {
+               compatible = "ti,wl1831-st";
+               enable-gpios = <&gpio 8 GPIO_ACTIVE_HIGH>;
+       };
 };
 
 &uart1 {
index 5b4ffe646a9beabe416a33d05e702bb1f47b39dd..25dd57485323507888ebfc66cebdcfc858f5a3a3 100644 (file)
@@ -41,8 +41,6 @@
 
        gpio-keys {
                compatible = "gpio-keys";
-               #address-cells = <1>;
-               #size-cells = <0>;
                autorepeat;
                sw19 {
                        label = "sw19";
index 668f7f26716abfa9bffdd6b13bab33d65a115a1d..259f21b0c0014690ded2d21a417d0cffb2d2b271 100644 (file)
@@ -41,8 +41,6 @@
 
        gpio-keys {
                compatible = "gpio-keys";
-               #address-cells = <1>;
-               #size-cells = <0>;
                autorepeat;
                sw19 {
                        label = "sw19";
index 9a9dd6a0142bb1df5ad086b459c5f34376857ca9..a61b3cc6f4c95ecf8396b1ff253fa1f794f10dd0 100644 (file)
@@ -41,8 +41,6 @@
 
        gpio-keys {
                compatible = "gpio-keys";
-               #address-cells = <1>;
-               #size-cells = <0>;
                autorepeat;
                sw19 {
                        label = "sw19";
index a091e6f030145fc09622270c00bd6a43391656ab..29ce23422acf221e0725e93949b99c79f975ccf7 100644 (file)
@@ -58,7 +58,7 @@
                };
 
                idle-states {
-                       entry-method = "arm,psci";
+                       entry-method = "psci";
 
                        CPU_SLEEP_0: cpu-sleep-0 {
                                compatible = "arm,idle-state";
index 514787d45deef04390cd8908d6e9b2c274d37192..db8d364f84768b669333dbe21334fcbb3d3e81c3 100644 (file)
@@ -38,6 +38,7 @@ CONFIG_ARCH_BCM_IPROC=y
 CONFIG_ARCH_BERLIN=y
 CONFIG_ARCH_BRCMSTB=y
 CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_K3=y
 CONFIG_ARCH_LAYERSCAPE=y
 CONFIG_ARCH_LG1K=y
 CONFIG_ARCH_HISI=y
@@ -179,6 +180,7 @@ CONFIG_MTD_M25P80=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_DENALI_DT=y
 CONFIG_MTD_NAND_MARVELL=y
+CONFIG_MTD_NAND_QCOM=y
 CONFIG_MTD_SPI_NOR=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=m
@@ -295,6 +297,8 @@ CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
 CONFIG_SERIAL_MVEBU_UART=y
 CONFIG_SERIAL_DEV_BUS=y
 CONFIG_VIRTIO_CONSOLE=y
+CONFIG_TCG_TPM=y
+CONFIG_TCG_TIS_I2C_INFINEON=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_MUX=y
 CONFIG_I2C_MUX_PCA954x=y
@@ -349,10 +353,12 @@ CONFIG_POWER_RESET_MSM=y
 CONFIG_POWER_RESET_XGENE=y
 CONFIG_POWER_RESET_SYSCON=y
 CONFIG_SYSCON_REBOOT_MODE=y
+CONFIG_BATTERY_SBS=m
 CONFIG_BATTERY_BQ27XXX=y
 CONFIG_SENSORS_ARM_SCPI=y
 CONFIG_SENSORS_LM90=m
 CONFIG_SENSORS_INA2XX=m
+CONFIG_SENSORS_RASPBERRYPI_HWMON=m
 CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
 CONFIG_CPU_THERMAL=y
 CONFIG_THERMAL_EMULATION=y
@@ -365,12 +371,14 @@ CONFIG_TEGRA_BPMP_THERMAL=m
 CONFIG_QCOM_TSENS=y
 CONFIG_UNIPHIER_THERMAL=y
 CONFIG_WATCHDOG=y
+CONFIG_ARM_SP805_WATCHDOG=y
 CONFIG_S3C2410_WATCHDOG=y
 CONFIG_MESON_GXBB_WATCHDOG=m
 CONFIG_MESON_WATCHDOG=m
 CONFIG_RENESAS_WDT=y
 CONFIG_UNIPHIER_WATCHDOG=y
 CONFIG_BCM2835_WDT=y
+CONFIG_MFD_BD9571MWV=y
 CONFIG_MFD_AXP20X_RSB=y
 CONFIG_MFD_CROS_EC=y
 CONFIG_CROS_EC_I2C=y
@@ -385,6 +393,7 @@ CONFIG_MFD_RK808=y
 CONFIG_MFD_SEC_CORE=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_AXP20X=y
+CONFIG_REGULATOR_BD9571MWV=y
 CONFIG_REGULATOR_FAN53555=y
 CONFIG_REGULATOR_GPIO=y
 CONFIG_REGULATOR_HI6421V530=y
@@ -395,6 +404,7 @@ CONFIG_REGULATOR_QCOM_SMD_RPM=y
 CONFIG_REGULATOR_QCOM_SPMI=y
 CONFIG_REGULATOR_RK808=y
 CONFIG_REGULATOR_S2MPS11=y
+CONFIG_REGULATOR_VCTRL=m
 CONFIG_RC_CORE=m
 CONFIG_RC_DECODERS=y
 CONFIG_RC_DEVICES=y
@@ -407,6 +417,8 @@ CONFIG_MEDIA_CONTROLLER=y
 CONFIG_VIDEO_V4L2_SUBDEV_API=y
 # CONFIG_DVB_NET is not set
 CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
 CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m
 CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
 CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
@@ -448,9 +460,20 @@ CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
 CONFIG_SND_BCM2835_SOC_I2S=m
+CONFIG_SND_SOC_ROCKCHIP=m
+CONFIG_SND_SOC_ROCKCHIP_I2S=m
+CONFIG_SND_SOC_ROCKCHIP_SPDIF=m
+CONFIG_SND_SOC_ROCKCHIP_RT5645=m
+CONFIG_SND_SOC_RK3399_GRU_SOUND=m
 CONFIG_SND_SOC_SAMSUNG=y
 CONFIG_SND_SOC_RCAR=m
 CONFIG_SND_SOC_AK4613=m
+CONFIG_SND_SOC_DA7219=m
+CONFIG_SND_SOC_MAX98357A=m
+CONFIG_SND_SOC_RL6231=m
+CONFIG_SND_SOC_RT5514=m
+CONFIG_SND_SOC_RT5514_SPI=m
+CONFIG_SND_SOC_RT5645=m
 CONFIG_SND_SIMPLE_CARD=m
 CONFIG_SND_AUDIO_GRAPH_CARD=m
 CONFIG_I2C_HID=m
@@ -583,6 +606,8 @@ CONFIG_ARCH_TEGRA_132_SOC=y
 CONFIG_ARCH_TEGRA_210_SOC=y
 CONFIG_ARCH_TEGRA_186_SOC=y
 CONFIG_ARCH_TEGRA_194_SOC=y
+CONFIG_ARCH_K3_AM6_SOC=y
+CONFIG_SOC_TI=y
 CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
 CONFIG_EXTCON_USB_GPIO=y
 CONFIG_EXTCON_USBC_CROS_EC=y
@@ -617,6 +642,7 @@ CONFIG_PHY_ROCKCHIP_INNO_USB2=y
 CONFIG_PHY_ROCKCHIP_PCIE=m
 CONFIG_PHY_ROCKCHIP_TYPEC=y
 CONFIG_PHY_TEGRA_XUSB=y
+CONFIG_HISI_PMU=y
 CONFIG_QCOM_L2_PMU=y
 CONFIG_QCOM_L3_PMU=y
 CONFIG_QCOM_QFPROM=y
index 6e9f33d14930eb045d293c4df7952afa555b56fa..067d8937d5af1e74a69ae7b14b1b0306a53fe087 100644 (file)
@@ -417,7 +417,7 @@ static int gcm_encrypt(struct aead_request *req)
                __aes_arm64_encrypt(ctx->aes_key.key_enc, tag, iv, nrounds);
                put_unaligned_be32(2, iv + GCM_IV_SIZE);
 
-               while (walk.nbytes >= AES_BLOCK_SIZE) {
+               while (walk.nbytes >= (2 * AES_BLOCK_SIZE)) {
                        int blocks = walk.nbytes / AES_BLOCK_SIZE;
                        u8 *dst = walk.dst.virt.addr;
                        u8 *src = walk.src.virt.addr;
@@ -437,11 +437,18 @@ static int gcm_encrypt(struct aead_request *req)
                                        NULL);
 
                        err = skcipher_walk_done(&walk,
-                                                walk.nbytes % AES_BLOCK_SIZE);
+                                                walk.nbytes % (2 * AES_BLOCK_SIZE));
                }
-               if (walk.nbytes)
+               if (walk.nbytes) {
                        __aes_arm64_encrypt(ctx->aes_key.key_enc, ks, iv,
                                            nrounds);
+                       if (walk.nbytes > AES_BLOCK_SIZE) {
+                               crypto_inc(iv, AES_BLOCK_SIZE);
+                               __aes_arm64_encrypt(ctx->aes_key.key_enc,
+                                                   ks + AES_BLOCK_SIZE, iv,
+                                                   nrounds);
+                       }
+               }
        }
 
        /* handle the tail */
@@ -545,7 +552,7 @@ static int gcm_decrypt(struct aead_request *req)
                __aes_arm64_encrypt(ctx->aes_key.key_enc, tag, iv, nrounds);
                put_unaligned_be32(2, iv + GCM_IV_SIZE);
 
-               while (walk.nbytes >= AES_BLOCK_SIZE) {
+               while (walk.nbytes >= (2 * AES_BLOCK_SIZE)) {
                        int blocks = walk.nbytes / AES_BLOCK_SIZE;
                        u8 *dst = walk.dst.virt.addr;
                        u8 *src = walk.src.virt.addr;
@@ -564,11 +571,21 @@ static int gcm_decrypt(struct aead_request *req)
                        } while (--blocks > 0);
 
                        err = skcipher_walk_done(&walk,
-                                                walk.nbytes % AES_BLOCK_SIZE);
+                                                walk.nbytes % (2 * AES_BLOCK_SIZE));
                }
-               if (walk.nbytes)
+               if (walk.nbytes) {
+                       if (walk.nbytes > AES_BLOCK_SIZE) {
+                               u8 *iv2 = iv + AES_BLOCK_SIZE;
+
+                               memcpy(iv2, iv, AES_BLOCK_SIZE);
+                               crypto_inc(iv2, AES_BLOCK_SIZE);
+
+                               __aes_arm64_encrypt(ctx->aes_key.key_enc, iv2,
+                                                   iv2, nrounds);
+                       }
                        __aes_arm64_encrypt(ctx->aes_key.key_enc, iv, iv,
                                            nrounds);
+               }
        }
 
        /* handle the tail */
index b7fb5274b250134253173384ff643578f5c06a29..0c4fc223f22575fbf76ff66d3e077249d86ad8c1 100644 (file)
@@ -69,5 +69,5 @@ static void __exit sm4_ce_mod_fini(void)
        crypto_unregister_alg(&sm4_ce_alg);
 }
 
-module_cpu_feature_match(SM3, sm4_ce_mod_init);
+module_cpu_feature_match(SM4, sm4_ce_mod_init);
 module_exit(sm4_ce_mod_fini);
index be3bf3d08916ca811b9294c890adbae1f91b9783..ae1f70450fb2129b5c195be0678ae9935bb3a450 100644 (file)
@@ -50,7 +50,8 @@
 #define ARM64_HW_DBM                           29
 #define ARM64_SSBD                             30
 #define ARM64_MISMATCHED_CACHE_TYPE            31
+#define ARM64_HAS_STAGE2_FWB                   32
 
-#define ARM64_NCAPS                            32
+#define ARM64_NCAPS                            33
 
 #endif /* __ASM_CPUCAPS_H */
index 6dd285e979c98bc0593dee460c68d12d3d5f0b22..aa45df752a166a56a3ace4808db6b985ac8d2898 100644 (file)
@@ -23,6 +23,7 @@
 #include <asm/types.h>
 
 /* Hyp Configuration Register (HCR) bits */
+#define HCR_FWB                (UL(1) << 46)
 #define HCR_TEA                (UL(1) << 37)
 #define HCR_TERR       (UL(1) << 36)
 #define HCR_TLOR       (UL(1) << 35)
index 0c97e45d1dc3e2e54946f5d9f59c92b80ec93485..6106a85ae0be70f91f8ad7b64bd7723e236843e5 100644 (file)
@@ -63,6 +63,8 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
                /* trap error record accesses */
                vcpu->arch.hcr_el2 |= HCR_TERR;
        }
+       if (cpus_have_const_cap(ARM64_HAS_STAGE2_FWB))
+               vcpu->arch.hcr_el2 |= HCR_FWB;
 
        if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features))
                vcpu->arch.hcr_el2 &= ~HCR_RW;
@@ -81,6 +83,21 @@ static inline unsigned long *vcpu_hcr(struct kvm_vcpu *vcpu)
        return (unsigned long *)&vcpu->arch.hcr_el2;
 }
 
+static inline void vcpu_clear_wfe_traps(struct kvm_vcpu *vcpu)
+{
+       vcpu->arch.hcr_el2 &= ~HCR_TWE;
+}
+
+static inline void vcpu_set_wfe_traps(struct kvm_vcpu *vcpu)
+{
+       vcpu->arch.hcr_el2 |= HCR_TWE;
+}
+
+static inline unsigned long vcpu_get_vsesr(struct kvm_vcpu *vcpu)
+{
+       return vcpu->arch.vsesr_el2;
+}
+
 static inline void vcpu_set_vsesr(struct kvm_vcpu *vcpu, u64 vsesr)
 {
        vcpu->arch.vsesr_el2 = vsesr;
index fe8777b12f8667c2c0b23952057fc13041276442..3d6d7336f871221fd29bcc3bc4faa2cee0a7765f 100644 (file)
@@ -61,8 +61,7 @@ struct kvm_arch {
        u64    vmid_gen;
        u32    vmid;
 
-       /* 1-level 2nd stage table and lock */
-       spinlock_t pgd_lock;
+       /* 1-level 2nd stage table, protected by kvm->mmu_lock */
        pgd_t *pgd;
 
        /* VTTBR value associated with above pgd and vmid */
@@ -350,9 +349,13 @@ unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu);
 int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
 int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
 int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+int __kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
+                             struct kvm_vcpu_events *events);
+
+int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
+                             struct kvm_vcpu_events *events);
 
 #define KVM_ARCH_WANT_MMU_NOTIFIER
-int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
 int kvm_unmap_hva_range(struct kvm *kvm,
                        unsigned long start, unsigned long end);
 void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
@@ -378,16 +381,23 @@ void handle_exit_early(struct kvm_vcpu *vcpu, struct kvm_run *run,
 int kvm_perf_init(void);
 int kvm_perf_teardown(void);
 
+void kvm_set_sei_esr(struct kvm_vcpu *vcpu, u64 syndrome);
+
 struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
 
-void __kvm_set_tpidr_el2(u64 tpidr_el2);
 DECLARE_PER_CPU(kvm_cpu_context_t, kvm_host_cpu_state);
 
 static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
                                       unsigned long hyp_stack_ptr,
                                       unsigned long vector_ptr)
 {
-       u64 tpidr_el2;
+       /*
+        * Calculate the raw per-cpu offset without a translation from the
+        * kernel's mapping to the linear mapping, and store it in tpidr_el2
+        * so that we can use adr_l to access per-cpu variables in EL2.
+        */
+       u64 tpidr_el2 = ((u64)this_cpu_ptr(&kvm_host_cpu_state) -
+                        (u64)kvm_ksym_ref(kvm_host_cpu_state));
 
        /*
         * Call initialization code, and switch to the full blown HYP code.
@@ -396,17 +406,7 @@ static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
         * cpus_have_const_cap() wrapper.
         */
        BUG_ON(!static_branch_likely(&arm64_const_caps_ready));
-       __kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr);
-
-       /*
-        * Calculate the raw per-cpu offset without a translation from the
-        * kernel's mapping to the linear mapping, and store it in tpidr_el2
-        * so that we can use adr_l to access per-cpu variables in EL2.
-        */
-       tpidr_el2 = (u64)this_cpu_ptr(&kvm_host_cpu_state)
-               - (u64)kvm_ksym_ref(kvm_host_cpu_state);
-
-       kvm_call_hyp(__kvm_set_tpidr_el2, tpidr_el2);
+       __kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr, tpidr_el2);
 }
 
 static inline bool kvm_arch_check_sve_has_vhe(void)
index fb9a7127bb752d6e627e873962cf39d6b1752687..d6fff7de5539f22ffa91202c587e13ee48d7d4de 100644 (file)
@@ -169,8 +169,12 @@ phys_addr_t kvm_get_idmap_vector(void);
 int kvm_mmu_init(void);
 void kvm_clear_hyp_idmap(void);
 
-#define        kvm_set_pte(ptep, pte)          set_pte(ptep, pte)
-#define        kvm_set_pmd(pmdp, pmd)          set_pmd(pmdp, pmd)
+#define kvm_mk_pmd(ptep)                                       \
+       __pmd(__phys_to_pmd_val(__pa(ptep)) | PMD_TYPE_TABLE)
+#define kvm_mk_pud(pmdp)                                       \
+       __pud(__phys_to_pud_val(__pa(pmdp)) | PMD_TYPE_TABLE)
+#define kvm_mk_pgd(pudp)                                       \
+       __pgd(__phys_to_pgd_val(__pa(pudp)) | PUD_TYPE_TABLE)
 
 static inline pte_t kvm_s2pte_mkwrite(pte_t pte)
 {
@@ -267,6 +271,15 @@ static inline void __clean_dcache_guest_page(kvm_pfn_t pfn, unsigned long size)
 {
        void *va = page_address(pfn_to_page(pfn));
 
+       /*
+        * With FWB, we ensure that the guest always accesses memory using
+        * cacheable attributes, and we don't have to clean to PoC when
+        * faulting in pages. Furthermore, FWB implies IDC, so cleaning to
+        * PoU is not required either in this case.
+        */
+       if (cpus_have_const_cap(ARM64_HAS_STAGE2_FWB))
+               return;
+
        kvm_flush_dcache_to_poc(va, size);
 }
 
@@ -287,20 +300,26 @@ static inline void __invalidate_icache_guest_page(kvm_pfn_t pfn,
 
 static inline void __kvm_flush_dcache_pte(pte_t pte)
 {
-       struct page *page = pte_page(pte);
-       kvm_flush_dcache_to_poc(page_address(page), PAGE_SIZE);
+       if (!cpus_have_const_cap(ARM64_HAS_STAGE2_FWB)) {
+               struct page *page = pte_page(pte);
+               kvm_flush_dcache_to_poc(page_address(page), PAGE_SIZE);
+       }
 }
 
 static inline void __kvm_flush_dcache_pmd(pmd_t pmd)
 {
-       struct page *page = pmd_page(pmd);
-       kvm_flush_dcache_to_poc(page_address(page), PMD_SIZE);
+       if (!cpus_have_const_cap(ARM64_HAS_STAGE2_FWB)) {
+               struct page *page = pmd_page(pmd);
+               kvm_flush_dcache_to_poc(page_address(page), PMD_SIZE);
+       }
 }
 
 static inline void __kvm_flush_dcache_pud(pud_t pud)
 {
-       struct page *page = pud_page(pud);
-       kvm_flush_dcache_to_poc(page_address(page), PUD_SIZE);
+       if (!cpus_have_const_cap(ARM64_HAS_STAGE2_FWB)) {
+               struct page *page = pud_page(pud);
+               kvm_flush_dcache_to_poc(page_address(page), PUD_SIZE);
+       }
 }
 
 #define kvm_virt_to_phys(x)            __pa_symbol(x)
index 49d99214f43c5011f2187fb5bc12c6d4537cd307..b96442960aead1692e94d28dd35d33e7954d84b3 100644 (file)
 #define MT_S2_NORMAL           0xf
 #define MT_S2_DEVICE_nGnRE     0x1
 
+/*
+ * Memory types for Stage-2 translation when ID_AA64MMFR2_EL1.FWB is 0001
+ * Stage-2 enforces Normal-WB and Device-nGnRE
+ */
+#define MT_S2_FWB_NORMAL       6
+#define MT_S2_FWB_DEVICE_nGnRE 1
+
 #ifdef CONFIG_ARM64_4K_PAGES
 #define IOREMAP_MAX_ORDER      (PUD_SHIFT)
 #else
index 108ecad7acc5617aa3c6c7573ba578b9e485f78d..78b942c1bea437c5a0e9124b86afd4c48503d999 100644 (file)
 #define PAGE_HYP_RO            __pgprot(_HYP_PAGE_DEFAULT | PTE_HYP | PTE_RDONLY | PTE_HYP_XN)
 #define PAGE_HYP_DEVICE                __pgprot(PROT_DEVICE_nGnRE | PTE_HYP)
 
-#define PAGE_S2                        __pgprot(_PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY | PTE_S2_XN)
-#define PAGE_S2_DEVICE         __pgprot(_PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_S2_XN)
+#define PAGE_S2_MEMATTR(attr)                                          \
+       ({                                                              \
+               u64 __val;                                              \
+               if (cpus_have_const_cap(ARM64_HAS_STAGE2_FWB))          \
+                       __val = PTE_S2_MEMATTR(MT_S2_FWB_ ## attr);     \
+               else                                                    \
+                       __val = PTE_S2_MEMATTR(MT_S2_ ## attr);         \
+               __val;                                                  \
+        })
+
+#define PAGE_S2_XN                                                     \
+       ({                                                              \
+               u64 __val;                                              \
+               if (cpus_have_const_cap(ARM64_HAS_CACHE_DIC))           \
+                       __val = 0;                                      \
+               else                                                    \
+                       __val = PTE_S2_XN;                              \
+               __val;                                                  \
+       })
+
+#define PAGE_S2                        __pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(NORMAL) | PTE_S2_RDONLY | PAGE_S2_XN)
+#define PAGE_S2_DEVICE         __pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(DEVICE_nGnRE) | PTE_S2_RDONLY | PAGE_S2_XN)
 
 #define PAGE_NONE              __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
 #define PAGE_SHARED            __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
index e205ec8489e9c04f46de172585d679a28d6ae418..c1470931b8974936ed2a86fb231c15764d08f573 100644 (file)
 #define SYS_ICC_DIR_EL1                        sys_reg(3, 0, 12, 11, 1)
 #define SYS_ICC_RPR_EL1                        sys_reg(3, 0, 12, 11, 3)
 #define SYS_ICC_SGI1R_EL1              sys_reg(3, 0, 12, 11, 5)
+#define SYS_ICC_ASGI1R_EL1             sys_reg(3, 0, 12, 11, 6)
+#define SYS_ICC_SGI0R_EL1              sys_reg(3, 0, 12, 11, 7)
 #define SYS_ICC_IAR1_EL1               sys_reg(3, 0, 12, 12, 0)
 #define SYS_ICC_EOIR1_EL1              sys_reg(3, 0, 12, 12, 1)
 #define SYS_ICC_HPPIR1_EL1             sys_reg(3, 0, 12, 12, 2)
 #define ID_AA64MMFR1_VMIDBITS_16       2
 
 /* id_aa64mmfr2 */
+#define ID_AA64MMFR2_FWB_SHIFT         40
 #define ID_AA64MMFR2_AT_SHIFT          32
 #define ID_AA64MMFR2_LVA_SHIFT         16
 #define ID_AA64MMFR2_IESB_SHIFT                12
index 0ad1cf233470d5abd212f05eea0f0ba832314012..a3233167be60226fa1e15e76767db26a527e5436 100644 (file)
@@ -33,6 +33,8 @@ static inline void __tlb_remove_table(void *_table)
 #define tlb_remove_entry(tlb, entry)   tlb_remove_page(tlb, entry)
 #endif /* CONFIG_HAVE_RCU_TABLE_FREE */
 
+static void tlb_flush(struct mmu_gather *tlb);
+
 #include <asm-generic/tlb.h>
 
 static inline void tlb_flush(struct mmu_gather *tlb)
index 4e76630dd6554673d71ad647c1108bb54f1bcea2..97c3478ee6e718c8ac2de4c01edee6a0dd4cd27e 100644 (file)
@@ -39,6 +39,7 @@
 #define __KVM_HAVE_GUEST_DEBUG
 #define __KVM_HAVE_IRQ_LINE
 #define __KVM_HAVE_READONLY_MEM
+#define __KVM_HAVE_VCPU_EVENTS
 
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
 
@@ -154,6 +155,18 @@ struct kvm_sync_regs {
 struct kvm_arch_memory_slot {
 };
 
+/* for KVM_GET/SET_VCPU_EVENTS */
+struct kvm_vcpu_events {
+       struct {
+               __u8 serror_pending;
+               __u8 serror_has_esr;
+               /* Align it to 8 bytes */
+               __u8 pad[6];
+               __u64 serror_esr;
+       } exception;
+       __u32 reserved[12];
+};
+
 /* If you need to interpret the index values, here is the key: */
 #define KVM_REG_ARM_COPROC_MASK                0x000000000FFF0000
 #define KVM_REG_ARM_COPROC_SHIFT       16
index 611e8921c3d4d91ba8d687ff89fcb90757b12555..e238b7932096d5641de25a6f16a9292cc1f3d517 100644 (file)
@@ -192,6 +192,7 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
 };
 
 static const struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
+       ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_FWB_SHIFT, 4, 0),
        ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_AT_SHIFT, 4, 0),
        ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_LVA_SHIFT, 4, 0),
        ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_IESB_SHIFT, 4, 0),
@@ -1026,6 +1027,14 @@ static void cpu_copy_el2regs(const struct arm64_cpu_capabilities *__unused)
 }
 #endif
 
+static void cpu_has_fwb(const struct arm64_cpu_capabilities *__unused)
+{
+       u64 val = read_sysreg_s(SYS_CLIDR_EL1);
+
+       /* Check that CLIDR_EL1.LOU{U,IS} are both 0 */
+       WARN_ON(val & (7 << 27 | 7 << 21));
+}
+
 static const struct arm64_cpu_capabilities arm64_features[] = {
        {
                .desc = "GIC system register CPU interface",
@@ -1182,6 +1191,17 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .type = ARM64_CPUCAP_SYSTEM_FEATURE,
                .matches = has_cache_dic,
        },
+       {
+               .desc = "Stage-2 Force Write-Back",
+               .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+               .capability = ARM64_HAS_STAGE2_FWB,
+               .sys_reg = SYS_ID_AA64MMFR2_EL1,
+               .sign = FTR_UNSIGNED,
+               .field_pos = ID_AA64MMFR2_FWB_SHIFT,
+               .min_field_value = 1,
+               .matches = has_cpuid_feature,
+               .cpu_enable = cpu_has_fwb,
+       },
 #ifdef CONFIG_ARM64_HW_AFDBM
        {
                /*
index cdd4d9d6d57548cc58dbbdaecdfb1e4e18685df8..07256b08226c0c935d7ced6530a4a7a85ee4c276 100644 (file)
@@ -289,6 +289,39 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
        return -EINVAL;
 }
 
+int __kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
+                             struct kvm_vcpu_events *events)
+{
+       events->exception.serror_pending = !!(vcpu->arch.hcr_el2 & HCR_VSE);
+       events->exception.serror_has_esr = cpus_have_const_cap(ARM64_HAS_RAS_EXTN);
+
+       if (events->exception.serror_pending && events->exception.serror_has_esr)
+               events->exception.serror_esr = vcpu_get_vsesr(vcpu);
+
+       return 0;
+}
+
+int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
+                             struct kvm_vcpu_events *events)
+{
+       bool serror_pending = events->exception.serror_pending;
+       bool has_esr = events->exception.serror_has_esr;
+
+       if (serror_pending && has_esr) {
+               if (!cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
+                       return -EINVAL;
+
+               if (!((events->exception.serror_esr) & ~ESR_ELx_ISS_MASK))
+                       kvm_set_sei_esr(vcpu, events->exception.serror_esr);
+               else
+                       return -EINVAL;
+       } else if (serror_pending) {
+               kvm_inject_vabt(vcpu);
+       }
+
+       return 0;
+}
+
 int __attribute_const__ kvm_target_cpu(void)
 {
        unsigned long implementor = read_cpuid_implementor();
index 6fd91b31a131857c9dd70002245f99220adc5a31..ea92251607862db0b33f9ef416ae86e8463b2d03 100644 (file)
@@ -57,6 +57,7 @@ __invalid:
         * x0: HYP pgd
         * x1: HYP stack
         * x2: HYP vectors
+        * x3: per-CPU offset
         */
 __do_hyp_init:
        /* Check for a stub HVC call */
@@ -119,9 +120,8 @@ CPU_BE(     orr     x4, x4, #SCTLR_ELx_EE)
        mov     sp, x1
        msr     vbar_el2, x2
 
-       /* copy tpidr_el1 into tpidr_el2 for use by HYP */
-       mrs     x1, tpidr_el1
-       msr     tpidr_el2, x1
+       /* Set tpidr_el2 for use by HYP */
+       msr     tpidr_el2, x3
 
        /* Hello, World! */
        eret
index d496ef579859627edd1ba98c1233d9584cd407e3..ca46153d79154bae1b0833231245129752484362 100644 (file)
@@ -98,8 +98,10 @@ static void activate_traps_vhe(struct kvm_vcpu *vcpu)
        val = read_sysreg(cpacr_el1);
        val |= CPACR_EL1_TTA;
        val &= ~CPACR_EL1_ZEN;
-       if (!update_fp_enabled(vcpu))
+       if (!update_fp_enabled(vcpu)) {
                val &= ~CPACR_EL1_FPEN;
+               __activate_traps_fpsimd32(vcpu);
+       }
 
        write_sysreg(val, cpacr_el1);
 
@@ -114,8 +116,10 @@ static void __hyp_text __activate_traps_nvhe(struct kvm_vcpu *vcpu)
 
        val = CPTR_EL2_DEFAULT;
        val |= CPTR_EL2_TTA | CPTR_EL2_TZ;
-       if (!update_fp_enabled(vcpu))
+       if (!update_fp_enabled(vcpu)) {
                val |= CPTR_EL2_TFP;
+               __activate_traps_fpsimd32(vcpu);
+       }
 
        write_sysreg(val, cptr_el2);
 }
@@ -129,7 +133,6 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
        if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN) && (hcr & HCR_VSE))
                write_sysreg_s(vcpu->arch.vsesr_el2, SYS_VSESR_EL2);
 
-       __activate_traps_fpsimd32(vcpu);
        if (has_vhe())
                activate_traps_vhe(vcpu);
        else
index 35bc16832efe28ae3e6a85d4e906f1e94024f0c4..9ce223944983b803e3b4161d57a5ff6e17e8ec5b 100644 (file)
@@ -288,8 +288,3 @@ void kvm_vcpu_put_sysregs(struct kvm_vcpu *vcpu)
 
        vcpu->arch.sysregs_loaded_on_cpu = false;
 }
-
-void __hyp_text __kvm_set_tpidr_el2(u64 tpidr_el2)
-{
-       asm("msr tpidr_el2, %0": : "r" (tpidr_el2));
-}
index d8e71659ba7e1bed0d7d21c94ff0931188b8118d..a55e91dfcf8fe8279c2dbe40c9747d26cb086e26 100644 (file)
@@ -164,9 +164,9 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
                inject_undef64(vcpu);
 }
 
-static void pend_guest_serror(struct kvm_vcpu *vcpu, u64 esr)
+void kvm_set_sei_esr(struct kvm_vcpu *vcpu, u64 esr)
 {
-       vcpu_set_vsesr(vcpu, esr);
+       vcpu_set_vsesr(vcpu, esr & ESR_ELx_ISS_MASK);
        *vcpu_hcr(vcpu) |= HCR_VSE;
 }
 
@@ -184,5 +184,5 @@ static void pend_guest_serror(struct kvm_vcpu *vcpu, u64 esr)
  */
 void kvm_inject_vabt(struct kvm_vcpu *vcpu)
 {
-       pend_guest_serror(vcpu, ESR_ELx_ISV);
+       kvm_set_sei_esr(vcpu, ESR_ELx_ISV);
 }
index 4e4aedaf7ab7152e93983fffc95b65579cd378e5..e37c78bbe1ca9cc750c354412ef64092af5fc5dc 100644 (file)
@@ -77,8 +77,12 @@ int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
        case KVM_CAP_ARM_PMU_V3:
                r = kvm_arm_support_pmu_v3();
                break;
+       case KVM_CAP_ARM_INJECT_SERROR_ESR:
+               r = cpus_have_const_cap(ARM64_HAS_RAS_EXTN);
+               break;
        case KVM_CAP_SET_GUEST_DEBUG:
        case KVM_CAP_VCPU_ATTRIBUTES:
+       case KVM_CAP_VCPU_EVENTS:
                r = 1;
                break;
        default:
index a4363735d3f8e11e1cac77f57cab32d23fac4915..22fbbdbece3caf19fcc070c736f30956c4419c8c 100644 (file)
@@ -194,7 +194,16 @@ static bool access_dcsw(struct kvm_vcpu *vcpu,
        if (!p->is_write)
                return read_from_write_only(vcpu, p, r);
 
-       kvm_set_way_flush(vcpu);
+       /*
+        * Only track S/W ops if we don't have FWB. It still indicates
+        * that the guest is a bit broken (S/W operations should only
+        * be done by firmware, knowing that there is only a single
+        * CPU left in the system, and certainly not from non-secure
+        * software).
+        */
+       if (!cpus_have_const_cap(ARM64_HAS_STAGE2_FWB))
+               kvm_set_way_flush(vcpu);
+
        return true;
 }
 
@@ -243,10 +252,43 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu,
                           struct sys_reg_params *p,
                           const struct sys_reg_desc *r)
 {
+       bool g1;
+
        if (!p->is_write)
                return read_from_write_only(vcpu, p, r);
 
-       vgic_v3_dispatch_sgi(vcpu, p->regval);
+       /*
+        * In a system where GICD_CTLR.DS=1, a ICC_SGI0R_EL1 access generates
+        * Group0 SGIs only, while ICC_SGI1R_EL1 can generate either group,
+        * depending on the SGI configuration. ICC_ASGI1R_EL1 is effectively
+        * equivalent to ICC_SGI0R_EL1, as there is no "alternative" secure
+        * group.
+        */
+       if (p->is_aarch32) {
+               switch (p->Op1) {
+               default:                /* Keep GCC quiet */
+               case 0:                 /* ICC_SGI1R */
+                       g1 = true;
+                       break;
+               case 1:                 /* ICC_ASGI1R */
+               case 2:                 /* ICC_SGI0R */
+                       g1 = false;
+                       break;
+               }
+       } else {
+               switch (p->Op2) {
+               default:                /* Keep GCC quiet */
+               case 5:                 /* ICC_SGI1R_EL1 */
+                       g1 = true;
+                       break;
+               case 6:                 /* ICC_ASGI1R_EL1 */
+               case 7:                 /* ICC_SGI0R_EL1 */
+                       g1 = false;
+                       break;
+               }
+       }
+
+       vgic_v3_dispatch_sgi(vcpu, p->regval, g1);
 
        return true;
 }
@@ -1303,6 +1345,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
        { SYS_DESC(SYS_ICC_DIR_EL1), read_from_write_only },
        { SYS_DESC(SYS_ICC_RPR_EL1), write_to_read_only },
        { SYS_DESC(SYS_ICC_SGI1R_EL1), access_gic_sgi },
+       { SYS_DESC(SYS_ICC_ASGI1R_EL1), access_gic_sgi },
+       { SYS_DESC(SYS_ICC_SGI0R_EL1), access_gic_sgi },
        { SYS_DESC(SYS_ICC_IAR1_EL1), write_to_read_only },
        { SYS_DESC(SYS_ICC_EOIR1_EL1), read_from_write_only },
        { SYS_DESC(SYS_ICC_HPPIR1_EL1), write_to_read_only },
@@ -1613,8 +1657,6 @@ static const struct sys_reg_desc cp14_64_regs[] = {
  * register).
  */
 static const struct sys_reg_desc cp15_regs[] = {
-       { Op1( 0), CRn( 0), CRm(12), Op2( 0), access_gic_sgi },
-
        { Op1( 0), CRn( 1), CRm( 0), Op2( 0), access_vm_reg, NULL, c1_SCTLR },
        { Op1( 0), CRn( 2), CRm( 0), Op2( 0), access_vm_reg, NULL, c2_TTBR0 },
        { Op1( 0), CRn( 2), CRm( 0), Op2( 1), access_vm_reg, NULL, c2_TTBR1 },
@@ -1737,8 +1779,10 @@ static const struct sys_reg_desc cp15_regs[] = {
 static const struct sys_reg_desc cp15_64_regs[] = {
        { Op1( 0), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR0 },
        { Op1( 0), CRn( 0), CRm( 9), Op2( 0), access_pmu_evcntr },
-       { Op1( 0), CRn( 0), CRm(12), Op2( 0), access_gic_sgi },
+       { Op1( 0), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_SGI1R */
        { Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR1 },
+       { Op1( 1), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_ASGI1R */
+       { Op1( 2), CRn( 0), CRm(12), Op2( 0), access_gic_sgi }, /* ICC_SGI0R */
        { Op1( 2), CRn( 0), CRm(14), Op2( 0), access_cntp_cval },
 };
 
index 65f86271f02bc1bf71a44b07fba51aefee49d381..8080c9f489c3e43af385066514f3f60cca629141 100644 (file)
@@ -985,8 +985,9 @@ int pmd_free_pte_page(pmd_t *pmdp, unsigned long addr)
 
        pmd = READ_ONCE(*pmdp);
 
-       /* No-op for empty entry and WARN_ON for valid entry */
-       if (!pmd_present(pmd) || !pmd_table(pmd)) {
+       if (!pmd_present(pmd))
+               return 1;
+       if (!pmd_table(pmd)) {
                VM_WARN_ON(!pmd_table(pmd));
                return 1;
        }
@@ -1007,8 +1008,9 @@ int pud_free_pmd_page(pud_t *pudp, unsigned long addr)
 
        pud = READ_ONCE(*pudp);
 
-       /* No-op for empty entry and WARN_ON for valid entry */
-       if (!pud_present(pud) || !pud_table(pud)) {
+       if (!pud_present(pud))
+               return 1;
+       if (!pud_table(pud)) {
                VM_WARN_ON(!pud_table(pud));
                return 1;
        }
index 6ab942e6c534a01be558b1a1e85511b4f6dacbe9..3fe8a948e94cf93e554e7b6b2c18e9175cd4b87f 100644 (file)
@@ -23,8 +23,7 @@ ifdef CONFIG_CPU_BIG_ENDIAN
 KBUILD_CFLAGS   += -mbig-endian
 KBUILD_AFLAGS   += -mbig-endian
 LINKFLAGS       += -mbig-endian
-KBUILD_LDFLAGS  += -mbig-endian
-LDFLAGS += -EB
+KBUILD_LDFLAGS  += -mbig-endian -EB
 CHECKFLAGS     += -D_BIG_ENDIAN
 endif
 
index 5e89d40be8cd9764bb3c8e80dc7cbcfa3f2ce959..0b334b671e90c95f817a8638a89655f7f717c4d8 100644 (file)
@@ -16,6 +16,7 @@ config H8300
        select OF_IRQ
        select OF_EARLY_FLATTREE
        select HAVE_MEMBLOCK
+       select NO_BOOTMEM
        select TIMER_OF
        select H8300_TMR8
        select HAVE_KERNEL_GZIP
index e1c02ca230cb0a9dbd985b59b0646eb86f0d9891..58634e6bae92893aedbf4172940f9e56ee97ec27 100644 (file)
@@ -8,6 +8,8 @@
 # (C) Copyright 2002-2015 Yoshinori Sato <ysato@users.sourceforge.jp>
 #
 
+KBUILD_DEFCONFIG := edosk2674_defconfig
+
 cflags-$(CONFIG_CPU_H8300H)    := -mh
 aflags-$(CONFIG_CPU_H8300H)    := -mh -Wa,--mach=h8300h
 ldflags-$(CONFIG_CPU_H8300H)   := -mh8300helf_linux
@@ -20,7 +22,9 @@ KBUILD_CFLAGS += -mint32 -fno-builtin
 KBUILD_CFLAGS += -D__linux__
 KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
 KBUILD_AFLAGS += $(aflags-y)
-LDFLAGS += $(ldflags-y)
+KBUILD_LDFLAGS += $(ldflags-y)
+
+CHECKFLAGS += -msize-long
 
 ifeq ($(CROSS_COMPILE),)
 CROSS_COMPILE := h8300-unknown-linux-
index f1c31cecdec8a2e1be00c741d5bf40bf81f8c4e9..595398b9d0180a805c0c70fc5a4d0501cdf76504 100644 (file)
@@ -73,7 +73,7 @@
        timer16: timer@ffff68 {
                compatible = "renesas,16bit-timer";
                reg = <0xffff68 8>, <0xffff60 8>;
-               interrupts = <24 0>;
+               interrupts = <26 0>;
                renesas,channel = <0>;
                clocks = <&fclk>;
                clock-names = "fck";
index ea0cb0cf6a8bb2ed519a6176dec51ef92b77d1b1..647a83bd40b7093ca9ac37f7e14593ca51e55c54 100644 (file)
@@ -29,11 +29,11 @@ static inline unsigned long ffz(unsigned long word)
 
        result = -1;
        __asm__("1:\n\t"
-               "shlr.l %2\n\t"
+               "shlr.l %1\n\t"
                "adds #1,%0\n\t"
                "bcs 1b"
-               : "=r"(result)
-               : "0"(result), "r"(word));
+               : "=r"(result),"=r"(word)
+               : "0"(result), "1"(word));
        return result;
 }
 
@@ -66,7 +66,7 @@ H8300_GEN_BITOP(change_bit, "bnot")
 
 #undef H8300_GEN_BITOP
 
-static inline int test_bit(int nr, const unsigned long *addr)
+static inline int test_bit(int nr, const volatile unsigned long *addr)
 {
        int ret = 0;
        unsigned char *b_addr;
@@ -162,11 +162,11 @@ static inline unsigned long __ffs(unsigned long word)
 
        result = -1;
        __asm__("1:\n\t"
-               "shlr.l %2\n\t"
+               "shlr.l %1\n\t"
                "adds #1,%0\n\t"
                "bcc 1b"
-               : "=r" (result)
-               : "0"(result), "r"(word));
+               : "=r" (result),"=r"(word)
+               : "0"(result), "1"(word));
        return result;
 }
 
index 313cafa853807866927bbf7f0a792e521f4b3fd6..66d383848ff1f2a7a27095b4764e0be075cb95c8 100644 (file)
@@ -4,6 +4,8 @@
 
 #include <uapi/asm/ptrace.h>
 
+struct task_struct;
+
 #ifndef __ASSEMBLY__
 #ifndef PS_S
 #define PS_S  (0x10)
index 602e478afbd5800eab9ba03277bf7d4db36336f0..1a1d30cb0609c60cc3a92528060a10f1f4d286e4 100644 (file)
@@ -129,7 +129,7 @@ void kgdb_arch_exit(void)
        /* Nothing to do */
 }
 
-const struct kgdb_arch arch_kgdb_ops = {
+struct kgdb_arch arch_kgdb_ops = {
        /* Breakpoint instruction: trapa #2 */
        .gdb_bpt_instr = { 0x57, 0x20 },
 };
index a4d0470c10a9ff98356ca33ff68152e072865c74..34e2df5c0d6d8724509cdbacab72c9914397fa2d 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
-#include <linux/of_platform.h>
 #include <linux/of_address.h>
 #include <linux/clk-provider.h>
 #include <linux/memblock.h>
@@ -71,10 +70,6 @@ void __init h8300_fdt_init(void *fdt, char *bootargs)
 
 static void __init bootmem_init(void)
 {
-       int bootmap_size;
-       unsigned long ram_start_pfn;
-       unsigned long free_ram_start_pfn;
-       unsigned long ram_end_pfn;
        struct memblock_region *region;
 
        memory_end = memory_start = 0;
@@ -88,33 +83,17 @@ static void __init bootmem_init(void)
        if (!memory_end)
                panic("No memory!");
 
-       ram_start_pfn = PFN_UP(memory_start);
-       /* free_ram_start_pfn is first page after kernel */
-       free_ram_start_pfn = PFN_UP(__pa(_end));
-       ram_end_pfn = PFN_DOWN(memblock_end_of_DRAM());
+       /* setup bootmem globals (we use no_bootmem, but mm still depends on this) */
+       min_low_pfn = PFN_UP(memory_start);
+       max_low_pfn = PFN_DOWN(memblock_end_of_DRAM());
+       max_pfn = max_low_pfn;
 
-       max_pfn = ram_end_pfn;
+       memblock_reserve(__pa(_stext), _end - _stext);
 
-       /*
-        * give all the memory to the bootmap allocator,  tell it to put the
-        * boot mem_map at the start of memory
-        */
-       bootmap_size = init_bootmem_node(NODE_DATA(0),
-                                        free_ram_start_pfn,
-                                        0,
-                                        ram_end_pfn);
-       /*
-        * free the usable memory,  we have to make sure we do not free
-        * the bootmem bitmap so we then reserve it after freeing it :-)
-        */
-       free_bootmem(PFN_PHYS(free_ram_start_pfn),
-                    (ram_end_pfn - free_ram_start_pfn) << PAGE_SHIFT);
-       reserve_bootmem(PFN_PHYS(free_ram_start_pfn), bootmap_size,
-                       BOOTMEM_DEFAULT);
+       early_init_fdt_reserve_self();
+       early_init_fdt_scan_reserved_mem();
 
-       for_each_memblock(reserved, region) {
-               reserve_bootmem(region->base, region->size, BOOTMEM_DEFAULT);
-       }
+       memblock_dump_all();
 }
 
 void __init setup_arch(char **cmdline_p)
@@ -188,15 +167,6 @@ const struct seq_operations cpuinfo_op = {
        .show   = show_cpuinfo,
 };
 
-static int __init device_probe(void)
-{
-       of_platform_populate(NULL, NULL, NULL, NULL);
-
-       return 0;
-}
-
-device_initcall(device_probe);
-
 #if defined(CONFIG_CPU_H8300H)
 #define get_wait(base, addr) ({                \
        int baddr;                      \
index 46138f55a9ea7eedb86eeb60e074655d863bcc69..03aa35b1a08c2701765da7a61bf5017f97099ce3 100644 (file)
 
 static void sim_write(struct console *con, const char *s, unsigned n)
 {
-       register const int fd __asm__("er0") = 1; /* stdout */
        register const char *_ptr __asm__("er1") = s;
        register const unsigned _len __asm__("er2") = n;
 
-       __asm__(".byte 0x5e,0x00,0x00,0xc7\n\t" /* jsr @0xc7 (sys_write) */
-               : : "g"(fd), "g"(_ptr), "g"(_len));
+       __asm__("sub.l er0,er0\n\t"             /* er0 = 1 (stdout) */
+               "inc.l #1,er0\n\t"
+               ".byte 0x5e,0x00,0x00,0xc7\n\t" /* jsr @0xc7 (sys_write) */
+               : : "g"(_ptr), "g"(_len):"er0");
 }
 
 static int __init sim_setup(struct earlycon_device *device, const char *opt)
index 2efaa18e995ad8d6694b6532bea265aeb3460658..4c5858b80f0eebe108d6d75bfbcfa55d8a65a381 100644 (file)
@@ -22,9 +22,7 @@ ldflags-y += $(call cc-option,-mv${CONFIG_HEXAGON_ARCH_VERSION})
 
 KBUILD_CFLAGS += $(cflags-y)
 KBUILD_AFLAGS += $(aflags-y)
-
-#  no KBUILD_LDFLAGS?
-LDFLAGS += $(ldflags-y)
+KBUILD_LDFLAGS += $(ldflags-y)
 
 # Thread-info register will be r19.  This value is not configureable;
 # it is hard-coded in several files.
index 2bf4ef792f2cea3442b115e9e7db10b3be89794f..8b4a0c1748c03feb1529a32977ea3a72ad5fa867 100644 (file)
@@ -28,6 +28,7 @@ config IA64
        select HAVE_ARCH_TRACEHOOK
        select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
+       select NO_BOOTMEM
        select HAVE_VIRT_CPU_ACCOUNTING
        select ARCH_HAS_DMA_MARK_CLEAN
        select ARCH_HAS_SG_CHAIN
index ee5b652d320a1423d8eddc364b7cec76f1ba514d..671ce1e3f6f29f9966bdbca5ae3df15229aecfae 100644 (file)
@@ -1805,7 +1805,7 @@ static struct ioc_iommu ioc_iommu_info[] __initdata = {
        { SX2000_IOC_ID, "sx2000", NULL },
 };
 
-static void ioc_init(unsigned long hpa, struct ioc *ioc)
+static void __init ioc_init(unsigned long hpa, struct ioc *ioc)
 {
        struct ioc_iommu *info;
 
@@ -2002,7 +2002,7 @@ sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle)
 #endif
 }
 
-static void acpi_sba_ioc_add(struct ioc *ioc)
+static void __init acpi_sba_ioc_add(struct ioc *ioc)
 {
        acpi_handle handle = ioc->handle;
        acpi_status status;
index f4db2168d1b89e00723d4cd7b6950855ae18f6c6..00e8e2a1eb19c304477cceb8af2f3b4c244132d3 100644 (file)
@@ -50,8 +50,7 @@ void foo(void)
 
        DEFINE(IA64_TASK_BLOCKED_OFFSET,offsetof (struct task_struct, blocked));
        DEFINE(IA64_TASK_CLEAR_CHILD_TID_OFFSET,offsetof (struct task_struct, clear_child_tid));
-       DEFINE(IA64_TASK_GROUP_LEADER_OFFSET, offsetof (struct task_struct, group_leader));
-       DEFINE(IA64_TASK_TGIDLINK_OFFSET, offsetof (struct task_struct, pids[PIDTYPE_PID].pid));
+       DEFINE(IA64_TASK_THREAD_PID_OFFSET,offsetof (struct task_struct, thread_pid));
        DEFINE(IA64_PID_LEVEL_OFFSET, offsetof (struct pid, level));
        DEFINE(IA64_PID_UPID_OFFSET, offsetof (struct pid, numbers[0]));
        DEFINE(IA64_TASK_PENDING_OFFSET,offsetof (struct task_struct, pending));
@@ -68,6 +67,7 @@ void foo(void)
        DEFINE(IA64_SIGNAL_GROUP_STOP_COUNT_OFFSET,offsetof (struct signal_struct,
                                                             group_stop_count));
        DEFINE(IA64_SIGNAL_SHARED_PENDING_OFFSET,offsetof (struct signal_struct, shared_pending));
+       DEFINE(IA64_SIGNAL_PIDS_TGID_OFFSET, offsetof (struct signal_struct, pids[PIDTYPE_TGID]));
 
        BLANK();
 
index fe742ffafc7af0aadecb9e22d043ebfc8b327553..d80c99a5f55dd105813846399c5589444a5c70b1 100644 (file)
@@ -62,16 +62,16 @@ ENTRY(fsys_getpid)
        .prologue
        .altrp b6
        .body
-       add r17=IA64_TASK_GROUP_LEADER_OFFSET,r16
+       add r17=IA64_TASK_SIGNAL_OFFSET,r16
        ;;
-       ld8 r17=[r17]                           // r17 = current->group_leader
+       ld8 r17=[r17]                           // r17 = current->signal
        add r9=TI_FLAGS+IA64_TASK_SIZE,r16
        ;;
        ld4 r9=[r9]
-       add r17=IA64_TASK_TGIDLINK_OFFSET,r17
+       add r17=IA64_SIGNAL_PIDS_TGID_OFFSET,r17
        ;;
        and r9=TIF_ALLWORK_MASK,r9
-       ld8 r17=[r17]                           // r17 = current->group_leader->pids[PIDTYPE_PID].pid
+       ld8 r17=[r17]                           // r17 = current->signal->pids[PIDTYPE_TGID]
        ;;
        add r8=IA64_PID_LEVEL_OFFSET,r17
        ;;
@@ -96,11 +96,11 @@ ENTRY(fsys_set_tid_address)
        .altrp b6
        .body
        add r9=TI_FLAGS+IA64_TASK_SIZE,r16
-       add r17=IA64_TASK_TGIDLINK_OFFSET,r16
+       add r17=IA64_TASK_THREAD_PID_OFFSET,r16
        ;;
        ld4 r9=[r9]
        tnat.z p6,p7=r32                // check argument register for being NaT
-       ld8 r17=[r17]                           // r17 = current->pids[PIDTYPE_PID].pid
+       ld8 r17=[r17]                           // r17 = current->thread_pid
        ;;
        and r9=TIF_ALLWORK_MASK,r9
        add r8=IA64_PID_LEVEL_OFFSET,r17
index ad43cbf70628c8db191631e7d5bef443b0b36dc0..0e6c2d9fb49876b6e7147151eec5cbb458c4231b 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/delay.h>
 #include <linux/cpu.h>
 #include <linux/kernel.h>
+#include <linux/memblock.h>
 #include <linux/reboot.h>
 #include <linux/sched/mm.h>
 #include <linux/sched/clock.h>
@@ -383,8 +384,16 @@ reserve_memory (void)
 
        sort_regions(rsvd_region, num_rsvd_regions);
        num_rsvd_regions = merge_regions(rsvd_region, num_rsvd_regions);
-}
 
+       /* reserve all regions except the end of memory marker with memblock */
+       for (n = 0; n < num_rsvd_regions - 1; n++) {
+               struct rsvd_region *region = &rsvd_region[n];
+               phys_addr_t addr = __pa(region->start);
+               phys_addr_t size = region->end - region->start;
+
+               memblock_reserve(addr, size);
+       }
+}
 
 /**
  * find_initrd - get initrd parameters from the boot parameter structure
index 7d64b30913d1f1b20396de5922b42c8f6b34864e..e2e40bbd391c6a3207dc8d5cd1215abad84371c5 100644 (file)
@@ -34,53 +34,6 @@ static unsigned long max_gap;
 /* physical address where the bootmem map is located */
 unsigned long bootmap_start;
 
-/**
- * find_bootmap_location - callback to find a memory area for the bootmap
- * @start: start of region
- * @end: end of region
- * @arg: unused callback data
- *
- * Find a place to put the bootmap and return its starting address in
- * bootmap_start.  This address must be page-aligned.
- */
-static int __init
-find_bootmap_location (u64 start, u64 end, void *arg)
-{
-       u64 needed = *(unsigned long *)arg;
-       u64 range_start, range_end, free_start;
-       int i;
-
-#if IGNORE_PFN0
-       if (start == PAGE_OFFSET) {
-               start += PAGE_SIZE;
-               if (start >= end)
-                       return 0;
-       }
-#endif
-
-       free_start = PAGE_OFFSET;
-
-       for (i = 0; i < num_rsvd_regions; i++) {
-               range_start = max(start, free_start);
-               range_end   = min(end, rsvd_region[i].start & PAGE_MASK);
-
-               free_start = PAGE_ALIGN(rsvd_region[i].end);
-
-               if (range_end <= range_start)
-                       continue; /* skip over empty range */
-
-               if (range_end - range_start >= needed) {
-                       bootmap_start = __pa(range_start);
-                       return -1;      /* done */
-               }
-
-               /* nothing more available in this segment */
-               if (range_end == end)
-                       return 0;
-       }
-       return 0;
-}
-
 #ifdef CONFIG_SMP
 static void *cpu_data;
 /**
@@ -196,8 +149,6 @@ setup_per_cpu_areas(void)
 void __init
 find_memory (void)
 {
-       unsigned long bootmap_size;
-
        reserve_memory();
 
        /* first find highest page frame number */
@@ -205,21 +156,12 @@ find_memory (void)
        max_low_pfn = 0;
        efi_memmap_walk(find_max_min_low_pfn, NULL);
        max_pfn = max_low_pfn;
-       /* how many bytes to cover all the pages */
-       bootmap_size = bootmem_bootmap_pages(max_pfn) << PAGE_SHIFT;
-
-       /* look for a location to hold the bootmap */
-       bootmap_start = ~0UL;
-       efi_memmap_walk(find_bootmap_location, &bootmap_size);
-       if (bootmap_start == ~0UL)
-               panic("Cannot find %ld bytes for bootmap\n", bootmap_size);
 
-       bootmap_size = init_bootmem_node(NODE_DATA(0),
-                       (bootmap_start >> PAGE_SHIFT), 0, max_pfn);
-
-       /* Free all available memory, then mark bootmem-map as being in use. */
-       efi_memmap_walk(filter_rsvd_memory, free_bootmem);
-       reserve_bootmem(bootmap_start, bootmap_size, BOOTMEM_DEFAULT);
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+       efi_memmap_walk(filter_memory, register_active_ranges);
+#else
+       memblock_add_node(0, PFN_PHYS(max_low_pfn), 0);
+#endif
 
        find_initrd();
 
@@ -244,11 +186,9 @@ paging_init (void)
        max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
 
 #ifdef CONFIG_VIRTUAL_MEM_MAP
-       efi_memmap_walk(filter_memory, register_active_ranges);
        efi_memmap_walk(find_largest_hole, (u64 *)&max_gap);
        if (max_gap < LARGE_GAP) {
                vmem_map = (struct page *) 0;
-               free_area_init_nodes(max_zone_pfns);
        } else {
                unsigned long map_size;
 
@@ -266,13 +206,10 @@ paging_init (void)
                 */
                NODE_DATA(0)->node_mem_map = vmem_map +
                        find_min_pfn_with_active_regions();
-               free_area_init_nodes(max_zone_pfns);
 
                printk("Virtual mem_map starts at 0x%p\n", mem_map);
        }
-#else /* !CONFIG_VIRTUAL_MEM_MAP */
-       memblock_add_node(0, PFN_PHYS(max_low_pfn), 0);
-       free_area_init_nodes(max_zone_pfns);
 #endif /* !CONFIG_VIRTUAL_MEM_MAP */
+       free_area_init_nodes(max_zone_pfns);
        zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
 }
index 7d9bd20319ffbc7f57789a49f066a46dba00a356..1928d5719e417d5b5899a7c2b48c73a3da3294bd 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/nmi.h>
 #include <linux/swap.h>
 #include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/acpi.h>
 #include <linux/efi.h>
 #include <linux/nodemask.h>
@@ -38,9 +39,6 @@ struct early_node_data {
        struct ia64_node_data *node_data;
        unsigned long pernode_addr;
        unsigned long pernode_size;
-#ifdef CONFIG_ZONE_DMA32
-       unsigned long num_dma_physpages;
-#endif
        unsigned long min_pfn;
        unsigned long max_pfn;
 };
@@ -60,33 +58,31 @@ pg_data_t *pgdat_list[MAX_NUMNODES];
             (((node)*PERCPU_PAGE_SIZE) & (MAX_NODE_ALIGN_OFFSET - 1)))
 
 /**
- * build_node_maps - callback to setup bootmem structs for each node
+ * build_node_maps - callback to setup mem_data structs for each node
  * @start: physical start of range
  * @len: length of range
  * @node: node where this range resides
  *
- * We allocate a struct bootmem_data for each piece of memory that we wish to
+ * Detect extents of each piece of memory that we wish to
  * treat as a virtually contiguous block (i.e. each node). Each such block
  * must start on an %IA64_GRANULE_SIZE boundary, so we round the address down
  * if necessary.  Any non-existent pages will simply be part of the virtual
- * memmap.  We also update min_low_pfn and max_low_pfn here as we receive
- * memory ranges from the caller.
+ * memmap.
  */
 static int __init build_node_maps(unsigned long start, unsigned long len,
                                  int node)
 {
        unsigned long spfn, epfn, end = start + len;
-       struct bootmem_data *bdp = &bootmem_node_data[node];
 
        epfn = GRANULEROUNDUP(end) >> PAGE_SHIFT;
        spfn = GRANULEROUNDDOWN(start) >> PAGE_SHIFT;
 
-       if (!bdp->node_low_pfn) {
-               bdp->node_min_pfn = spfn;
-               bdp->node_low_pfn = epfn;
+       if (!mem_data[node].min_pfn) {
+               mem_data[node].min_pfn = spfn;
+               mem_data[node].max_pfn = epfn;
        } else {
-               bdp->node_min_pfn = min(spfn, bdp->node_min_pfn);
-               bdp->node_low_pfn = max(epfn, bdp->node_low_pfn);
+               mem_data[node].min_pfn = min(spfn, mem_data[node].min_pfn);
+               mem_data[node].max_pfn = max(epfn, mem_data[node].max_pfn);
        }
 
        return 0;
@@ -269,7 +265,6 @@ static void __init fill_pernode(int node, unsigned long pernode,
 {
        void *cpu_data;
        int cpus = early_nr_cpus_node(node);
-       struct bootmem_data *bdp = &bootmem_node_data[node];
 
        mem_data[node].pernode_addr = pernode;
        mem_data[node].pernode_size = pernodesize;
@@ -284,8 +279,6 @@ static void __init fill_pernode(int node, unsigned long pernode,
 
        mem_data[node].node_data = __va(pernode);
        pernode += L1_CACHE_ALIGN(sizeof(struct ia64_node_data));
-
-       pgdat_list[node]->bdata = bdp;
        pernode += L1_CACHE_ALIGN(sizeof(pg_data_t));
 
        cpu_data = per_cpu_node_setup(cpu_data, node);
@@ -325,20 +318,16 @@ static int __init find_pernode_space(unsigned long start, unsigned long len,
                                     int node)
 {
        unsigned long spfn, epfn;
-       unsigned long pernodesize = 0, pernode, pages, mapsize;
-       struct bootmem_data *bdp = &bootmem_node_data[node];
+       unsigned long pernodesize = 0, pernode;
 
        spfn = start >> PAGE_SHIFT;
        epfn = (start + len) >> PAGE_SHIFT;
 
-       pages = bdp->node_low_pfn - bdp->node_min_pfn;
-       mapsize = bootmem_bootmap_pages(pages) << PAGE_SHIFT;
-
        /*
         * Make sure this memory falls within this node's usable memory
         * since we may have thrown some away in build_maps().
         */
-       if (spfn < bdp->node_min_pfn || epfn > bdp->node_low_pfn)
+       if (spfn < mem_data[node].min_pfn || epfn > mem_data[node].max_pfn)
                return 0;
 
        /* Don't setup this node's local space twice... */
@@ -353,31 +342,12 @@ static int __init find_pernode_space(unsigned long start, unsigned long len,
        pernode = NODEDATA_ALIGN(start, node);
 
        /* Is this range big enough for what we want to store here? */
-       if (start + len > (pernode + pernodesize + mapsize))
+       if (start + len > (pernode + pernodesize))
                fill_pernode(node, pernode, pernodesize);
 
        return 0;
 }
 
-/**
- * free_node_bootmem - free bootmem allocator memory for use
- * @start: physical start of range
- * @len: length of range
- * @node: node where this range resides
- *
- * Simply calls the bootmem allocator to free the specified ranged from
- * the given pg_data_t's bdata struct.  After this function has been called
- * for all the entries in the EFI memory map, the bootmem allocator will
- * be ready to service allocation requests.
- */
-static int __init free_node_bootmem(unsigned long start, unsigned long len,
-                                   int node)
-{
-       free_bootmem_node(pgdat_list[node], start, len);
-
-       return 0;
-}
-
 /**
  * reserve_pernode_space - reserve memory for per-node space
  *
@@ -387,28 +357,17 @@ static int __init free_node_bootmem(unsigned long start, unsigned long len,
  */
 static void __init reserve_pernode_space(void)
 {
-       unsigned long base, size, pages;
-       struct bootmem_data *bdp;
+       unsigned long base, size;
        int node;
 
        for_each_online_node(node) {
-               pg_data_t *pdp = pgdat_list[node];
-
                if (node_isset(node, memory_less_mask))
                        continue;
 
-               bdp = pdp->bdata;
-
-               /* First the bootmem_map itself */
-               pages = bdp->node_low_pfn - bdp->node_min_pfn;
-               size = bootmem_bootmap_pages(pages) << PAGE_SHIFT;
-               base = __pa(bdp->node_bootmem_map);
-               reserve_bootmem_node(pdp, base, size, BOOTMEM_DEFAULT);
-
                /* Now the per-node space */
                size = mem_data[node].pernode_size;
                base = __pa(mem_data[node].pernode_addr);
-               reserve_bootmem_node(pdp, base, size, BOOTMEM_DEFAULT);
+               memblock_reserve(base, size);
        }
 }
 
@@ -528,6 +487,7 @@ void __init find_memory(void)
        int node;
 
        reserve_memory();
+       efi_memmap_walk(filter_memory, register_active_ranges);
 
        if (num_online_nodes() == 0) {
                printk(KERN_ERR "node info missing!\n");
@@ -544,38 +504,8 @@ void __init find_memory(void)
        efi_memmap_walk(find_max_min_low_pfn, NULL);
 
        for_each_online_node(node)
-               if (bootmem_node_data[node].node_low_pfn) {
+               if (mem_data[node].min_pfn)
                        node_clear(node, memory_less_mask);
-                       mem_data[node].min_pfn = ~0UL;
-               }
-
-       efi_memmap_walk(filter_memory, register_active_ranges);
-
-       /*
-        * Initialize the boot memory maps in reverse order since that's
-        * what the bootmem allocator expects
-        */
-       for (node = MAX_NUMNODES - 1; node >= 0; node--) {
-               unsigned long pernode, pernodesize, map;
-               struct bootmem_data *bdp;
-
-               if (!node_online(node))
-                       continue;
-               else if (node_isset(node, memory_less_mask))
-                       continue;
-
-               bdp = &bootmem_node_data[node];
-               pernode = mem_data[node].pernode_addr;
-               pernodesize = mem_data[node].pernode_size;
-               map = pernode + pernodesize;
-
-               init_bootmem_node(pgdat_list[node],
-                                 map>>PAGE_SHIFT,
-                                 bdp->node_min_pfn,
-                                 bdp->node_low_pfn);
-       }
-
-       efi_memmap_walk(filter_rsvd_memory, free_node_bootmem);
 
        reserve_pernode_space();
        memory_less_nodes();
@@ -654,36 +584,6 @@ void call_pernode_memory(unsigned long start, unsigned long len, void *arg)
        }
 }
 
-/**
- * count_node_pages - callback to build per-node memory info structures
- * @start: physical start of range
- * @len: length of range
- * @node: node where this range resides
- *
- * Each node has it's own number of physical pages, DMAable pages, start, and
- * end page frame number.  This routine will be called by call_pernode_memory()
- * for each piece of usable memory and will setup these values for each node.
- * Very similar to build_maps().
- */
-static __init int count_node_pages(unsigned long start, unsigned long len, int node)
-{
-       unsigned long end = start + len;
-
-#ifdef CONFIG_ZONE_DMA32
-       if (start <= __pa(MAX_DMA_ADDRESS))
-               mem_data[node].num_dma_physpages +=
-                       (min(end, __pa(MAX_DMA_ADDRESS)) - start) >>PAGE_SHIFT;
-#endif
-       start = GRANULEROUNDDOWN(start);
-       end = GRANULEROUNDUP(end);
-       mem_data[node].max_pfn = max(mem_data[node].max_pfn,
-                                    end >> PAGE_SHIFT);
-       mem_data[node].min_pfn = min(mem_data[node].min_pfn,
-                                    start >> PAGE_SHIFT);
-
-       return 0;
-}
-
 /**
  * paging_init - setup page tables
  *
@@ -700,8 +600,6 @@ void __init paging_init(void)
 
        max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
 
-       efi_memmap_walk(filter_rsvd_memory, count_node_pages);
-
        sparse_memory_present_with_active_regions(MAX_NUMNODES);
        sparse_init();
 
index f0dd9fc84002a3415ed5ee5680f06fa8a02f5069..997c9f20ea0f937667031760193efe02fec00faf 100644 (file)
@@ -69,7 +69,7 @@ KBUILD_CFLAGS += -D__uClinux__
 KBUILD_AFLAGS += -D__uClinux__
 endif
 
-LDFLAGS := -m m68kelf
+KBUILD_LDFLAGS := -m m68kelf
 KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds
 
 ifdef CONFIG_SUN3
index 3534aa6a4dc2bc7e833001739582af3660a579d1..1b083c500b9a170beb6c030d882f9d9f675369c5 100644 (file)
@@ -98,11 +98,10 @@ static time64_t pmu_read_time(void)
 
        if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
                return 0;
-       while (!req.complete)
-               pmu_poll();
+       pmu_wait_complete(&req);
 
-       time = (u32)((req.reply[1] << 24) | (req.reply[2] << 16) |
-                    (req.reply[3] << 8) | req.reply[4]);
+       time = (u32)((req.reply[0] << 24) | (req.reply[1] << 16) |
+                    (req.reply[2] << 8) | req.reply[3]);
 
        return time - RTC_OFFSET;
 }
@@ -116,8 +115,7 @@ static void pmu_write_time(time64_t time)
                        (data >> 24) & 0xFF, (data >> 16) & 0xFF,
                        (data >> 8) & 0xFF, data & 0xFF) < 0)
                return;
-       while (!req.complete)
-               pmu_poll();
+       pmu_wait_complete(&req);
 }
 
 static __u8 pmu_read_pram(int offset)
index 70dde040779b56feaeaa650a7c342a23750a1fce..f5453d944ff5e19d341925590cca753ffb4fcd7e 100644 (file)
@@ -172,7 +172,7 @@ void __init cf_bootmem_alloc(void)
        high_memory = (void *)_ramend;
 
        /* Reserve kernel text/data/bss */
-       memblock_reserve(memstart, memstart - _rambase);
+       memblock_reserve(_rambase, memstart - _rambase);
 
        m68k_virt_to_node_shift = fls(_ramend - 1) - 6;
        module_fixup(NULL, __start_fixup, __stop_fixup);
index 6163a39ddeb6f827fbe6991df616dd2effb8e9a0..ace5c5bf18361f52ca438f5a2b8da073abd05403 100644 (file)
@@ -2,6 +2,8 @@ config MICROBLAZE
        def_bool y
        select ARCH_NO_SWAP
        select ARCH_HAS_GCOV_PROFILE_ALL
+       select ARCH_HAS_SYNC_DMA_FOR_CPU
+       select ARCH_HAS_SYNC_DMA_FOR_DEVICE
        select ARCH_MIGHT_HAVE_PC_PARPORT
        select ARCH_NO_COHERENT_DMA_MMAP if !MMU
        select ARCH_WANT_IPC_PARSE_VERSION
@@ -9,6 +11,8 @@ config MICROBLAZE
        select TIMER_OF
        select CLONE_BACKWARDS3
        select COMMON_CLK
+       select DMA_NONCOHERENT_OPS
+       select DMA_NONCOHERENT_MMAP
        select GENERIC_ATOMIC64
        select GENERIC_CLOCKEVENTS
        select GENERIC_CPU_DEVICES
index d269dd4b8279574f5681ffed4bd5b07caa003aed..4f3ab5707265204f309b31695cb3a60a4f7a8d1c 100644 (file)
@@ -40,11 +40,11 @@ CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR) += -mxl-pattern-compare
 ifdef CONFIG_CPU_BIG_ENDIAN
 KBUILD_CFLAGS += -mbig-endian
 KBUILD_AFLAGS += -mbig-endian
-LD += -EB
+KBUILD_LDFLAGS += -EB
 else
 KBUILD_CFLAGS += -mlittle-endian
 KBUILD_AFLAGS += -mlittle-endian
-LD += -EL
+KBUILD_LDFLAGS += -EL
 endif
 
 CPUFLAGS-1 += $(call cc-option,-mcpu=v$(CPU_VER))
index fe6a6c6e5003c30624ab37d63b2b29d3cab2de82..569ba9e670c11474c53102eaab2cf669a8bb1319 100644 (file)
@@ -5,6 +5,7 @@ generic-y += bugs.h
 generic-y += compat.h
 generic-y += device.h
 generic-y += div64.h
+generic-y += dma-mapping.h
 generic-y += emergency-restart.h
 generic-y += exec.h
 generic-y += extable.h
diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h
deleted file mode 100644 (file)
index add50c1..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Implements the generic device dma API for microblaze and the pci
- *
- * Copyright (C) 2009-2010 Michal Simek <monstr@monstr.eu>
- * Copyright (C) 2009-2010 PetaLogix
- *
- * 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.
- *
- * This file is base on powerpc and x86 dma-mapping.h versions
- * Copyright (C) 2004 IBM
- */
-
-#ifndef _ASM_MICROBLAZE_DMA_MAPPING_H
-#define _ASM_MICROBLAZE_DMA_MAPPING_H
-
-/*
- * Available generic sets of operations
- */
-extern const struct dma_map_ops dma_nommu_ops;
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-       return &dma_nommu_ops;
-}
-
-#endif /* _ASM_MICROBLAZE_DMA_MAPPING_H */
index db8b1fa83452c1fec163e068acb723d18b6166d8..7b650ab14fa089f22cf2953c135fdcff08da7e9a 100644 (file)
@@ -553,11 +553,6 @@ void __init *early_get_page(void);
 
 extern unsigned long ioremap_bot, ioremap_base;
 
-void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle);
-void consistent_free(size_t size, void *vaddr);
-void consistent_sync(void *vaddr, size_t size, int direction);
-void consistent_sync_page(struct page *page, unsigned long offset,
-       size_t size, int direction);
 unsigned long consistent_virt_to_pfn(void *vaddr);
 
 void setup_memory(void);
index 3145e7dc8ab191fb7fde8692fcd0eaeef0265ee3..71032cf6466994b570601647a3975449464c9450 100644 (file)
@@ -8,29 +8,15 @@
  */
 
 #include <linux/device.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-noncoherent.h>
 #include <linux/gfp.h>
 #include <linux/dma-debug.h>
 #include <linux/export.h>
 #include <linux/bug.h>
 #include <asm/cacheflush.h>
 
-static void *dma_nommu_alloc_coherent(struct device *dev, size_t size,
-                                      dma_addr_t *dma_handle, gfp_t flag,
-                                      unsigned long attrs)
-{
-       return consistent_alloc(flag, size, dma_handle);
-}
-
-static void dma_nommu_free_coherent(struct device *dev, size_t size,
-                                    void *vaddr, dma_addr_t dma_handle,
-                                    unsigned long attrs)
-{
-       consistent_free(size, vaddr);
-}
-
-static inline void __dma_sync(unsigned long paddr,
-                             size_t size, enum dma_data_direction direction)
+static void __dma_sync(struct device *dev, phys_addr_t paddr, size_t size,
+               enum dma_data_direction direction)
 {
        switch (direction) {
        case DMA_TO_DEVICE:
@@ -45,113 +31,21 @@ static inline void __dma_sync(unsigned long paddr,
        }
 }
 
-static int dma_nommu_map_sg(struct device *dev, struct scatterlist *sgl,
-                            int nents, enum dma_data_direction direction,
-                            unsigned long attrs)
+void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
+               size_t size, enum dma_data_direction dir)
 {
-       struct scatterlist *sg;
-       int i;
-
-       /* FIXME this part of code is untested */
-       for_each_sg(sgl, sg, nents, i) {
-               sg->dma_address = sg_phys(sg);
-
-               if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
-                       continue;
-
-               __dma_sync(sg_phys(sg), sg->length, direction);
-       }
-
-       return nents;
-}
-
-static inline dma_addr_t dma_nommu_map_page(struct device *dev,
-                                            struct page *page,
-                                            unsigned long offset,
-                                            size_t size,
-                                            enum dma_data_direction direction,
-                                            unsigned long attrs)
-{
-       if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
-               __dma_sync(page_to_phys(page) + offset, size, direction);
-       return page_to_phys(page) + offset;
+       __dma_sync(dev, paddr, size, dir);
 }
 
-static inline void dma_nommu_unmap_page(struct device *dev,
-                                        dma_addr_t dma_address,
-                                        size_t size,
-                                        enum dma_data_direction direction,
-                                        unsigned long attrs)
+void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
+               size_t size, enum dma_data_direction dir)
 {
-/* There is not necessary to do cache cleanup
- *
- * phys_to_virt is here because in __dma_sync_page is __virt_to_phys and
- * dma_address is physical address
- */
-       if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
-               __dma_sync(dma_address, size, direction);
+       __dma_sync(dev, paddr, size, dir);
 }
 
-static inline void
-dma_nommu_sync_single_for_cpu(struct device *dev,
-                              dma_addr_t dma_handle, size_t size,
-                              enum dma_data_direction direction)
-{
-       /*
-        * It's pointless to flush the cache as the memory segment
-        * is given to the CPU
-        */
-
-       if (direction == DMA_FROM_DEVICE)
-               __dma_sync(dma_handle, size, direction);
-}
-
-static inline void
-dma_nommu_sync_single_for_device(struct device *dev,
-                                 dma_addr_t dma_handle, size_t size,
-                                 enum dma_data_direction direction)
-{
-       /*
-        * It's pointless to invalidate the cache if the device isn't
-        * supposed to write to the relevant region
-        */
-
-       if (direction == DMA_TO_DEVICE)
-               __dma_sync(dma_handle, size, direction);
-}
-
-static inline void
-dma_nommu_sync_sg_for_cpu(struct device *dev,
-                          struct scatterlist *sgl, int nents,
-                          enum dma_data_direction direction)
-{
-       struct scatterlist *sg;
-       int i;
-
-       /* FIXME this part of code is untested */
-       if (direction == DMA_FROM_DEVICE)
-               for_each_sg(sgl, sg, nents, i)
-                       __dma_sync(sg->dma_address, sg->length, direction);
-}
-
-static inline void
-dma_nommu_sync_sg_for_device(struct device *dev,
-                             struct scatterlist *sgl, int nents,
-                             enum dma_data_direction direction)
-{
-       struct scatterlist *sg;
-       int i;
-
-       /* FIXME this part of code is untested */
-       if (direction == DMA_TO_DEVICE)
-               for_each_sg(sgl, sg, nents, i)
-                       __dma_sync(sg->dma_address, sg->length, direction);
-}
-
-static
-int dma_nommu_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
-                            void *cpu_addr, dma_addr_t handle, size_t size,
-                            unsigned long attrs)
+int arch_dma_mmap(struct device *dev, struct vm_area_struct *vma,
+               void *cpu_addr, dma_addr_t handle, size_t size,
+               unsigned long attrs)
 {
 #ifdef CONFIG_MMU
        unsigned long user_count = vma_pages(vma);
@@ -170,17 +64,3 @@ int dma_nommu_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
        return -ENXIO;
 #endif
 }
-
-const struct dma_map_ops dma_nommu_ops = {
-       .alloc                  = dma_nommu_alloc_coherent,
-       .free                   = dma_nommu_free_coherent,
-       .mmap                   = dma_nommu_mmap_coherent,
-       .map_sg                 = dma_nommu_map_sg,
-       .map_page               = dma_nommu_map_page,
-       .unmap_page             = dma_nommu_unmap_page,
-       .sync_single_for_cpu    = dma_nommu_sync_single_for_cpu,
-       .sync_single_for_device = dma_nommu_sync_single_for_device,
-       .sync_sg_for_cpu        = dma_nommu_sync_sg_for_cpu,
-       .sync_sg_for_device     = dma_nommu_sync_sg_for_device,
-};
-EXPORT_SYMBOL(dma_nommu_ops);
index 4655ff342c6406498c4640fca7c470333205f4f4..f264fdcf152aa85ea86ea66016851172099300f3 100644 (file)
@@ -341,11 +341,6 @@ start_here:
        /* Initialize r31 with current task address */
        addik   r31, r0, init_task
 
-       /*
-        * Call platform dependent initialize function.
-        * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for
-        * the function.
-        */
        addik   r11, r0, machine_early_init
        brald   r15, r11
        nop
index b06c3a7faf20b51724fadd84f02ca33cc7390cc6..c9a278ac795a88885d151ebdf3bd27dd559006c4 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/gfp.h>
+#include <linux/dma-noncoherent.h>
 
 #include <asm/pgalloc.h>
 #include <linux/io.h>
@@ -59,7 +60,8 @@
  * uncached region.  This will no doubt cause big problems if memory allocated
  * here is not also freed properly. -- JW
  */
-void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle)
+void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+               gfp_t gfp, unsigned long attrs)
 {
        unsigned long order, vaddr;
        void *ret;
@@ -154,7 +156,6 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle)
 
        return ret;
 }
-EXPORT_SYMBOL(consistent_alloc);
 
 #ifdef CONFIG_MMU
 static pte_t *consistent_virt_to_pte(void *vaddr)
@@ -178,7 +179,8 @@ unsigned long consistent_virt_to_pfn(void *vaddr)
 /*
  * free page(s) as defined by the above mapping.
  */
-void consistent_free(size_t size, void *vaddr)
+void arch_dma_free(struct device *dev, size_t size, void *vaddr,
+               dma_addr_t dma_addr, unsigned long attrs)
 {
        struct page *page;
 
@@ -218,49 +220,3 @@ void consistent_free(size_t size, void *vaddr)
        flush_tlb_all();
 #endif
 }
-EXPORT_SYMBOL(consistent_free);
-
-/*
- * make an area consistent.
- */
-void consistent_sync(void *vaddr, size_t size, int direction)
-{
-       unsigned long start;
-       unsigned long end;
-
-       start = (unsigned long)vaddr;
-
-       /* Convert start address back down to unshadowed memory region */
-#ifdef CONFIG_XILINX_UNCACHED_SHADOW
-       start &= ~UNCACHED_SHADOW_MASK;
-#endif
-       end = start + size;
-
-       switch (direction) {
-       case PCI_DMA_NONE:
-               BUG();
-       case PCI_DMA_FROMDEVICE:        /* invalidate only */
-               invalidate_dcache_range(start, end);
-               break;
-       case PCI_DMA_TODEVICE:          /* writeback only */
-               flush_dcache_range(start, end);
-               break;
-       case PCI_DMA_BIDIRECTIONAL:     /* writeback and invalidate */
-               flush_dcache_range(start, end);
-               break;
-       }
-}
-EXPORT_SYMBOL(consistent_sync);
-
-/*
- * consistent_sync_page makes memory consistent. identical
- * to consistent_sync, but takes a struct page instead of a
- * virtual address
- */
-void consistent_sync_page(struct page *page, unsigned long offset,
-       size_t size, int direction)
-{
-       unsigned long start = (unsigned long)page_address(page) + offset;
-       consistent_sync((void *)start, size, direction);
-}
-EXPORT_SYMBOL(consistent_sync_page);
index f34346d560954065c6504e952aa251ed684474f4..2ffd171af8b60b463e408efc2ac69fb89e61a20c 100644 (file)
@@ -597,19 +597,6 @@ static void pcibios_fixup_resources(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);
 
-/*
- * We need to avoid collisions with `mirrored' VGA ports
- * and other strange ISA hardware, so we always want the
- * addresses to be allocated in the 0x000-0x0ff region
- * modulo 0x400.
- *
- * Why? Because some silly external IO cards only decode
- * the low 10 bits of the IO address. The 0x00-0xff region
- * is reserved for motherboard devices that decode all 16
- * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
- * but we want to try to avoid allocating at 0x2900-0x2bff
- * which might have be mirrored at 0x0100-0x03ff..
- */
 int pcibios_add_device(struct pci_dev *dev)
 {
        dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
index 14c7da5fd039d6266b71210739f398389a814bb5..b800909ddccf712b95fb8cca3a72a45ea632c78a 100644 (file)
@@ -157,6 +157,7 @@ void __init xilinx_pci_init(void)
 
        /* Set the max bus number to 255, and bus/subbus no's to 0 */
        pci_reg = of_iomap(pci_node, 0);
+       WARN_ON(!pci_reg);
        out_be32(pci_reg + XPLB_PCI_BUS, 0x000000ff);
        iounmap(pci_reg);
 
index 2af13b162e5e564cd8ac710e7154c108664f92f8..35511999156af4a2d3559b3ac9d6c0038630451e 100644 (file)
@@ -33,6 +33,7 @@ config MIPS
        select GENERIC_SMP_IDLE_THREAD
        select GENERIC_TIME_VSYSCALL
        select HANDLE_DOMAIN_IRQ
+       select HAVE_ARCH_COMPILER_H
        select HAVE_ARCH_JUMP_LABEL
        select HAVE_ARCH_KGDB
        select HAVE_ARCH_MMAP_RND_BITS if MMU
index 5425df002a6b11965b9c22273a1b20ba128afbd6..d74b3742fa5d8d38d0b3995d988119b8c8b15cf5 100644 (file)
@@ -309,7 +309,7 @@ endif
 # instead of .eh_frame so we don't discard them.
 KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
 
-LDFLAGS                        += -m $(ld-emul)
+KBUILD_LDFLAGS         += -m $(ld-emul)
 
 ifdef CONFIG_MIPS
 CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \
index abe77add8789042441d400a3d01434d41dcfc8de..3c453a1f1ff10c218e809ec1f5efe2bb70b1ef7d 100644 (file)
@@ -92,7 +92,7 @@ UIMAGE_LOADADDR = $(VMLINUZ_LOAD_ADDRESS)
 vmlinuzobjs-y += $(obj)/piggy.o
 
 quiet_cmd_zld = LD      $@
-      cmd_zld = $(LD) $(LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T $< $(vmlinuzobjs-y) -o $@
+      cmd_zld = $(LD) $(KBUILD_LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T $< $(vmlinuzobjs-y) -o $@
 quiet_cmd_strip = STRIP          $@
       cmd_strip = $(STRIP) -s $@
 vmlinuz: $(src)/ld.script $(vmlinuzobjs-y) $(obj)/calc_vmlinuz_load_addr
index 576f1a62dea99b9608518e3b7ffae467d770f990..f901ed043c71b983f5e26ba721b24bbc83c14490 100644 (file)
@@ -5,3 +5,4 @@
 #include <asm-generic/asm-prototypes.h>
 #include <linux/uaccess.h>
 #include <asm/ftrace.h>
+#include <asm/mmu_context.h>
index 0269b3de8b5197ab171ea9e4e4870ab4fe68dea9..d4ea7a5b60cf469772ed1651fd58d1f7010402e4 100644 (file)
@@ -122,8 +122,8 @@ static __inline__ int atomic_fetch_##op##_relaxed(int i, atomic_t * v)            \
                "       " #asm_op " %0, %1, %3                          \n"   \
                "       sc      %0, %2                                  \n"   \
                "\t" __scbeqz " %0, 1b                                  \n"   \
-               "       move    %0, %1                                  \n"   \
                "       .set    mips0                                   \n"   \
+               "       move    %0, %1                                  \n"   \
                : "=&r" (result), "=&r" (temp),                               \
                  "+" GCC_OFF_SMALL_ASM() (v->counter)                        \
                : "Ir" (i));                                                  \
@@ -190,9 +190,11 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
                __asm__ __volatile__(
                "       .set    "MIPS_ISA_LEVEL"                        \n"
                "1:     ll      %1, %2          # atomic_sub_if_positive\n"
+               "       .set    mips0                                   \n"
                "       subu    %0, %1, %3                              \n"
                "       move    %1, %0                                  \n"
                "       bltz    %0, 1f                                  \n"
+               "       .set    "MIPS_ISA_LEVEL"                        \n"
                "       sc      %1, %2                                  \n"
                "\t" __scbeqz " %1, 1b                                  \n"
                "1:                                                     \n"
index e081a265f4227475d17fef0d53cf07f7e9ffb6a3..cc2eb1b06050c4255810843ba0ef513d2441bcdd 100644 (file)
@@ -8,6 +8,41 @@
 #ifndef _ASM_COMPILER_H
 #define _ASM_COMPILER_H
 
+/*
+ * With GCC 4.5 onwards we can use __builtin_unreachable to indicate to the
+ * compiler that a particular code path will never be hit. This allows it to be
+ * optimised out of the generated binary.
+ *
+ * Unfortunately at least GCC 4.6.3 through 7.3.0 inclusive suffer from a bug
+ * that can lead to instructions from beyond an unreachable statement being
+ * incorrectly reordered into earlier delay slots if the unreachable statement
+ * is the only content of a case in a switch statement. This can lead to
+ * seemingly random behaviour, such as invalid memory accesses from incorrectly
+ * reordered loads or stores. See this potential GCC fix for details:
+ *
+ *   https://gcc.gnu.org/ml/gcc-patches/2015-09/msg00360.html
+ *
+ * It is unclear whether GCC 8 onwards suffer from the same issue - nothing
+ * relevant is mentioned in GCC 8 release notes and nothing obviously relevant
+ * stands out in GCC commit logs, but these newer GCC versions generate very
+ * different code for the testcase which doesn't exhibit the bug.
+ *
+ * GCC also handles stack allocation suboptimally when calling noreturn
+ * functions or calling __builtin_unreachable():
+ *
+ *   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82365
+ *
+ * We work around both of these issues by placing a volatile asm statement,
+ * which GCC is prevented from reordering past, prior to __builtin_unreachable
+ * calls.
+ *
+ * The .insn statement is required to ensure that any branches to the
+ * statement, which sadly must be kept due to the asm statement, are known to
+ * be branches to code and satisfy linker requirements for microMIPS kernels.
+ */
+#undef barrier_before_unreachable
+#define barrier_before_unreachable() asm volatile(".insn")
+
 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
 #define GCC_IMM_ASM() "n"
 #define GCC_REG_ACCUM "$0"
index a9af1d2dcd699114d00a55689c29137cef384841..2c1c53d12179302140d3576dddd11a732a5b13d9 100644 (file)
@@ -931,7 +931,6 @@ enum kvm_mips_fault_result kvm_trap_emul_gva_fault(struct kvm_vcpu *vcpu,
                                                   bool write);
 
 #define KVM_ARCH_WANT_MMU_NOTIFIER
-int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
 int kvm_unmap_hva_range(struct kvm *kvm,
                        unsigned long start, unsigned long end);
 void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
index b509371a6b0cce4842ab634c80c658e35d245db6..94414561de0e7b9c46d6d6af17c42de6e8519ab6 100644 (file)
@@ -32,6 +32,7 @@ do {                                                                  \
 } while (0)
 
 extern void tlbmiss_handler_setup_pgd(unsigned long);
+extern char tlbmiss_handler_setup_pgd_end[];
 
 /* Note: This is also implemented with uasm in arch/mips/kvm/entry.c */
 #define TLBMISS_HANDLER_SETUP_PGD(pgd)                                 \
index 4ed7ebed3bf1f060d2f6965618120751e519605a..6d97e23f30abdded461a1b93f17feb9fd5d85a65 100644 (file)
@@ -24,4 +24,13 @@ void build_tlb_write_entry(u32 **p, struct uasm_label **l,
                           struct uasm_reloc **r,
                           enum tlb_write_entry wmode);
 
+extern void handle_tlbl(void);
+extern char handle_tlbl_end[];
+
+extern void handle_tlbs(void);
+extern char handle_tlbs_end[];
+
+extern void handle_tlbm(void);
+extern char handle_tlbm_end[];
+
 #endif /* __ASM_TLBEX_H */
index f8871d5b7eb3e863bc5abf6b77dbd2f04fdd877d..9dab0ed1b227804f92b16de32a9098ae20d1365a 100644 (file)
 #include <asm/mmu_context.h>
 #include <asm/types.h>
 #include <asm/stacktrace.h>
+#include <asm/tlbex.h>
 #include <asm/uasm.h>
 
 extern void check_wait(void);
 extern asmlinkage void rollback_handle_int(void);
 extern asmlinkage void handle_int(void);
-extern u32 handle_tlbl[];
-extern u32 handle_tlbs[];
-extern u32 handle_tlbm[];
 extern asmlinkage void handle_adel(void);
 extern asmlinkage void handle_ades(void);
 extern asmlinkage void handle_ibe(void);
index f7a0645ccb82c446af586d6cbcf7b683c6b47a6b..4aaff3b3175c4c6323052d531a795a22fbcad618 100644 (file)
@@ -224,7 +224,7 @@ unsigned long arch_uretprobe_hijack_return_addr(
 int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm,
        unsigned long vaddr)
 {
-       return uprobe_write_opcode(mm, vaddr, UPROBE_SWBP_INSN);
+       return uprobe_write_opcode(auprobe, mm, vaddr, UPROBE_SWBP_INSN);
 }
 
 void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
index 019035d7225c4fd942c96c6628b6605f8d2af1b4..8f845f6e5f4266568288969b9b19b7357b86598b 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
@@ -20,6 +21,7 @@
 
 #include <asm/abi.h>
 #include <asm/mips-cps.h>
+#include <asm/page.h>
 #include <asm/vdso.h>
 
 /* Kernel-provided data used by the VDSO. */
@@ -128,12 +130,30 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
        vvar_size = gic_size + PAGE_SIZE;
        size = vvar_size + image->size;
 
+       /*
+        * Find a region that's large enough for us to perform the
+        * colour-matching alignment below.
+        */
+       if (cpu_has_dc_aliases)
+               size += shm_align_mask + 1;
+
        base = get_unmapped_area(NULL, 0, size, 0, 0);
        if (IS_ERR_VALUE(base)) {
                ret = base;
                goto out;
        }
 
+       /*
+        * If we suffer from dcache aliasing, ensure that the VDSO data page
+        * mapping is coloured the same as the kernel's mapping of that memory.
+        * This ensures that when the kernel updates the VDSO data userland
+        * will observe it without requiring cache invalidations.
+        */
+       if (cpu_has_dc_aliases) {
+               base = __ALIGN_MASK(base, shm_align_mask);
+               base += ((unsigned long)&vdso_data - gic_size) & shm_align_mask;
+       }
+
        data_addr = base + gic_size;
        vdso_addr = data_addr + PAGE_SIZE;
 
index ee64db03279336db79ac5c98e7634074d47608ac..d8dcdb350405900928b83e7afa2112ecf3122518 100644 (file)
@@ -512,16 +512,6 @@ static int kvm_unmap_hva_handler(struct kvm *kvm, gfn_t gfn, gfn_t gfn_end,
        return 1;
 }
 
-int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
-{
-       unsigned long end = hva + PAGE_SIZE;
-
-       handle_hva_to_gpa(kvm, hva, end, &kvm_unmap_hva_handler, NULL);
-
-       kvm_mips_callbacks->flush_shadow_all(kvm);
-       return 0;
-}
-
 int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end)
 {
        handle_hva_to_gpa(kvm, start, end, &kvm_unmap_hva_handler, NULL);
index 9ab1326f57c976f5643394dacc21075c534eb4d9..78ce4cff101271c2c1bd9582e0b278102fb9448e 100644 (file)
@@ -38,7 +38,7 @@ $(obj)/rom.bin: $(obj)/rom
 
 # Rule to make the bootloader
 $(obj)/rom: $(addprefix $(obj)/,$(OBJECTS))
-       $(LD) $(LDFLAGS) $(LDSCRIPT) -o $@ $^
+       $(LD) $(KBUILD_LDFLAGS) $(LDSCRIPT) -o $@ $^
 
 $(obj)/%.o: $(obj)/%.gz
        $(LD) -r -o $@ -b binary $<
index 111ad475aa0cdd111ebe362af928414d9499f666..4c2483f410c26b5b65ded652c1b0694b06a9bf92 100644 (file)
@@ -4,12 +4,12 @@
 #include "libgcc.h"
 
 /*
- * GCC 7 suboptimally generates __multi3 calls for mips64r6, so for that
- * specific case only we'll implement it here.
+ * GCC 7 & older can suboptimally generate __multi3 calls for mips64r6, so for
+ * that specific case only we implement that intrinsic here.
  *
  * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82981
  */
-#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPSR6) && (__GNUC__ == 7)
+#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPSR6) && (__GNUC__ < 8)
 
 /* multiply 64-bit values, low 64-bits returned */
 static inline long long notrace dmulu(long long a, long long b)
index a5427c6e97574c6a1a0dbad628f7a75a3feed516..00fef578c8cdcfbc1359e476255d81f5c6cd4363 100644 (file)
  * Copyright (C) 2012  Ralf Baechle <ralf@linux-mips.org>
  */
 #include <asm/asm.h>
+#include <asm/export.h>
 #include <asm/regdef.h>
 
 #define FASTPATH_SIZE  128
 
-EXPORT(tlbmiss_handler_setup_pgd_start)
 LEAF(tlbmiss_handler_setup_pgd)
 1:     j       1b              /* Dummy, will be replaced. */
        .space  64
 END(tlbmiss_handler_setup_pgd)
 EXPORT(tlbmiss_handler_setup_pgd_end)
+EXPORT_SYMBOL_GPL(tlbmiss_handler_setup_pgd)
 
 LEAF(handle_tlbm)
        .space          FASTPATH_SIZE * 4
index 49312a14cd1702e148c22d71c68384c41ef717de..06771429164317c3e8bfe5da8e02e33445fb0b14 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <asm/cacheflush.h>
 #include <asm/cpu-type.h>
+#include <asm/mmu_context.h>
 #include <asm/pgtable.h>
 #include <asm/war.h>
 #include <asm/uasm.h>
@@ -253,8 +254,10 @@ static void output_pgtable_bits_defines(void)
        pr_debug("\n");
 }
 
-static inline void dump_handler(const char *symbol, const u32 *handler, int count)
+static inline void dump_handler(const char *symbol, const void *start, const void *end)
 {
+       unsigned int count = (end - start) / sizeof(u32);
+       const u32 *handler = start;
        int i;
 
        pr_debug("LEAF(%s)\n", symbol);
@@ -402,12 +405,6 @@ static void build_restore_work_registers(u32 **p)
  * CONFIG_MIPS_PGD_C0_CONTEXT implies 64 bit and lack of pgd_current,
  * we cannot do r3000 under these circumstances.
  *
- * Declare pgd_current here instead of including mmu_context.h to avoid type
- * conflicts for tlbmiss_handler_setup_pgd
- */
-extern unsigned long pgd_current[];
-
-/*
  * The R3000 TLB handler is simple.
  */
 static void build_r3000_tlb_refill_handler(void)
@@ -444,8 +441,7 @@ static void build_r3000_tlb_refill_handler(void)
 
        memcpy((void *)ebase, tlb_handler, 0x80);
        local_flush_icache_range(ebase, ebase + 0x80);
-
-       dump_handler("r3000_tlb_refill", (u32 *)ebase, 32);
+       dump_handler("r3000_tlb_refill", (u32 *)ebase, (u32 *)(ebase + 0x80));
 }
 #endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
 
@@ -1465,8 +1461,7 @@ static void build_r4000_tlb_refill_handler(void)
 
        memcpy((void *)ebase, final_handler, 0x100);
        local_flush_icache_range(ebase, ebase + 0x100);
-
-       dump_handler("r4000_tlb_refill", (u32 *)ebase, 64);
+       dump_handler("r4000_tlb_refill", (u32 *)ebase, (u32 *)(ebase + 0x100));
 }
 
 static void setup_pw(void)
@@ -1568,31 +1563,21 @@ static void build_loongson3_tlb_refill_handler(void)
        uasm_resolve_relocs(relocs, labels);
        memcpy((void *)(ebase + 0x80), tlb_handler, 0x80);
        local_flush_icache_range(ebase + 0x80, ebase + 0x100);
-       dump_handler("loongson3_tlb_refill", (u32 *)(ebase + 0x80), 32);
+       dump_handler("loongson3_tlb_refill",
+                    (u32 *)(ebase + 0x80), (u32 *)(ebase + 0x100));
 }
 
-extern u32 handle_tlbl[], handle_tlbl_end[];
-extern u32 handle_tlbs[], handle_tlbs_end[];
-extern u32 handle_tlbm[], handle_tlbm_end[];
-extern u32 tlbmiss_handler_setup_pgd_start[];
-extern u32 tlbmiss_handler_setup_pgd[];
-EXPORT_SYMBOL_GPL(tlbmiss_handler_setup_pgd);
-extern u32 tlbmiss_handler_setup_pgd_end[];
-
 static void build_setup_pgd(void)
 {
        const int a0 = 4;
        const int __maybe_unused a1 = 5;
        const int __maybe_unused a2 = 6;
-       u32 *p = tlbmiss_handler_setup_pgd_start;
-       const int tlbmiss_handler_setup_pgd_size =
-               tlbmiss_handler_setup_pgd_end - tlbmiss_handler_setup_pgd_start;
+       u32 *p = (u32 *)msk_isa16_mode((ulong)tlbmiss_handler_setup_pgd);
 #ifndef CONFIG_MIPS_PGD_C0_CONTEXT
        long pgdc = (long)pgd_current;
 #endif
 
-       memset(tlbmiss_handler_setup_pgd, 0, tlbmiss_handler_setup_pgd_size *
-                                       sizeof(tlbmiss_handler_setup_pgd[0]));
+       memset(p, 0, tlbmiss_handler_setup_pgd_end - (char *)p);
        memset(labels, 0, sizeof(labels));
        memset(relocs, 0, sizeof(relocs));
        pgd_reg = allocate_kscratch();
@@ -1645,15 +1630,15 @@ static void build_setup_pgd(void)
        else
                uasm_i_nop(&p);
 #endif
-       if (p >= tlbmiss_handler_setup_pgd_end)
+       if (p >= (u32 *)tlbmiss_handler_setup_pgd_end)
                panic("tlbmiss_handler_setup_pgd space exceeded");
 
        uasm_resolve_relocs(relocs, labels);
        pr_debug("Wrote tlbmiss_handler_setup_pgd (%u instructions).\n",
-                (unsigned int)(p - tlbmiss_handler_setup_pgd));
+                (unsigned int)(p - (u32 *)tlbmiss_handler_setup_pgd));
 
        dump_handler("tlbmiss_handler", tlbmiss_handler_setup_pgd,
-                                       tlbmiss_handler_setup_pgd_size);
+                                       tlbmiss_handler_setup_pgd_end);
 }
 
 static void
@@ -1922,12 +1907,11 @@ build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte,
 
 static void build_r3000_tlb_load_handler(void)
 {
-       u32 *p = handle_tlbl;
-       const int handle_tlbl_size = handle_tlbl_end - handle_tlbl;
+       u32 *p = (u32 *)handle_tlbl;
        struct uasm_label *l = labels;
        struct uasm_reloc *r = relocs;
 
-       memset(handle_tlbl, 0, handle_tlbl_size * sizeof(handle_tlbl[0]));
+       memset(p, 0, handle_tlbl_end - (char *)p);
        memset(labels, 0, sizeof(labels));
        memset(relocs, 0, sizeof(relocs));
 
@@ -1941,24 +1925,23 @@ static void build_r3000_tlb_load_handler(void)
        uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
        uasm_i_nop(&p);
 
-       if (p >= handle_tlbl_end)
+       if (p >= (u32 *)handle_tlbl_end)
                panic("TLB load handler fastpath space exceeded");
 
        uasm_resolve_relocs(relocs, labels);
        pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
-                (unsigned int)(p - handle_tlbl));
+                (unsigned int)(p - (u32 *)handle_tlbl));
 
-       dump_handler("r3000_tlb_load", handle_tlbl, handle_tlbl_size);
+       dump_handler("r3000_tlb_load", handle_tlbl, handle_tlbl_end);
 }
 
 static void build_r3000_tlb_store_handler(void)
 {
-       u32 *p = handle_tlbs;
-       const int handle_tlbs_size = handle_tlbs_end - handle_tlbs;
+       u32 *p = (u32 *)handle_tlbs;
        struct uasm_label *l = labels;
        struct uasm_reloc *r = relocs;
 
-       memset(handle_tlbs, 0, handle_tlbs_size * sizeof(handle_tlbs[0]));
+       memset(p, 0, handle_tlbs_end - (char *)p);
        memset(labels, 0, sizeof(labels));
        memset(relocs, 0, sizeof(relocs));
 
@@ -1972,24 +1955,23 @@ static void build_r3000_tlb_store_handler(void)
        uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
        uasm_i_nop(&p);
 
-       if (p >= handle_tlbs_end)
+       if (p >= (u32 *)handle_tlbs_end)
                panic("TLB store handler fastpath space exceeded");
 
        uasm_resolve_relocs(relocs, labels);
        pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
-                (unsigned int)(p - handle_tlbs));
+                (unsigned int)(p - (u32 *)handle_tlbs));
 
-       dump_handler("r3000_tlb_store", handle_tlbs, handle_tlbs_size);
+       dump_handler("r3000_tlb_store", handle_tlbs, handle_tlbs_end);
 }
 
 static void build_r3000_tlb_modify_handler(void)
 {
-       u32 *p = handle_tlbm;
-       const int handle_tlbm_size = handle_tlbm_end - handle_tlbm;
+       u32 *p = (u32 *)handle_tlbm;
        struct uasm_label *l = labels;
        struct uasm_reloc *r = relocs;
 
-       memset(handle_tlbm, 0, handle_tlbm_size * sizeof(handle_tlbm[0]));
+       memset(p, 0, handle_tlbm_end - (char *)p);
        memset(labels, 0, sizeof(labels));
        memset(relocs, 0, sizeof(relocs));
 
@@ -2003,14 +1985,14 @@ static void build_r3000_tlb_modify_handler(void)
        uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
        uasm_i_nop(&p);
 
-       if (p >= handle_tlbm_end)
+       if (p >= (u32 *)handle_tlbm_end)
                panic("TLB modify handler fastpath space exceeded");
 
        uasm_resolve_relocs(relocs, labels);
        pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
-                (unsigned int)(p - handle_tlbm));
+                (unsigned int)(p - (u32 *)handle_tlbm));
 
-       dump_handler("r3000_tlb_modify", handle_tlbm, handle_tlbm_size);
+       dump_handler("r3000_tlb_modify", handle_tlbm, handle_tlbm_end);
 }
 #endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
 
@@ -2102,12 +2084,11 @@ build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l,
 static void build_r4000_tlb_load_handler(void)
 {
        u32 *p = (u32 *)msk_isa16_mode((ulong)handle_tlbl);
-       const int handle_tlbl_size = handle_tlbl_end - handle_tlbl;
        struct uasm_label *l = labels;
        struct uasm_reloc *r = relocs;
        struct work_registers wr;
 
-       memset(handle_tlbl, 0, handle_tlbl_size * sizeof(handle_tlbl[0]));
+       memset(p, 0, handle_tlbl_end - (char *)p);
        memset(labels, 0, sizeof(labels));
        memset(relocs, 0, sizeof(relocs));
 
@@ -2288,25 +2269,24 @@ static void build_r4000_tlb_load_handler(void)
        uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
        uasm_i_nop(&p);
 
-       if (p >= handle_tlbl_end)
+       if (p >= (u32 *)handle_tlbl_end)
                panic("TLB load handler fastpath space exceeded");
 
        uasm_resolve_relocs(relocs, labels);
        pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
-                (unsigned int)(p - handle_tlbl));
+                (unsigned int)(p - (u32 *)handle_tlbl));
 
-       dump_handler("r4000_tlb_load", handle_tlbl, handle_tlbl_size);
+       dump_handler("r4000_tlb_load", handle_tlbl, handle_tlbl_end);
 }
 
 static void build_r4000_tlb_store_handler(void)
 {
        u32 *p = (u32 *)msk_isa16_mode((ulong)handle_tlbs);
-       const int handle_tlbs_size = handle_tlbs_end - handle_tlbs;
        struct uasm_label *l = labels;
        struct uasm_reloc *r = relocs;
        struct work_registers wr;
 
-       memset(handle_tlbs, 0, handle_tlbs_size * sizeof(handle_tlbs[0]));
+       memset(p, 0, handle_tlbs_end - (char *)p);
        memset(labels, 0, sizeof(labels));
        memset(relocs, 0, sizeof(relocs));
 
@@ -2343,25 +2323,24 @@ static void build_r4000_tlb_store_handler(void)
        uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
        uasm_i_nop(&p);
 
-       if (p >= handle_tlbs_end)
+       if (p >= (u32 *)handle_tlbs_end)
                panic("TLB store handler fastpath space exceeded");
 
        uasm_resolve_relocs(relocs, labels);
        pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
-                (unsigned int)(p - handle_tlbs));
+                (unsigned int)(p - (u32 *)handle_tlbs));
 
-       dump_handler("r4000_tlb_store", handle_tlbs, handle_tlbs_size);
+       dump_handler("r4000_tlb_store", handle_tlbs, handle_tlbs_end);
 }
 
 static void build_r4000_tlb_modify_handler(void)
 {
        u32 *p = (u32 *)msk_isa16_mode((ulong)handle_tlbm);
-       const int handle_tlbm_size = handle_tlbm_end - handle_tlbm;
        struct uasm_label *l = labels;
        struct uasm_reloc *r = relocs;
        struct work_registers wr;
 
-       memset(handle_tlbm, 0, handle_tlbm_size * sizeof(handle_tlbm[0]));
+       memset(p, 0, handle_tlbm_end - (char *)p);
        memset(labels, 0, sizeof(labels));
        memset(relocs, 0, sizeof(relocs));
 
@@ -2399,14 +2378,14 @@ static void build_r4000_tlb_modify_handler(void)
        uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
        uasm_i_nop(&p);
 
-       if (p >= handle_tlbm_end)
+       if (p >= (u32 *)handle_tlbm_end)
                panic("TLB modify handler fastpath space exceeded");
 
        uasm_resolve_relocs(relocs, labels);
        pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
-                (unsigned int)(p - handle_tlbm));
+                (unsigned int)(p - (u32 *)handle_tlbm));
 
-       dump_handler("r4000_tlb_modify", handle_tlbm, handle_tlbm_size);
+       dump_handler("r4000_tlb_modify", handle_tlbm, handle_tlbm_end);
 }
 
 static void flush_tlb_handlers(void)
index 1d4248fa55e995fdc7cba95f9209372ed6533b52..7068f341133d7eb038bb94a9953a3b9946d9bf51 100644 (file)
@@ -40,6 +40,10 @@ config NDS32
        select NO_IOPORT_MAP
        select RTC_LIB
        select THREAD_INFO_IN_TASK
+       select HAVE_FUNCTION_TRACER
+       select HAVE_FUNCTION_GRAPH_TRACER
+       select HAVE_FTRACE_MCOUNT_RECORD
+       select HAVE_DYNAMIC_FTRACE
        help
          Andes(nds32) Linux support.
 
index 031c676821ff8797a879c6af56aeffd9ea4c4ed3..3509fac104919ff8d9727d4cdfe2185d10473746 100644 (file)
@@ -5,6 +5,10 @@ KBUILD_DEFCONFIG := defconfig
 
 comma = ,
 
+ifdef CONFIG_FUNCTION_TRACER
+arch-y += -malways-save-lp -mno-relax
+endif
+
 KBUILD_CFLAGS  += $(call cc-option, -mno-sched-prolog-epilog)
 KBUILD_CFLAGS  += -mcmodel=large
 
@@ -33,12 +37,12 @@ endif
 ifdef CONFIG_CPU_LITTLE_ENDIAN
 KBUILD_CFLAGS   += $(call cc-option, -EL)
 KBUILD_AFLAGS   += $(call cc-option, -EL)
-LDFLAGS         += $(call cc-option, -EL)
+KBUILD_LDFLAGS  += $(call cc-option, -EL)
 CHECKFLAGS      += -D__NDS32_EL__
 else
 KBUILD_CFLAGS   += $(call cc-option, -EB)
 KBUILD_AFLAGS   += $(call cc-option, -EB)
-LDFLAGS         += $(call cc-option, -EB)
+KBUILD_LDFLAGS  += $(call cc-option, -EB)
 CHECKFLAGS      += -D__NDS32_EB__
 endif
 
index 56c47905880256455a17943427651b0bb72e03ed..f5f9cf7e054401431f89b72af891c5a44b20baba 100644 (file)
@@ -121,9 +121,9 @@ struct elf32_hdr;
  */
 #define ELF_CLASS      ELFCLASS32
 #ifdef __NDS32_EB__
-#define ELF_DATA       ELFDATA2MSB;
+#define ELF_DATA       ELFDATA2MSB
 #else
-#define ELF_DATA       ELFDATA2LSB;
+#define ELF_DATA       ELFDATA2LSB
 #endif
 #define ELF_ARCH       EM_NDS32
 #define USE_ELF_CORE_DUMP
diff --git a/arch/nds32/include/asm/ftrace.h b/arch/nds32/include/asm/ftrace.h
new file mode 100644 (file)
index 0000000..2f96cc9
--- /dev/null
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASM_NDS32_FTRACE_H
+#define __ASM_NDS32_FTRACE_H
+
+#ifdef CONFIG_FUNCTION_TRACER
+
+#define HAVE_FUNCTION_GRAPH_FP_TEST
+
+#define MCOUNT_ADDR ((unsigned long)(_mcount))
+/* mcount call is composed of three instructions:
+ * sethi + ori + jral
+ */
+#define MCOUNT_INSN_SIZE 12
+
+extern void _mcount(unsigned long parent_ip);
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+
+#define FTRACE_ADDR ((unsigned long)_ftrace_caller)
+
+#ifdef __NDS32_EL__
+#define INSN_NOP               0x09000040
+#define INSN_SIZE(insn)                (((insn & 0x00000080) == 0) ? 4 : 2)
+#define IS_SETHI(insn)         ((insn & 0x000000fe) == 0x00000046)
+#define ENDIAN_CONVERT(insn)   be32_to_cpu(insn)
+#else /* __NDS32_EB__ */
+#define INSN_NOP               0x40000009
+#define INSN_SIZE(insn)                (((insn & 0x80000000) == 0) ? 4 : 2)
+#define IS_SETHI(insn)         ((insn & 0xfe000000) == 0x46000000)
+#define ENDIAN_CONVERT(insn)   (insn)
+#endif
+
+extern void _ftrace_caller(unsigned long parent_ip);
+static inline unsigned long ftrace_call_adjust(unsigned long addr)
+{
+       return addr;
+}
+struct dyn_arch_ftrace {
+};
+
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#endif /* CONFIG_FUNCTION_TRACER */
+
+#endif /* __ASM_NDS32_FTRACE_H */
index 19b19394a936cfdecaa51dba9159ee03473b76e7..68c38151c3e41c24c24081f92449a097bf077f02 100644 (file)
@@ -17,6 +17,7 @@
 #else
 #define FP_OFFSET (-2)
 #endif
+#define LP_OFFSET (-1)
 
 extern void __init early_trap_init(void);
 static inline void GIE_ENABLE(void)
index 18a009f3804d5e94ac23bd67b6eb4144ffa2c614..362a32d9bd16871e1db6c45d544eb2c4450bfeb5 100644 (file)
@@ -38,7 +38,7 @@ struct exception_table_entry {
 extern int fixup_exception(struct pt_regs *regs);
 
 #define KERNEL_DS      ((mm_segment_t) { ~0UL })
-#define USER_DS        ((mm_segment_t) {TASK_SIZE - 1})
+#define USER_DS                ((mm_segment_t) {TASK_SIZE - 1})
 
 #define get_ds()       (KERNEL_DS)
 #define get_fs()       (current_thread_info()->addr_limit)
@@ -49,11 +49,11 @@ static inline void set_fs(mm_segment_t fs)
        current_thread_info()->addr_limit = fs;
 }
 
-#define segment_eq(a, b)    ((a) == (b))
+#define segment_eq(a, b)       ((a) == (b))
 
 #define __range_ok(addr, size) (size <= get_fs() && addr <= (get_fs() -size))
 
-#define access_ok(type, addr, size)                 \
+#define access_ok(type, addr, size)    \
        __range_ok((unsigned long)addr, (unsigned long)size)
 /*
  * Single-value transfer routines.  They automatically use the right
@@ -75,70 +75,73 @@ static inline void set_fs(mm_segment_t fs)
  * versions are void (ie, don't return a value as such).
  */
 
-#define get_user(x,p)                                                  \
-({                                                                     \
-       long __e = -EFAULT;                                             \
-       if(likely(access_ok(VERIFY_READ,  p, sizeof(*p)))) {            \
-               __e = __get_user(x,p);                                  \
-       } else                                                          \
-               x = 0;                                                  \
-       __e;                                                            \
-})
-#define __get_user(x,ptr)                                              \
+#define get_user       __get_user                                      \
+
+#define __get_user(x, ptr)                                             \
 ({                                                                     \
        long __gu_err = 0;                                              \
-       __get_user_err((x),(ptr),__gu_err);                             \
+       __get_user_check((x), (ptr), __gu_err);                         \
        __gu_err;                                                       \
 })
 
-#define __get_user_error(x,ptr,err)                                    \
+#define __get_user_error(x, ptr, err)                                  \
 ({                                                                     \
-       __get_user_err((x),(ptr),err);                                  \
-       (void) 0;                                                       \
+       __get_user_check((x), (ptr), (err));                            \
+       (void)0;                                                        \
 })
 
-#define __get_user_err(x,ptr,err)                                      \
+#define __get_user_check(x, ptr, err)                                  \
+({                                                                     \
+       const __typeof__(*(ptr)) __user *__p = (ptr);                   \
+       might_fault();                                                  \
+       if (access_ok(VERIFY_READ, __p, sizeof(*__p))) {                \
+               __get_user_err((x), __p, (err));                        \
+       } else {                                                        \
+               (x) = 0; (err) = -EFAULT;                               \
+       }                                                               \
+})
+
+#define __get_user_err(x, ptr, err)                                    \
 do {                                                                   \
-       unsigned long __gu_addr = (unsigned long)(ptr);                 \
        unsigned long __gu_val;                                         \
        __chk_user_ptr(ptr);                                            \
        switch (sizeof(*(ptr))) {                                       \
        case 1:                                                         \
-               __get_user_asm("lbi",__gu_val,__gu_addr,err);           \
+               __get_user_asm("lbi", __gu_val, (ptr), (err));          \
                break;                                                  \
        case 2:                                                         \
-               __get_user_asm("lhi",__gu_val,__gu_addr,err);           \
+               __get_user_asm("lhi", __gu_val, (ptr), (err));          \
                break;                                                  \
        case 4:                                                         \
-               __get_user_asm("lwi",__gu_val,__gu_addr,err);           \
+               __get_user_asm("lwi", __gu_val, (ptr), (err));          \
                break;                                                  \
        case 8:                                                         \
-               __get_user_asm_dword(__gu_val,__gu_addr,err);           \
+               __get_user_asm_dword(__gu_val, (ptr), (err));           \
                break;                                                  \
        default:                                                        \
                BUILD_BUG();                                            \
                break;                                                  \
        }                                                               \
-       (x) = (__typeof__(*(ptr)))__gu_val;                             \
+       (x) = (__force __typeof__(*(ptr)))__gu_val;                     \
 } while (0)
 
-#define __get_user_asm(inst,x,addr,err)                                        \
-       asm volatile(                                                   \
-       "1:     "inst"  %1,[%2]\n"                                      \
-       "2:\n"                                                          \
-       "       .section .fixup,\"ax\"\n"                               \
-       "       .align  2\n"                                            \
-       "3:     move %0, %3\n"                                          \
-       "       move %1, #0\n"                                          \
-       "       b       2b\n"                                           \
-       "       .previous\n"                                            \
-       "       .section __ex_table,\"a\"\n"                            \
-       "       .align  3\n"                                            \
-       "       .long   1b, 3b\n"                                       \
-       "       .previous"                                              \
-       : "+r" (err), "=&r" (x)                                         \
-       : "r" (addr), "i" (-EFAULT)                                     \
-       : "cc")
+#define __get_user_asm(inst, x, addr, err)                             \
+       __asm__ __volatile__ (                                          \
+               "1:     "inst"  %1,[%2]\n"                              \
+               "2:\n"                                                  \
+               "       .section .fixup,\"ax\"\n"                       \
+               "       .align  2\n"                                    \
+               "3:     move %0, %3\n"                                  \
+               "       move %1, #0\n"                                  \
+               "       b       2b\n"                                   \
+               "       .previous\n"                                    \
+               "       .section __ex_table,\"a\"\n"                    \
+               "       .align  3\n"                                    \
+               "       .long   1b, 3b\n"                               \
+               "       .previous"                                      \
+               : "+r" (err), "=&r" (x)                                 \
+               : "r" (addr), "i" (-EFAULT)                             \
+               : "cc")
 
 #ifdef __NDS32_EB__
 #define __gu_reg_oper0 "%H1"
@@ -149,61 +152,66 @@ do {                                                                      \
 #endif
 
 #define __get_user_asm_dword(x, addr, err)                             \
-       asm volatile(                                                   \
-       "\n1:\tlwi " __gu_reg_oper0 ",[%2]\n"                           \
-       "\n2:\tlwi " __gu_reg_oper1 ",[%2+4]\n"                         \
-       "3:\n"                                                          \
-       "       .section .fixup,\"ax\"\n"                               \
-       "       .align  2\n"                                            \
-       "4:     move    %0, %3\n"                                       \
-       "       b       3b\n"                                           \
-       "       .previous\n"                                            \
-       "       .section __ex_table,\"a\"\n"                            \
-       "       .align  3\n"                                            \
-       "       .long   1b, 4b\n"                                       \
-       "       .long   2b, 4b\n"                                       \
-       "       .previous"                                              \
-       : "+r"(err), "=&r"(x)                                           \
-       : "r"(addr), "i"(-EFAULT)                                       \
-       : "cc")
-#define put_user(x,p)                                                  \
-({                                                                     \
-       long __e = -EFAULT;                                             \
-       if(likely(access_ok(VERIFY_WRITE,  p, sizeof(*p)))) {           \
-               __e = __put_user(x,p);                                  \
-       }                                                               \
-       __e;                                                            \
-})
-#define __put_user(x,ptr)                                              \
+       __asm__ __volatile__ (                                          \
+               "\n1:\tlwi " __gu_reg_oper0 ",[%2]\n"                   \
+               "\n2:\tlwi " __gu_reg_oper1 ",[%2+4]\n"                 \
+               "3:\n"                                                  \
+               "       .section .fixup,\"ax\"\n"                       \
+               "       .align  2\n"                                    \
+               "4:     move    %0, %3\n"                               \
+               "       b       3b\n"                                   \
+               "       .previous\n"                                    \
+               "       .section __ex_table,\"a\"\n"                    \
+               "       .align  3\n"                                    \
+               "       .long   1b, 4b\n"                               \
+               "       .long   2b, 4b\n"                               \
+               "       .previous"                                      \
+               : "+r"(err), "=&r"(x)                                   \
+               : "r"(addr), "i"(-EFAULT)                               \
+               : "cc")
+
+#define put_user       __put_user                                      \
+
+#define __put_user(x, ptr)                                             \
 ({                                                                     \
        long __pu_err = 0;                                              \
-       __put_user_err((x),(ptr),__pu_err);                             \
+       __put_user_err((x), (ptr), __pu_err);                           \
        __pu_err;                                                       \
 })
 
-#define __put_user_error(x,ptr,err)                                    \
+#define __put_user_error(x, ptr, err)                                  \
+({                                                                     \
+       __put_user_err((x), (ptr), (err));                              \
+       (void)0;                                                        \
+})
+
+#define __put_user_check(x, ptr, err)                                  \
 ({                                                                     \
-       __put_user_err((x),(ptr),err);                                  \
-       (void) 0;                                                       \
+       __typeof__(*(ptr)) __user *__p = (ptr);                         \
+       might_fault();                                                  \
+       if (access_ok(VERIFY_WRITE, __p, sizeof(*__p))) {               \
+               __put_user_err((x), __p, (err));                        \
+       } else  {                                                       \
+               (err) = -EFAULT;                                        \
+       }                                                               \
 })
 
-#define __put_user_err(x,ptr,err)                                      \
+#define __put_user_err(x, ptr, err)                                    \
 do {                                                                   \
-       unsigned long __pu_addr = (unsigned long)(ptr);                 \
        __typeof__(*(ptr)) __pu_val = (x);                              \
        __chk_user_ptr(ptr);                                            \
        switch (sizeof(*(ptr))) {                                       \
        case 1:                                                         \
-               __put_user_asm("sbi",__pu_val,__pu_addr,err);           \
+               __put_user_asm("sbi", __pu_val, (ptr), (err));          \
                break;                                                  \
        case 2:                                                         \
-               __put_user_asm("shi",__pu_val,__pu_addr,err);           \
+               __put_user_asm("shi", __pu_val, (ptr), (err));          \
                break;                                                  \
        case 4:                                                         \
-               __put_user_asm("swi",__pu_val,__pu_addr,err);           \
+               __put_user_asm("swi", __pu_val, (ptr), (err));          \
                break;                                                  \
        case 8:                                                         \
-               __put_user_asm_dword(__pu_val,__pu_addr,err);           \
+               __put_user_asm_dword(__pu_val, (ptr), (err));           \
                break;                                                  \
        default:                                                        \
                BUILD_BUG();                                            \
@@ -211,22 +219,22 @@ do {                                                                      \
        }                                                               \
 } while (0)
 
-#define __put_user_asm(inst,x,addr,err)                                        \
-       asm volatile(                                                   \
-       "1:     "inst"  %1,[%2]\n"                                      \
-       "2:\n"                                                          \
-       "       .section .fixup,\"ax\"\n"                               \
-       "       .align  2\n"                                            \
-       "3:     move    %0, %3\n"                                       \
-       "       b       2b\n"                                           \
-       "       .previous\n"                                            \
-       "       .section __ex_table,\"a\"\n"                            \
-       "       .align  3\n"                                            \
-       "       .long   1b, 3b\n"                                       \
-       "       .previous"                                              \
-       : "+r" (err)                                                    \
-       : "r" (x), "r" (addr), "i" (-EFAULT)                            \
-       : "cc")
+#define __put_user_asm(inst, x, addr, err)                             \
+       __asm__ __volatile__ (                                          \
+               "1:     "inst"  %1,[%2]\n"                              \
+               "2:\n"                                                  \
+               "       .section .fixup,\"ax\"\n"                       \
+               "       .align  2\n"                                    \
+               "3:     move    %0, %3\n"                               \
+               "       b       2b\n"                                   \
+               "       .previous\n"                                    \
+               "       .section __ex_table,\"a\"\n"                    \
+               "       .align  3\n"                                    \
+               "       .long   1b, 3b\n"                               \
+               "       .previous"                                      \
+               : "+r" (err)                                            \
+               : "r" (x), "r" (addr), "i" (-EFAULT)                    \
+               : "cc")
 
 #ifdef __NDS32_EB__
 #define __pu_reg_oper0 "%H2"
@@ -237,23 +245,24 @@ do {                                                                      \
 #endif
 
 #define __put_user_asm_dword(x, addr, err)                             \
-       asm volatile(                                                   \
-       "\n1:\tswi " __pu_reg_oper0 ",[%1]\n"                           \
-       "\n2:\tswi " __pu_reg_oper1 ",[%1+4]\n"                         \
-       "3:\n"                                                          \
-       "       .section .fixup,\"ax\"\n"                               \
-       "       .align  2\n"                                            \
-       "4:     move    %0, %3\n"                                       \
-       "       b       3b\n"                                           \
-       "       .previous\n"                                            \
-       "       .section __ex_table,\"a\"\n"                            \
-       "       .align  3\n"                                            \
-       "       .long   1b, 4b\n"                                       \
-       "       .long   2b, 4b\n"                                       \
-       "       .previous"                                              \
-       : "+r"(err)                                                     \
-       : "r"(addr), "r"(x), "i"(-EFAULT)                               \
-       : "cc")
+       __asm__ __volatile__ (                                          \
+               "\n1:\tswi " __pu_reg_oper0 ",[%1]\n"                   \
+               "\n2:\tswi " __pu_reg_oper1 ",[%1+4]\n"                 \
+               "3:\n"                                                  \
+               "       .section .fixup,\"ax\"\n"                       \
+               "       .align  2\n"                                    \
+               "4:     move    %0, %3\n"                               \
+               "       b       3b\n"                                   \
+               "       .previous\n"                                    \
+               "       .section __ex_table,\"a\"\n"                    \
+               "       .align  3\n"                                    \
+               "       .long   1b, 4b\n"                               \
+               "       .long   2b, 4b\n"                               \
+               "       .previous"                                      \
+               : "+r"(err)                                             \
+               : "r"(addr), "r"(x), "i"(-EFAULT)                       \
+               : "cc")
+
 extern unsigned long __arch_clear_user(void __user * addr, unsigned long n);
 extern long strncpy_from_user(char *dest, const char __user * src, long count);
 extern __must_check long strlen_user(const char __user * str);
index 42792743e8b953290b7cec0b4722684c72744df3..27cded39fa66266171a427afc988ad9db35fe75e 100644 (file)
@@ -21,3 +21,9 @@ extra-y := head.o vmlinux.lds
 
 
 obj-y                          += vdso/
+
+obj-$(CONFIG_FUNCTION_TRACER)   += ftrace.o
+
+ifdef CONFIG_FUNCTION_TRACER
+CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE)
+endif
index 0c6d031a1c4a9df00dc991c0f52dbdd7bddab51c..0c5386e72098e45f48b925efee3431bb275a1398 100644 (file)
@@ -9,7 +9,8 @@
 
 void __iomem *atl2c_base;
 static const struct of_device_id atl2c_ids[] __initconst = {
-       {.compatible = "andestech,atl2c",}
+       {.compatible = "andestech,atl2c",},
+       {}
 };
 
 static int __init atl2c_of_init(void)
index b8ae4e9a6b93db793d0b6b7d434adcdb47827743..21a144071566989af1daa55400a0c9fab98b34ee 100644 (file)
@@ -118,7 +118,7 @@ common_exception_handler:
        /* interrupt */
 2:
 #ifdef CONFIG_TRACE_IRQFLAGS
-       jal     trace_hardirqs_off
+       jal     __trace_hardirqs_off
 #endif
        move    $r0, $sp
        sethi   $lp, hi20(ret_from_intr)
index 03e4f7788a1882a15cf89e68aa325978cbc3b0ce..f00af92f7e22fde904fc6e54999a9ebcdde7e950 100644 (file)
@@ -138,8 +138,8 @@ no_work_pending:
 #ifdef CONFIG_TRACE_IRQFLAGS
        lwi     $p0, [$sp+(#IPSW_OFFSET)]
        andi    $p0, $p0, #0x1
-       la      $r10, trace_hardirqs_off
-       la      $r9, trace_hardirqs_on
+       la      $r10, __trace_hardirqs_off
+       la      $r9, __trace_hardirqs_on
        cmovz   $r9, $p0, $r10
        jral    $r9
 #endif
diff --git a/arch/nds32/kernel/ftrace.c b/arch/nds32/kernel/ftrace.c
new file mode 100644 (file)
index 0000000..a0a9679
--- /dev/null
@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/ftrace.h>
+#include <linux/uaccess.h>
+#include <asm/cacheflush.h>
+
+#ifndef CONFIG_DYNAMIC_FTRACE
+extern void (*ftrace_trace_function)(unsigned long, unsigned long,
+                                    struct ftrace_ops*, struct pt_regs*);
+extern int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace);
+extern void ftrace_graph_caller(void);
+
+noinline void __naked ftrace_stub(unsigned long ip, unsigned long parent_ip,
+                                 struct ftrace_ops *op, struct pt_regs *regs)
+{
+       __asm__ ("");  /* avoid to optimize as pure function */
+}
+
+noinline void _mcount(unsigned long parent_ip)
+{
+       /* save all state by the compiler prologue */
+
+       unsigned long ip = (unsigned long)__builtin_return_address(0);
+
+       if (ftrace_trace_function != ftrace_stub)
+               ftrace_trace_function(ip - MCOUNT_INSN_SIZE, parent_ip,
+                                     NULL, NULL);
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       if (ftrace_graph_return != (trace_func_graph_ret_t)ftrace_stub
+           || ftrace_graph_entry != ftrace_graph_entry_stub)
+               ftrace_graph_caller();
+#endif
+
+       /* restore all state by the compiler epilogue */
+}
+EXPORT_SYMBOL(_mcount);
+
+#else /* CONFIG_DYNAMIC_FTRACE */
+
+noinline void __naked ftrace_stub(unsigned long ip, unsigned long parent_ip,
+                                 struct ftrace_ops *op, struct pt_regs *regs)
+{
+       __asm__ ("");  /* avoid to optimize as pure function */
+}
+
+noinline void __naked _mcount(unsigned long parent_ip)
+{
+       __asm__ ("");  /* avoid to optimize as pure function */
+}
+EXPORT_SYMBOL(_mcount);
+
+#define XSTR(s) STR(s)
+#define STR(s) #s
+void _ftrace_caller(unsigned long parent_ip)
+{
+       /* save all state needed by the compiler prologue */
+
+       /*
+        * prepare arguments for real tracing function
+        * first  arg : __builtin_return_address(0) - MCOUNT_INSN_SIZE
+        * second arg : parent_ip
+        */
+       __asm__ __volatile__ (
+               "move $r1, %0                              \n\t"
+               "addi $r0, %1, #-" XSTR(MCOUNT_INSN_SIZE) "\n\t"
+               :
+               : "r" (parent_ip), "r" (__builtin_return_address(0)));
+
+       /* a placeholder for the call to a real tracing function */
+       __asm__ __volatile__ (
+               "ftrace_call:           \n\t"
+               "nop                    \n\t"
+               "nop                    \n\t"
+               "nop                    \n\t");
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       /* a placeholder for the call to ftrace_graph_caller */
+       __asm__ __volatile__ (
+               "ftrace_graph_call:     \n\t"
+               "nop                    \n\t"
+               "nop                    \n\t"
+               "nop                    \n\t");
+#endif
+       /* restore all state needed by the compiler epilogue */
+}
+
+int __init ftrace_dyn_arch_init(void)
+{
+       return 0;
+}
+
+int ftrace_arch_code_modify_prepare(void)
+{
+       set_all_modules_text_rw();
+       return 0;
+}
+
+int ftrace_arch_code_modify_post_process(void)
+{
+       set_all_modules_text_ro();
+       return 0;
+}
+
+static unsigned long gen_sethi_insn(unsigned long addr)
+{
+       unsigned long opcode = 0x46000000;
+       unsigned long imm = addr >> 12;
+       unsigned long rt_num = 0xf << 20;
+
+       return ENDIAN_CONVERT(opcode | rt_num | imm);
+}
+
+static unsigned long gen_ori_insn(unsigned long addr)
+{
+       unsigned long opcode = 0x58000000;
+       unsigned long imm = addr & 0x0000fff;
+       unsigned long rt_num = 0xf << 20;
+       unsigned long ra_num = 0xf << 15;
+
+       return ENDIAN_CONVERT(opcode | rt_num | ra_num | imm);
+}
+
+static unsigned long gen_jral_insn(unsigned long addr)
+{
+       unsigned long opcode = 0x4a000001;
+       unsigned long rt_num = 0x1e << 20;
+       unsigned long rb_num = 0xf << 10;
+
+       return ENDIAN_CONVERT(opcode | rt_num | rb_num);
+}
+
+static void ftrace_gen_call_insn(unsigned long *call_insns,
+                                unsigned long addr)
+{
+       call_insns[0] = gen_sethi_insn(addr); /* sethi $r15, imm20u       */
+       call_insns[1] = gen_ori_insn(addr);   /* ori   $r15, $r15, imm15u */
+       call_insns[2] = gen_jral_insn(addr);  /* jral  $lp,  $r15         */
+}
+
+static int __ftrace_modify_code(unsigned long pc, unsigned long *old_insn,
+                               unsigned long *new_insn, bool validate)
+{
+       unsigned long orig_insn[3];
+
+       if (validate) {
+               if (probe_kernel_read(orig_insn, (void *)pc, MCOUNT_INSN_SIZE))
+                       return -EFAULT;
+               if (memcmp(orig_insn, old_insn, MCOUNT_INSN_SIZE))
+                       return -EINVAL;
+       }
+
+       if (probe_kernel_write((void *)pc, new_insn, MCOUNT_INSN_SIZE))
+               return -EPERM;
+
+       return 0;
+}
+
+static int ftrace_modify_code(unsigned long pc, unsigned long *old_insn,
+                             unsigned long *new_insn, bool validate)
+{
+       int ret;
+
+       ret = __ftrace_modify_code(pc, old_insn, new_insn, validate);
+       if (ret)
+               return ret;
+
+       flush_icache_range(pc, pc + MCOUNT_INSN_SIZE);
+
+       return ret;
+}
+
+int ftrace_update_ftrace_func(ftrace_func_t func)
+{
+       unsigned long pc = (unsigned long)&ftrace_call;
+       unsigned long old_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP};
+       unsigned long new_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP};
+
+       if (func != ftrace_stub)
+               ftrace_gen_call_insn(new_insn, (unsigned long)func);
+
+       return ftrace_modify_code(pc, old_insn, new_insn, false);
+}
+
+int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+{
+       unsigned long pc = rec->ip;
+       unsigned long nop_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP};
+       unsigned long call_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP};
+
+       ftrace_gen_call_insn(call_insn, addr);
+
+       return ftrace_modify_code(pc, nop_insn, call_insn, true);
+}
+
+int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
+                   unsigned long addr)
+{
+       unsigned long pc = rec->ip;
+       unsigned long nop_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP};
+       unsigned long call_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP};
+
+       ftrace_gen_call_insn(call_insn, addr);
+
+       return ftrace_modify_code(pc, call_insn, nop_insn, true);
+}
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
+                          unsigned long frame_pointer)
+{
+       unsigned long return_hooker = (unsigned long)&return_to_handler;
+       struct ftrace_graph_ent trace;
+       unsigned long old;
+       int err;
+
+       if (unlikely(atomic_read(&current->tracing_graph_pause)))
+               return;
+
+       old = *parent;
+
+       trace.func = self_addr;
+       trace.depth = current->curr_ret_stack + 1;
+
+       /* Only trace if the calling function expects to */
+       if (!ftrace_graph_entry(&trace))
+               return;
+
+       err = ftrace_push_return_trace(old, self_addr, &trace.depth,
+                                      frame_pointer, NULL);
+
+       if (err == -EBUSY)
+               return;
+
+       *parent = return_hooker;
+}
+
+noinline void ftrace_graph_caller(void)
+{
+       unsigned long *parent_ip =
+               (unsigned long *)(__builtin_frame_address(2) - 4);
+
+       unsigned long selfpc =
+               (unsigned long)(__builtin_return_address(1) - MCOUNT_INSN_SIZE);
+
+       unsigned long frame_pointer =
+               (unsigned long)__builtin_frame_address(3);
+
+       prepare_ftrace_return(parent_ip, selfpc, frame_pointer);
+}
+
+extern unsigned long ftrace_return_to_handler(unsigned long frame_pointer);
+void __naked return_to_handler(void)
+{
+       __asm__ __volatile__ (
+               /* save state needed by the ABI     */
+               "smw.adm $r0,[$sp],$r1,#0x0  \n\t"
+
+               /* get original return address      */
+               "move $r0, $fp               \n\t"
+               "bal ftrace_return_to_handler\n\t"
+               "move $lp, $r0               \n\t"
+
+               /* restore state nedded by the ABI  */
+               "lmw.bim $r0,[$sp],$r1,#0x0  \n\t");
+}
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+extern unsigned long ftrace_graph_call;
+
+static int ftrace_modify_graph_caller(bool enable)
+{
+       unsigned long pc = (unsigned long)&ftrace_graph_call;
+       unsigned long nop_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP};
+       unsigned long call_insn[3] = {INSN_NOP, INSN_NOP, INSN_NOP};
+
+       ftrace_gen_call_insn(call_insn, (unsigned long)ftrace_graph_caller);
+
+       if (enable)
+               return ftrace_modify_code(pc, nop_insn, call_insn, true);
+       else
+               return ftrace_modify_code(pc, call_insn, nop_insn, true);
+}
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+       return ftrace_modify_graph_caller(true);
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+       return ftrace_modify_graph_caller(false);
+}
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+noinline void __trace_hardirqs_off(void)
+{
+       trace_hardirqs_off();
+}
+noinline void __trace_hardirqs_on(void)
+{
+       trace_hardirqs_on();
+}
+#endif /* CONFIG_TRACE_IRQFLAGS */
index 4167283d8293f16c65e5f1b100a40201265a1c26..1e31829cbc2a71ec4dd3c6be62874245cda010c2 100644 (file)
@@ -40,7 +40,7 @@ void do_reloc16(unsigned int val, unsigned int *loc, unsigned int val_mask,
 
        tmp2 = tmp & loc_mask;
        if (partial_in_place) {
-               tmp &= (!loc_mask);
+               tmp &= (~loc_mask);
                tmp =
                    tmp2 | ((tmp + ((val & val_mask) >> val_shift)) & val_mask);
        } else {
@@ -70,7 +70,7 @@ void do_reloc32(unsigned int val, unsigned int *loc, unsigned int val_mask,
 
        tmp2 = tmp & loc_mask;
        if (partial_in_place) {
-               tmp &= (!loc_mask);
+               tmp &= (~loc_mask);
                tmp =
                    tmp2 | ((tmp + ((val & val_mask) >> val_shift)) & val_mask);
        } else {
index 8b231e910ea68980dbd517be895200ad19e49f55..d974c0c1c65f34123af8c7d2a63e2fb3e390e9f9 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/sched/debug.h>
 #include <linux/sched/task_stack.h>
 #include <linux/stacktrace.h>
+#include <linux/ftrace.h>
 
 void save_stack_trace(struct stack_trace *trace)
 {
@@ -16,6 +17,7 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
        unsigned long *fpn;
        int skip = trace->skip;
        int savesched;
+       int graph_idx = 0;
 
        if (tsk == current) {
                __asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(fpn));
@@ -29,10 +31,12 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
               && (fpn >= (unsigned long *)TASK_SIZE)) {
                unsigned long lpp, fpp;
 
-               lpp = fpn[-1];
+               lpp = fpn[LP_OFFSET];
                fpp = fpn[FP_OFFSET];
                if (!__kernel_text_address(lpp))
                        break;
+               else
+                       lpp = ftrace_graph_ret_addr(tsk, &graph_idx, lpp, NULL);
 
                if (savesched || !in_sched_functions(lpp)) {
                        if (skip) {
index a6205fd4db521eaf83c606d399975a4fe275c250..1496aab48998817c00cb175dbd8b09b3453d73dd 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/kdebug.h>
 #include <linux/sched/task_stack.h>
 #include <linux/uaccess.h>
+#include <linux/ftrace.h>
 
 #include <asm/proc-fns.h>
 #include <asm/unistd.h>
@@ -94,28 +95,6 @@ static void dump_instr(struct pt_regs *regs)
        set_fs(fs);
 }
 
-#ifdef CONFIG_FUNCTION_GRAPH_TRACER
-#include <linux/ftrace.h>
-static void
-get_real_ret_addr(unsigned long *addr, struct task_struct *tsk, int *graph)
-{
-       if (*addr == (unsigned long)return_to_handler) {
-               int index = tsk->curr_ret_stack;
-
-               if (tsk->ret_stack && index >= *graph) {
-                       index -= *graph;
-                       *addr = tsk->ret_stack[index].ret;
-                       (*graph)++;
-               }
-       }
-}
-#else
-static inline void
-get_real_ret_addr(unsigned long *addr, struct task_struct *tsk, int *graph)
-{
-}
-#endif
-
 #define LOOP_TIMES (100)
 static void __dump(struct task_struct *tsk, unsigned long *base_reg)
 {
@@ -126,7 +105,8 @@ static void __dump(struct task_struct *tsk, unsigned long *base_reg)
                while (!kstack_end(base_reg)) {
                        ret_addr = *base_reg++;
                        if (__kernel_text_address(ret_addr)) {
-                               get_real_ret_addr(&ret_addr, tsk, &graph);
+                               ret_addr = ftrace_graph_ret_addr(
+                                               tsk, &graph, ret_addr, NULL);
                                print_ip_sym(ret_addr);
                        }
                        if (--cnt < 0)
@@ -137,15 +117,12 @@ static void __dump(struct task_struct *tsk, unsigned long *base_reg)
                       !((unsigned long)base_reg & 0x3) &&
                       ((unsigned long)base_reg >= TASK_SIZE)) {
                        unsigned long next_fp;
-#if !defined(NDS32_ABI_2)
-                       ret_addr = base_reg[0];
-                       next_fp = base_reg[1];
-#else
-                       ret_addr = base_reg[-1];
+                       ret_addr = base_reg[LP_OFFSET];
                        next_fp = base_reg[FP_OFFSET];
-#endif
                        if (__kernel_text_address(ret_addr)) {
-                               get_real_ret_addr(&ret_addr, tsk, &graph);
+
+                               ret_addr = ftrace_graph_ret_addr(
+                                               tsk, &graph, ret_addr, NULL);
                                print_ip_sym(ret_addr);
                        }
                        if (--cnt < 0)
@@ -196,11 +173,10 @@ void die(const char *str, struct pt_regs *regs, int err)
        pr_emerg("CPU: %i\n", smp_processor_id());
        show_regs(regs);
        pr_emerg("Process %s (pid: %d, stack limit = 0x%p)\n",
-                tsk->comm, tsk->pid, task_thread_info(tsk) + 1);
+                tsk->comm, tsk->pid, end_of_stack(tsk));
 
        if (!user_mode(regs) || in_interrupt()) {
-               dump_mem("Stack: ", regs->sp,
-                        THREAD_SIZE + (unsigned long)task_thread_info(tsk));
+               dump_mem("Stack: ", regs->sp, (regs->sp + PAGE_SIZE) & PAGE_MASK);
                dump_instr(regs);
                dump_stack();
        }
index 288313b886efa269fb0e13eb9231d50879e72947..9e90f30a181d7d9c9b06dc04d230c02bfde67b78 100644 (file)
@@ -13,14 +13,26 @@ OUTPUT_ARCH(nds32)
 ENTRY(_stext_lma)
 jiffies = jiffies_64;
 
+#if defined(CONFIG_GCOV_KERNEL)
+#define NDS32_EXIT_KEEP(x)     x
+#else
+#define NDS32_EXIT_KEEP(x)
+#endif
+
 SECTIONS
 {
        _stext_lma = TEXTADDR - LOAD_OFFSET;
        . = TEXTADDR;
        __init_begin = .;
        HEAD_TEXT_SECTION
+       .exit.text : {
+               NDS32_EXIT_KEEP(EXIT_TEXT)
+       }
        INIT_TEXT_SECTION(PAGE_SIZE)
        INIT_DATA_SECTION(16)
+       .exit.data : {
+               NDS32_EXIT_KEEP(EXIT_DATA)
+       }
        PERCPU_SECTION(L1_CACHE_BYTES)
        __init_end = .;
 
index 7a49f0d28d14c106ea9300c8e54ad18aa6471e0b..f1da8a7b17ff49b4965f4f5d9e647b9e1d1e258d 100644 (file)
@@ -3,15 +3,6 @@
 config TRACE_IRQFLAGS_SUPPORT
        def_bool y
 
-config DEBUG_STACK_USAGE
-       bool "Enable stack utilization instrumentation"
-       depends on DEBUG_KERNEL
-       help
-         Enables the display of the minimum amount of free stack which each
-         task has ever had available in the sysrq-T and sysrq-P debug output.
-
-         This option will slow down process creation somewhat.
-
 config EARLY_PRINTK
        bool "Activate early kernel debugging"
        default y
index ed5f32d8fbd8a92fb41a22acf3d12ec172cdc64e..e0081e7348271d212b56ea5e28680d4e07ce59cb 100644 (file)
@@ -6,6 +6,8 @@
 
 config OPENRISC
        def_bool y
+       select ARCH_HAS_SYNC_DMA_FOR_DEVICE
+       select DMA_NONCOHERENT_OPS
        select OF
        select OF_EARLY_FLATTREE
        select IRQ_DOMAIN
index 65964d390b10c79ba12805005b90ef311b925d18..eb87cd8327c89e9b7941617d3df3927c1a2d9da8 100644 (file)
@@ -7,6 +7,7 @@ generic-y += current.h
 generic-y += device.h
 generic-y += div64.h
 generic-y += dma.h
+generic-y += dma-mapping.h
 generic-y += emergency-restart.h
 generic-y += exec.h
 generic-y += extable.h
diff --git a/arch/openrisc/include/asm/dma-mapping.h b/arch/openrisc/include/asm/dma-mapping.h
deleted file mode 100644 (file)
index e212a1f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * OpenRISC Linux
- *
- * Linux architectural port borrowing liberally from similar works of
- * others.  All original copyrights apply as per the original source
- * declaration.
- *
- * OpenRISC implementation:
- * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
- *
- * This program is free software; 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_OPENRISC_DMA_MAPPING_H
-#define __ASM_OPENRISC_DMA_MAPPING_H
-
-/*
- * See Documentation/DMA-API-HOWTO.txt and
- * Documentation/DMA-API.txt for documentation.
- */
-
-#include <linux/dma-debug.h>
-#include <linux/dma-mapping.h>
-
-extern const struct dma_map_ops or1k_dma_map_ops;
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-       return &or1k_dma_map_ops;
-}
-
-#endif /* __ASM_OPENRISC_DMA_MAPPING_H */
index ec7fd45704d23ddd99ea2437204476b26bd1914c..159336adfa2f66ff2ea2d491ce32b559a82f3ff9 100644 (file)
@@ -19,9 +19,7 @@
  * the only thing implemented properly.  The rest need looking into...
  */
 
-#include <linux/dma-mapping.h>
-#include <linux/dma-debug.h>
-#include <linux/export.h>
+#include <linux/dma-noncoherent.h>
 
 #include <asm/cpuinfo.h>
 #include <asm/spr_defs.h>
@@ -80,10 +78,9 @@ page_clear_nocache(pte_t *pte, unsigned long addr,
  * is being ignored for now; uncached but write-combined memory is a
  * missing feature of the OR1K.
  */
-static void *
-or1k_dma_alloc(struct device *dev, size_t size,
-              dma_addr_t *dma_handle, gfp_t gfp,
-              unsigned long attrs)
+void *
+arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+               gfp_t gfp, unsigned long attrs)
 {
        unsigned long va;
        void *page;
@@ -115,9 +112,9 @@ or1k_dma_alloc(struct device *dev, size_t size,
        return (void *)va;
 }
 
-static void
-or1k_dma_free(struct device *dev, size_t size, void *vaddr,
-             dma_addr_t dma_handle, unsigned long attrs)
+void
+arch_dma_free(struct device *dev, size_t size, void *vaddr,
+               dma_addr_t dma_handle, unsigned long attrs)
 {
        unsigned long va = (unsigned long)vaddr;
        struct mm_walk walk = {
@@ -133,19 +130,12 @@ or1k_dma_free(struct device *dev, size_t size, void *vaddr,
        free_pages_exact(vaddr, size);
 }
 
-static dma_addr_t
-or1k_map_page(struct device *dev, struct page *page,
-             unsigned long offset, size_t size,
-             enum dma_data_direction dir,
-             unsigned long attrs)
+void arch_sync_dma_for_device(struct device *dev, phys_addr_t addr, size_t size,
+               enum dma_data_direction dir)
 {
        unsigned long cl;
-       dma_addr_t addr = page_to_phys(page) + offset;
        struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
 
-       if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
-               return addr;
-
        switch (dir) {
        case DMA_TO_DEVICE:
                /* Flush the dcache for the requested range */
@@ -167,83 +157,4 @@ or1k_map_page(struct device *dev, struct page *page,
                 */
                break;
        }
-
-       return addr;
-}
-
-static void
-or1k_unmap_page(struct device *dev, dma_addr_t dma_handle,
-               size_t size, enum dma_data_direction dir,
-               unsigned long attrs)
-{
-       /* Nothing special to do here... */
-}
-
-static int
-or1k_map_sg(struct device *dev, struct scatterlist *sg,
-           int nents, enum dma_data_direction dir,
-           unsigned long attrs)
-{
-       struct scatterlist *s;
-       int i;
-
-       for_each_sg(sg, s, nents, i) {
-               s->dma_address = or1k_map_page(dev, sg_page(s), s->offset,
-                                              s->length, dir, 0);
-       }
-
-       return nents;
 }
-
-static void
-or1k_unmap_sg(struct device *dev, struct scatterlist *sg,
-             int nents, enum dma_data_direction dir,
-             unsigned long attrs)
-{
-       struct scatterlist *s;
-       int i;
-
-       for_each_sg(sg, s, nents, i) {
-               or1k_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, 0);
-       }
-}
-
-static void
-or1k_sync_single_for_cpu(struct device *dev,
-                        dma_addr_t dma_handle, size_t size,
-                        enum dma_data_direction dir)
-{
-       unsigned long cl;
-       dma_addr_t addr = dma_handle;
-       struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
-
-       /* Invalidate the dcache for the requested range */
-       for (cl = addr; cl < addr + size; cl += cpuinfo->dcache_block_size)
-               mtspr(SPR_DCBIR, cl);
-}
-
-static void
-or1k_sync_single_for_device(struct device *dev,
-                           dma_addr_t dma_handle, size_t size,
-                           enum dma_data_direction dir)
-{
-       unsigned long cl;
-       dma_addr_t addr = dma_handle;
-       struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()];
-
-       /* Flush the dcache for the requested range */
-       for (cl = addr; cl < addr + size; cl += cpuinfo->dcache_block_size)
-               mtspr(SPR_DCBFR, cl);
-}
-
-const struct dma_map_ops or1k_dma_map_ops = {
-       .alloc = or1k_dma_alloc,
-       .free = or1k_dma_free,
-       .map_page = or1k_map_page,
-       .unmap_page = or1k_unmap_page,
-       .map_sg = or1k_map_sg,
-       .unmap_sg = or1k_unmap_sg,
-       .sync_single_for_cpu = or1k_sync_single_for_cpu,
-       .sync_single_for_device = or1k_sync_single_for_device,
-};
-EXPORT_SYMBOL(or1k_dma_map_ops);
index f019d3ec0c1cd81f7361f30ddcf6af7b3f3bb9e0..d00973aab7f186972151adbdb5f23090cb5f8d73 100644 (file)
@@ -235,6 +235,7 @@ typedef unsigned long elf_greg_t;
 #define SET_PERSONALITY(ex) \
 ({     \
        set_personality((current->personality & ~PER_MASK) | PER_LINUX); \
+       clear_thread_flag(TIF_32BIT); \
        current->thread.map_base = DEFAULT_MAP_BASE; \
        current->thread.task_size = DEFAULT_TASK_SIZE; \
  })
@@ -243,9 +244,11 @@ typedef unsigned long elf_greg_t;
 
 #define COMPAT_SET_PERSONALITY(ex) \
 ({     \
-       set_thread_flag(TIF_32BIT); \
-       current->thread.map_base = DEFAULT_MAP_BASE32; \
-       current->thread.task_size = DEFAULT_TASK_SIZE32; \
+       if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \
+               set_thread_flag(TIF_32BIT); \
+               current->thread.map_base = DEFAULT_MAP_BASE32; \
+               current->thread.task_size = DEFAULT_TASK_SIZE32; \
+       } else clear_thread_flag(TIF_32BIT); \
  })
 
 /*
index 49f6f3d772cc643b7cced383bf17ec73a6b1fd6b..cd6fe4febeadb34b811ed6b4e0b2caf54971efa5 100644 (file)
 name:          ASM_NL\
        .export name
 
-#ifdef CONFIG_64BIT
-#define ENDPROC(name) \
-       END(name)
-#else
-#define ENDPROC(name) \
-       .type name, @function !\
-       END(name)
-#endif
-
 #define ENTRY_CFI(name, ...) \
        ENTRY(name)     ASM_NL\
        .proc           ASM_NL\
index 2dbe5580a1a4420ba693329a0f2622f68f759276..2bd5e695bdadd9d12ebf903a18ed56637e58ecb6 100644 (file)
@@ -256,11 +256,7 @@ on downward growing arches, it looks like this:
  * it in here from the current->personality
  */
 
-#ifdef CONFIG_64BIT
-#define USER_WIDE_MODE (!test_thread_flag(TIF_32BIT))
-#else
-#define USER_WIDE_MODE 0
-#endif
+#define USER_WIDE_MODE (!is_32bit_task())
 
 #define start_thread(regs, new_pc, new_sp) do {                \
        elf_addr_t *sp = (elf_addr_t *)new_sp;          \
index e00013248907e771a12b8543be2326d0f3c7980c..8ecc1f0c0483d5a4a60dd44c08b6e49b9d3b776e 100644 (file)
@@ -2,7 +2,9 @@
 #ifndef __ASM_TRAPS_H
 #define __ASM_TRAPS_H
 
-#ifdef __KERNEL__
+#define PARISC_ITLB_TRAP       6 /* defined by architecture. Do not change. */
+
+#if !defined(__ASSEMBLY__)
 struct pt_regs;
 
 /* traps.c */
index f133b7efbebbf882ac0e26d3edf02c0924175930..9547e5261a8b8f6e3c17a7a31e69f9ef8f37e1f4 100644 (file)
@@ -73,8 +73,10 @@ unwind_table_remove(struct unwind_table *table);
 
 void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t, 
                       struct pt_regs *regs);
-void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t);
-void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs);
+void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info,
+                       struct task_struct *t);
+void unwind_frame_init_task(struct unwind_frame_info *info,
+                       struct task_struct *task, struct pt_regs *regs);
 int unwind_once(struct unwind_frame_info *info);
 int unwind_to_user(struct unwind_frame_info *info);
 
index c7508f5717fb511ee463fc9aac83270a00d71cc4..242c5ab6561130e6dd673f9d401485317c59b658 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/signal.h>
 #include <asm/unistd.h>
 #include <asm/ldcw.h>
+#include <asm/traps.h>
 #include <asm/thread_info.h>
 
 #include <linux/linkage.h>
@@ -692,7 +693,7 @@ ENTRY(fault_vector_20)
        def              3
        extint           4
        def              5
-       itlb_20          6
+       itlb_20          PARISC_ITLB_TRAP
        def              7
        def              8
        def              9
@@ -735,7 +736,7 @@ ENTRY(fault_vector_11)
        def              3
        extint           4
        def              5
-       itlb_11          6
+       itlb_11          PARISC_ITLB_TRAP
        def              7
        def              8
        def              9
@@ -776,7 +777,7 @@ END(fault_vector_11)
         * copy_thread moved args into task save area.
         */
 
-ENTRY_CFI(ret_from_kernel_thread)
+ENTRY(ret_from_kernel_thread)
        /* Call schedule_tail first though */
        BL      schedule_tail, %r2
        nop
@@ -791,7 +792,7 @@ ENTRY_CFI(ret_from_kernel_thread)
        copy    %r31, %r2
        b       finish_child_return
        nop
-ENDPROC_CFI(ret_from_kernel_thread)
+END(ret_from_kernel_thread)
 
 
        /*
@@ -815,9 +816,8 @@ ENTRY_CFI(_switch_to)
        LDREG   TASK_THREAD_INFO(%r25), %r25
        bv      %r0(%r2)
        mtctl   %r25,%cr30
-ENDPROC_CFI(_switch_to)
 
-ENTRY_CFI(_switch_to_ret)
+ENTRY(_switch_to_ret)
        mtctl   %r0, %cr0               /* Needed for single stepping */
        callee_rest
        callee_rest_float
@@ -825,7 +825,7 @@ ENTRY_CFI(_switch_to_ret)
        LDREG   -RP_OFFSET(%r30), %r2
        bv      %r0(%r2)
        copy    %r26, %r28
-ENDPROC_CFI(_switch_to_ret)
+ENDPROC_CFI(_switch_to)
 
        /*
         * Common rfi return path for interruptions, kernel execve, and
@@ -886,14 +886,12 @@ ENTRY_CFI(syscall_exit_rfi)
        STREG   %r19,PT_SR5(%r16)
        STREG   %r19,PT_SR6(%r16)
        STREG   %r19,PT_SR7(%r16)
-ENDPROC_CFI(syscall_exit_rfi)
 
-ENTRY_CFI(intr_return)
+ENTRY(intr_return)
        /* check for reschedule */
        mfctl   %cr30,%r1
        LDREG   TI_FLAGS(%r1),%r19      /* sched.h: TIF_NEED_RESCHED */
        bb,<,n  %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
-ENDPROC_CFI(intr_return)
 
        .import do_notify_resume,code
 intr_check_sig:
@@ -1049,6 +1047,7 @@ intr_extint:
 
        b       do_cpu_irq_mask
        ldo     R%intr_return(%r2), %r2 /* return to intr_return, not here */
+ENDPROC_CFI(syscall_exit_rfi)
 
 
        /* Generic interruptions (illegal insn, unaligned, page fault, etc) */
@@ -1068,21 +1067,12 @@ ENTRY_CFI(intr_save)            /* for os_hpmc */
        save_specials   %r29
 
        /* If this trap is a itlb miss, skip saving/adjusting isr/ior */
-
-       /*
-        * FIXME: 1) Use a #define for the hardwired "6" below (and in
-        *           traps.c.
-        *        2) Once we start executing code above 4 Gb, we need
-        *           to adjust iasq/iaoq here in the same way we
-        *           adjust isr/ior below.
-        */
-
-       cmpib,COND(=),n        6,%r26,skip_save_ior
+       cmpib,COND(=),n        PARISC_ITLB_TRAP,%r26,skip_save_ior
 
 
-       mfctl           %cr20, %r16 /* isr */
+       mfctl           %isr, %r16
        nop             /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */
-       mfctl           %cr21, %r17 /* ior */
+       mfctl           %ior, %r17
 
 
 #ifdef CONFIG_64BIT
@@ -1094,22 +1084,34 @@ ENTRY_CFI(intr_save)            /* for os_hpmc */
        extrd,u,*<>     %r8,PSW_W_BIT,1,%r0
        depdi           0,1,2,%r17
 
-       /*
-        * FIXME: This code has hardwired assumptions about the split
-        *        between space bits and offset bits. This will change
-        *        when we allow alternate page sizes.
-        */
-
-       /* adjust isr/ior. */
-       extrd,u         %r16,63,SPACEID_SHIFT,%r1       /* get high bits from isr for ior */
-       depd            %r1,31,SPACEID_SHIFT,%r17       /* deposit them into ior */
-       depdi           0,63,SPACEID_SHIFT,%r16         /* clear them from isr */
+       /* adjust isr/ior: get high bits from isr and deposit in ior */
+       space_adjust    %r16,%r17,%r1
 #endif
        STREG           %r16, PT_ISR(%r29)
        STREG           %r17, PT_IOR(%r29)
 
+#if 0 && defined(CONFIG_64BIT)
+       /* Revisit when we have 64-bit code above 4Gb */
+       b,n             intr_save2
 
 skip_save_ior:
+       /* We have a itlb miss, and when executing code above 4 Gb on ILP64, we
+        * need to adjust iasq/iaoq here in the same way we adjusted isr/ior
+        * above.
+        */
+       extrd,u,*       %r8,PSW_W_BIT,1,%r1
+       cmpib,COND(=),n 1,%r1,intr_save2
+       LDREG           PT_IASQ0(%r29), %r16
+       LDREG           PT_IAOQ0(%r29), %r17
+       /* adjust iasq/iaoq */
+       space_adjust    %r16,%r17,%r1
+       STREG           %r16, PT_IASQ0(%r29)
+       STREG           %r17, PT_IAOQ0(%r29)
+#else
+skip_save_ior:
+#endif
+
+intr_save2:
        virt_map
        save_general    %r29
 
@@ -1747,7 +1749,7 @@ fork_like fork
 fork_like vfork
 
        /* Set the return value for the child */
-ENTRY_CFI(child_return)
+ENTRY(child_return)
        BL      schedule_tail, %r2
        nop
 finish_child_return:
@@ -1759,7 +1761,7 @@ finish_child_return:
        reg_restore %r1
        b       syscall_exit
        copy    %r0,%r28
-ENDPROC_CFI(child_return)
+END(child_return)
 
 ENTRY_CFI(sys_rt_sigreturn_wrapper)
        LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
@@ -1791,7 +1793,7 @@ ENTRY_CFI(sys_rt_sigreturn_wrapper)
        LDREG   PT_GR28(%r1),%r28  /* reload original r28 for syscall_exit */
 ENDPROC_CFI(sys_rt_sigreturn_wrapper)
 
-ENTRY_CFI(syscall_exit)
+ENTRY(syscall_exit)
        /* NOTE: Not all syscalls exit this way.  rt_sigreturn will exit
         * via syscall_exit_rfi if the signal was received while the process
         * was running.
@@ -1990,15 +1992,13 @@ syscall_do_resched:
 #else
        nop
 #endif
-ENDPROC_CFI(syscall_exit)
+END(syscall_exit)
 
 
 #ifdef CONFIG_FUNCTION_TRACER
 
        .import ftrace_function_trampoline,code
        .align L1_CACHE_BYTES
-       .globl mcount
-       .type  mcount, @function
 ENTRY_CFI(mcount, caller)
 _mcount:
        .export _mcount,data
@@ -2027,8 +2027,6 @@ ENDPROC_CFI(mcount)
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
        .align 8
-       .globl return_to_handler
-       .type  return_to_handler, @function
 ENTRY_CFI(return_to_handler, caller,frame=FRAME_SIZE)
        .export parisc_return_to_handler,data
 parisc_return_to_handler:
@@ -2078,6 +2076,7 @@ ENDPROC_CFI(return_to_handler)
 /* void call_on_stack(unsigned long param1, void *func,
                      unsigned long new_stack) */
 ENTRY_CFI(call_on_stack, FRAME=2*FRAME_SIZE,CALLS,SAVE_RP,SAVE_SP)
+ENTRY(_call_on_stack)
        copy    %sp, %r1
 
        /* Regarding the HPPA calling conventions for function pointers,
index 45cc65902fcebb88edc6f98d96241d4a1dbf7617..82bd0d0927ce30338cc0c5b9adf3e85c5d28795c 100644 (file)
@@ -288,6 +288,8 @@ void __init collect_boot_cpu_data(void)
                printk(KERN_INFO "model %s\n",
                        boot_cpu_data.pdc.sys_model_name);
 
+       dump_stack_set_arch_desc("%s", boot_cpu_data.pdc.sys_model_name);
+
        boot_cpu_data.hversion =  boot_cpu_data.pdc.model.hversion;
        boot_cpu_data.sversion =  boot_cpu_data.pdc.model.sversion;
 
index 2fe914c5f533524edd13abc1affbf85df8f6f854..ec5835e83a7a756c9fecda603f57f42bec6ed870 100644 (file)
@@ -16,20 +16,7 @@ static void dump_trace(struct task_struct *task, struct stack_trace *trace)
 {
        struct unwind_frame_info info;
 
-       /* initialize unwind info */
-       if (task == current) {
-               unsigned long sp;
-               struct pt_regs r;
-HERE:
-               asm volatile ("copy %%r30, %0" : "=r"(sp));
-               memset(&r, 0, sizeof(struct pt_regs));
-               r.iaoq[0] = (unsigned long)&&HERE;
-               r.gr[2] = (unsigned long)__builtin_return_address(0);
-               r.gr[30] = sp;
-               unwind_frame_init(&info, task, &r);
-       } else {
-               unwind_frame_init_from_blocked_task(&info, task);
-       }
+       unwind_frame_init_task(&info, task, NULL);
 
        /* unwind stack and save entries in stack_trace struct */
        trace->nr_entries = 0;
index 43b308cfdf532264d73e64ba5037950dd5a24fcb..376ea0d1b2759d2657741f8f8683f77e61a71b2d 100644 (file)
@@ -156,11 +156,6 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
        int do_color_align, last_mmap;
        struct vm_unmapped_area_info info;
 
-#ifdef CONFIG_64BIT
-       /* This should only ever run for 32-bit processes.  */
-       BUG_ON(!test_thread_flag(TIF_32BIT));
-#endif
-
        /* requested length too big for entire address space */
        if (len > TASK_SIZE)
                return -ENOMEM;
index 5f7e57fcaeef0333da7482f8af566a0e4da7fc00..f453997a7b8f219e2657cfd146660658d87c3d2a 100644 (file)
@@ -108,12 +108,8 @@ linux_gateway_entry:
        mtsp    %r0,%sr6                        /* get kernel space into sr6 */
 
 #ifdef CONFIG_64BIT
-       /* for now we can *always* set the W bit on entry to the syscall
-        * since we don't support wide userland processes.  We could
-        * also save the current SM other than in r0 and restore it on
-        * exit from the syscall, and also use that value to know
-        * whether to do narrow or wide syscalls. -PB
-        */
+       /* Store W bit on entry to the syscall in case it's a wide userland
+        * process. */
        ssm     PSW_SM_W, %r1
        extrd,u %r1,PSW_W_BIT,1,%r1
        /* sp must be aligned on 4, so deposit the W bit setting into
@@ -227,8 +223,7 @@ linux_gateway_entry:
        or,=    %r2,%r2,%r2
        ldo     R%sys_call_table64(%r1), %r19
 #else
-       ldil    L%sys_call_table, %r1
-       ldo     R%sys_call_table(%r1), %r19
+       load32  sys_call_table, %r19
 #endif 
        comiclr,>>      __NR_Linux_syscalls, %r20, %r0
        b,n     .Lsyscall_nosys
@@ -331,8 +326,6 @@ tracesys_next:
         *  task->thread.regs.gr[20] above.
         */
        copy    %ret0,%r20
-       ldil    L%sys_call_table,%r1
-       ldo     R%sys_call_table(%r1), %r19
 
        ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
        LDREG   TI_TASK(%r1), %r1
@@ -354,6 +347,23 @@ tracesys_next:
        comiclr,>>      __NR_Linux_syscalls, %r20, %r0
        b,n     .Ltracesys_nosys
 
+       /* Note!  We cannot use the syscall table that is mapped
+       nearby since the gateway page is mapped execute-only. */
+
+#ifdef CONFIG_64BIT
+       LDREG   TASK_PT_GR30(%r1), %r19         /* get users sp back */
+       extrd,u %r19,63,1,%r2                   /* W hidden in bottom bit */
+
+       ldil    L%sys_call_table, %r1
+       or,=    %r2,%r2,%r2
+       addil   L%(sys_call_table64-sys_call_table), %r1
+       ldo     R%sys_call_table(%r1), %r19
+       or,=    %r2,%r2,%r2
+       ldo     R%sys_call_table64(%r1), %r19
+#else
+       load32  sys_call_table, %r19
+#endif
+
        LDREGX  %r20(%r19), %r19
 
        /* If this is a sys_rt_sigreturn call, and the signal was received
@@ -464,16 +474,13 @@ tracesys_sigexit:
 lws_start:
 
 #ifdef CONFIG_64BIT
-       /* FIXME: If we are a 64-bit kernel just
-        *        turn this on unconditionally.
-        */
        ssm     PSW_SM_W, %r1
        extrd,u %r1,PSW_W_BIT,1,%r1
        /* sp must be aligned on 4, so deposit the W bit setting into
         * the bottom of sp temporarily */
        or,ev   %r1,%r30,%r30
 
-       /* Clip LWS number to a 32-bit value always */
+       /* Clip LWS number to a 32-bit value for 32-bit processes */
        depdi   0, 31, 32, %r20
 #endif 
 
index 318815212518962bec3bf8391abd791ad30f6879..68f10f87073dab74f414ebf5bdef2dd681707fb4 100644 (file)
@@ -45,7 +45,7 @@
 
 #include "../math-emu/math-emu.h"      /* for handle_fpe() */
 
-static void parisc_show_stack(struct task_struct *task, unsigned long *sp,
+static void parisc_show_stack(struct task_struct *task,
        struct pt_regs *regs);
 
 static int printbinary(char *buf, unsigned long x, int nbits)
@@ -152,7 +152,7 @@ void show_regs(struct pt_regs *regs)
                printk("%s IAOQ[1]: %pS\n", level, (void *) regs->iaoq[1]);
                printk("%s RP(r2): %pS\n", level, (void *) regs->gr[2]);
 
-               parisc_show_stack(current, NULL, regs);
+               parisc_show_stack(current, regs);
        }
 }
 
@@ -185,44 +185,19 @@ static void do_show_stack(struct unwind_frame_info *info)
        printk(KERN_CRIT "\n");
 }
 
-static void parisc_show_stack(struct task_struct *task, unsigned long *sp,
+static void parisc_show_stack(struct task_struct *task,
        struct pt_regs *regs)
 {
        struct unwind_frame_info info;
-       struct task_struct *t;
 
-       t = task ? task : current;
-       if (regs) {
-               unwind_frame_init(&info, t, regs);
-               goto show_stack;
-       }
-
-       if (t == current) {
-               unsigned long sp;
-
-HERE:
-               asm volatile ("copy %%r30, %0" : "=r"(sp));
-               {
-                       struct pt_regs r;
-
-                       memset(&r, 0, sizeof(struct pt_regs));
-                       r.iaoq[0] = (unsigned long)&&HERE;
-                       r.gr[2] = (unsigned long)__builtin_return_address(0);
-                       r.gr[30] = sp;
-
-                       unwind_frame_init(&info, current, &r);
-               }
-       } else {
-               unwind_frame_init_from_blocked_task(&info, t);
-       }
+       unwind_frame_init_task(&info, task, regs);
 
-show_stack:
        do_show_stack(&info);
 }
 
 void show_stack(struct task_struct *t, unsigned long *sp)
 {
-       return parisc_show_stack(t, sp, NULL);
+       parisc_show_stack(t, NULL);
 }
 
 int is_valid_bugaddr(unsigned long iaoq)
@@ -557,7 +532,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
                cpu_lpmc(5, regs);
                return;
 
-       case  6:
+       case  PARISC_ITLB_TRAP:
                /* Instruction TLB miss fault/Instruction page fault */
                fault_address = regs->iaoq[0];
                fault_space   = regs->iasq[0];
index 5cdf13069dd99d41e3f4d2061e4d82474296e80f..f329b466e68f66acc3f8fb8669de2b92776e29df 100644 (file)
@@ -209,6 +209,8 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int
         * We have to use void * instead of a function pointer, because
         * function pointers aren't a pointer to the function on 64-bit.
         * Make them const so the compiler knows they live in .text
+        * Note: We could use dereference_kernel_function_descriptor()
+        * instead but we want to keep it simple here.
         */
        extern void * const handle_interruption;
        extern void * const ret_from_kernel_thread;
@@ -216,7 +218,7 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int
        extern void * const intr_return;
        extern void * const _switch_to_ret;
 #ifdef CONFIG_IRQSTACKS
-       extern void * const call_on_stack;
+       extern void * const _call_on_stack;
 #endif /* CONFIG_IRQSTACKS */
 
        if (pc == (unsigned long) &handle_interruption) {
@@ -251,7 +253,7 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int
        }
 
 #ifdef CONFIG_IRQSTACKS
-       if (pc == (unsigned long) &call_on_stack) {
+       if (pc == (unsigned long) &_call_on_stack) {
                info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ);
                info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET);
                return 1;
@@ -403,9 +405,31 @@ void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct
        kfree(r2);
 }
 
-void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs)
+#define get_parisc_stackpointer() ({ \
+       unsigned long sp; \
+       __asm__("copy %%r30, %0" : "=r"(sp)); \
+       (sp); \
+})
+
+void unwind_frame_init_task(struct unwind_frame_info *info,
+       struct task_struct *task, struct pt_regs *regs)
 {
-       unwind_frame_init(info, current, regs);
+       task = task ? task : current;
+
+       if (task == current) {
+               struct pt_regs r;
+
+               if (!regs) {
+                       memset(&r, 0, sizeof(r));
+                       r.iaoq[0] =  _THIS_IP_;
+                       r.gr[2] = _RET_IP_;
+                       r.gr[30] = get_parisc_stackpointer();
+                       regs = &r;
+               }
+               unwind_frame_init(info, task, &r);
+       } else {
+               unwind_frame_init_from_blocked_task(info, task);
+       }
 }
 
 int unwind_once(struct unwind_frame_info *next_frame)
@@ -442,19 +466,12 @@ int unwind_to_user(struct unwind_frame_info *info)
 unsigned long return_address(unsigned int level)
 {
        struct unwind_frame_info info;
-       struct pt_regs r;
-       unsigned long sp;
 
        /* initialize unwind info */
-       asm volatile ("copy %%r30, %0" : "=r"(sp));
-       memset(&r, 0, sizeof(struct pt_regs));
-       r.iaoq[0] = _THIS_IP_;
-       r.gr[2] = _RET_IP_;
-       r.gr[30] = sp;
-       unwind_frame_init(&info, current, &r);
+       unwind_frame_init_task(&info, current, NULL);
 
        /* unwind stack */
-       ++level;
+       level += 2;
        do {
                if (unwind_once(&info) < 0 || info.ip == 0)
                        return 0;
index 8397c7bd5880805a457f5db43b35425f6787310e..11a1acba164a1629f10a3080946c80f64feb0eca 100644 (file)
@@ -76,14 +76,14 @@ endif
 
 ifdef CONFIG_CPU_LITTLE_ENDIAN
 KBUILD_CFLAGS  += -mlittle-endian
-LDFLAGS                += -EL
+KBUILD_LDFLAGS += -EL
 LDEMULATION    := lppc
 GNUTARGET      := powerpcle
 MULTIPLEWORD   := -mno-multiple
 KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-save-toc-indirect)
 else
 KBUILD_CFLAGS += $(call cc-option,-mbig-endian)
-LDFLAGS                += -EB
+KBUILD_LDFLAGS += -EB
 LDEMULATION    := ppc
 GNUTARGET      := powerpc
 MULTIPLEWORD   := -mmultiple
@@ -108,7 +108,7 @@ aflags-$(CONFIG_CPU_LITTLE_ENDIAN)  += -mlittle-endian
 ifeq ($(HAS_BIARCH),y)
 KBUILD_CFLAGS  += -m$(BITS)
 KBUILD_AFLAGS  += -m$(BITS) -Wl,-a$(BITS)
-LDFLAGS                += -m elf$(BITS)$(LDEMULATION)
+KBUILD_LDFLAGS += -m elf$(BITS)$(LDEMULATION)
 KBUILD_ARFLAGS += --target=elf$(BITS)-$(GNUTARGET)
 endif
 
index 676118743a064784cb232218384127b13087cfe0..13a688fc8cd0c90177493aee7f3b2f1806843dd3 100644 (file)
 
 #define _PAGE_PTE              0x4000000000000000UL    /* distinguishes PTEs from pointers */
 #define _PAGE_PRESENT          0x8000000000000000UL    /* pte contains a translation */
+/*
+ * We need to mark a pmd pte invalid while splitting. We can do that by clearing
+ * the _PAGE_PRESENT bit. But then that will be taken as a swap pte. In order to
+ * differentiate between two use a SW field when invalidating.
+ *
+ * We do that temporary invalidate for regular pte entry in ptep_set_access_flags
+ *
+ * This is used only when _PAGE_PRESENT is cleared.
+ */
+#define _PAGE_INVALID          _RPAGE_SW0
 
 /*
  * Top and bottom bits of RPN which can be used by hash
@@ -568,7 +578,13 @@ static inline pte_t pte_clear_savedwrite(pte_t pte)
 
 static inline int pte_present(pte_t pte)
 {
-       return !!(pte_raw(pte) & cpu_to_be64(_PAGE_PRESENT));
+       /*
+        * A pte is considerent present if _PAGE_PRESENT is set.
+        * We also need to consider the pte present which is marked
+        * invalid during ptep_set_access_flags. Hence we look for _PAGE_INVALID
+        * if we find _PAGE_PRESENT cleared.
+        */
+       return !!(pte_raw(pte) & cpu_to_be64(_PAGE_PRESENT | _PAGE_INVALID));
 }
 
 #ifdef CONFIG_PPC_MEM_KEYS
index 2160be2e4339d5946c8f8a048a3563f4482bc36c..b321c82b3624726eb479453911642a87d7687f38 100644 (file)
@@ -51,17 +51,14 @@ static inline int pte_present(pte_t pte)
 #define pte_access_permitted pte_access_permitted
 static inline bool pte_access_permitted(pte_t pte, bool write)
 {
-       unsigned long pteval = pte_val(pte);
        /*
         * A read-only access is controlled by _PAGE_USER bit.
         * We have _PAGE_READ set for WRITE and EXECUTE
         */
-       unsigned long need_pte_bits = _PAGE_PRESENT | _PAGE_USER;
-
-       if (write)
-               need_pte_bits |= _PAGE_WRITE;
+       if (!pte_present(pte) || !pte_user(pte) || !pte_read(pte))
+               return false;
 
-       if ((pteval & need_pte_bits) != need_pte_bits)
+       if (write && !pte_write(pte))
                return false;
 
        return true;
index 834e7e29f1e4e0e9b948095aa8959e3f60d4be2a..ff3866473afe411f63c3d4e968ff6b574694402b 100644 (file)
@@ -308,6 +308,7 @@ extern void opal_configure_cores(void);
 extern int opal_get_chars(uint32_t vtermno, char *buf, int count);
 extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
 extern int opal_put_chars_atomic(uint32_t vtermno, const char *buf, int total_len);
+extern int opal_flush_chars(uint32_t vtermno, bool wait);
 extern int opal_flush_console(uint32_t vtermno);
 
 extern void hvc_opal_init_early(void);
index 16b077801a5f97125f48cc9d597580cef7f8f65d..a4a718dbfec6e0e4dbcfbf80b020f54689258290 100644 (file)
@@ -92,6 +92,7 @@ extern int stop_topology_update(void);
 extern int prrn_is_enabled(void);
 extern int find_and_online_cpu_nid(int cpu);
 extern int timed_topology_update(int nsecs);
+extern void __init shared_proc_topology_init(void);
 #else
 static inline int start_topology_update(void)
 {
@@ -113,6 +114,10 @@ static inline int timed_topology_update(int nsecs)
 {
        return 0;
 }
+
+#ifdef CONFIG_SMP
+static inline void shared_proc_topology_init(void) {}
+#endif
 #endif /* CONFIG_NUMA && CONFIG_PPC_SPLPAR */
 
 #include <asm-generic/topology.h>
index 986ec476fd5dca380316415e34ec83292051d1c6..a711d22339ea76d75cc09a1a9e215764147eb983 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/crash_dump.h>
 #include <linux/kobject.h>
 #include <linux/sysfs.h>
+#include <linux/slab.h>
 
 #include <asm/debugfs.h>
 #include <asm/page.h>
@@ -1019,13 +1020,6 @@ static int fadump_setup_crash_memory_ranges(void)
        pr_debug("Setup crash memory ranges.\n");
        crash_mem_ranges = 0;
 
-       /* allocate memory for crash memory ranges for the first time */
-       if (!max_crash_mem_ranges) {
-               ret = allocate_crash_memory_ranges();
-               if (ret)
-                       return ret;
-       }
-
        /*
         * add the first memory chunk (RMA_START through boot_memory_size) as
         * a separate memory chunk. The reason is, at the time crash firmware
index dd7471fe20bd4960e3a8db2cd34deb64fde061b2..a09b3c7ca176e1d52b3f0c8c538cee8be3abcf29 100644 (file)
@@ -32,6 +32,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
        cmpwi   0,r4,0
        beqlr
 
+       /* This sequence is similar to prep_irq_for_idle() */
+
        /* Hard disable interrupts */
        mfmsr   r7
        rldicl  r0,r7,48,1
@@ -41,10 +43,15 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
        /* Check if something happened while soft-disabled */
        lbz     r0,PACAIRQHAPPENED(r13)
        cmpwi   cr0,r0,0
-       bnelr
+       bne-    2f
 
-       /* Soft-enable interrupts */
+       /*
+        * Soft-enable interrupts. This will make power4_fixup_nap return
+        * to our caller with interrupts enabled (soft and hard). The caller
+        * can cope with either interrupts disabled or enabled upon return.
+        */
 #ifdef CONFIG_TRACE_IRQFLAGS
+       /* Tell the tracer interrupts are on, because idle responds to them. */
        mflr    r0
        std     r0,16(r1)
        stdu    r1,-128(r1)
@@ -73,3 +80,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
        isync
        b       1b
 
+2:     /* Return if an interrupt had happened while soft disabled */
+       /* Set the HARD_DIS flag because interrupts are now hard disabled */
+       ori     r0,r0,PACA_IRQ_HARD_DIS
+       stb     r0,PACAIRQHAPPENED(r13)
+       blr
index b19d832ef386b31a0e4462771e38998d8f0848a7..61c1fadbc644441bcd90b3fb05363891ecdf7082 100644 (file)
@@ -1160,6 +1160,11 @@ void __init smp_cpus_done(unsigned int max_cpus)
        if (smp_ops && smp_ops->bringup_done)
                smp_ops->bringup_done();
 
+       /*
+        * On a shared LPAR, associativity needs to be requested.
+        * Hence, get numa topology before dumping cpu topology
+        */
+       shared_proc_topology_init();
        dump_numa_cpu_topology();
 
        /*
index 070e96f1773a464b1aebf7c316e2de1028dd6c2f..c85adb8582713075426ab05b537c6910d19d467a 100644 (file)
@@ -315,22 +315,21 @@ void user_single_step_siginfo(struct task_struct *tsk,
        info->si_addr = (void __user *)regs->nip;
 }
 
-static bool show_unhandled_signals_ratelimited(void)
+static void show_signal_msg(int signr, struct pt_regs *regs, int code,
+                           unsigned long addr)
 {
        static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
                                      DEFAULT_RATELIMIT_BURST);
-       return show_unhandled_signals && __ratelimit(&rs);
-}
 
-static void show_signal_msg(int signr, struct pt_regs *regs, int code,
-                           unsigned long addr)
-{
-       if (!show_unhandled_signals_ratelimited())
+       if (!show_unhandled_signals)
                return;
 
        if (!unhandled_signal(current, signr))
                return;
 
+       if (!__ratelimit(&rs))
+               return;
+
        pr_info("%s[%d]: %s (%d) at %lx nip %lx lr %lx code %x",
                current->comm, current->pid, signame(signr), signr,
                addr, regs->nip, regs->link, code);
index 3c0e8fb2b773ebaf3bdfe404b2909d2d5ed48b4a..68e14afecac85b1d1fd0eff661f6a3aabe0217a6 100644 (file)
@@ -358,7 +358,7 @@ static int kvmppc_mmu_book3s_64_hv_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
        unsigned long pp, key;
        unsigned long v, orig_v, gr;
        __be64 *hptep;
-       int index;
+       long int index;
        int virtmode = vcpu->arch.shregs.msr & (data ? MSR_DR : MSR_IR);
 
        if (kvm_is_radix(vcpu->kvm))
index 0af1c0aea1fe659fca4723e17a02cc17eb8fa08f..fd6e8c13685f4c0223749647ad04c34a71ad4589 100644 (file)
@@ -725,10 +725,10 @@ int kvm_unmap_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
                                              gpa, shift);
                kvmppc_radix_tlbie_page(kvm, gpa, shift);
                if ((old & _PAGE_DIRTY) && memslot->dirty_bitmap) {
-                       unsigned long npages = 1;
+                       unsigned long psize = PAGE_SIZE;
                        if (shift)
-                               npages = 1ul << (shift - PAGE_SHIFT);
-                       kvmppc_update_dirty_map(memslot, gfn, npages);
+                               psize = 1ul << shift;
+                       kvmppc_update_dirty_map(memslot, gfn, psize);
                }
        }
        return 0;                               
index 574fc1dcb2bf98288db933d62c8f4ebb97fbab75..3e3a71594e63194acf20174576642b5b2454059d 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/compiler.h>
 #include <linux/of.h>
 
+#include <asm/ftrace.h>
 #include <asm/reg.h>
 #include <asm/ppc-opcode.h>
 #include <asm/asm-prototypes.h>
index 47ee43bbd6960d4d0d5c9cf5ec5e00f956613c79..614ebb4261f76593bb07f52f2fd0a2db7307d4fe 100644 (file)
@@ -514,7 +514,7 @@ static void kvmppc_set_msr_pr(struct kvm_vcpu *vcpu, u64 msr)
        /*
         * When switching from 32 to 64-bit, we may have a stale 32-bit
         * magic page around, we need to flush it. Typically 32-bit magic
-        * page will be instanciated when calling into RTAS. Note: We
+        * page will be instantiated when calling into RTAS. Note: We
         * assume that such transition only happens while in kernel mode,
         * ie, we never transition from user 32-bit to kernel 64-bit with
         * a 32-bit magic page around.
index 126f02b3ffb8271e0cac825e13ecf5146de0afe8..30c2eb7669549a1076b1ce9776c55a8babfc7b21 100644 (file)
@@ -38,7 +38,7 @@
  * Virtual mode variants of the hcalls for use on radix/radix
  * with AIL. They require the VCPU's VP to be "pushed"
  *
- * We still instanciate them here because we use some of the
+ * We still instantiate them here because we use some of the
  * generated utility functions as well in this file.
  */
 #define XIVE_RUNTIME_CHECKS
index 4a892d894a0f1b2d96ed319ab0f4a622104c7526..dbd8f762140b6942b32f41a8466cb3bfc7aee840 100644 (file)
 #include <asm/mmu_context.h>
 #include <asm/pgalloc.h>
 
-static DEFINE_SPINLOCK(mmu_context_lock);
 static DEFINE_IDA(mmu_context_ida);
 
 static int alloc_context_id(int min_id, int max_id)
 {
-       int index, err;
-
-again:
-       if (!ida_pre_get(&mmu_context_ida, GFP_KERNEL))
-               return -ENOMEM;
-
-       spin_lock(&mmu_context_lock);
-       err = ida_get_new_above(&mmu_context_ida, min_id, &index);
-       spin_unlock(&mmu_context_lock);
-
-       if (err == -EAGAIN)
-               goto again;
-       else if (err)
-               return err;
-
-       if (index > max_id) {
-               spin_lock(&mmu_context_lock);
-               ida_remove(&mmu_context_ida, index);
-               spin_unlock(&mmu_context_lock);
-               return -ENOMEM;
-       }
-
-       return index;
+       return ida_alloc_range(&mmu_context_ida, min_id, max_id, GFP_KERNEL);
 }
 
 void hash__reserve_context_id(int id)
 {
-       int rc, result = 0;
-
-       do {
-               if (!ida_pre_get(&mmu_context_ida, GFP_KERNEL))
-                       break;
-
-               spin_lock(&mmu_context_lock);
-               rc = ida_get_new_above(&mmu_context_ida, id, &result);
-               spin_unlock(&mmu_context_lock);
-       } while (rc == -EAGAIN);
+       int result = ida_alloc_range(&mmu_context_ida, id, id, GFP_KERNEL);
 
        WARN(result != id, "mmu: Failed to reserve context id %d (rc %d)\n", id, result);
 }
@@ -172,9 +140,7 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 
 void __destroy_context(int context_id)
 {
-       spin_lock(&mmu_context_lock);
-       ida_remove(&mmu_context_ida, context_id);
-       spin_unlock(&mmu_context_lock);
+       ida_free(&mmu_context_ida, context_id);
 }
 EXPORT_SYMBOL_GPL(__destroy_context);
 
@@ -182,13 +148,11 @@ static void destroy_contexts(mm_context_t *ctx)
 {
        int index, context_id;
 
-       spin_lock(&mmu_context_lock);
        for (index = 0; index < ARRAY_SIZE(ctx->extended_id); index++) {
                context_id = ctx->extended_id[index];
                if (context_id)
-                       ida_remove(&mmu_context_ida, context_id);
+                       ida_free(&mmu_context_ida, context_id);
        }
-       spin_unlock(&mmu_context_lock);
 }
 
 static void pte_frag_destroy(void *pte_frag)
index a4ca576125580d5449d7fadb87decb06d03c41e9..c9ee9e23845f20d3f3b4b523e40a2a453d30ed7c 100644 (file)
@@ -129,6 +129,7 @@ long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long entries,
        long i, j, ret = 0, locked_entries = 0;
        unsigned int pageshift;
        unsigned long flags;
+       unsigned long cur_ua;
        struct page *page = NULL;
 
        mutex_lock(&mem_list_mutex);
@@ -177,7 +178,8 @@ long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long entries,
        }
 
        for (i = 0; i < entries; ++i) {
-               if (1 != get_user_pages_fast(ua + (i << PAGE_SHIFT),
+               cur_ua = ua + (i << PAGE_SHIFT);
+               if (1 != get_user_pages_fast(cur_ua,
                                        1/* pages */, 1/* iswrite */, &page)) {
                        ret = -EFAULT;
                        for (j = 0; j < i; ++j)
@@ -196,7 +198,7 @@ long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long entries,
                if (is_migrate_cma_page(page)) {
                        if (mm_iommu_move_page_from_cma(page))
                                goto populate;
-                       if (1 != get_user_pages_fast(ua + (i << PAGE_SHIFT),
+                       if (1 != get_user_pages_fast(cur_ua,
                                                1/* pages */, 1/* iswrite */,
                                                &page)) {
                                ret = -EFAULT;
@@ -210,20 +212,21 @@ long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long entries,
                }
 populate:
                pageshift = PAGE_SHIFT;
-               if (PageCompound(page)) {
+               if (mem->pageshift > PAGE_SHIFT && PageCompound(page)) {
                        pte_t *pte;
                        struct page *head = compound_head(page);
                        unsigned int compshift = compound_order(head);
+                       unsigned int pteshift;
 
                        local_irq_save(flags); /* disables as well */
-                       pte = find_linux_pte(mm->pgd, ua, NULL, &pageshift);
-                       local_irq_restore(flags);
+                       pte = find_linux_pte(mm->pgd, cur_ua, NULL, &pteshift);
 
                        /* Double check it is still the same pinned page */
                        if (pte && pte_page(*pte) == head &&
-                                       pageshift == compshift)
-                               pageshift = max_t(unsigned int, pageshift,
+                           pteshift == compshift + PAGE_SHIFT)
+                               pageshift = max_t(unsigned int, pteshift,
                                                PAGE_SHIFT);
+                       local_irq_restore(flags);
                }
                mem->pageshift = min(mem->pageshift, pageshift);
                mem->hpas[i] = page_to_pfn(page) << PAGE_SHIFT;
index 0c7e05d8924481f3e4b3fca1d23cb293bab5320d..35ac5422903a0ee5494c92b637bcc64604c7cba3 100644 (file)
@@ -1078,7 +1078,6 @@ static int prrn_enabled;
 static void reset_topology_timer(void);
 static int topology_timer_secs = 1;
 static int topology_inited;
-static int topology_update_needed;
 
 /*
  * Change polling interval for associativity changes.
@@ -1306,11 +1305,8 @@ int numa_update_cpu_topology(bool cpus_locked)
        struct device *dev;
        int weight, new_nid, i = 0;
 
-       if (!prrn_enabled && !vphn_enabled) {
-               if (!topology_inited)
-                       topology_update_needed = 1;
+       if (!prrn_enabled && !vphn_enabled && topology_inited)
                return 0;
-       }
 
        weight = cpumask_weight(&cpu_associativity_changes_mask);
        if (!weight)
@@ -1423,7 +1419,6 @@ int numa_update_cpu_topology(bool cpus_locked)
 
 out:
        kfree(updates);
-       topology_update_needed = 0;
        return changed;
 }
 
@@ -1551,6 +1546,15 @@ int prrn_is_enabled(void)
        return prrn_enabled;
 }
 
+void __init shared_proc_topology_init(void)
+{
+       if (lppaca_shared_proc(get_lppaca())) {
+               bitmap_fill(cpumask_bits(&cpu_associativity_changes_mask),
+                           nr_cpumask_bits);
+               numa_update_cpu_topology(false);
+       }
+}
+
 static int topology_read(struct seq_file *file, void *v)
 {
        if (vphn_enabled || prrn_enabled)
@@ -1608,10 +1612,6 @@ static int topology_update_init(void)
                return -ENOMEM;
 
        topology_inited = 1;
-       if (topology_update_needed)
-               bitmap_fill(cpumask_bits(&cpu_associativity_changes_mask),
-                                       nr_cpumask_bits);
-
        return 0;
 }
 device_initcall(topology_update_init);
index 7be99fd9af152ebc0fc24b851ccf8193fd868d05..c879979faa73b766cc1336bfacf0d3b6c65db5ea 100644 (file)
@@ -1045,20 +1045,22 @@ void radix__ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep,
        struct mm_struct *mm = vma->vm_mm;
        unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESSED |
                                              _PAGE_RW | _PAGE_EXEC);
+
+       unsigned long change = pte_val(entry) ^ pte_val(*ptep);
        /*
         * To avoid NMMU hang while relaxing access, we need mark
         * the pte invalid in between.
         */
-       if (atomic_read(&mm->context.copros) > 0) {
+       if ((change & _PAGE_RW) && atomic_read(&mm->context.copros) > 0) {
                unsigned long old_pte, new_pte;
 
-               old_pte = __radix_pte_update(ptep, ~0, 0);
+               old_pte = __radix_pte_update(ptep, _PAGE_PRESENT, _PAGE_INVALID);
                /*
                 * new value of pte
                 */
                new_pte = old_pte | set;
                radix__flush_tlb_page_psize(mm, address, psize);
-               __radix_pte_update(ptep, 0, new_pte);
+               __radix_pte_update(ptep, _PAGE_INVALID, new_pte);
        } else {
                __radix_pte_update(ptep, 0, set);
                /*
index 0b095fa540491845ca390be4f06a794f2c6f4c0f..9f574e59d178618af5ba5056f13241f0776f9852 100644 (file)
@@ -70,7 +70,7 @@ static inline void slb_shadow_update(unsigned long ea, int ssize,
 
 static inline void slb_shadow_clear(enum slb_index index)
 {
-       WRITE_ONCE(get_slb_shadow()->save_area[index].esid, 0);
+       WRITE_ONCE(get_slb_shadow()->save_area[index].esid, cpu_to_be64(index));
 }
 
 static inline void create_shadowed_slbe(unsigned long ea, int ssize,
index fa89f30e7f27c138c0610777f4d86321be60239e..d4d4118205978df0c36ed67e681aa951d16c7ca7 100644 (file)
@@ -1192,7 +1192,7 @@ static void pmac_i2c_devscan(void (*callback)(struct device_node *dev,
                { NULL, NULL, 0 },
        };
 
-       /* Only some devices need to have platform functions instanciated
+       /* Only some devices need to have platform functions instantiated
         * here. For now, we have a table. Others, like 9554 i2c GPIOs used
         * on Xserve, if we ever do a driver for them, will use their own
         * platform function instance
index 404c379db168cf614036293c8787c75b6b656d58..38fe4087484a61e7ead4fed3ea89db130b596b8b 100644 (file)
@@ -370,12 +370,8 @@ static int __opal_put_chars(uint32_t vtermno, const char *data, int total_len, b
        olen = cpu_to_be64(total_len);
        rc = opal_console_write(vtermno, &olen, data);
        if (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
-               if (rc == OPAL_BUSY_EVENT) {
-                       mdelay(OPAL_BUSY_DELAY_MS);
+               if (rc == OPAL_BUSY_EVENT)
                        opal_poll_events(NULL);
-               } else if (rc == OPAL_BUSY_EVENT) {
-                       mdelay(OPAL_BUSY_DELAY_MS);
-               }
                written = -EAGAIN;
                goto out;
        }
@@ -401,15 +397,6 @@ out:
        if (atomic)
                spin_unlock_irqrestore(&opal_write_lock, flags);
 
-       /* In the -EAGAIN case, callers loop, so we have to flush the console
-        * here in case they have interrupts off (and we don't want to wait
-        * for async flushing if we can make immediate progress here). If
-        * necessary the API could be made entirely non-flushing if the
-        * callers had a ->flush API to use.
-        */
-       if (written == -EAGAIN)
-               opal_flush_console(vtermno);
-
        return written;
 }
 
@@ -429,40 +416,74 @@ int opal_put_chars_atomic(uint32_t vtermno, const char *data, int total_len)
        return __opal_put_chars(vtermno, data, total_len, true);
 }
 
-int opal_flush_console(uint32_t vtermno)
+static s64 __opal_flush_console(uint32_t vtermno)
 {
        s64 rc;
 
        if (!opal_check_token(OPAL_CONSOLE_FLUSH)) {
                __be64 evt;
 
-               WARN_ONCE(1, "opal: OPAL_CONSOLE_FLUSH missing.\n");
                /*
                 * If OPAL_CONSOLE_FLUSH is not implemented in the firmware,
                 * the console can still be flushed by calling the polling
                 * function while it has OPAL_EVENT_CONSOLE_OUTPUT events.
                 */
-               do {
-                       opal_poll_events(&evt);
-               } while (be64_to_cpu(evt) & OPAL_EVENT_CONSOLE_OUTPUT);
+               WARN_ONCE(1, "opal: OPAL_CONSOLE_FLUSH missing.\n");
+
+               opal_poll_events(&evt);
+               if (!(be64_to_cpu(evt) & OPAL_EVENT_CONSOLE_OUTPUT))
+                       return OPAL_SUCCESS;
+               return OPAL_BUSY;
 
-               return OPAL_SUCCESS;
+       } else {
+               rc = opal_console_flush(vtermno);
+               if (rc == OPAL_BUSY_EVENT) {
+                       opal_poll_events(NULL);
+                       rc = OPAL_BUSY;
+               }
+               return rc;
        }
 
-       do  {
-               rc = OPAL_BUSY;
-               while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
-                       rc = opal_console_flush(vtermno);
-                       if (rc == OPAL_BUSY_EVENT) {
-                               mdelay(OPAL_BUSY_DELAY_MS);
-                               opal_poll_events(NULL);
-                       } else if (rc == OPAL_BUSY) {
-                               mdelay(OPAL_BUSY_DELAY_MS);
+}
+
+/*
+ * opal_flush_console spins until the console is flushed
+ */
+int opal_flush_console(uint32_t vtermno)
+{
+       for (;;) {
+               s64 rc = __opal_flush_console(vtermno);
+
+               if (rc == OPAL_BUSY || rc == OPAL_PARTIAL) {
+                       mdelay(1);
+                       continue;
+               }
+
+               return opal_error_code(rc);
+       }
+}
+
+/*
+ * opal_flush_chars is an hvc interface that sleeps until the console is
+ * flushed if wait, otherwise it will return -EBUSY if the console has data,
+ * -EAGAIN if it has data and some of it was flushed.
+ */
+int opal_flush_chars(uint32_t vtermno, bool wait)
+{
+       for (;;) {
+               s64 rc = __opal_flush_console(vtermno);
+
+               if (rc == OPAL_BUSY || rc == OPAL_PARTIAL) {
+                       if (wait) {
+                               msleep(OPAL_BUSY_DELAY_MS);
+                               continue;
                        }
+                       if (rc == OPAL_PARTIAL)
+                               return -EAGAIN;
                }
-       } while (rc == OPAL_PARTIAL); /* More to flush */
 
-       return opal_error_code(rc);
+               return opal_error_code(rc);
+       }
 }
 
 static int opal_recover_mce(struct pt_regs *regs,
index 4e6302bf4073c2fb67b2c923d4bed859e2920e4f..cde710297a4e434c58d32f07da8ee61d0a24d4a7 100644 (file)
@@ -3228,12 +3228,49 @@ static void pnv_pci_ioda_create_dbgfs(void)
 #endif /* CONFIG_DEBUG_FS */
 }
 
+static void pnv_pci_enable_bridge(struct pci_bus *bus)
+{
+       struct pci_dev *dev = bus->self;
+       struct pci_bus *child;
+
+       /* Empty bus ? bail */
+       if (list_empty(&bus->devices))
+               return;
+
+       /*
+        * If there's a bridge associated with that bus enable it. This works
+        * around races in the generic code if the enabling is done during
+        * parallel probing. This can be removed once those races have been
+        * fixed.
+        */
+       if (dev) {
+               int rc = pci_enable_device(dev);
+               if (rc)
+                       pci_err(dev, "Error enabling bridge (%d)\n", rc);
+               pci_set_master(dev);
+       }
+
+       /* Perform the same to child busses */
+       list_for_each_entry(child, &bus->children, node)
+               pnv_pci_enable_bridge(child);
+}
+
+static void pnv_pci_enable_bridges(void)
+{
+       struct pci_controller *hose;
+
+       list_for_each_entry(hose, &hose_list, list_node)
+               pnv_pci_enable_bridge(hose->bus);
+}
+
 static void pnv_pci_ioda_fixup(void)
 {
        pnv_pci_ioda_setup_PEs();
        pnv_pci_ioda_setup_iommu_api();
        pnv_pci_ioda_create_dbgfs();
 
+       pnv_pci_enable_bridges();
+
 #ifdef CONFIG_EEH
        pnv_eeh_post_init();
 #endif
index ff9f488123310b0503dcb1b139af6d3ee4afe567..e59e0e60e5b5755609f15fa8f2a87d0e497f2a04 100644 (file)
@@ -515,35 +515,17 @@ int init_winctx_regs(struct vas_window *window, struct vas_winctx *winctx)
        return 0;
 }
 
-static DEFINE_SPINLOCK(vas_ida_lock);
-
 static void vas_release_window_id(struct ida *ida, int winid)
 {
-       spin_lock(&vas_ida_lock);
-       ida_remove(ida, winid);
-       spin_unlock(&vas_ida_lock);
+       ida_free(ida, winid);
 }
 
 static int vas_assign_window_id(struct ida *ida)
 {
-       int rc, winid;
-
-       do {
-               rc = ida_pre_get(ida, GFP_KERNEL);
-               if (!rc)
-                       return -EAGAIN;
-
-               spin_lock(&vas_ida_lock);
-               rc = ida_get_new(ida, &winid);
-               spin_unlock(&vas_ida_lock);
-       } while (rc == -EAGAIN);
-
-       if (rc)
-               return rc;
+       int winid = ida_alloc_max(ida, VAS_WINDOWS_PER_CHIP - 1, GFP_KERNEL);
 
-       if (winid > VAS_WINDOWS_PER_CHIP) {
-               pr_err("Too many (%d) open windows\n", winid);
-               vas_release_window_id(ida, winid);
+       if (winid == -ENOSPC) {
+               pr_err("Too many (%d) open windows\n", VAS_WINDOWS_PER_CHIP);
                return -EAGAIN;
        }
 
index e8f5b0551095b45e629d7dd69d7af747ee0aaf32..959a2a62f23329775beba45473e944395005192a 100644 (file)
@@ -266,7 +266,7 @@ static unsigned int xive_get_irq(void)
         * of pending priorities. This will also have the effect of
         * updating the CPPR to the most favored pending interrupts.
         *
-        * In the future, if we have a way to differenciate a first
+        * In the future, if we have a way to differentiate a first
         * entry (on HW interrupt) from a replay triggered by EOI,
         * we could skip this on replays unless we soft-mask tells us
         * that a new HW interrupt occurred.
index 9ddd88bb30b724c4683cd52a4195be604b1a57a4..61ec42405ec9630082beb941cb58a963127c13ad 100644 (file)
@@ -29,7 +29,7 @@ ifeq ($(CONFIG_ARCH_RV64I),y)
        KBUILD_CFLAGS   += $(call cc-ifversion, -ge, 0500, -DCONFIG_ARCH_SUPPORTS_INT128)
 
        KBUILD_MARCH = rv64im
-       LDFLAGS += -melf64lriscv
+       KBUILD_LDFLAGS += -melf64lriscv
 else
        BITS := 32
        UTS_MACHINE := riscv32
@@ -37,7 +37,7 @@ else
        KBUILD_CFLAGS += -mabi=ilp32
        KBUILD_AFLAGS += -mabi=ilp32
        KBUILD_MARCH = rv32im
-       LDFLAGS += -melf32lriscv
+       KBUILD_LDFLAGS += -melf32lriscv
 endif
 
 KBUILD_CFLAGS += -Wall
index 576ffdca06baf1d7fe51de655a63286550c93626..efdbe311e9363f03fbb6394b698e898a8687787d 100644 (file)
@@ -1,6 +1,7 @@
 generic-y += bugs.h
 generic-y += cacheflush.h
 generic-y += checksum.h
+generic-y += compat.h
 generic-y += cputime.h
 generic-y += device.h
 generic-y += div64.h
diff --git a/arch/riscv/include/asm/compat.h b/arch/riscv/include/asm/compat.h
deleted file mode 100644 (file)
index 044aecf..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2012 ARM Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef __ASM_COMPAT_H
-#define __ASM_COMPAT_H
-#ifdef CONFIG_COMPAT
-
-#if defined(CONFIG_64BIT)
-#define COMPAT_UTS_MACHINE "riscv64\0\0"
-#elif defined(CONFIG_32BIT)
-#define COMPAT_UTS_MACHINE "riscv32\0\0"
-#else
-#error "Unknown RISC-V base ISA"
-#endif
-
-#endif /*CONFIG_COMPAT*/
-#endif /*__ASM_COMPAT_H*/
index c229509288ea2d77c9efe72cfb1ccb0105371296..439dc7072e05bf37a722bb983b69dabed39651fa 100644 (file)
 #ifndef _ASM_RISCV_TLB_H
 #define _ASM_RISCV_TLB_H
 
+struct mmu_gather;
+
+static void tlb_flush(struct mmu_gather *tlb);
+
 #include <asm-generic/tlb.h>
 
 static inline void tlb_flush(struct mmu_gather *tlb)
index 080fb28061de7e230348c65395c12ef0ed2051af..0caea01d5ccabf58de5e7199c77ae38d650f13c0 100644 (file)
  *   GNU General Public License for more details.
  */
 
+/*
+ * There is explicitly no include guard here because this file is expected to
+ * be included multiple times.  See uapi/asm/syscalls.h for more info.
+ */
+
 #define __ARCH_WANT_SYS_CLONE
 #include <uapi/asm/unistd.h>
 #include <uapi/asm/syscalls.h>
index 541544d64c33b2f95a0d2f3a1f7f3e80498ea006..ec6180a4b55df1ba259f5c3eab6cc19735a4afe9 100644 (file)
@@ -38,8 +38,6 @@ struct vdso_data {
        (void __user *)((unsigned long)(base) + __vdso_##name);                 \
 })
 
-#ifdef CONFIG_SMP
 asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t);
-#endif
 
 #endif /* _ASM_RISCV_VDSO_H */
index 818655b0d5356a1f5c0768419c6bd98ca5a58ec6..206dc4b0f6ea8423bf6446e2e13e679373a43ec5 100644 (file)
@@ -1,10 +1,13 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Copyright (C) 2017 SiFive
+ * Copyright (C) 2017-2018 SiFive
  */
 
-#ifndef _ASM__UAPI__SYSCALLS_H
-#define _ASM__UAPI__SYSCALLS_H
+/*
+ * There is explicitly no include guard here because this file is expected to
+ * be included multiple times in order to define the syscall macros via
+ * __SYSCALL.
+ */
 
 /*
  * Allows the instruction cache to be flushed from userspace.  Despite RISC-V
@@ -20,7 +23,7 @@
  * caller.  We don't currently do anything with the address range, that's just
  * in there for forwards compatibility.
  */
+#ifndef __NR_riscv_flush_icache
 #define __NR_riscv_flush_icache (__NR_arch_specific_syscall + 15)
-__SYSCALL(__NR_riscv_flush_icache, sys_riscv_flush_icache)
-
 #endif
+__SYSCALL(__NR_riscv_flush_icache, sys_riscv_flush_icache)
index f7181ed8aafc64f94040a65fe99e8adab281cb86..fb03a4482ad60ac7ca66f86429897275020c5ffd 100644 (file)
@@ -48,7 +48,6 @@ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
 }
 #endif /* !CONFIG_64BIT */
 
-#ifdef CONFIG_SMP
 /*
  * Allows the instruction cache to be flushed from userspace.  Despite RISC-V
  * having a direct 'fence.i' instruction available to userspace (which we
@@ -66,15 +65,11 @@ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
 SYSCALL_DEFINE3(riscv_flush_icache, uintptr_t, start, uintptr_t, end,
        uintptr_t, flags)
 {
-       struct mm_struct *mm = current->mm;
-       bool local = (flags & SYS_RISCV_FLUSH_ICACHE_LOCAL) != 0;
-
        /* Check the reserved flags. */
        if (unlikely(flags & ~SYS_RISCV_FLUSH_ICACHE_ALL))
                return -EINVAL;
 
-       flush_icache_mm(mm, local);
+       flush_icache_mm(current->mm, flags & SYS_RISCV_FLUSH_ICACHE_LOCAL);
 
        return 0;
 }
-#endif
index a6afa60074cb441c638e352c1e6fbb73f5fc2475..9a9c7a6fe925915f561dd48c454e1e02d5ee7a51 100644 (file)
@@ -135,11 +135,12 @@ config S390
        select HAVE_DYNAMIC_FTRACE
        select HAVE_DYNAMIC_FTRACE_WITH_REGS
        select HAVE_EFFICIENT_UNALIGNED_ACCESS
+       select HAVE_FENTRY
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_FUNCTION_TRACER
        select HAVE_FUTEX_CMPXCHG if FUTEX
-       select HAVE_GCC_PLUGINS if BROKEN
+       select HAVE_GCC_PLUGINS
        select HAVE_KERNEL_BZIP2
        select HAVE_KERNEL_GZIP
        select HAVE_KERNEL_LZ4
@@ -157,6 +158,7 @@ config S390
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_MEMBLOCK_PHYS_MAP
        select HAVE_MOD_ARCH_SPECIFIC
+       select HAVE_NOP_MCOUNT
        select HAVE_OPROFILE
        select HAVE_PERF_EVENTS
        select HAVE_REGS_AND_STACK_ACCESS_API
index eee6703093c32e884f00bd07554511a8ccb090f6..ee65185bbc807284b8729b5c9d52c129fafba30e 100644 (file)
@@ -11,7 +11,7 @@
 #
 
 LD_BFD         := elf64-s390
-LDFLAGS                := -m elf64_s390
+KBUILD_LDFLAGS := -m elf64_s390
 KBUILD_AFLAGS_MODULE += -fPIC
 KBUILD_CFLAGS_MODULE += -fPIC
 KBUILD_AFLAGS  += -m64
@@ -96,13 +96,15 @@ ifdef CONFIG_EXPOLINE
 endif
 
 ifdef CONFIG_FUNCTION_TRACER
-# make use of hotpatch feature if the compiler supports it
-cc_hotpatch    := -mhotpatch=0,3
-ifeq ($(call cc-option-yn,$(cc_hotpatch)),y)
-CC_FLAGS_FTRACE := $(cc_hotpatch)
-KBUILD_AFLAGS  += -DCC_USING_HOTPATCH
-KBUILD_CFLAGS  += -DCC_USING_HOTPATCH
-endif
+  ifeq ($(call cc-option-yn,-mfentry -mnop-mcount),n)
+    # make use of hotpatch feature if the compiler supports it
+    cc_hotpatch        := -mhotpatch=0,3
+    ifeq ($(call cc-option-yn,$(cc_hotpatch)),y)
+      CC_FLAGS_FTRACE := $(cc_hotpatch)
+      KBUILD_AFLAGS    += -DCC_USING_HOTPATCH
+      KBUILD_CFLAGS    += -DCC_USING_HOTPATCH
+    endif
+  endif
 endif
 
 # Test CFI features of binutils
index 046e044a48d096890067560f4c80e0cafa2879dc..8c00fd509c45555fbde5ef9febe6b732c3c4f46b 100644 (file)
@@ -49,23 +49,23 @@ struct ap_queue_status {
 /**
  * ap_intructions_available() - Test if AP instructions are available.
  *
- * Returns 0 if the AP instructions are installed.
+ * Returns true if the AP instructions are installed, otherwise false.
  */
-static inline int ap_instructions_available(void)
+static inline bool ap_instructions_available(void)
 {
        register unsigned long reg0 asm ("0") = AP_MKQID(0, 0);
-       register unsigned long reg1 asm ("1") = -ENODEV;
-       register unsigned long reg2 asm ("2");
+       register unsigned long reg1 asm ("1") = 0;
+       register unsigned long reg2 asm ("2") = 0;
 
        asm volatile(
                "   .long 0xb2af0000\n"         /* PQAP(TAPQ) */
-               "0: la    %0,0\n"
+               "0: la    %0,1\n"
                "1:\n"
                EX_TABLE(0b, 1b)
-               : "+d" (reg1), "=d" (reg2)
+               : "+d" (reg1), "+d" (reg2)
                : "d" (reg0)
                : "cc");
-       return reg1;
+       return reg1 != 0;
 }
 
 /**
index cfccc0edd00d7ba6b3c5150d36f2a27e183dd21e..8ea270fdc7fb2d9ffabe5df27d362b9520056553 100644 (file)
@@ -4,7 +4,7 @@
 
 #define ARCH_SUPPORTS_FTRACE_OPS 1
 
-#ifdef CC_USING_HOTPATCH
+#if defined(CC_USING_HOTPATCH) || defined(CC_USING_NOP_MCOUNT)
 #define MCOUNT_INSN_SIZE       6
 #else
 #define MCOUNT_INSN_SIZE       24
@@ -42,7 +42,7 @@ struct ftrace_insn {
 static inline void ftrace_generate_nop_insn(struct ftrace_insn *insn)
 {
 #ifdef CONFIG_FUNCTION_TRACER
-#ifdef CC_USING_HOTPATCH
+#if defined(CC_USING_HOTPATCH) || defined(CC_USING_NOP_MCOUNT)
        /* brcl 0,0 */
        insn->opc = 0xc004;
        insn->disp = 0;
@@ -57,7 +57,7 @@ static inline void ftrace_generate_nop_insn(struct ftrace_insn *insn)
 static inline int is_ftrace_nop(struct ftrace_insn *insn)
 {
 #ifdef CONFIG_FUNCTION_TRACER
-#ifdef CC_USING_HOTPATCH
+#if defined(CC_USING_HOTPATCH) || defined(CC_USING_NOP_MCOUNT)
        if (insn->disp == 0)
                return 1;
 #else
index f31a15044c24a56875661aa6d3e195d75bd9ef9c..a8418e1379eb7ee08c92acd034eae000cb19c695 100644 (file)
@@ -16,7 +16,13 @@ typedef struct {
        unsigned long asce;
        unsigned long asce_limit;
        unsigned long vdso_base;
-       /* The mmu context allocates 4K page tables. */
+       /*
+        * The following bitfields need a down_write on the mm
+        * semaphore when they are written to. As they are only
+        * written once, they can be read without a lock.
+        *
+        * The mmu context allocates 4K page tables.
+        */
        unsigned int alloc_pgste:1;
        /* The mmu context uses extended page tables. */
        unsigned int has_pgste:1;
index b62e0614e44045ad85d8539fee06fad2cd12ae56..2bb1f3bb98ac5cc6f3c7bb0ac74dedda5e202058 100644 (file)
  * - length(n_modulus) = inputdatalength
  */
 struct ica_rsa_modexpo {
-       char __user *   inputdata;
-       unsigned int    inputdatalength;
-       char __user *   outputdata;
-       unsigned int    outputdatalength;
-       char __user *   b_key;
-       char __user *   n_modulus;
+       char __user  *inputdata;
+       unsigned int  inputdatalength;
+       char __user  *outputdata;
+       unsigned int  outputdatalength;
+       char __user  *b_key;
+       char __user  *n_modulus;
 };
 
 /**
@@ -55,15 +55,15 @@ struct ica_rsa_modexpo {
  * - length(u_mult_inv) = inputdatalength/2 + 8
  */
 struct ica_rsa_modexpo_crt {
-       char __user *   inputdata;
-       unsigned int    inputdatalength;
-       char __user *   outputdata;
-       unsigned int    outputdatalength;
-       char __user *   bp_key;
-       char __user *   bq_key;
-       char __user *   np_prime;
-       char __user *   nq_prime;
-       char __user *   u_mult_inv;
+       char __user  *inputdata;
+       unsigned int  inputdatalength;
+       char __user  *outputdata;
+       unsigned int  outputdatalength;
+       char __user  *bp_key;
+       char __user  *bq_key;
+       char __user  *np_prime;
+       char __user  *nq_prime;
+       char __user  *u_mult_inv;
 };
 
 /**
@@ -93,18 +93,18 @@ struct CPRBX {
        unsigned int    req_extbl;      /* request extension block len   */
        unsigned char   pad_001[4];     /* reserved                      */
        unsigned int    rpld_extbl;     /* replied extension block len   */
-       unsigned char   padx000[16 - sizeof (char *)];
-       unsigned char req_parmb;      /* request parm block 'address'  */
-       unsigned char   padx001[16 - sizeof (char *)];
-       unsigned char req_datab;      /* request data block 'address'  */
-       unsigned char   padx002[16 - sizeof (char *)];
-       unsigned char rpl_parmb;      /* reply parm block 'address'    */
-       unsigned char   padx003[16 - sizeof (char *)];
-       unsigned char rpl_datab;      /* reply data block 'address'    */
-       unsigned char   padx004[16 - sizeof (char *)];
-       unsigned char req_extb;       /* request extension block 'addr'*/
-       unsigned char   padx005[16 - sizeof (char *)];
-       unsigned char rpl_extb;       /* reply extension block 'address'*/
+       unsigned char   padx000[16 - sizeof(char *)];
+       unsigned char  *req_parmb;      /* request parm block 'address'  */
+       unsigned char   padx001[16 - sizeof(char *)];
+       unsigned char  *req_datab;      /* request data block 'address'  */
+       unsigned char   padx002[16 - sizeof(char *)];
+       unsigned char  *rpl_parmb;      /* reply parm block 'address'    */
+       unsigned char   padx003[16 - sizeof(char *)];
+       unsigned char  *rpl_datab;      /* reply data block 'address'    */
+       unsigned char   padx004[16 - sizeof(char *)];
+       unsigned char  *req_extb;       /* request extension block 'addr'*/
+       unsigned char   padx005[16 - sizeof(char *)];
+       unsigned char  *rpl_extb;       /* reply extension block 'address'*/
        unsigned short  ccp_rtcode;     /* server return code            */
        unsigned short  ccp_rscode;     /* server reason code            */
        unsigned int    mac_data_len;   /* Mac Data Length               */
@@ -127,17 +127,17 @@ struct ica_xcRB {
        unsigned int    user_defined;
        unsigned short  request_ID;
        unsigned int    request_control_blk_length;
-       unsigned char   padding1[16 - sizeof (char *)];
-       char __user *   request_control_blk_addr;
+       unsigned char   padding1[16 - sizeof(char *)];
+       char __user    *request_control_blk_addr;
        unsigned int    request_data_length;
-       char            padding2[16 - sizeof (char *)];
-       char __user *   request_data_address;
+       char            padding2[16 - sizeof(char *)];
+       char __user    *request_data_address;
        unsigned int    reply_control_blk_length;
-       char            padding3[16 - sizeof (char *)];
-       char __user *   reply_control_blk_addr;
+       char            padding3[16 - sizeof(char *)];
+       char __user    *reply_control_blk_addr;
        unsigned int    reply_data_length;
-       char            padding4[16 - sizeof (char *)];
-       char __user *   reply_data_addr;
+       char            padding4[16 - sizeof(char *)];
+       char __user    *reply_data_addr;
        unsigned short  priority_window;
        unsigned int    status;
 } __attribute__((packed));
@@ -233,7 +233,7 @@ struct zcrypt_device_matrix_ext {
        struct zcrypt_device_status_ext device[MAX_ZDEV_ENTRIES_EXT];
 };
 
-#define AUTOSELECT ((unsigned int)0xFFFFFFFF)
+#define AUTOSELECT 0xFFFFFFFF
 
 #define ZCRYPT_IOCTL_MAGIC 'z'
 
index 11aea745a2a6ebce7ea29a894b822d3bcc560c7b..66e830f1c7bfefc2711305172cbdacaac48e0527 100644 (file)
 #include <asm/gmap.h>
 #include <asm/nmi.h>
 
-/*
- * Make sure that the compiler is new enough. We want a compiler that
- * is known to work with the "Q" assembler constraint.
- */
-#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)
-#error Your compiler is too old; please use version 4.3 or newer
-#endif
-
 int main(void)
 {
        /* task struct offsets */
index c3620bafc374d38d42a83d84e20fbb11eb6421a1..376f6b6dfb3cb14b00174adef95820836c3ee0a6 100644 (file)
@@ -293,19 +293,6 @@ int remap_oldmem_pfn_range(struct vm_area_struct *vma, unsigned long from,
                                                       prot);
 }
 
-/*
- * Alloc memory and panic in case of ENOMEM
- */
-static void *kzalloc_panic(int len)
-{
-       void *rc;
-
-       rc = kzalloc(len, GFP_KERNEL);
-       if (!rc)
-               panic("s390 kdump kzalloc (%d) failed", len);
-       return rc;
-}
-
 static const char *nt_name(Elf64_Word type)
 {
        const char *name = "LINUX";
@@ -451,11 +438,15 @@ static void *get_vmcoreinfo_old(unsigned long *size)
        if (copy_oldmem_kernel(nt_name, addr + sizeof(note),
                               sizeof(nt_name) - 1))
                return NULL;
-       if (strcmp(nt_name, "VMCOREINFO") != 0)
+       if (strcmp(nt_name, VMCOREINFO_NOTE_NAME) != 0)
+               return NULL;
+       vmcoreinfo = kzalloc(note.n_descsz, GFP_KERNEL);
+       if (!vmcoreinfo)
                return NULL;
-       vmcoreinfo = kzalloc_panic(note.n_descsz);
-       if (copy_oldmem_kernel(vmcoreinfo, addr + 24, note.n_descsz))
+       if (copy_oldmem_kernel(vmcoreinfo, addr + 24, note.n_descsz)) {
+               kfree(vmcoreinfo);
                return NULL;
+       }
        *size = note.n_descsz;
        return vmcoreinfo;
 }
@@ -465,39 +456,38 @@ static void *get_vmcoreinfo_old(unsigned long *size)
  */
 static void *nt_vmcoreinfo(void *ptr)
 {
+       const char *name = VMCOREINFO_NOTE_NAME;
        unsigned long size;
        void *vmcoreinfo;
 
        vmcoreinfo = os_info_old_entry(OS_INFO_VMCOREINFO, &size);
-       if (!vmcoreinfo)
-               vmcoreinfo = get_vmcoreinfo_old(&size);
+       if (vmcoreinfo)
+               return nt_init_name(ptr, 0, vmcoreinfo, size, name);
+
+       vmcoreinfo = get_vmcoreinfo_old(&size);
        if (!vmcoreinfo)
                return ptr;
-       return nt_init_name(ptr, 0, vmcoreinfo, size, "VMCOREINFO");
+       ptr = nt_init_name(ptr, 0, vmcoreinfo, size, name);
+       kfree(vmcoreinfo);
+       return ptr;
 }
 
 static size_t nt_vmcoreinfo_size(void)
 {
-       const char *name = "VMCOREINFO";
-       char nt_name[11];
-       Elf64_Nhdr note;
-       void *addr;
-
-       if (copy_oldmem_kernel(&addr, &S390_lowcore.vmcore_info, sizeof(addr)))
-               return 0;
-
-       if (copy_oldmem_kernel(&note, addr, sizeof(note)))
-               return 0;
+       const char *name = VMCOREINFO_NOTE_NAME;
+       unsigned long size;
+       void *vmcoreinfo;
 
-       memset(nt_name, 0, sizeof(nt_name));
-       if (copy_oldmem_kernel(nt_name, addr + sizeof(note),
-                              sizeof(nt_name) - 1))
-               return 0;
+       vmcoreinfo = os_info_old_entry(OS_INFO_VMCOREINFO, &size);
+       if (vmcoreinfo)
+               return nt_size_name(size, name);
 
-       if (strcmp(nt_name, name) != 0)
+       vmcoreinfo = get_vmcoreinfo_old(&size);
+       if (!vmcoreinfo)
                return 0;
 
-       return nt_size_name(note.n_descsz, name);
+       kfree(vmcoreinfo);
+       return nt_size_name(size, name);
 }
 
 /*
@@ -660,7 +650,15 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
 
        alloc_size = get_elfcorehdr_size(mem_chunk_cnt);
 
-       hdr = kzalloc_panic(alloc_size);
+       hdr = kzalloc(alloc_size, GFP_KERNEL);
+
+       /* Without elfcorehdr /proc/vmcore cannot be created. Thus creating
+        * a dump with this crash kernel will fail. Panic now to allow other
+        * dump mechanisms to take over.
+        */
+       if (!hdr)
+               panic("s390 kdump allocating elfcorehdr failed");
+
        /* Init elf header */
        ptr = ehdr_init(hdr, mem_chunk_cnt);
        /* Init program headers */
index c15caeab1dbfb1257e18d138680a786f4a1c1a11..7f8246c9be08e6c7d229e28777704b53f4f4224a 100644 (file)
@@ -111,15 +111,15 @@ __u8 _ebcasc[256] =
           0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
  /* 0x38  -SBS   -IT  -RFF  -CU3   DC4   NAK  ----   SUB */
           0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
- /* 0x40    SP   RSP           \81ä              ----       */
+ /* 0x40    SP   RSP           ä              ----       */
           0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
  /* 0x48                       .     <     (     +     | */
           0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
  /* 0x50     &                                      ---- */
           0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
- /* 0x58           \81ß     !     $     *     )     ;       */
+ /* 0x58           ß     !     $     *     )     ;       */
           0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
- /* 0x60     -     /  ----     \81Ä  ----  ----  ----       */
+ /* 0x60     -     /  ----     Ä  ----  ----  ----       */
           0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
  /* 0x68              ----     ,     %     _     >     ? */ 
           0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
@@ -131,7 +131,7 @@ __u8 _ebcasc[256] =
           0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
  /* 0x88     h     i              ----  ----  ----       */
           0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
- /* 0x90     \81°     j     k     l     m     n     o     p */
+ /* 0x90     Â°     j     k     l     m     n     o     p */
           0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
  /* 0x98     q     r                    ----        ---- */
           0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
@@ -139,25 +139,25 @@ __u8 _ebcasc[256] =
           0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
  /* 0xA8     y     z              ----  ----  ----  ---- */
           0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
- /* 0xB0     ^                    ----     \81§  ----       */
+ /* 0xB0     ^                    ----     Â§  ----       */
           0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
  /* 0xB8        ----     [     ]  ----  ----  ----  ---- */
           0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
  /* 0xC0     {     A     B     C     D     E     F     G */
           0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- /* 0xC8     H     I  ----           \81ö              ---- */
+ /* 0xC8     H     I  ----           ö              ---- */
           0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
  /* 0xD0     }     J     K     L     M     N     O     P */
           0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
- /* 0xD8     Q     R  ----           \81ü                   */
+ /* 0xD8     Q     R  ----           ü                   */
           0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
  /* 0xE0     \           S     T     U     V     W     X */
           0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- /* 0xE8     Y     Z        ----     \81Ö  ----  ----  ---- */
+ /* 0xE8     Y     Z        ----     Ö  ----  ----  ---- */
           0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
  /* 0xF0     0     1     2     3     4     5     6     7 */
           0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- /* 0xF8     8     9  ----  ----     \81Ü  ----  ----  ---- */
+ /* 0xF8     8     9  ----  ----     Ü  ----  ----  ---- */
           0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
 };
 
@@ -260,15 +260,15 @@ __u8 _ebcasc_500[256] =
           0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
  /* 0x38  -SBS   -IT  -RFF  -CU3   DC4   NAK  ----   SUB */
           0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
- /* 0x40    SP   RSP           \81ä              ----       */
+ /* 0x40    SP   RSP           ä              ----       */
           0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
  /* 0x48                 [     .     <     (     +     ! */
           0x87, 0xA4, 0x5B, 0x2E, 0x3C, 0x28, 0x2B, 0x21,
  /* 0x50     &                                      ---- */
           0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
- /* 0x58           \81ß     ]     $     *     )     ;     ^ */
+ /* 0x58           ß     ]     $     *     )     ;     ^ */
           0x8D, 0xE1, 0x5D, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
- /* 0x60     -     /  ----     \81Ä  ----  ----  ----       */
+ /* 0x60     -     /  ----     Ä  ----  ----  ----       */
           0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
  /* 0x68              ----     ,     %     _     >     ? */ 
           0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
@@ -280,7 +280,7 @@ __u8 _ebcasc_500[256] =
           0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
  /* 0x88     h     i              ----  ----  ----       */
           0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
- /* 0x90     \81°     j     k     l     m     n     o     p */
+ /* 0x90     Â°     j     k     l     m     n     o     p */
           0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
  /* 0x98     q     r                    ----        ---- */
           0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
@@ -288,25 +288,25 @@ __u8 _ebcasc_500[256] =
           0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
  /* 0xA8     y     z              ----  ----  ----  ---- */
           0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
- /* 0xB0                          ----     \81§  ----       */
+ /* 0xB0                          ----     Â§  ----       */
           0x9B, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
  /* 0xB8        ----           |  ----  ----  ----  ---- */
           0xAB, 0x07, 0xAA, 0x7C, 0x07, 0x07, 0x07, 0x07,
  /* 0xC0     {     A     B     C     D     E     F     G */
           0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- /* 0xC8     H     I  ----           \81ö              ---- */
+ /* 0xC8     H     I  ----           ö              ---- */
           0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
  /* 0xD0     }     J     K     L     M     N     O     P */
           0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
- /* 0xD8     Q     R  ----           \81ü                   */
+ /* 0xD8     Q     R  ----           ü                   */
           0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
  /* 0xE0     \           S     T     U     V     W     X */
           0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- /* 0xE8     Y     Z        ----     \81Ö  ----  ----  ---- */
+ /* 0xE8     Y     Z        ----     Ö  ----  ----  ---- */
           0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
  /* 0xF0     0     1     2     3     4     5     6     7 */
           0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- /* 0xF8     8     9  ----  ----     \81Ü  ----  ----  ---- */
+ /* 0xF8     8     9  ----  ----     Ü  ----  ----  ---- */
           0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
 };
 
index dc76d813e4207e34b9c30cc181b3cec6ed1f5e99..84be7f02d0c2157029cb2868231b67c7603bbf42 100644 (file)
@@ -61,7 +61,7 @@ unsigned long ftrace_plt;
 
 static inline void ftrace_generate_orig_insn(struct ftrace_insn *insn)
 {
-#ifdef CC_USING_HOTPATCH
+#if defined(CC_USING_HOTPATCH) || defined(CC_USING_NOP_MCOUNT)
        /* brcl 0,0 */
        insn->opc = 0xc004;
        insn->disp = 0;
index 27110f3294edcdf30935048d5553f712caf44116..e93fbf02490cf2fc24da579d46eaae59e225d9e2 100644 (file)
@@ -35,7 +35,7 @@ ENTRY(ftrace_caller)
        .globl  ftrace_regs_caller
        .set    ftrace_regs_caller,ftrace_caller
        lgr     %r1,%r15
-#ifndef CC_USING_HOTPATCH
+#if !(defined(CC_USING_HOTPATCH) || defined(CC_USING_NOP_MCOUNT))
        aghi    %r0,MCOUNT_RETURN_FIXUP
 #endif
        aghi    %r15,-STACK_FRAME_SIZE
index cb198d4a6dca7566b0cfba4f34854f9b6074f972..5c53e977be62710ad9ed2001e739ca863e2ca02e 100644 (file)
@@ -665,7 +665,7 @@ static void cpumsf_output_event_pid(struct perf_event *event,
                goto out;
 
        /* Update the process ID (see also kernel/events/core.c) */
-       data->tid_entry.pid = cpumsf_pid_type(event, pid, __PIDTYPE_TGID);
+       data->tid_entry.pid = cpumsf_pid_type(event, pid, PIDTYPE_TGID);
        data->tid_entry.tid = cpumsf_pid_type(event, pid, PIDTYPE_PID);
 
        perf_output_sample(&handle, &header, data, event);
index 91ad4a9425c0b74c024f07fe8347651c91f4bfb7..f69333fd2fa3818c5eeb8bff9240f67e29f37ef0 100644 (file)
@@ -695,7 +695,9 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
                        r = -EINVAL;
                else {
                        r = 0;
+                       down_write(&kvm->mm->mmap_sem);
                        kvm->mm->context.allow_gmap_hpage_1m = 1;
+                       up_write(&kvm->mm->mmap_sem);
                        /*
                         * We might have to create fake 4k page
                         * tables. To avoid that the hardware works on
index d68f10441a164f2c22236adaa143edf6b1d0f7d0..8679bd74d337a583a3dde940d0cef1f427373a4b 100644 (file)
@@ -280,9 +280,11 @@ retry:
                        goto retry;
                }
        }
-       if (rc)
-               return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
        up_read(&current->mm->mmap_sem);
+       if (rc == -EFAULT)
+               return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
+       if (rc < 0)
+               return rc;
        vcpu->run->s.regs.gprs[reg1] &= ~0xff;
        vcpu->run->s.regs.gprs[reg1] |= key;
        return 0;
@@ -324,9 +326,11 @@ retry:
                        goto retry;
                }
        }
-       if (rc < 0)
-               return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
        up_read(&current->mm->mmap_sem);
+       if (rc == -EFAULT)
+               return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
+       if (rc < 0)
+               return rc;
        kvm_s390_set_psw_cc(vcpu, rc);
        return 0;
 }
@@ -390,12 +394,12 @@ static int handle_sske(struct kvm_vcpu *vcpu)
                                              FAULT_FLAG_WRITE, &unlocked);
                        rc = !rc ? -EAGAIN : rc;
                }
+               up_read(&current->mm->mmap_sem);
                if (rc == -EFAULT)
                        return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
-
-               up_read(&current->mm->mmap_sem);
-               if (rc >= 0)
-                       start += PAGE_SIZE;
+               if (rc < 0)
+                       return rc;
+               start += PAGE_SIZE;
        }
 
        if (m3 & (SSKE_MC | SSKE_MR)) {
@@ -1002,13 +1006,15 @@ static int handle_pfmf(struct kvm_vcpu *vcpu)
                                                      FAULT_FLAG_WRITE, &unlocked);
                                rc = !rc ? -EAGAIN : rc;
                        }
+                       up_read(&current->mm->mmap_sem);
                        if (rc == -EFAULT)
                                return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
-
-                       up_read(&current->mm->mmap_sem);
-                       if (rc >= 0)
-                               start += PAGE_SIZE;
+                       if (rc == -EAGAIN)
+                               continue;
+                       if (rc < 0)
+                               return rc;
                }
+               start += PAGE_SIZE;
        }
        if (vcpu->run->s.regs.gprs[reg1] & PFMF_FSC) {
                if (psw_bits(vcpu->arch.sie_block->gpsw).eaba == PSW_BITS_AMODE_64BIT) {
index 63844b95c22c9902df769928313b988ee7d7667b..a2b28cd1e3fedb2bdcc6dbb1cff530ba0e3371a7 100644 (file)
@@ -173,7 +173,8 @@ static int shadow_crycb(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
                return set_validity_icpt(scb_s, 0x0039U);
 
        /* copy only the wrapping keys */
-       if (read_guest_real(vcpu, crycb_addr + 72, &vsie_page->crycb, 56))
+       if (read_guest_real(vcpu, crycb_addr + 72,
+                           vsie_page->crycb.dea_wrapping_key_mask, 56))
                return set_validity_icpt(scb_s, 0x0035U);
 
        scb_s->ecb3 |= ecb3_flags;
index 4902fed221c0effa59ff21fedabdda152641d112..9f6f392a44619ef41b910f5e6899c69d07a24edf 100644 (file)
@@ -420,7 +420,8 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
        /* Request MSI interrupts */
        hwirq = 0;
        for_each_pci_msi_entry(msi, pdev) {
-               rc = -EIO;
+               if (hwirq >= msi_vecs)
+                       break;
                irq = irq_alloc_desc(0);        /* Alloc irq on node 0 */
                if (irq < 0)
                        return -ENOMEM;
index 57f7cdac70a3114891c044f8cda2ae6fb6d48dc7..04388a254ffb220c6f9a9c12c092270c971a9cb9 100644 (file)
@@ -93,7 +93,6 @@ static int pci_perf_show(struct seq_file *m, void *v)
        }
 
        /* header */
-       seq_printf(m, "FMB @ %p\n", zdev->fmb);
        seq_printf(m, "Update interval: %u ms\n", zdev->fmb_update);
        seq_printf(m, "Samples: %u\n", zdev->fmb->samples);
        seq_printf(m, "Last update TOD: %Lx\n", zdev->fmb->last_update);
index 65300193b99f316c6d3f39c7db60f545272789c3..c521ade2557c5157f675edaa92c40f23585273fd 100644 (file)
@@ -122,11 +122,11 @@ endif
 ifdef CONFIG_CPU_LITTLE_ENDIAN
 ld-bfd                 := elf32-$(UTS_MACHINE)-linux
 LDFLAGS_vmlinux                += --defsym jiffies=jiffies_64 --oformat $(ld-bfd)
-LDFLAGS                        += -EL
+KBUILD_LDFLAGS         += -EL
 else
 ld-bfd                 := elf32-$(UTS_MACHINE)big-linux
 LDFLAGS_vmlinux                += --defsym jiffies=jiffies_64+4 --oformat $(ld-bfd)
-LDFLAGS                        += -EB
+KBUILD_LDFLAGS         += -EB
 endif
 
 export ld-bfd BITS
index 2d58c26bff9a72f9c2d98ca3757eef5faa5356c9..e6f2a38d2e61ece051d30350ad332b7b2acab229 100644 (file)
@@ -45,9 +45,13 @@ config SPARC
        select LOCKDEP_SMALL if LOCKDEP
        select NEED_DMA_MAP_STATE
        select NEED_SG_DMA_LENGTH
+       select HAVE_MEMBLOCK
+       select NO_BOOTMEM
 
 config SPARC32
        def_bool !64BIT
+       select ARCH_HAS_SYNC_DMA_FOR_CPU
+       select DMA_NONCOHERENT_OPS
        select GENERIC_ATOMIC64
        select CLZ_TAB
        select HAVE_UID16
@@ -60,7 +64,6 @@ config SPARC64
        select HAVE_KRETPROBES
        select HAVE_KPROBES
        select HAVE_RCU_TABLE_FREE if SMP
-       select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_ARCH_TRANSPARENT_HUGEPAGE
        select HAVE_DYNAMIC_FTRACE
@@ -79,7 +82,6 @@ config SPARC64
        select IRQ_PREFLOW_FASTEOI
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select HAVE_C_RECORDMCOUNT
-       select NO_BOOTMEM
        select HAVE_ARCH_AUDITSYSCALL
        select ARCH_SUPPORTS_ATOMIC_RMW
        select HAVE_NMI
index 966a13d2b127e7c4933aaf561d90f47a36a8a67d..048a033d6102739c2a2d16099aac733dbe864f3f 100644 (file)
@@ -9,10 +9,10 @@
 # Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
 
 # We are not yet configured - so test on arch
-ifeq ($(ARCH),sparc)
-        KBUILD_DEFCONFIG := sparc32_defconfig
-else
+ifeq ($(ARCH),sparc64)
         KBUILD_DEFCONFIG := sparc64_defconfig
+else
+        KBUILD_DEFCONFIG := sparc32_defconfig
 endif
 
 ifeq ($(CONFIG_SPARC32),y)
@@ -21,7 +21,7 @@ ifeq ($(CONFIG_SPARC32),y)
 #
 
 CHECKFLAGS     += -D__sparc__
-LDFLAGS        := -m elf32_sparc
+KBUILD_LDFLAGS := -m elf32_sparc
 export BITS    := 32
 UTS_MACHINE    := sparc
 
@@ -40,7 +40,7 @@ else
 #
 
 CHECKFLAGS    += -D__sparc__ -D__sparc_v9__ -D__arch64__
-LDFLAGS       := -m elf64_sparc
+KBUILD_LDFLAGS := -m elf64_sparc
 export BITS   := 64
 UTS_MACHINE   := sparc64
 
index 12ae33daf52f2a9308918331ac992d0a4cb482ab..e17566376934f5b5dc796083b4c11fcb36aa140f 100644 (file)
@@ -7,7 +7,6 @@
 #include <linux/dma-debug.h>
 
 extern const struct dma_map_ops *dma_ops;
-extern const struct dma_map_ops pci32_dma_ops;
 
 extern struct bus_type pci_bus_type;
 
@@ -15,11 +14,11 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
 #ifdef CONFIG_SPARC_LEON
        if (sparc_cpu_model == sparc_leon)
-               return &pci32_dma_ops;
+               return &dma_noncoherent_ops;
 #endif
 #if defined(CONFIG_SPARC32) && defined(CONFIG_PCI)
        if (bus == &pci_bus_type)
-               return &pci32_dma_ops;
+               return &dma_noncoherent_ops;
 #endif
        return dma_ops;
 }
index cca9134cfa7d2984cbc7b7b8c47073dd51b9de21..6799c93c9f274ff0c9a60a68131ae61f74fba937 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/scatterlist.h>
+#include <linux/dma-noncoherent.h>
 #include <linux/of_device.h>
 
 #include <asm/io.h>
@@ -434,42 +435,41 @@ arch_initcall(sparc_register_ioport);
 /* Allocate and map kernel buffer using consistent mode DMA for a device.
  * hwdev should be valid struct pci_dev pointer for PCI devices.
  */
-static void *pci32_alloc_coherent(struct device *dev, size_t len,
-                                 dma_addr_t *pba, gfp_t gfp,
-                                 unsigned long attrs)
+void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+               gfp_t gfp, unsigned long attrs)
 {
-       unsigned long len_total = PAGE_ALIGN(len);
+       unsigned long len_total = PAGE_ALIGN(size);
        void *va;
        struct resource *res;
        int order;
 
-       if (len == 0) {
+       if (size == 0) {
                return NULL;
        }
-       if (len > 256*1024) {                   /* __get_free_pages() limit */
+       if (size > 256*1024) {                  /* __get_free_pages() limit */
                return NULL;
        }
 
        order = get_order(len_total);
        va = (void *) __get_free_pages(gfp, order);
        if (va == NULL) {
-               printk("pci_alloc_consistent: no %ld pages\n", len_total>>PAGE_SHIFT);
+               printk("%s: no %ld pages\n", __func__, len_total>>PAGE_SHIFT);
                goto err_nopages;
        }
 
        if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) {
-               printk("pci_alloc_consistent: no core\n");
+               printk("%s: no core\n", __func__);
                goto err_nomem;
        }
 
        if (allocate_resource(&_sparc_dvma, res, len_total,
            _sparc_dvma.start, _sparc_dvma.end, PAGE_SIZE, NULL, NULL) != 0) {
-               printk("pci_alloc_consistent: cannot occupy 0x%lx", len_total);
+               printk("%s: cannot occupy 0x%lx", __func__, len_total);
                goto err_nova;
        }
        srmmu_mapiorange(0, virt_to_phys(va), res->start, len_total);
 
-       *pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */
+       *dma_handle = virt_to_phys(va);
        return (void *) res->start;
 
 err_nova:
@@ -481,184 +481,53 @@ err_nopages:
 }
 
 /* Free and unmap a consistent DMA buffer.
- * cpu_addr is what was returned from pci_alloc_consistent,
- * size must be the same as what as passed into pci_alloc_consistent,
- * and likewise dma_addr must be the same as what *dma_addrp was set to.
+ * cpu_addr is what was returned arch_dma_alloc, size must be the same as what
+ * was passed into arch_dma_alloc, and likewise dma_addr must be the same as
+ * what *dma_ndler was set to.
  *
  * References to the memory and mappings associated with cpu_addr/dma_addr
  * past this call are illegal.
  */
-static void pci32_free_coherent(struct device *dev, size_t n, void *p,
-                               dma_addr_t ba, unsigned long attrs)
+void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
+               dma_addr_t dma_addr, unsigned long attrs)
 {
        struct resource *res;
 
        if ((res = lookup_resource(&_sparc_dvma,
-           (unsigned long)p)) == NULL) {
-               printk("pci_free_consistent: cannot free %p\n", p);
+           (unsigned long)cpu_addr)) == NULL) {
+               printk("%s: cannot free %p\n", __func__, cpu_addr);
                return;
        }
 
-       if (((unsigned long)p & (PAGE_SIZE-1)) != 0) {
-               printk("pci_free_consistent: unaligned va %p\n", p);
+       if (((unsigned long)cpu_addr & (PAGE_SIZE-1)) != 0) {
+               printk("%s: unaligned va %p\n", __func__, cpu_addr);
                return;
        }
 
-       n = PAGE_ALIGN(n);
-       if (resource_size(res) != n) {
-               printk("pci_free_consistent: region 0x%lx asked 0x%lx\n",
-                   (long)resource_size(res), (long)n);
+       size = PAGE_ALIGN(size);
+       if (resource_size(res) != size) {
+               printk("%s: region 0x%lx asked 0x%zx\n", __func__,
+                   (long)resource_size(res), size);
                return;
        }
 
-       dma_make_coherent(ba, n);
-       srmmu_unmapiorange((unsigned long)p, n);
+       dma_make_coherent(dma_addr, size);
+       srmmu_unmapiorange((unsigned long)cpu_addr, size);
 
        release_resource(res);
        kfree(res);
-       free_pages((unsigned long)phys_to_virt(ba), get_order(n));
-}
-
-/*
- * Same as pci_map_single, but with pages.
- */
-static dma_addr_t pci32_map_page(struct device *dev, struct page *page,
-                                unsigned long offset, size_t size,
-                                enum dma_data_direction dir,
-                                unsigned long attrs)
-{
-       /* IIep is write-through, not flushing. */
-       return page_to_phys(page) + offset;
-}
-
-static void pci32_unmap_page(struct device *dev, dma_addr_t ba, size_t size,
-                            enum dma_data_direction dir, unsigned long attrs)
-{
-       if (dir != PCI_DMA_TODEVICE && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
-               dma_make_coherent(ba, PAGE_ALIGN(size));
-}
-
-/* Map a set of buffers described by scatterlist in streaming
- * mode for DMA.  This is the scatter-gather version of the
- * above pci_map_single interface.  Here the scatter gather list
- * elements are each tagged with the appropriate dma address
- * and length.  They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- *       DMA address/length pairs than there are SG table elements.
- *       (for example via virtual mapping capabilities)
- *       The routine returns the number of addr/length pairs actually
- *       used, at most nents.
- *
- * Device ownership issues as mentioned above for pci_map_single are
- * the same here.
- */
-static int pci32_map_sg(struct device *device, struct scatterlist *sgl,
-                       int nents, enum dma_data_direction dir,
-                       unsigned long attrs)
-{
-       struct scatterlist *sg;
-       int n;
-
-       /* IIep is write-through, not flushing. */
-       for_each_sg(sgl, sg, nents, n) {
-               sg->dma_address = sg_phys(sg);
-               sg->dma_length = sg->length;
-       }
-       return nents;
-}
-
-/* Unmap a set of streaming mode DMA translations.
- * Again, cpu read rules concerning calls here are the same as for
- * pci_unmap_single() above.
- */
-static void pci32_unmap_sg(struct device *dev, struct scatterlist *sgl,
-                          int nents, enum dma_data_direction dir,
-                          unsigned long attrs)
-{
-       struct scatterlist *sg;
-       int n;
-
-       if (dir != PCI_DMA_TODEVICE && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) {
-               for_each_sg(sgl, sg, nents, n) {
-                       dma_make_coherent(sg_phys(sg), PAGE_ALIGN(sg->length));
-               }
-       }
-}
-
-/* Make physical memory consistent for a single
- * streaming mode DMA translation before or after a transfer.
- *
- * If you perform a pci_map_single() but wish to interrogate the
- * buffer using the cpu, yet do not wish to teardown the PCI dma
- * mapping, you must call this function before doing so.  At the
- * next point you give the PCI dma address back to the card, you
- * must first perform a pci_dma_sync_for_device, and then the
- * device again owns the buffer.
- */
-static void pci32_sync_single_for_cpu(struct device *dev, dma_addr_t ba,
-                                     size_t size, enum dma_data_direction dir)
-{
-       if (dir != PCI_DMA_TODEVICE) {
-               dma_make_coherent(ba, PAGE_ALIGN(size));
-       }
-}
-
-static void pci32_sync_single_for_device(struct device *dev, dma_addr_t ba,
-                                        size_t size, enum dma_data_direction dir)
-{
-       if (dir != PCI_DMA_TODEVICE) {
-               dma_make_coherent(ba, PAGE_ALIGN(size));
-       }
+       free_pages((unsigned long)phys_to_virt(dma_addr), get_order(size));
 }
 
-/* Make physical memory consistent for a set of streaming
- * mode DMA translations after a transfer.
- *
- * The same as pci_dma_sync_single_* but for a scatter-gather list,
- * same rules and usage.
- */
-static void pci32_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl,
-                                 int nents, enum dma_data_direction dir)
-{
-       struct scatterlist *sg;
-       int n;
-
-       if (dir != PCI_DMA_TODEVICE) {
-               for_each_sg(sgl, sg, nents, n) {
-                       dma_make_coherent(sg_phys(sg), PAGE_ALIGN(sg->length));
-               }
-       }
-}
+/* IIep is write-through, not flushing on cpu to device transfer. */
 
-static void pci32_sync_sg_for_device(struct device *device, struct scatterlist *sgl,
-                                    int nents, enum dma_data_direction dir)
+void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
+               size_t size, enum dma_data_direction dir)
 {
-       struct scatterlist *sg;
-       int n;
-
-       if (dir != PCI_DMA_TODEVICE) {
-               for_each_sg(sgl, sg, nents, n) {
-                       dma_make_coherent(sg_phys(sg), PAGE_ALIGN(sg->length));
-               }
-       }
+       if (dir != PCI_DMA_TODEVICE)
+               dma_make_coherent(paddr, PAGE_ALIGN(size));
 }
 
-/* note: leon re-uses pci32_dma_ops */
-const struct dma_map_ops pci32_dma_ops = {
-       .alloc                  = pci32_alloc_coherent,
-       .free                   = pci32_free_coherent,
-       .map_page               = pci32_map_page,
-       .unmap_page             = pci32_unmap_page,
-       .map_sg                 = pci32_map_sg,
-       .unmap_sg               = pci32_unmap_sg,
-       .sync_single_for_cpu    = pci32_sync_single_for_cpu,
-       .sync_single_for_device = pci32_sync_single_for_device,
-       .sync_sg_for_cpu        = pci32_sync_sg_for_cpu,
-       .sync_sg_for_device     = pci32_sync_sg_for_device,
-};
-EXPORT_SYMBOL(pci32_dma_ops);
-
 const struct dma_map_ops *dma_ops = &sbus_dma_ops;
 EXPORT_SYMBOL(dma_ops);
 
index 3641a294ed5478ef3065d0cca08b6c54618fc0e2..e4abe9b8f97a60ba0304479e975b16442bfa9af7 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/irq.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
+#include <linux/dma-mapping.h>
 #include <asm/leon.h>
 #include <asm/leon_amba.h>
 
@@ -381,6 +382,9 @@ static struct platform_device * __init scan_one_device(struct device_node *dp,
        else
                dev_set_name(&op->dev, "%08x", dp->phandle);
 
+       op->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+       op->dev.dma_mask = &op->dev.coherent_dma_mask;
+
        if (of_device_register(op)) {
                printk("%s: Could not register of device.\n",
                       dp->full_name);
index 44e4d4435bed78032b1b7a0d9935e577ec196538..6df6086968c6a6064b2fe35f3c5ff03e7083fbc2 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
+#include <linux/dma-mapping.h>
 #include <linux/init.h>
 #include <linux/export.h>
 #include <linux/mod_devicetable.h>
@@ -675,6 +676,8 @@ static struct platform_device * __init scan_one_device(struct device_node *dp,
                dev_set_name(&op->dev, "root");
        else
                dev_set_name(&op->dev, "%08x", dp->phandle);
+       op->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+       op->dev.dma_mask = &op->dev.coherent_dma_mask;
 
        if (of_device_register(op)) {
                printk("%s: Could not register of device.\n",
index 7f3d9c59719afc4ea89bce33641c0e88777c3fb4..452e4d08085500dd302a6c482b6dc6e67eddc8be 100644 (file)
@@ -197,23 +197,27 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig,
 
 SYSCALL_DEFINE2(getdomainname, char __user *, name, int, len)
 {
-       int nlen, err;
-       
+       int nlen, err;
+       char tmp[__NEW_UTS_LEN + 1];
+
        if (len < 0)
                return -EINVAL;
 
-       down_read(&uts_sem);
-       
+       down_read(&uts_sem);
+
        nlen = strlen(utsname()->domainname) + 1;
        err = -EINVAL;
        if (nlen > len)
-               goto out;
+               goto out_unlock;
+       memcpy(tmp, utsname()->domainname, nlen);
 
-       err = -EFAULT;
-       if (!copy_to_user(name, utsname()->domainname, nlen))
-               err = 0;
+       up_read(&uts_sem);
 
-out:
+       if (copy_to_user(name, tmp, nlen))
+               return -EFAULT;
+       return 0;
+
+out_unlock:
        up_read(&uts_sem);
        return err;
 }
index 63baa8aa94142b9da0a2cdf9022b7f54d0761a74..274ed0b9b3e0aa95ca8e1d7030034bd0bb1e3a79 100644 (file)
@@ -519,23 +519,27 @@ asmlinkage void sparc_breakpoint(struct pt_regs *regs)
 
 SYSCALL_DEFINE2(getdomainname, char __user *, name, int, len)
 {
-        int nlen, err;
+       int nlen, err;
+       char tmp[__NEW_UTS_LEN + 1];
 
        if (len < 0)
                return -EINVAL;
 
-       down_read(&uts_sem);
-       
+       down_read(&uts_sem);
+
        nlen = strlen(utsname()->domainname) + 1;
        err = -EINVAL;
        if (nlen > len)
-               goto out;
+               goto out_unlock;
+       memcpy(tmp, utsname()->domainname, nlen);
+
+       up_read(&uts_sem);
 
-       err = -EFAULT;
-       if (!copy_to_user(name, utsname()->domainname, nlen))
-               err = 0;
+       if (copy_to_user(name, tmp, nlen))
+               return -EFAULT;
+       return 0;
 
-out:
+out_unlock:
        up_read(&uts_sem);
        return err;
 }
index 95fe4f081ba3b152c59fa001f279b976c8152e41..92634d4e440c26be54dddd96c22160259654dd1e 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/highmem.h>
 #include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/pagemap.h>
 #include <linux/poison.h>
 #include <linux/gfp.h>
@@ -101,13 +102,46 @@ static unsigned long calc_max_low_pfn(void)
        return tmp;
 }
 
+static void __init find_ramdisk(unsigned long end_of_phys_memory)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+       unsigned long size;
+
+       /* Now have to check initial ramdisk, so that it won't pass
+        * the end of memory
+        */
+       if (sparc_ramdisk_image) {
+               if (sparc_ramdisk_image >= (unsigned long)&_end - 2 * PAGE_SIZE)
+                       sparc_ramdisk_image -= KERNBASE;
+               initrd_start = sparc_ramdisk_image + phys_base;
+               initrd_end = initrd_start + sparc_ramdisk_size;
+               if (initrd_end > end_of_phys_memory) {
+                       printk(KERN_CRIT "initrd extends beyond end of memory "
+                              "(0x%016lx > 0x%016lx)\ndisabling initrd\n",
+                              initrd_end, end_of_phys_memory);
+                       initrd_start = 0;
+               } else {
+                       /* Reserve the initrd image area. */
+                       size = initrd_end - initrd_start;
+                       memblock_reserve(initrd_start, size);
+
+                       initrd_start = (initrd_start - phys_base) + PAGE_OFFSET;
+                       initrd_end = (initrd_end - phys_base) + PAGE_OFFSET;
+               }
+       }
+#endif
+}
+
 unsigned long __init bootmem_init(unsigned long *pages_avail)
 {
-       unsigned long bootmap_size, start_pfn;
-       unsigned long end_of_phys_memory = 0UL;
-       unsigned long bootmap_pfn, bytes_avail, size;
+       unsigned long start_pfn, bytes_avail, size;
+       unsigned long end_of_phys_memory = 0;
+       unsigned long high_pages = 0;
        int i;
 
+       memblock_set_bottom_up(true);
+       memblock_allow_resize();
+
        bytes_avail = 0UL;
        for (i = 0; sp_banks[i].num_bytes != 0; i++) {
                end_of_phys_memory = sp_banks[i].base_addr +
@@ -124,24 +158,25 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
                                if (sp_banks[i].num_bytes == 0) {
                                        sp_banks[i].base_addr = 0xdeadbeef;
                                } else {
+                                       memblock_add(sp_banks[i].base_addr,
+                                                    sp_banks[i].num_bytes);
                                        sp_banks[i+1].num_bytes = 0;
                                        sp_banks[i+1].base_addr = 0xdeadbeef;
                                }
                                break;
                        }
                }
+               memblock_add(sp_banks[i].base_addr, sp_banks[i].num_bytes);
        }
 
        /* Start with page aligned address of last symbol in kernel
-        * image.  
+        * image.
         */
        start_pfn  = (unsigned long)__pa(PAGE_ALIGN((unsigned long) &_end));
 
        /* Now shift down to get the real physical page frame number. */
        start_pfn >>= PAGE_SHIFT;
 
-       bootmap_pfn = start_pfn;
-
        max_pfn = end_of_phys_memory >> PAGE_SHIFT;
 
        max_low_pfn = max_pfn;
@@ -150,85 +185,19 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
        if (max_low_pfn > pfn_base + (SRMMU_MAXMEM >> PAGE_SHIFT)) {
                highstart_pfn = pfn_base + (SRMMU_MAXMEM >> PAGE_SHIFT);
                max_low_pfn = calc_max_low_pfn();
+               high_pages = calc_highpages();
                printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
-                   calc_highpages() >> (20 - PAGE_SHIFT));
+                   high_pages >> (20 - PAGE_SHIFT));
        }
 
-#ifdef CONFIG_BLK_DEV_INITRD
-       /* Now have to check initial ramdisk, so that bootmap does not overwrite it */
-       if (sparc_ramdisk_image) {
-               if (sparc_ramdisk_image >= (unsigned long)&_end - 2 * PAGE_SIZE)
-                       sparc_ramdisk_image -= KERNBASE;
-               initrd_start = sparc_ramdisk_image + phys_base;
-               initrd_end = initrd_start + sparc_ramdisk_size;
-               if (initrd_end > end_of_phys_memory) {
-                       printk(KERN_CRIT "initrd extends beyond end of memory "
-                                        "(0x%016lx > 0x%016lx)\ndisabling initrd\n",
-                              initrd_end, end_of_phys_memory);
-                       initrd_start = 0;
-               }
-               if (initrd_start) {
-                       if (initrd_start >= (start_pfn << PAGE_SHIFT) &&
-                           initrd_start < (start_pfn << PAGE_SHIFT) + 2 * PAGE_SIZE)
-                               bootmap_pfn = PAGE_ALIGN (initrd_end) >> PAGE_SHIFT;
-               }
-       }
-#endif 
-       /* Initialize the boot-time allocator. */
-       bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, pfn_base,
-                                        max_low_pfn);
-
-       /* Now register the available physical memory with the
-        * allocator.
-        */
-       *pages_avail = 0;
-       for (i = 0; sp_banks[i].num_bytes != 0; i++) {
-               unsigned long curr_pfn, last_pfn;
+       find_ramdisk(end_of_phys_memory);
 
-               curr_pfn = sp_banks[i].base_addr >> PAGE_SHIFT;
-               if (curr_pfn >= max_low_pfn)
-                       break;
-
-               last_pfn = (sp_banks[i].base_addr + sp_banks[i].num_bytes) >> PAGE_SHIFT;
-               if (last_pfn > max_low_pfn)
-                       last_pfn = max_low_pfn;
-
-               /*
-                * .. finally, did all the rounding and playing
-                * around just make the area go away?
-                */
-               if (last_pfn <= curr_pfn)
-                       continue;
-
-               size = (last_pfn - curr_pfn) << PAGE_SHIFT;
-               *pages_avail += last_pfn - curr_pfn;
-
-               free_bootmem(sp_banks[i].base_addr, size);
-       }
-
-#ifdef CONFIG_BLK_DEV_INITRD
-       if (initrd_start) {
-               /* Reserve the initrd image area. */
-               size = initrd_end - initrd_start;
-               reserve_bootmem(initrd_start, size, BOOTMEM_DEFAULT);
-               *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
-
-               initrd_start = (initrd_start - phys_base) + PAGE_OFFSET;
-               initrd_end = (initrd_end - phys_base) + PAGE_OFFSET;            
-       }
-#endif
        /* Reserve the kernel text/data/bss. */
        size = (start_pfn << PAGE_SHIFT) - phys_base;
-       reserve_bootmem(phys_base, size, BOOTMEM_DEFAULT);
-       *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
+       memblock_reserve(phys_base, size);
 
-       /* Reserve the bootmem map.   We do not account for it
-        * in pages_avail because we will release that memory
-        * in free_all_bootmem.
-        */
-       size = bootmap_size;
-       reserve_bootmem((bootmap_pfn << PAGE_SHIFT), size, BOOTMEM_DEFAULT);
-       *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
+       size = memblock_phys_mem_size() - memblock_reserved_size();
+       *pages_avail = (size >> PAGE_SHIFT) - high_pages;
 
        return max_pfn;
 }
@@ -322,7 +291,7 @@ void __init mem_init(void)
 
                map_high_region(start_pfn, end_pfn);
        }
-       
+
        mem_init_print_info(NULL);
 }
 
index 44ddc3e8fa662087bde49aea114c5e4a2f382e6b..ab1066c38944ee40bae5d76ca5d0da2d966bccea 100644 (file)
@@ -133,7 +133,7 @@ export LDS_ELF_FORMAT := $(ELF_FORMAT)
 # The wrappers will select whether using "malloc" or the kernel allocator.
 LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
 
-LD_FLAGS_CMDLINE = $(foreach opt,$(LDFLAGS),-Wl,$(opt))
+LD_FLAGS_CMDLINE = $(foreach opt,$(KBUILD_LDFLAGS),-Wl,$(opt))
 
 # Used by link-vmlinux.sh which has special support for um link
 export CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE)
index b0312f8947cee149cc1cea4d5b4bb851499a7b86..1a0be022f91d8d6d89bc154642e3bd29619e483c 100644 (file)
@@ -124,6 +124,7 @@ config X86
        select HAVE_ARCH_MMAP_RND_BITS          if MMU
        select HAVE_ARCH_MMAP_RND_COMPAT_BITS   if MMU && COMPAT
        select HAVE_ARCH_COMPAT_MMAP_BASES      if MMU && COMPAT
+       select HAVE_ARCH_PREL32_RELOCATIONS
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_THREAD_STRUCT_WHITELIST
        select HAVE_ARCH_TRACEHOOK
@@ -179,7 +180,8 @@ config X86
        select HAVE_HARDLOCKUP_DETECTOR_PERF    if PERF_EVENTS && HAVE_PERF_EVENTS_NMI
        select HAVE_PERF_REGS
        select HAVE_PERF_USER_STACK_DUMP
-       select HAVE_RCU_TABLE_FREE
+       select HAVE_RCU_TABLE_FREE              if PARAVIRT
+       select HAVE_RCU_TABLE_INVALIDATE        if HAVE_RCU_TABLE_FREE
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_RELIABLE_STACKTRACE         if X86_64 && (UNWINDER_FRAME_POINTER || UNWINDER_ORC) && STACK_VALIDATION
        select HAVE_STACKPROTECTOR              if CC_HAS_SANE_STACKPROTECTOR
@@ -2841,7 +2843,7 @@ config X86_SYSFB
          This option, if enabled, marks VGA/VBE/EFI framebuffers as generic
          framebuffers so the new generic system-framebuffer drivers can be
          used on x86. If the framebuffer is not compatible with the generic
-         modes, it is adverticed as fallback platform framebuffer so legacy
+         modes, it is advertised as fallback platform framebuffer so legacy
          drivers like efifb, vesafb and uvesafb can pick it up.
          If this option is not selected, all system framebuffers are always
          marked as fallback platform framebuffers as usual.
index 7e3c07d6ad424b228b0c50f2370fdb195794b61c..8f6e7eb8ae9fc2342b79cb0fc65de922dee11f2e 100644 (file)
@@ -175,22 +175,6 @@ ifdef CONFIG_FUNCTION_GRAPH_TRACER
   endif
 endif
 
-ifndef CC_HAVE_ASM_GOTO
-  $(error Compiler lacks asm-goto support.)
-endif
-
-#
-# Jump labels need '-maccumulate-outgoing-args' for gcc < 4.5.2 to prevent a
-# GCC bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46226).  There's no way
-# to test for this bug at compile-time because the test case needs to execute,
-# which is a no-go for cross compilers.  So check the GCC version instead.
-#
-ifdef CONFIG_JUMP_LABEL
-  ifneq ($(ACCUMULATE_OUTGOING_ARGS), 1)
-       ACCUMULATE_OUTGOING_ARGS = $(call cc-if-fullversion, -lt, 040502, 1)
-  endif
-endif
-
 ifeq ($(ACCUMULATE_OUTGOING_ARGS), 1)
        # This compiler flag is not supported by Clang:
        KBUILD_CFLAGS += $(call cc-option,-maccumulate-outgoing-args,)
@@ -219,7 +203,7 @@ sha256_ni_instr :=$(call as-instr,sha256msg1 %xmm0$(comma)%xmm1,-DCONFIG_AS_SHA2
 KBUILD_AFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr) $(avx2_instr) $(avx512_instr) $(sha1_ni_instr) $(sha256_ni_instr)
 KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr) $(avx2_instr) $(avx512_instr) $(sha1_ni_instr) $(sha256_ni_instr)
 
-LDFLAGS := -m elf_$(UTS_MACHINE)
+KBUILD_LDFLAGS := -m elf_$(UTS_MACHINE)
 
 #
 # The 64-bit kernel must be aligned to 2MB.  Pass -z max-page-size=0x200000 to
@@ -227,7 +211,7 @@ LDFLAGS := -m elf_$(UTS_MACHINE)
 # by the linker.
 #
 ifdef CONFIG_X86_64
-LDFLAGS += $(call ld-option, -z max-page-size=0x200000)
+KBUILD_LDFLAGS += $(call ld-option, -z max-page-size=0x200000)
 endif
 
 # Speed up the build
@@ -312,6 +296,13 @@ PHONY += vdso_install
 vdso_install:
        $(Q)$(MAKE) $(build)=arch/x86/entry/vdso $@
 
+archprepare: checkbin
+checkbin:
+ifndef CC_HAVE_ASM_GOTO
+       @echo Compiler lacks asm-goto support.
+       @exit 1
+endif
+
 archclean:
        $(Q)rm -rf $(objtree)/arch/i386
        $(Q)rm -rf $(objtree)/arch/x86_64
index 5296f8c9e7f0dc13f46f5844ebfa8c37aab3b455..91085a08de6cbb1e42bc6b106346256586b6740e 100644 (file)
@@ -4,7 +4,7 @@ core-y += arch/x86/crypto/
 ifeq ($(CONFIG_X86_32),y)
 START := 0x8048000
 
-LDFLAGS                        += -m elf_i386
+KBUILD_LDFLAGS         += -m elf_i386
 ELF_ARCH               := i386
 ELF_FORMAT             := elf32-i386
 CHECKFLAGS     += -D__i386__
@@ -43,7 +43,7 @@ KBUILD_CFLAGS += -fno-builtin -m64
 
 CHECKFLAGS  += -m64 -D__x86_64__
 KBUILD_AFLAGS += -m64
-LDFLAGS += -m elf_x86_64
+KBUILD_LDFLAGS += -m elf_x86_64
 KBUILD_CPPFLAGS += -m64
 
 ELF_ARCH := i386:x86-64
index 169c2feda14a055472a5e81481c2a4d2bd5717b8..28764dacf0182f5ca5ae26e6a2ff6caf700655b5 100644 (file)
@@ -42,16 +42,16 @@ KBUILD_AFLAGS  := $(KBUILD_CFLAGS) -D__ASSEMBLY__
 GCOV_PROFILE := n
 UBSAN_SANITIZE :=n
 
-LDFLAGS := -m elf_$(UTS_MACHINE)
+KBUILD_LDFLAGS := -m elf_$(UTS_MACHINE)
 # Compressed kernel should be built as PIE since it may be loaded at any
 # address by the bootloader.
 ifeq ($(CONFIG_X86_32),y)
-LDFLAGS += $(call ld-option, -pie) $(call ld-option, --no-dynamic-linker)
+KBUILD_LDFLAGS += $(call ld-option, -pie) $(call ld-option, --no-dynamic-linker)
 else
 # To build 64-bit compressed kernel as PIE, we disable relocation
 # overflow check to avoid relocation overflow error with a new linker
 # command-line option, -z noreloc-overflow.
-LDFLAGS += $(shell $(LD) --help 2>&1 | grep -q "\-z noreloc-overflow" \
+KBUILD_LDFLAGS += $(shell $(LD) --help 2>&1 | grep -q "\-z noreloc-overflow" \
        && echo "-z noreloc-overflow -pie --no-dynamic-linker")
 endif
 LDFLAGS_vmlinux := -T
index 302517929932bb52405d5396c57f084691090e5e..d1e19f358b6ec5fbc5c682e02d2b36149b0aa43a 100644 (file)
  * _ctype[] in lib/ctype.c is needed by isspace() of linux/ctype.h.
  * While both lib/ctype.c and lib/cmdline.c will bring EXPORT_SYMBOL
  * which is meaningless and will cause compiling error in some cases.
- * So do not include linux/export.h and define EXPORT_SYMBOL(sym)
- * as empty.
  */
-#define _LINUX_EXPORT_H
-#define EXPORT_SYMBOL(sym)
+#define __DISABLE_EXPORTS
 
 #include "misc.h"
 #include "error.h"
index 9bd139569b410d9e41cff15fb36aeb366930be95..cb2deb61c5d96dc53aabdeb7bd880ed436f75db7 100644 (file)
@@ -223,34 +223,34 @@ ALL_F:      .octa 0xffffffffffffffffffffffffffffffff
        pcmpeqd TWOONE(%rip), \TMP2
        pand    POLY(%rip), \TMP2
        pxor    \TMP2, \TMP3
-       movdqa  \TMP3, HashKey(%arg2)
+       movdqu  \TMP3, HashKey(%arg2)
 
        movdqa     \TMP3, \TMP5
        pshufd     $78, \TMP3, \TMP1
        pxor       \TMP3, \TMP1
-       movdqa     \TMP1, HashKey_k(%arg2)
+       movdqu     \TMP1, HashKey_k(%arg2)
 
        GHASH_MUL  \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
 # TMP5 = HashKey^2<<1 (mod poly)
-       movdqa     \TMP5, HashKey_2(%arg2)
+       movdqu     \TMP5, HashKey_2(%arg2)
 # HashKey_2 = HashKey^2<<1 (mod poly)
        pshufd     $78, \TMP5, \TMP1
        pxor       \TMP5, \TMP1
-       movdqa     \TMP1, HashKey_2_k(%arg2)
+       movdqu     \TMP1, HashKey_2_k(%arg2)
 
        GHASH_MUL  \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
 # TMP5 = HashKey^3<<1 (mod poly)
-       movdqa     \TMP5, HashKey_3(%arg2)
+       movdqu     \TMP5, HashKey_3(%arg2)
        pshufd     $78, \TMP5, \TMP1
        pxor       \TMP5, \TMP1
-       movdqa     \TMP1, HashKey_3_k(%arg2)
+       movdqu     \TMP1, HashKey_3_k(%arg2)
 
        GHASH_MUL  \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
 # TMP5 = HashKey^3<<1 (mod poly)
-       movdqa     \TMP5, HashKey_4(%arg2)
+       movdqu     \TMP5, HashKey_4(%arg2)
        pshufd     $78, \TMP5, \TMP1
        pxor       \TMP5, \TMP1
-       movdqa     \TMP1, HashKey_4_k(%arg2)
+       movdqu     \TMP1, HashKey_4_k(%arg2)
 .endm
 
 # GCM_INIT initializes a gcm_context struct to prepare for encoding/decoding.
@@ -271,7 +271,7 @@ ALL_F:      .octa 0xffffffffffffffffffffffffffffffff
        movdqu %xmm0, CurCount(%arg2) # ctx_data.current_counter = iv
 
        PRECOMPUTE \SUBKEY, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
-       movdqa HashKey(%arg2), %xmm13
+       movdqu HashKey(%arg2), %xmm13
 
        CALC_AAD_HASH %xmm13, \AAD, \AADLEN, %xmm0, %xmm1, %xmm2, %xmm3, \
        %xmm4, %xmm5, %xmm6
@@ -997,7 +997,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        pshufd    $78, \XMM5, \TMP6
        pxor      \XMM5, \TMP6
        paddd     ONE(%rip), \XMM0              # INCR CNT
-       movdqa    HashKey_4(%arg2), \TMP5
+       movdqu    HashKey_4(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP4           # TMP4 = a1*b1
        movdqa    \XMM0, \XMM1
        paddd     ONE(%rip), \XMM0              # INCR CNT
@@ -1016,7 +1016,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        pxor      (%arg1), \XMM2
        pxor      (%arg1), \XMM3
        pxor      (%arg1), \XMM4
-       movdqa    HashKey_4_k(%arg2), \TMP5
+       movdqu    HashKey_4_k(%arg2), \TMP5
        PCLMULQDQ 0x00, \TMP5, \TMP6           # TMP6 = (a1+a0)*(b1+b0)
        movaps 0x10(%arg1), \TMP1
        AESENC    \TMP1, \XMM1              # Round 1
@@ -1031,7 +1031,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        movdqa    \XMM6, \TMP1
        pshufd    $78, \XMM6, \TMP2
        pxor      \XMM6, \TMP2
-       movdqa    HashKey_3(%arg2), \TMP5
+       movdqu    HashKey_3(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP1           # TMP1 = a1 * b1
        movaps 0x30(%arg1), \TMP3
        AESENC    \TMP3, \XMM1              # Round 3
@@ -1044,7 +1044,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        AESENC    \TMP3, \XMM2
        AESENC    \TMP3, \XMM3
        AESENC    \TMP3, \XMM4
-       movdqa    HashKey_3_k(%arg2), \TMP5
+       movdqu    HashKey_3_k(%arg2), \TMP5
        PCLMULQDQ 0x00, \TMP5, \TMP2           # TMP2 = (a1+a0)*(b1+b0)
        movaps 0x50(%arg1), \TMP3
        AESENC    \TMP3, \XMM1              # Round 5
@@ -1058,7 +1058,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        movdqa    \XMM7, \TMP1
        pshufd    $78, \XMM7, \TMP2
        pxor      \XMM7, \TMP2
-       movdqa    HashKey_2(%arg2), \TMP5
+       movdqu    HashKey_2(%arg2), \TMP5
 
         # Multiply TMP5 * HashKey using karatsuba
 
@@ -1074,7 +1074,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        AESENC    \TMP3, \XMM2
        AESENC    \TMP3, \XMM3
        AESENC    \TMP3, \XMM4
-       movdqa    HashKey_2_k(%arg2), \TMP5
+       movdqu    HashKey_2_k(%arg2), \TMP5
        PCLMULQDQ 0x00, \TMP5, \TMP2           # TMP2 = (a1+a0)*(b1+b0)
        movaps 0x80(%arg1), \TMP3
        AESENC    \TMP3, \XMM1             # Round 8
@@ -1092,7 +1092,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        movdqa    \XMM8, \TMP1
        pshufd    $78, \XMM8, \TMP2
        pxor      \XMM8, \TMP2
-       movdqa    HashKey(%arg2), \TMP5
+       movdqu    HashKey(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP1          # TMP1 = a1*b1
        movaps 0x90(%arg1), \TMP3
        AESENC    \TMP3, \XMM1            # Round 9
@@ -1121,7 +1121,7 @@ aes_loop_par_enc_done\@:
        AESENCLAST \TMP3, \XMM2
        AESENCLAST \TMP3, \XMM3
        AESENCLAST \TMP3, \XMM4
-       movdqa    HashKey_k(%arg2), \TMP5
+       movdqu    HashKey_k(%arg2), \TMP5
        PCLMULQDQ 0x00, \TMP5, \TMP2          # TMP2 = (a1+a0)*(b1+b0)
        movdqu    (%arg4,%r11,1), \TMP3
        pxor      \TMP3, \XMM1                 # Ciphertext/Plaintext XOR EK
@@ -1205,7 +1205,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        pshufd    $78, \XMM5, \TMP6
        pxor      \XMM5, \TMP6
        paddd     ONE(%rip), \XMM0              # INCR CNT
-       movdqa    HashKey_4(%arg2), \TMP5
+       movdqu    HashKey_4(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP4           # TMP4 = a1*b1
        movdqa    \XMM0, \XMM1
        paddd     ONE(%rip), \XMM0              # INCR CNT
@@ -1224,7 +1224,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        pxor      (%arg1), \XMM2
        pxor      (%arg1), \XMM3
        pxor      (%arg1), \XMM4
-       movdqa    HashKey_4_k(%arg2), \TMP5
+       movdqu    HashKey_4_k(%arg2), \TMP5
        PCLMULQDQ 0x00, \TMP5, \TMP6           # TMP6 = (a1+a0)*(b1+b0)
        movaps 0x10(%arg1), \TMP1
        AESENC    \TMP1, \XMM1              # Round 1
@@ -1239,7 +1239,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        movdqa    \XMM6, \TMP1
        pshufd    $78, \XMM6, \TMP2
        pxor      \XMM6, \TMP2
-       movdqa    HashKey_3(%arg2), \TMP5
+       movdqu    HashKey_3(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP1           # TMP1 = a1 * b1
        movaps 0x30(%arg1), \TMP3
        AESENC    \TMP3, \XMM1              # Round 3
@@ -1252,7 +1252,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        AESENC    \TMP3, \XMM2
        AESENC    \TMP3, \XMM3
        AESENC    \TMP3, \XMM4
-       movdqa    HashKey_3_k(%arg2), \TMP5
+       movdqu    HashKey_3_k(%arg2), \TMP5
        PCLMULQDQ 0x00, \TMP5, \TMP2           # TMP2 = (a1+a0)*(b1+b0)
        movaps 0x50(%arg1), \TMP3
        AESENC    \TMP3, \XMM1              # Round 5
@@ -1266,7 +1266,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        movdqa    \XMM7, \TMP1
        pshufd    $78, \XMM7, \TMP2
        pxor      \XMM7, \TMP2
-       movdqa    HashKey_2(%arg2), \TMP5
+       movdqu    HashKey_2(%arg2), \TMP5
 
         # Multiply TMP5 * HashKey using karatsuba
 
@@ -1282,7 +1282,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        AESENC    \TMP3, \XMM2
        AESENC    \TMP3, \XMM3
        AESENC    \TMP3, \XMM4
-       movdqa    HashKey_2_k(%arg2), \TMP5
+       movdqu    HashKey_2_k(%arg2), \TMP5
        PCLMULQDQ 0x00, \TMP5, \TMP2           # TMP2 = (a1+a0)*(b1+b0)
        movaps 0x80(%arg1), \TMP3
        AESENC    \TMP3, \XMM1             # Round 8
@@ -1300,7 +1300,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
        movdqa    \XMM8, \TMP1
        pshufd    $78, \XMM8, \TMP2
        pxor      \XMM8, \TMP2
-       movdqa    HashKey(%arg2), \TMP5
+       movdqu    HashKey(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP1          # TMP1 = a1*b1
        movaps 0x90(%arg1), \TMP3
        AESENC    \TMP3, \XMM1            # Round 9
@@ -1329,7 +1329,7 @@ aes_loop_par_dec_done\@:
        AESENCLAST \TMP3, \XMM2
        AESENCLAST \TMP3, \XMM3
        AESENCLAST \TMP3, \XMM4
-       movdqa    HashKey_k(%arg2), \TMP5
+       movdqu    HashKey_k(%arg2), \TMP5
        PCLMULQDQ 0x00, \TMP5, \TMP2          # TMP2 = (a1+a0)*(b1+b0)
        movdqu    (%arg4,%r11,1), \TMP3
        pxor      \TMP3, \XMM1                 # Ciphertext/Plaintext XOR EK
@@ -1405,10 +1405,10 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
        movdqa    \XMM1, \TMP6
        pshufd    $78, \XMM1, \TMP2
        pxor      \XMM1, \TMP2
-       movdqa    HashKey_4(%arg2), \TMP5
+       movdqu    HashKey_4(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP6       # TMP6 = a1*b1
        PCLMULQDQ 0x00, \TMP5, \XMM1       # XMM1 = a0*b0
-       movdqa    HashKey_4_k(%arg2), \TMP4
+       movdqu    HashKey_4_k(%arg2), \TMP4
        PCLMULQDQ 0x00, \TMP4, \TMP2       # TMP2 = (a1+a0)*(b1+b0)
        movdqa    \XMM1, \XMMDst
        movdqa    \TMP2, \XMM1              # result in TMP6, XMMDst, XMM1
@@ -1418,10 +1418,10 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
        movdqa    \XMM2, \TMP1
        pshufd    $78, \XMM2, \TMP2
        pxor      \XMM2, \TMP2
-       movdqa    HashKey_3(%arg2), \TMP5
+       movdqu    HashKey_3(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP1       # TMP1 = a1*b1
        PCLMULQDQ 0x00, \TMP5, \XMM2       # XMM2 = a0*b0
-       movdqa    HashKey_3_k(%arg2), \TMP4
+       movdqu    HashKey_3_k(%arg2), \TMP4
        PCLMULQDQ 0x00, \TMP4, \TMP2       # TMP2 = (a1+a0)*(b1+b0)
        pxor      \TMP1, \TMP6
        pxor      \XMM2, \XMMDst
@@ -1433,10 +1433,10 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
        movdqa    \XMM3, \TMP1
        pshufd    $78, \XMM3, \TMP2
        pxor      \XMM3, \TMP2
-       movdqa    HashKey_2(%arg2), \TMP5
+       movdqu    HashKey_2(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP1       # TMP1 = a1*b1
        PCLMULQDQ 0x00, \TMP5, \XMM3       # XMM3 = a0*b0
-       movdqa    HashKey_2_k(%arg2), \TMP4
+       movdqu    HashKey_2_k(%arg2), \TMP4
        PCLMULQDQ 0x00, \TMP4, \TMP2       # TMP2 = (a1+a0)*(b1+b0)
        pxor      \TMP1, \TMP6
        pxor      \XMM3, \XMMDst
@@ -1446,10 +1446,10 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
        movdqa    \XMM4, \TMP1
        pshufd    $78, \XMM4, \TMP2
        pxor      \XMM4, \TMP2
-       movdqa    HashKey(%arg2), \TMP5
+       movdqu    HashKey(%arg2), \TMP5
        PCLMULQDQ 0x11, \TMP5, \TMP1        # TMP1 = a1*b1
        PCLMULQDQ 0x00, \TMP5, \XMM4       # XMM4 = a0*b0
-       movdqa    HashKey_k(%arg2), \TMP4
+       movdqu    HashKey_k(%arg2), \TMP4
        PCLMULQDQ 0x00, \TMP4, \TMP2       # TMP2 = (a1+a0)*(b1+b0)
        pxor      \TMP1, \TMP6
        pxor      \XMM4, \XMMDst
index 9f695f517747e409868226b0c7aea4afb29215ec..fa3f439f0a9200321a96efd2ba874dbda4824cff 100644 (file)
@@ -68,9 +68,9 @@ $(obj)/vdso-image-%.c: $(obj)/vdso%.so.dbg $(obj)/vdso%.so $(obj)/vdso2c FORCE
 CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \
        $(filter -g%,$(KBUILD_CFLAGS)) $(call cc-option, -fno-stack-protector) \
        -fno-omit-frame-pointer -foptimize-sibling-calls \
-       -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
+       -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO $(RETPOLINE_VDSO_CFLAGS)
 
-$(vobjs): KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS)) $(CFL)
+$(vobjs): KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL)
 
 #
 # vDSO code runs in userspace and -pg doesn't help with profiling anyway.
@@ -132,11 +132,13 @@ KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32))
 KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32))
 KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32))
 KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32))
+KBUILD_CFLAGS_32 := $(filter-out $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS_32))
 KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic
 KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector)
 KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls)
 KBUILD_CFLAGS_32 += -fno-omit-frame-pointer
 KBUILD_CFLAGS_32 += -DDISABLE_BRANCH_PROFILING
+KBUILD_CFLAGS_32 += $(RETPOLINE_VDSO_CFLAGS)
 $(obj)/vdso32.so.dbg: KBUILD_CFLAGS = $(KBUILD_CFLAGS_32)
 
 $(obj)/vdso32.so.dbg: FORCE \
index 5f4829f10129c5bfd59b803d0ddd4a21be0b3107..dfb2f7c0d0192bcd16569d03badd498f355accf7 100644 (file)
@@ -2465,7 +2465,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
 
        perf_callchain_store(entry, regs->ip);
 
-       if (!current->mm)
+       if (!nmi_uaccess_okay())
                return;
 
        if (perf_callchain_user32(regs, entry))
index 1147e1fed7fff45e28e9c18e59e81542d1647d7f..ef5f29f913d7b064f1a086ac0674bebb4c8a845a 100644 (file)
@@ -9,6 +9,7 @@
 #include <asm/mshyperv.h>
 #include <asm/msr.h>
 #include <asm/tlbflush.h>
+#include <asm/tlb.h>
 
 #define CREATE_TRACE_POINTS
 #include <asm/trace/hyperv.h>
@@ -231,4 +232,5 @@ void hyperv_setup_mmu_ops(void)
 
        pr_info("Using hypercall for remote TLB flush\n");
        pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others;
+       pv_mmu_ops.tlb_remove_table = tlb_remove_table;
 }
index de690c2d2e33aafc529e30d0b8066534c1789669..a0ab9ab61c754c6a413744bd54eb9599bfbf5dc1 100644 (file)
@@ -8,5 +8,6 @@ generated-y += xen-hypercalls.h
 
 generic-y += dma-contiguous.h
 generic-y += early_ioremap.h
+generic-y += export.h
 generic-y += mcs_spinlock.h
 generic-y += mm-arch-hooks.h
index b143717b92b3447c480495e23be68470bc7bf463..ce84388e540c918a01e31599bc78881a5b9d2954 100644 (file)
@@ -80,11 +80,11 @@ static __always_inline void arch_atomic_sub(int i, atomic_t *v)
  * true if the result is zero, or false for all
  * other cases.
  */
-#define arch_atomic_sub_and_test arch_atomic_sub_and_test
 static __always_inline bool arch_atomic_sub_and_test(int i, atomic_t *v)
 {
        GEN_BINARY_RMWcc(LOCK_PREFIX "subl", v->counter, "er", i, "%0", e);
 }
+#define arch_atomic_sub_and_test arch_atomic_sub_and_test
 
 /**
  * arch_atomic_inc - increment atomic variable
@@ -92,12 +92,12 @@ static __always_inline bool arch_atomic_sub_and_test(int i, atomic_t *v)
  *
  * Atomically increments @v by 1.
  */
-#define arch_atomic_inc arch_atomic_inc
 static __always_inline void arch_atomic_inc(atomic_t *v)
 {
        asm volatile(LOCK_PREFIX "incl %0"
                     : "+m" (v->counter));
 }
+#define arch_atomic_inc arch_atomic_inc
 
 /**
  * arch_atomic_dec - decrement atomic variable
@@ -105,12 +105,12 @@ static __always_inline void arch_atomic_inc(atomic_t *v)
  *
  * Atomically decrements @v by 1.
  */
-#define arch_atomic_dec arch_atomic_dec
 static __always_inline void arch_atomic_dec(atomic_t *v)
 {
        asm volatile(LOCK_PREFIX "decl %0"
                     : "+m" (v->counter));
 }
+#define arch_atomic_dec arch_atomic_dec
 
 /**
  * arch_atomic_dec_and_test - decrement and test
@@ -120,11 +120,11 @@ static __always_inline void arch_atomic_dec(atomic_t *v)
  * returns true if the result is 0, or false for all other
  * cases.
  */
-#define arch_atomic_dec_and_test arch_atomic_dec_and_test
 static __always_inline bool arch_atomic_dec_and_test(atomic_t *v)
 {
        GEN_UNARY_RMWcc(LOCK_PREFIX "decl", v->counter, "%0", e);
 }
+#define arch_atomic_dec_and_test arch_atomic_dec_and_test
 
 /**
  * arch_atomic_inc_and_test - increment and test
@@ -134,11 +134,11 @@ static __always_inline bool arch_atomic_dec_and_test(atomic_t *v)
  * and returns true if the result is zero, or false for all
  * other cases.
  */
-#define arch_atomic_inc_and_test arch_atomic_inc_and_test
 static __always_inline bool arch_atomic_inc_and_test(atomic_t *v)
 {
        GEN_UNARY_RMWcc(LOCK_PREFIX "incl", v->counter, "%0", e);
 }
+#define arch_atomic_inc_and_test arch_atomic_inc_and_test
 
 /**
  * arch_atomic_add_negative - add and test if negative
@@ -149,11 +149,11 @@ static __always_inline bool arch_atomic_inc_and_test(atomic_t *v)
  * if the result is negative, or false when
  * result is greater than or equal to zero.
  */
-#define arch_atomic_add_negative arch_atomic_add_negative
 static __always_inline bool arch_atomic_add_negative(int i, atomic_t *v)
 {
        GEN_BINARY_RMWcc(LOCK_PREFIX "addl", v->counter, "er", i, "%0", s);
 }
+#define arch_atomic_add_negative arch_atomic_add_negative
 
 /**
  * arch_atomic_add_return - add integer and return
index ef959f02d0702b8d16979f1dd3ad6c1f405363e9..6a5b0ec460da8c5c6f4fe83074c6b2ec916bae80 100644 (file)
@@ -205,12 +205,12 @@ static inline long long arch_atomic64_sub(long long i, atomic64_t *v)
  *
  * Atomically increments @v by 1.
  */
-#define arch_atomic64_inc arch_atomic64_inc
 static inline void arch_atomic64_inc(atomic64_t *v)
 {
        __alternative_atomic64(inc, inc_return, /* no output */,
                               "S" (v) : "memory", "eax", "ecx", "edx");
 }
+#define arch_atomic64_inc arch_atomic64_inc
 
 /**
  * arch_atomic64_dec - decrement atomic64 variable
@@ -218,12 +218,12 @@ static inline void arch_atomic64_inc(atomic64_t *v)
  *
  * Atomically decrements @v by 1.
  */
-#define arch_atomic64_dec arch_atomic64_dec
 static inline void arch_atomic64_dec(atomic64_t *v)
 {
        __alternative_atomic64(dec, dec_return, /* no output */,
                               "S" (v) : "memory", "eax", "ecx", "edx");
 }
+#define arch_atomic64_dec arch_atomic64_dec
 
 /**
  * arch_atomic64_add_unless - add unless the number is a given value
@@ -245,7 +245,6 @@ static inline int arch_atomic64_add_unless(atomic64_t *v, long long a,
        return (int)a;
 }
 
-#define arch_atomic64_inc_not_zero arch_atomic64_inc_not_zero
 static inline int arch_atomic64_inc_not_zero(atomic64_t *v)
 {
        int r;
@@ -253,8 +252,8 @@ static inline int arch_atomic64_inc_not_zero(atomic64_t *v)
                             "S" (v) : "ecx", "edx", "memory");
        return r;
 }
+#define arch_atomic64_inc_not_zero arch_atomic64_inc_not_zero
 
-#define arch_atomic64_dec_if_positive arch_atomic64_dec_if_positive
 static inline long long arch_atomic64_dec_if_positive(atomic64_t *v)
 {
        long long r;
@@ -262,6 +261,7 @@ static inline long long arch_atomic64_dec_if_positive(atomic64_t *v)
                             "S" (v) : "ecx", "memory");
        return r;
 }
+#define arch_atomic64_dec_if_positive arch_atomic64_dec_if_positive
 
 #undef alternative_atomic64
 #undef __alternative_atomic64
index 4343d9b4f30e32056d5f6d5d1d6a273b556a3bba..5f851d92eecd9ee8eaad86c6b002937633e9144f 100644 (file)
@@ -71,11 +71,11 @@ static inline void arch_atomic64_sub(long i, atomic64_t *v)
  * true if the result is zero, or false for all
  * other cases.
  */
-#define arch_atomic64_sub_and_test arch_atomic64_sub_and_test
 static inline bool arch_atomic64_sub_and_test(long i, atomic64_t *v)
 {
        GEN_BINARY_RMWcc(LOCK_PREFIX "subq", v->counter, "er", i, "%0", e);
 }
+#define arch_atomic64_sub_and_test arch_atomic64_sub_and_test
 
 /**
  * arch_atomic64_inc - increment atomic64 variable
@@ -83,13 +83,13 @@ static inline bool arch_atomic64_sub_and_test(long i, atomic64_t *v)
  *
  * Atomically increments @v by 1.
  */
-#define arch_atomic64_inc arch_atomic64_inc
 static __always_inline void arch_atomic64_inc(atomic64_t *v)
 {
        asm volatile(LOCK_PREFIX "incq %0"
                     : "=m" (v->counter)
                     : "m" (v->counter));
 }
+#define arch_atomic64_inc arch_atomic64_inc
 
 /**
  * arch_atomic64_dec - decrement atomic64 variable
@@ -97,13 +97,13 @@ static __always_inline void arch_atomic64_inc(atomic64_t *v)
  *
  * Atomically decrements @v by 1.
  */
-#define arch_atomic64_dec arch_atomic64_dec
 static __always_inline void arch_atomic64_dec(atomic64_t *v)
 {
        asm volatile(LOCK_PREFIX "decq %0"
                     : "=m" (v->counter)
                     : "m" (v->counter));
 }
+#define arch_atomic64_dec arch_atomic64_dec
 
 /**
  * arch_atomic64_dec_and_test - decrement and test
@@ -113,11 +113,11 @@ static __always_inline void arch_atomic64_dec(atomic64_t *v)
  * returns true if the result is 0, or false for all other
  * cases.
  */
-#define arch_atomic64_dec_and_test arch_atomic64_dec_and_test
 static inline bool arch_atomic64_dec_and_test(atomic64_t *v)
 {
        GEN_UNARY_RMWcc(LOCK_PREFIX "decq", v->counter, "%0", e);
 }
+#define arch_atomic64_dec_and_test arch_atomic64_dec_and_test
 
 /**
  * arch_atomic64_inc_and_test - increment and test
@@ -127,11 +127,11 @@ static inline bool arch_atomic64_dec_and_test(atomic64_t *v)
  * and returns true if the result is zero, or false for all
  * other cases.
  */
-#define arch_atomic64_inc_and_test arch_atomic64_inc_and_test
 static inline bool arch_atomic64_inc_and_test(atomic64_t *v)
 {
        GEN_UNARY_RMWcc(LOCK_PREFIX "incq", v->counter, "%0", e);
 }
+#define arch_atomic64_inc_and_test arch_atomic64_inc_and_test
 
 /**
  * arch_atomic64_add_negative - add and test if negative
@@ -142,11 +142,11 @@ static inline bool arch_atomic64_inc_and_test(atomic64_t *v)
  * if the result is negative, or false when
  * result is greater than or equal to zero.
  */
-#define arch_atomic64_add_negative arch_atomic64_add_negative
 static inline bool arch_atomic64_add_negative(long i, atomic64_t *v)
 {
        GEN_BINARY_RMWcc(LOCK_PREFIX "addq", v->counter, "er", i, "%0", s);
 }
+#define arch_atomic64_add_negative arch_atomic64_add_negative
 
 /**
  * arch_atomic64_add_return - add and return
diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h
deleted file mode 100644 (file)
index 2a51d66..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifdef CONFIG_64BIT
-#define KSYM_ALIGN 16
-#endif
-#include <asm-generic/export.h>
index 023b4a9fc8465e3c643824582d9d77124a2150b3..5f26962eff427d21294389fda52e3ab842f9aeae 100644 (file)
@@ -33,6 +33,11 @@ enum irq_remap_cap {
        IRQ_POSTING_CAP = 0,
 };
 
+enum {
+       IRQ_REMAP_XAPIC_MODE,
+       IRQ_REMAP_X2APIC_MODE,
+};
+
 struct vcpu_data {
        u64 pi_desc_addr;       /* Physical address of PI Descriptor */
        u32 vector;             /* Guest vector of the interrupt */
index c14f2a74b2be7495f1ee00c92322a58cc43d10a6..15450a675031d3562b4a9da3d3b15816c11003fb 100644 (file)
@@ -33,7 +33,8 @@ extern inline unsigned long native_save_fl(void)
        return flags;
 }
 
-static inline void native_restore_fl(unsigned long flags)
+extern inline void native_restore_fl(unsigned long flags);
+extern inline void native_restore_fl(unsigned long flags)
 {
        asm volatile("push %0 ; popf"
                     : /* no output */
index 395c9631e000a3a17aa574c1b25fcc2cafd5b5fb..75f1e35e7c1537d8323cf7ce17d05c95759c350b 100644 (file)
@@ -22,10 +22,20 @@ enum die_val {
        DIE_NMIUNKNOWN,
 };
 
+enum show_regs_mode {
+       SHOW_REGS_SHORT,
+       /*
+        * For when userspace crashed, but we don't think it's our fault, and
+        * therefore don't print kernel registers.
+        */
+       SHOW_REGS_USER,
+       SHOW_REGS_ALL
+};
+
 extern void die(const char *, struct pt_regs *,long);
 extern int __must_check __die(const char *, struct pt_regs *, long);
 extern void show_stack_regs(struct pt_regs *regs);
-extern void __show_regs(struct pt_regs *regs, int all);
+extern void __show_regs(struct pt_regs *regs, enum show_regs_mode);
 extern void show_iret_regs(struct pt_regs *regs);
 extern unsigned long oops_begin(void);
 extern void oops_end(unsigned long, struct pt_regs *, int signr);
index 00ddb0c9e612a6e084298ef0f7372b924b76ba12..8e90488c3d56895f62080666e2141df1731092f3 100644 (file)
@@ -1237,19 +1237,12 @@ enum emulation_result {
 #define EMULTYPE_NO_DECODE         (1 << 0)
 #define EMULTYPE_TRAP_UD           (1 << 1)
 #define EMULTYPE_SKIP              (1 << 2)
-#define EMULTYPE_RETRY             (1 << 3)
-#define EMULTYPE_NO_REEXECUTE      (1 << 4)
-#define EMULTYPE_NO_UD_ON_FAIL     (1 << 5)
-#define EMULTYPE_VMWARE                    (1 << 6)
-int x86_emulate_instruction(struct kvm_vcpu *vcpu, unsigned long cr2,
-                           int emulation_type, void *insn, int insn_len);
-
-static inline int emulate_instruction(struct kvm_vcpu *vcpu,
-                       int emulation_type)
-{
-       return x86_emulate_instruction(vcpu, 0,
-                       emulation_type | EMULTYPE_NO_REEXECUTE, NULL, 0);
-}
+#define EMULTYPE_ALLOW_RETRY       (1 << 3)
+#define EMULTYPE_NO_UD_ON_FAIL     (1 << 4)
+#define EMULTYPE_VMWARE                    (1 << 5)
+int kvm_emulate_instruction(struct kvm_vcpu *vcpu, int emulation_type);
+int kvm_emulate_instruction_from_buffer(struct kvm_vcpu *vcpu,
+                                       void *insn, int insn_len);
 
 void kvm_enable_efer_bits(u64);
 bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer);
@@ -1450,7 +1443,6 @@ asmlinkage void kvm_spurious_fault(void);
        ____kvm_handle_fault_on_reboot(insn, "")
 
 #define KVM_ARCH_WANT_MMU_NOTIFIER
-int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
 int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end);
 int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end);
 int kvm_test_age_hva(struct kvm *kvm, unsigned long hva);
@@ -1463,7 +1455,7 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event);
 void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu);
 
 int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low,
-                   unsigned long ipi_bitmap_high, int min,
+                   unsigned long ipi_bitmap_high, u32 min,
                    unsigned long icr, int op_64_bit);
 
 u64 kvm_get_arch_capabilities(void);
index 8c7b3e5a2d019262eafbb9ccd0514f3278c9255e..3a17107594c88a83f013ecc1123c10d76c6d30c2 100644 (file)
@@ -148,6 +148,7 @@ enum mce_notifier_prios {
        MCE_PRIO_LOWEST         = 0,
 };
 
+struct notifier_block;
 extern void mce_register_decode_chain(struct notifier_block *nb);
 extern void mce_unregister_decode_chain(struct notifier_block *nb);
 
index d49bbf4bb5c867ef5a086a15b02882d694a961f6..e375d4266b53e35bbe2383d7633d478f29871c4f 100644 (file)
@@ -309,6 +309,11 @@ static inline void flush_tlb_others(const struct cpumask *cpumask,
        PVOP_VCALL2(pv_mmu_ops.flush_tlb_others, cpumask, info);
 }
 
+static inline void paravirt_tlb_remove_table(struct mmu_gather *tlb, void *table)
+{
+       PVOP_VCALL2(pv_mmu_ops.tlb_remove_table, tlb, table);
+}
+
 static inline int paravirt_pgd_alloc(struct mm_struct *mm)
 {
        return PVOP_CALL1(int, pv_mmu_ops.pgd_alloc, mm);
index 180bc0bff0fbd98195b8e81ce9aa7232dde06ee2..4b75acc23b30bad579578b6988140f55bc88f6b9 100644 (file)
@@ -54,6 +54,7 @@ struct desc_struct;
 struct task_struct;
 struct cpumask;
 struct flush_tlb_info;
+struct mmu_gather;
 
 /*
  * Wrapper type for pointers to code which uses the non-standard
@@ -222,6 +223,8 @@ struct pv_mmu_ops {
        void (*flush_tlb_others)(const struct cpumask *cpus,
                                 const struct flush_tlb_info *info);
 
+       void (*tlb_remove_table)(struct mmu_gather *tlb, void *table);
+
        /* Hooks for allocating and freeing a pagetable top-level */
        int  (*pgd_alloc)(struct mm_struct *mm);
        void (*pgd_free)(struct mm_struct *mm, pgd_t *pgd);
index a564084c6141d42f603b257160a34685e1bffdbe..f8b1ad2c38280c823c103b5d3f6326a340c1060f 100644 (file)
@@ -2,6 +2,8 @@
 #ifndef _ASM_X86_PGTABLE_3LEVEL_H
 #define _ASM_X86_PGTABLE_3LEVEL_H
 
+#include <asm/atomic64_32.h>
+
 /*
  * Intel Physical Address Extension (PAE) Mode - three-level page
  * tables on PPro+ CPUs.
@@ -150,10 +152,7 @@ static inline pte_t native_ptep_get_and_clear(pte_t *ptep)
 {
        pte_t res;
 
-       /* xchg acts as a barrier before the setting of the high bits */
-       res.pte_low = xchg(&ptep->pte_low, 0);
-       res.pte_high = ptep->pte_high;
-       ptep->pte_high = 0;
+       res.pte = (pteval_t)arch_atomic64_xchg((atomic64_t *)ptep, 0);
 
        return res;
 }
index e4ffa565a69f0633cab94325bd894eac4bbe6a19..690c0307afed0932974e5965ccf7bed98daa10f9 100644 (file)
@@ -1195,7 +1195,7 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
                return xchg(pmdp, pmd);
        } else {
                pmd_t old = *pmdp;
-               *pmdp = pmd;
+               WRITE_ONCE(*pmdp, pmd);
                return old;
        }
 }
index f773d5e6c8cc465da7069987f9f24d6507c259af..ce2b59047cb839053043508d75ea47f8a726c8b9 100644 (file)
@@ -55,15 +55,15 @@ struct mm_struct;
 void set_pte_vaddr_p4d(p4d_t *p4d_page, unsigned long vaddr, pte_t new_pte);
 void set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte);
 
-static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr,
-                                   pte_t *ptep)
+static inline void native_set_pte(pte_t *ptep, pte_t pte)
 {
-       *ptep = native_make_pte(0);
+       WRITE_ONCE(*ptep, pte);
 }
 
-static inline void native_set_pte(pte_t *ptep, pte_t pte)
+static inline void native_pte_clear(struct mm_struct *mm, unsigned long addr,
+                                   pte_t *ptep)
 {
-       *ptep = pte;
+       native_set_pte(ptep, native_make_pte(0));
 }
 
 static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
@@ -73,7 +73,7 @@ static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
 
 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
 {
-       *pmdp = pmd;
+       WRITE_ONCE(*pmdp, pmd);
 }
 
 static inline void native_pmd_clear(pmd_t *pmd)
@@ -109,7 +109,7 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp)
 
 static inline void native_set_pud(pud_t *pudp, pud_t pud)
 {
-       *pudp = pud;
+       WRITE_ONCE(*pudp, pud);
 }
 
 static inline void native_pud_clear(pud_t *pud)
@@ -137,13 +137,13 @@ static inline void native_set_p4d(p4d_t *p4dp, p4d_t p4d)
        pgd_t pgd;
 
        if (pgtable_l5_enabled() || !IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION)) {
-               *p4dp = p4d;
+               WRITE_ONCE(*p4dp, p4d);
                return;
        }
 
        pgd = native_make_pgd(native_p4d_val(p4d));
        pgd = pti_set_user_pgtbl((pgd_t *)p4dp, pgd);
-       *p4dp = native_make_p4d(native_pgd_val(pgd));
+       WRITE_ONCE(*p4dp, native_make_p4d(native_pgd_val(pgd)));
 }
 
 static inline void native_p4d_clear(p4d_t *p4d)
@@ -153,7 +153,7 @@ static inline void native_p4d_clear(p4d_t *p4d)
 
 static inline void native_set_pgd(pgd_t *pgdp, pgd_t pgd)
 {
-       *pgdp = pti_set_user_pgtbl(pgdp, pgd);
+       WRITE_ONCE(*pgdp, pti_set_user_pgtbl(pgdp, pgd));
 }
 
 static inline void native_pgd_clear(pgd_t *pgd)
index 682286aca88141c5ec5315597020f6e7e0c9b0fc..d53c54b842daca1c847d8076aadd89564b23cf00 100644 (file)
@@ -132,6 +132,8 @@ struct cpuinfo_x86 {
        /* Index into per_cpu list: */
        u16                     cpu_index;
        u32                     microcode;
+       /* Address space bits used by the cache internally */
+       u8                      x86_cache_bits;
        unsigned                initialized : 1;
 } __randomize_layout;
 
@@ -181,9 +183,9 @@ extern const struct seq_operations cpuinfo_op;
 
 extern void cpu_detect(struct cpuinfo_x86 *c);
 
-static inline unsigned long l1tf_pfn_limit(void)
+static inline unsigned long long l1tf_pfn_limit(void)
 {
-       return BIT(boot_cpu_data.x86_phys_bits - 1 - PAGE_SHIFT) - 1;
+       return BIT_ULL(boot_cpu_data.x86_cache_bits - 1 - PAGE_SHIFT);
 }
 
 extern void early_cpu_init(void);
index 34cffcef7375dfa15cb30832972aa3d71e86d678..07a25753e85c5cd53b2613a71db91862fa31684f 100644 (file)
@@ -89,4 +89,46 @@ extern int kernel_set_to_readonly;
 void set_kernel_text_rw(void);
 void set_kernel_text_ro(void);
 
+#ifdef CONFIG_X86_64
+static inline int set_mce_nospec(unsigned long pfn)
+{
+       unsigned long decoy_addr;
+       int rc;
+
+       /*
+        * Mark the linear address as UC to make sure we don't log more
+        * errors because of speculative access to the page.
+        * We would like to just call:
+        *      set_memory_uc((unsigned long)pfn_to_kaddr(pfn), 1);
+        * but doing that would radically increase the odds of a
+        * speculative access to the poison page because we'd have
+        * the virtual address of the kernel 1:1 mapping sitting
+        * around in registers.
+        * Instead we get tricky.  We create a non-canonical address
+        * that looks just like the one we want, but has bit 63 flipped.
+        * This relies on set_memory_uc() properly sanitizing any __pa()
+        * results with __PHYSICAL_MASK or PTE_PFN_MASK.
+        */
+       decoy_addr = (pfn << PAGE_SHIFT) + (PAGE_OFFSET ^ BIT(63));
+
+       rc = set_memory_uc(decoy_addr, 1);
+       if (rc)
+               pr_warn("Could not invalidate pfn=0x%lx from 1:1 map\n", pfn);
+       return rc;
+}
+#define set_mce_nospec set_mce_nospec
+
+/* Restore full speculative operation to the pfn. */
+static inline int clear_mce_nospec(unsigned long pfn)
+{
+       return set_memory_wb((unsigned long) pfn_to_kaddr(pfn), 1);
+}
+#define clear_mce_nospec clear_mce_nospec
+#else
+/*
+ * Few people would run a 32-bit kernel on a machine that supports
+ * recoverable errors because they have too much memory to boot 32-bit.
+ */
+#endif
+
 #endif /* _ASM_X86_SET_MEMORY_H */
index 5f9012ff52ed3c879887df556613979fb0e7d184..33d3c88a7225ff938d81c8912d5ec05457b07e60 100644 (file)
@@ -39,6 +39,7 @@ extern void do_signal(struct pt_regs *regs);
 
 #define __ARCH_HAS_SA_RESTORER
 
+#include <asm/asm.h>
 #include <uapi/asm/sigcontext.h>
 
 #ifdef __i386__
@@ -86,9 +87,9 @@ static inline int __const_sigismember(sigset_t *set, int _sig)
 
 static inline int __gen_sigismember(sigset_t *set, int _sig)
 {
-       unsigned char ret;
-       asm("btl %2,%1\n\tsetc %0"
-           : "=qm"(ret) : "m"(*set), "Ir"(_sig-1) : "cc");
+       bool ret;
+       asm("btl %2,%1" CC_SET(c)
+           : CC_OUT(c) (ret) : "m"(*set), "Ir"(_sig-1));
        return ret;
 }
 
index b6dc698f992a54646266ba7a4dc2901e7bdfa109..f335aad404a479e98e4a5d38dc41ee5e5aa419ec 100644 (file)
@@ -111,6 +111,6 @@ static inline unsigned long caller_frame_pointer(void)
        return (unsigned long)frame;
 }
 
-void show_opcodes(u8 *rip, const char *loglvl);
+void show_opcodes(struct pt_regs *regs, const char *loglvl);
 void show_ip(struct pt_regs *regs, const char *loglvl);
 #endif /* _ASM_X86_STACKTRACE_H */
index 511bf5fae8b82abb7ebbd7f4173f70afae9d1538..58ce5288878e85db5c475d8891c0fff2817a20e4 100644 (file)
@@ -148,6 +148,22 @@ static inline unsigned long build_cr3_noflush(pgd_t *pgd, u16 asid)
 #define __flush_tlb_one_user(addr) __native_flush_tlb_one_user(addr)
 #endif
 
+static inline bool tlb_defer_switch_to_init_mm(void)
+{
+       /*
+        * If we have PCID, then switching to init_mm is reasonably
+        * fast.  If we don't have PCID, then switching to init_mm is
+        * quite slow, so we try to defer it in the hopes that we can
+        * avoid it entirely.  The latter approach runs the risk of
+        * receiving otherwise unnecessary IPIs.
+        *
+        * This choice is just a heuristic.  The tlb code can handle this
+        * function returning true or false regardless of whether we have
+        * PCID.
+        */
+       return !static_cpu_has(X86_FEATURE_PCID);
+}
+
 struct tlb_context {
        u64 ctx_id;
        u64 tlb_gen;
@@ -159,8 +175,16 @@ struct tlb_state {
         * are on.  This means that it may not match current->active_mm,
         * which will contain the previous user mm when we're in lazy TLB
         * mode even if we've already switched back to swapper_pg_dir.
+        *
+        * During switch_mm_irqs_off(), loaded_mm will be set to
+        * LOADED_MM_SWITCHING during the brief interrupts-off window
+        * when CR3 and loaded_mm would otherwise be inconsistent.  This
+        * is for nmi_uaccess_okay()'s benefit.
         */
        struct mm_struct *loaded_mm;
+
+#define LOADED_MM_SWITCHING ((struct mm_struct *)1)
+
        u16 loaded_mm_asid;
        u16 next_asid;
        /* last user mm's ctx id */
@@ -230,6 +254,38 @@ struct tlb_state {
 };
 DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate);
 
+/*
+ * Blindly accessing user memory from NMI context can be dangerous
+ * if we're in the middle of switching the current user task or
+ * switching the loaded mm.  It can also be dangerous if we
+ * interrupted some kernel code that was temporarily using a
+ * different mm.
+ */
+static inline bool nmi_uaccess_okay(void)
+{
+       struct mm_struct *loaded_mm = this_cpu_read(cpu_tlbstate.loaded_mm);
+       struct mm_struct *current_mm = current->mm;
+
+       VM_WARN_ON_ONCE(!loaded_mm);
+
+       /*
+        * The condition we want to check is
+        * current_mm->pgd == __va(read_cr3_pa()).  This may be slow, though,
+        * if we're running in a VM with shadow paging, and nmi_uaccess_okay()
+        * is supposed to be reasonably fast.
+        *
+        * Instead, we check the almost equivalent but somewhat conservative
+        * condition below, and we rely on the fact that switch_mm_irqs_off()
+        * sets loaded_mm to LOADED_MM_SWITCHING before writing to CR3.
+        */
+       if (loaded_mm != current_mm)
+               return false;
+
+       VM_WARN_ON_ONCE(current_mm->pgd != __va(read_cr3_pa()));
+
+       return true;
+}
+
 /* Initialize cr4 shadow for this CPU. */
 static inline void cr4_init_shadow(void)
 {
@@ -536,11 +592,9 @@ extern void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch);
 #ifndef CONFIG_PARAVIRT
 #define flush_tlb_others(mask, info)   \
        native_flush_tlb_others(mask, info)
-#endif
-
-extern void tlb_flush_remove_tables(struct mm_struct *mm);
-extern void tlb_flush_remove_tables_local(void *arg);
 
-#define HAVE_TLB_FLUSH_REMOVE_TABLES
+#define paravirt_tlb_remove_table(tlb, page) \
+       tlb_remove_page(tlb, (void *)(page))
+#endif
 
 #endif /* _ASM_X86_TLBFLUSH_H */
index fb856c9f04494b6633d9ea8fd3ebb9204cc2c620..53748541c487ab00d8bd1ee9b4d05305aa33171d 100644 (file)
@@ -93,7 +93,7 @@ static inline unsigned int __getcpu(void)
         *
         * If RDPID is available, use it.
         */
-       alternative_io ("lsl %[p],%[seg]",
+       alternative_io ("lsl %[seg],%[p]",
                        ".byte 0xf3,0x0f,0xc7,0xf8", /* RDPID %eax/rax */
                        X86_FEATURE_RDPID,
                        [p] "=a" (p), [seg] "r" (__PER_CPU_SEG));
index 95f9107449bfb85c11b21b3c255edaeeb7e8ad87..9527ba5d62daba4fe5ca96d9c1ba2986f9612ccc 100644 (file)
@@ -74,6 +74,7 @@
 #define SECONDARY_EXEC_ENABLE_INVPCID          0x00001000
 #define SECONDARY_EXEC_ENABLE_VMFUNC            0x00002000
 #define SECONDARY_EXEC_SHADOW_VMCS              0x00004000
+#define SECONDARY_EXEC_ENCLS_EXITING           0x00008000
 #define SECONDARY_EXEC_RDSEED_EXITING          0x00010000
 #define SECONDARY_EXEC_ENABLE_PML               0x00020000
 #define SECONDARY_EXEC_XSAVES                  0x00100000
@@ -213,6 +214,8 @@ enum vmcs_field {
        VMWRITE_BITMAP_HIGH             = 0x00002029,
        XSS_EXIT_BITMAP                 = 0x0000202C,
        XSS_EXIT_BITMAP_HIGH            = 0x0000202D,
+       ENCLS_EXITING_BITMAP            = 0x0000202E,
+       ENCLS_EXITING_BITMAP_HIGH       = 0x0000202F,
        TSC_MULTIPLIER                  = 0x00002032,
        TSC_MULTIPLIER_HIGH             = 0x00002033,
        GUEST_PHYSICAL_ADDRESS          = 0x00002400,
index 6b2f90a0b149284f7e7f0bf103de6abd96607aa7..ef05bea7010de473c4a73f5d99a1f74af2327ebc 100644 (file)
@@ -197,17 +197,6 @@ extern struct { char _entry[32]; } hypercall_page[];
        (type)__res;                                                    \
 })
 
-#define _hypercall5(type, name, a1, a2, a3, a4, a5)                    \
-({                                                                     \
-       __HYPERCALL_DECLS;                                              \
-       __HYPERCALL_5ARG(a1, a2, a3, a4, a5);                           \
-       asm volatile (__HYPERCALL                                       \
-                     : __HYPERCALL_5PARAM                              \
-                     : __HYPERCALL_ENTRY(name)                         \
-                     : __HYPERCALL_CLOBBER5);                          \
-       (type)__res;                                                    \
-})
-
 static inline long
 xen_single_call(unsigned int call,
                unsigned long a1, unsigned long a2,
@@ -266,47 +255,12 @@ HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
        return _hypercall2(int, set_gdt, frame_list, entries);
 }
 
-static inline int
-HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
-{
-       return _hypercall2(int, stack_switch, ss, esp);
-}
-
-#ifdef CONFIG_X86_32
-static inline int
-HYPERVISOR_set_callbacks(unsigned long event_selector,
-                        unsigned long event_address,
-                        unsigned long failsafe_selector,
-                        unsigned long failsafe_address)
-{
-       return _hypercall4(int, set_callbacks,
-                          event_selector, event_address,
-                          failsafe_selector, failsafe_address);
-}
-#else  /* CONFIG_X86_64 */
-static inline int
-HYPERVISOR_set_callbacks(unsigned long event_address,
-                       unsigned long failsafe_address,
-                       unsigned long syscall_address)
-{
-       return _hypercall3(int, set_callbacks,
-                          event_address, failsafe_address,
-                          syscall_address);
-}
-#endif  /* CONFIG_X86_{32,64} */
-
 static inline int
 HYPERVISOR_callback_op(int cmd, void *arg)
 {
        return _hypercall2(int, callback_op, cmd, arg);
 }
 
-static inline int
-HYPERVISOR_fpu_taskswitch(int set)
-{
-       return _hypercall1(int, fpu_taskswitch, set);
-}
-
 static inline int
 HYPERVISOR_sched_op(int cmd, void *arg)
 {
@@ -418,19 +372,6 @@ HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
        return _hypercall3(int, grant_table_op, cmd, uop, count);
 }
 
-static inline int
-HYPERVISOR_update_va_mapping_otherdomain(unsigned long va, pte_t new_val,
-                                        unsigned long flags, domid_t domid)
-{
-       if (sizeof(new_val) == sizeof(long))
-               return _hypercall4(int, update_va_mapping_otherdomain, va,
-                                  new_val.pte, flags, domid);
-       else
-               return _hypercall5(int, update_va_mapping_otherdomain, va,
-                                  new_val.pte, new_val.pte >> 32,
-                                  flags, domid);
-}
-
 static inline int
 HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type)
 {
@@ -465,12 +406,6 @@ HYPERVISOR_suspend(unsigned long start_info_mfn)
        return _hypercall3(int, sched_op, SCHEDOP_shutdown, &r, start_info_mfn);
 }
 
-static inline int
-HYPERVISOR_nmi_op(unsigned long op, unsigned long arg)
-{
-       return _hypercall2(int, nmi_op, op, arg);
-}
-
 static inline unsigned long __must_check
 HYPERVISOR_hvm_op(int op, void *arg)
 {
@@ -528,39 +463,6 @@ MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va,
        trace_xen_mc_entry(mcl, sizeof(new_val) == sizeof(long) ? 3 : 4);
 }
 
-static inline void
-MULTI_grant_table_op(struct multicall_entry *mcl, unsigned int cmd,
-                    void *uop, unsigned int count)
-{
-       mcl->op = __HYPERVISOR_grant_table_op;
-       mcl->args[0] = cmd;
-       mcl->args[1] = (unsigned long)uop;
-       mcl->args[2] = count;
-
-       trace_xen_mc_entry(mcl, 3);
-}
-
-static inline void
-MULTI_update_va_mapping_otherdomain(struct multicall_entry *mcl, unsigned long va,
-                                   pte_t new_val, unsigned long flags,
-                                   domid_t domid)
-{
-       mcl->op = __HYPERVISOR_update_va_mapping_otherdomain;
-       mcl->args[0] = va;
-       if (sizeof(new_val) == sizeof(long)) {
-               mcl->args[1] = new_val.pte;
-               mcl->args[2] = flags;
-               mcl->args[3] = domid;
-       } else {
-               mcl->args[1] = new_val.pte;
-               mcl->args[2] = new_val.pte >> 32;
-               mcl->args[3] = flags;
-               mcl->args[4] = domid;
-       }
-
-       trace_xen_mc_entry(mcl, sizeof(new_val) == sizeof(long) ? 4 : 5);
-}
-
 static inline void
 MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr,
                        struct desc_struct desc)
@@ -581,16 +483,6 @@ MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr,
        trace_xen_mc_entry(mcl, sizeof(maddr) == sizeof(long) ? 2 : 4);
 }
 
-static inline void
-MULTI_memory_op(struct multicall_entry *mcl, unsigned int cmd, void *arg)
-{
-       mcl->op = __HYPERVISOR_memory_op;
-       mcl->args[0] = cmd;
-       mcl->args[1] = (unsigned long)arg;
-
-       trace_xen_mc_entry(mcl, 2);
-}
-
 static inline void
 MULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req,
                 int count, int *success_count, domid_t domid)
@@ -617,16 +509,6 @@ MULTI_mmuext_op(struct multicall_entry *mcl, struct mmuext_op *op, int count,
        trace_xen_mc_entry(mcl, 4);
 }
 
-static inline void
-MULTI_set_gdt(struct multicall_entry *mcl, unsigned long *frames, int entries)
-{
-       mcl->op = __HYPERVISOR_set_gdt;
-       mcl->args[0] = (unsigned long)frames;
-       mcl->args[1] = entries;
-
-       trace_xen_mc_entry(mcl, 2);
-}
-
 static inline void
 MULTI_stack_switch(struct multicall_entry *mcl,
                   unsigned long ss, unsigned long esp)
index dde437f5d14ff828dccff19275033ff2330acc60..158ad1483c4352b2f93c7cbb931dfdb8dd40c3bf 100644 (file)
@@ -108,7 +108,7 @@ static long acpi_processor_ffh_cstate_probe_cpu(void *_cx)
                        cx->type);
        }
        snprintf(cx->desc,
-                       ACPI_CX_DESC_LEN, "ACPI FFH INTEL MWAIT 0x%x",
+                       ACPI_CX_DESC_LEN, "ACPI FFH MWAIT 0x%x",
                        cx->address);
 out:
        return retval;
index 014f214da5815d62f8f094f5e69f670c440ef69b..b9d5e7c9ef43e66c0b8d19fc0346be1779fa78d4 100644 (file)
@@ -684,8 +684,6 @@ void *__init_or_module text_poke_early(void *addr, const void *opcode,
  * It means the size must be writable atomically and the address must be aligned
  * in a way that permits an atomic write. It also makes sure we fit on a single
  * page.
- *
- * Note: Must be called under text_mutex.
  */
 void *text_poke(void *addr, const void *opcode, size_t len)
 {
@@ -700,6 +698,8 @@ void *text_poke(void *addr, const void *opcode, size_t len)
         */
        BUG_ON(!after_bootmem);
 
+       lockdep_assert_held(&text_mutex);
+
        if (!core_kernel_text((unsigned long)addr)) {
                pages[0] = vmalloc_to_page(addr);
                pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
@@ -782,8 +782,6 @@ int poke_int3_handler(struct pt_regs *regs)
  *     - replace the first byte (int3) by the first byte of
  *       replacing opcode
  *     - sync cores
- *
- * Note: must be called under text_mutex.
  */
 void *text_poke_bp(void *addr, const void *opcode, size_t len, void *handler)
 {
@@ -792,6 +790,9 @@ void *text_poke_bp(void *addr, const void *opcode, size_t len, void *handler)
        bp_int3_handler = handler;
        bp_int3_addr = (u8 *)addr + sizeof(int3);
        bp_patching_in_progress = true;
+
+       lockdep_assert_held(&text_mutex);
+
        /*
         * Corresponding read barrier in int3 notifier for making sure the
         * in_progress and handler are correctly ordered wrt. patching.
index 9f148e3d45b4fe2ec57eecf5bd13ba528f97fa37..7654febd510277bedf28f8cef6a5d599bcfe1f5c 100644 (file)
@@ -413,7 +413,7 @@ static int activate_managed(struct irq_data *irqd)
        if (WARN_ON_ONCE(cpumask_empty(vector_searchmask))) {
                /* Something in the core code broke! Survive gracefully */
                pr_err("Managed startup for irq %u, but no CPU\n", irqd->irq);
-               return EINVAL;
+               return -EINVAL;
        }
 
        ret = assign_managed_vector(irqd, vector_searchmask);
index cb4a16292aa7cb84c21d175844f3122db016a0a0..40bdaea97fe7cac25f2b04bc239fdc520d68f09e 100644 (file)
@@ -668,6 +668,45 @@ EXPORT_SYMBOL_GPL(l1tf_mitigation);
 enum vmx_l1d_flush_state l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_AUTO;
 EXPORT_SYMBOL_GPL(l1tf_vmx_mitigation);
 
+/*
+ * These CPUs all support 44bits physical address space internally in the
+ * cache but CPUID can report a smaller number of physical address bits.
+ *
+ * The L1TF mitigation uses the top most address bit for the inversion of
+ * non present PTEs. When the installed memory reaches into the top most
+ * address bit due to memory holes, which has been observed on machines
+ * which report 36bits physical address bits and have 32G RAM installed,
+ * then the mitigation range check in l1tf_select_mitigation() triggers.
+ * This is a false positive because the mitigation is still possible due to
+ * the fact that the cache uses 44bit internally. Use the cache bits
+ * instead of the reported physical bits and adjust them on the affected
+ * machines to 44bit if the reported bits are less than 44.
+ */
+static void override_cache_bits(struct cpuinfo_x86 *c)
+{
+       if (c->x86 != 6)
+               return;
+
+       switch (c->x86_model) {
+       case INTEL_FAM6_NEHALEM:
+       case INTEL_FAM6_WESTMERE:
+       case INTEL_FAM6_SANDYBRIDGE:
+       case INTEL_FAM6_IVYBRIDGE:
+       case INTEL_FAM6_HASWELL_CORE:
+       case INTEL_FAM6_HASWELL_ULT:
+       case INTEL_FAM6_HASWELL_GT3E:
+       case INTEL_FAM6_BROADWELL_CORE:
+       case INTEL_FAM6_BROADWELL_GT3E:
+       case INTEL_FAM6_SKYLAKE_MOBILE:
+       case INTEL_FAM6_SKYLAKE_DESKTOP:
+       case INTEL_FAM6_KABYLAKE_MOBILE:
+       case INTEL_FAM6_KABYLAKE_DESKTOP:
+               if (c->x86_cache_bits < 44)
+                       c->x86_cache_bits = 44;
+               break;
+       }
+}
+
 static void __init l1tf_select_mitigation(void)
 {
        u64 half_pa;
@@ -675,6 +714,8 @@ static void __init l1tf_select_mitigation(void)
        if (!boot_cpu_has_bug(X86_BUG_L1TF))
                return;
 
+       override_cache_bits(&boot_cpu_data);
+
        switch (l1tf_mitigation) {
        case L1TF_MITIGATION_OFF:
        case L1TF_MITIGATION_FLUSH_NOWARN:
@@ -694,14 +735,13 @@ static void __init l1tf_select_mitigation(void)
        return;
 #endif
 
-       /*
-        * This is extremely unlikely to happen because almost all
-        * systems have far more MAX_PA/2 than RAM can be fit into
-        * DIMM slots.
-        */
        half_pa = (u64)l1tf_pfn_limit() << PAGE_SHIFT;
        if (e820__mapped_any(half_pa, ULLONG_MAX - half_pa, E820_TYPE_RAM)) {
                pr_warn("System has more than MAX_PA/2 memory. L1TF mitigation not effective.\n");
+               pr_info("You may make it effective by booting the kernel with mem=%llu parameter.\n",
+                               half_pa);
+               pr_info("However, doing so will make a part of your RAM unusable.\n");
+               pr_info("Reading https://www.kernel.org/doc/html/latest/admin-guide/l1tf.html might help you decide.\n");
                return;
        }
 
index 84dee5ab745a2657499334c831ea2467408e81d4..44c4ef3d989b59b7bd98ebf617f8e5ee1d2a9548 100644 (file)
@@ -919,6 +919,7 @@ void get_cpu_address_sizes(struct cpuinfo_x86 *c)
        else if (cpu_has(c, X86_FEATURE_PAE) || cpu_has(c, X86_FEATURE_PSE36))
                c->x86_phys_bits = 36;
 #endif
+       c->x86_cache_bits = c->x86_phys_bits;
 }
 
 static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
index 401e8c1331089ebcd6b752fddc71d3214f6d331a..fc3c07fe7df58a22c01c8c1180d0b394bde8b59a 100644 (file)
@@ -150,6 +150,9 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
        if (cpu_has(c, X86_FEATURE_HYPERVISOR))
                return false;
 
+       if (c->x86 != 6)
+               return false;
+
        for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) {
                if (c->x86_model == spectre_bad_microcodes[i].model &&
                    c->x86_stepping == spectre_bad_microcodes[i].stepping)
index 374d1aa66952df3ec3af6a712077e16430e3f87a..ceb67cd5918ff4b0b5dbce93fa1f3a36670084bc 100644 (file)
@@ -113,21 +113,6 @@ static inline void mce_register_injector_chain(struct notifier_block *nb)  { }
 static inline void mce_unregister_injector_chain(struct notifier_block *nb)    { }
 #endif
 
-#ifndef CONFIG_X86_64
-/*
- * On 32-bit systems it would be difficult to safely unmap a poison page
- * from the kernel 1:1 map because there are no non-canonical addresses that
- * we can use to refer to the address without risking a speculative access.
- * However, this isn't much of an issue because:
- * 1) Few unmappable pages are in the 1:1 map. Most are in HIGHMEM which
- *    are only mapped into the kernel as needed
- * 2) Few people would run a 32-bit kernel on a machine that supports
- *    recoverable errors because they have too much memory to boot 32-bit.
- */
-static inline void mce_unmap_kpfn(unsigned long pfn) {}
-#define mce_unmap_kpfn mce_unmap_kpfn
-#endif
-
 struct mca_config {
        bool dont_log_ce;
        bool cmci_disabled;
index 4b767284b7f5e59e529c5c7e1ae90174d7d23654..953b3ce92dccf0f684ce90e3a27015c99e692470 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/irq_work.h>
 #include <linux/export.h>
 #include <linux/jump_label.h>
+#include <linux/set_memory.h>
 
 #include <asm/intel-family.h>
 #include <asm/processor.h>
@@ -50,7 +51,6 @@
 #include <asm/mce.h>
 #include <asm/msr.h>
 #include <asm/reboot.h>
-#include <asm/set_memory.h>
 
 #include "mce-internal.h"
 
@@ -108,10 +108,6 @@ static struct irq_work mce_irq_work;
 
 static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs);
 
-#ifndef mce_unmap_kpfn
-static void mce_unmap_kpfn(unsigned long pfn);
-#endif
-
 /*
  * CPU/chipset specific EDAC code can register a notifier call here to print
  * MCE errors in a human-readable form.
@@ -602,7 +598,7 @@ static int srao_decode_notifier(struct notifier_block *nb, unsigned long val,
        if (mce_usable_address(mce) && (mce->severity == MCE_AO_SEVERITY)) {
                pfn = mce->addr >> PAGE_SHIFT;
                if (!memory_failure(pfn, 0))
-                       mce_unmap_kpfn(pfn);
+                       set_mce_nospec(pfn);
        }
 
        return NOTIFY_OK;
@@ -1072,38 +1068,10 @@ static int do_memory_failure(struct mce *m)
        if (ret)
                pr_err("Memory error not recovered");
        else
-               mce_unmap_kpfn(m->addr >> PAGE_SHIFT);
+               set_mce_nospec(m->addr >> PAGE_SHIFT);
        return ret;
 }
 
-#ifndef mce_unmap_kpfn
-static void mce_unmap_kpfn(unsigned long pfn)
-{
-       unsigned long decoy_addr;
-
-       /*
-        * Unmap this page from the kernel 1:1 mappings to make sure
-        * we don't log more errors because of speculative access to
-        * the page.
-        * We would like to just call:
-        *      set_memory_np((unsigned long)pfn_to_kaddr(pfn), 1);
-        * but doing that would radically increase the odds of a
-        * speculative access to the poison page because we'd have
-        * the virtual address of the kernel 1:1 mapping sitting
-        * around in registers.
-        * Instead we get tricky.  We create a non-canonical address
-        * that looks just like the one we want, but has bit 63 flipped.
-        * This relies on set_memory_np() not checking whether we passed
-        * a legal address.
-        */
-
-       decoy_addr = (pfn << PAGE_SHIFT) + (PAGE_OFFSET ^ BIT(63));
-
-       if (set_memory_np(decoy_addr, 1))
-               pr_warn("Could not invalidate pfn=0x%lx from 1:1 map\n", pfn);
-}
-#endif
-
 
 /*
  * Cases where we avoid rendezvous handler timeout:
index 0624957aa0681fe7a260389fe8b64740383ff7c9..07b5fc00b188047cdd2830f164626e19de9da8f9 100644 (file)
@@ -504,6 +504,7 @@ static enum ucode_state apply_microcode_amd(int cpu)
        struct microcode_amd *mc_amd;
        struct ucode_cpu_info *uci;
        struct ucode_patch *p;
+       enum ucode_state ret;
        u32 rev, dummy;
 
        BUG_ON(raw_smp_processor_id() != cpu);
@@ -521,9 +522,8 @@ static enum ucode_state apply_microcode_amd(int cpu)
 
        /* need to apply patch? */
        if (rev >= mc_amd->hdr.patch_id) {
-               c->microcode = rev;
-               uci->cpu_sig.rev = rev;
-               return UCODE_OK;
+               ret = UCODE_OK;
+               goto out;
        }
 
        if (__apply_microcode_amd(mc_amd)) {
@@ -531,13 +531,21 @@ static enum ucode_state apply_microcode_amd(int cpu)
                        cpu, mc_amd->hdr.patch_id);
                return UCODE_ERROR;
        }
-       pr_info("CPU%d: new patch_level=0x%08x\n", cpu,
-               mc_amd->hdr.patch_id);
 
-       uci->cpu_sig.rev = mc_amd->hdr.patch_id;
-       c->microcode = mc_amd->hdr.patch_id;
+       rev = mc_amd->hdr.patch_id;
+       ret = UCODE_UPDATED;
+
+       pr_info("CPU%d: new patch_level=0x%08x\n", cpu, rev);
 
-       return UCODE_UPDATED;
+out:
+       uci->cpu_sig.rev = rev;
+       c->microcode     = rev;
+
+       /* Update boot_cpu_data's revision too, if we're on the BSP: */
+       if (c->cpu_index == boot_cpu_data.cpu_index)
+               boot_cpu_data.microcode = rev;
+
+       return ret;
 }
 
 static int install_equiv_cpu_table(const u8 *buf)
index 97ccf4c3b45bec517605813b1f24518b10466002..16936a24795c8457b789f7b428216cfc5bd1fb4e 100644 (file)
@@ -795,6 +795,7 @@ static enum ucode_state apply_microcode_intel(int cpu)
        struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
        struct cpuinfo_x86 *c = &cpu_data(cpu);
        struct microcode_intel *mc;
+       enum ucode_state ret;
        static int prev_rev;
        u32 rev;
 
@@ -817,9 +818,8 @@ static enum ucode_state apply_microcode_intel(int cpu)
         */
        rev = intel_get_microcode_revision();
        if (rev >= mc->hdr.rev) {
-               uci->cpu_sig.rev = rev;
-               c->microcode = rev;
-               return UCODE_OK;
+               ret = UCODE_OK;
+               goto out;
        }
 
        /*
@@ -848,10 +848,17 @@ static enum ucode_state apply_microcode_intel(int cpu)
                prev_rev = rev;
        }
 
+       ret = UCODE_UPDATED;
+
+out:
        uci->cpu_sig.rev = rev;
-       c->microcode = rev;
+       c->microcode     = rev;
+
+       /* Update boot_cpu_data's revision too, if we're on the BSP: */
+       if (c->cpu_index == boot_cpu_data.cpu_index)
+               boot_cpu_data.microcode = rev;
 
-       return UCODE_UPDATED;
+       return ret;
 }
 
 static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
index 9c8652974f8ed1f6a8ed20f97ac843ec332706f2..2b5886401e5f4eb2c221f813675927a53cc97d61 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/bug.h>
 #include <linux/nmi.h>
 #include <linux/sysfs.h>
+#include <linux/kasan.h>
 
 #include <asm/cpu_entry_area.h>
 #include <asm/stacktrace.h>
@@ -89,14 +90,24 @@ static void printk_stack_address(unsigned long address, int reliable,
  * Thus, the 2/3rds prologue and 64 byte OPCODE_BUFSIZE is just a random
  * guesstimate in attempt to achieve all of the above.
  */
-void show_opcodes(u8 *rip, const char *loglvl)
+void show_opcodes(struct pt_regs *regs, const char *loglvl)
 {
 #define PROLOGUE_SIZE 42
 #define EPILOGUE_SIZE 21
 #define OPCODE_BUFSIZE (PROLOGUE_SIZE + 1 + EPILOGUE_SIZE)
        u8 opcodes[OPCODE_BUFSIZE];
+       unsigned long prologue = regs->ip - PROLOGUE_SIZE;
+       bool bad_ip;
 
-       if (probe_kernel_read(opcodes, rip - PROLOGUE_SIZE, OPCODE_BUFSIZE)) {
+       /*
+        * Make sure userspace isn't trying to trick us into dumping kernel
+        * memory by pointing the userspace instruction pointer at it.
+        */
+       bad_ip = user_mode(regs) &&
+               __chk_range_not_ok(prologue, OPCODE_BUFSIZE, TASK_SIZE_MAX);
+
+       if (bad_ip || probe_kernel_read(opcodes, (u8 *)prologue,
+                                       OPCODE_BUFSIZE)) {
                printk("%sCode: Bad RIP value.\n", loglvl);
        } else {
                printk("%sCode: %" __stringify(PROLOGUE_SIZE) "ph <%02x> %"
@@ -112,7 +123,7 @@ void show_ip(struct pt_regs *regs, const char *loglvl)
 #else
        printk("%sRIP: %04x:%pS\n", loglvl, (int)regs->cs, (void *)regs->ip);
 #endif
-       show_opcodes((u8 *)regs->ip, loglvl);
+       show_opcodes(regs, loglvl);
 }
 
 void show_iret_regs(struct pt_regs *regs)
@@ -135,7 +146,7 @@ static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs,
         * they can be printed in the right context.
         */
        if (!partial && on_stack(info, regs, sizeof(*regs))) {
-               __show_regs(regs, 0);
+               __show_regs(regs, SHOW_REGS_SHORT);
 
        } else if (partial && on_stack(info, (void *)regs + IRET_FRAME_OFFSET,
                                       IRET_FRAME_SIZE)) {
@@ -333,7 +344,7 @@ void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
        oops_exit();
 
        /* Executive summary in case the oops scrolled away */
-       __show_regs(&exec_summary_regs, true);
+       __show_regs(&exec_summary_regs, SHOW_REGS_ALL);
 
        if (!signr)
                return;
@@ -346,7 +357,10 @@ void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
         * We're not going to return, but we might be on an IST stack or
         * have very little stack space left.  Rewind the stack and kill
         * the task.
+        * Before we rewind the stack, we have to tell KASAN that we're going to
+        * reuse the task stack and that existing poisons are invalid.
         */
+       kasan_unpoison_task_stack(current);
        rewind_stack_do_exit(signr);
 }
 NOKPROBE_SYMBOL(oops_end);
@@ -393,14 +407,9 @@ void die(const char *str, struct pt_regs *regs, long err)
 
 void show_regs(struct pt_regs *regs)
 {
-       bool all = true;
-
        show_regs_print_info(KERN_DEFAULT);
 
-       if (IS_ENABLED(CONFIG_X86_32))
-               all = !user_mode(regs);
-
-       __show_regs(regs, all);
+       __show_regs(regs, user_mode(regs) ? SHOW_REGS_USER : SHOW_REGS_ALL);
 
        /*
         * When in-kernel, we also print out the stack at the time of the fault..
index 0f471bd934172e673770936e9903d3c81623a6cb..d9b71924c23c9b939986b2d2ab153ba15b7077c3 100644 (file)
@@ -45,6 +45,7 @@
 #include <asm/apic.h>
 #include <asm/apicdef.h>
 #include <asm/hypervisor.h>
+#include <asm/tlb.h>
 
 static int kvmapf = 1;
 
@@ -636,8 +637,10 @@ static void __init kvm_guest_init(void)
 
        if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) &&
            !kvm_para_has_hint(KVM_HINTS_REALTIME) &&
-           kvm_para_has_feature(KVM_FEATURE_STEAL_TIME))
+           kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) {
                pv_mmu_ops.flush_tlb_others = kvm_flush_tlb_others;
+               pv_mmu_ops.tlb_remove_table = tlb_remove_table;
+       }
 
        if (kvm_para_has_feature(KVM_FEATURE_PV_EOI))
                apic_set_eoi_write(kvm_guest_apic_eoi_write);
index 930c88341e4ec875013d99f8c844ecace51088fb..afdb303285f874d481c7de2fbe7fd9f80873a424 100644 (file)
@@ -41,6 +41,7 @@
 #include <asm/tlbflush.h>
 #include <asm/timer.h>
 #include <asm/special_insns.h>
+#include <asm/tlb.h>
 
 /*
  * nop stub, which must not clobber anything *including the stack* to
@@ -409,6 +410,7 @@ struct pv_mmu_ops pv_mmu_ops __ro_after_init = {
        .flush_tlb_kernel = native_flush_tlb_global,
        .flush_tlb_one_user = native_flush_tlb_one_user,
        .flush_tlb_others = native_flush_tlb_others,
+       .tlb_remove_table = (void (*)(struct mmu_gather *, void *))tlb_remove_page,
 
        .pgd_alloc = __paravirt_pgd_alloc,
        .pgd_free = paravirt_nop,
index acfd04121da301a25ecd9475ed954baa2b600977..7ba73fe0d917de810abf81b3f344f2b68fa2c491 100644 (file)
@@ -40,8 +40,14 @@ int iommu_detected __read_mostly = 0;
  * devices and allow every device to access to whole physical memory. This is
  * useful if a user wants to use an IOMMU only for KVM device assignment to
  * guests and not for driver dma translation.
+ * It is also possible to disable by default in kernel config, and enable with
+ * iommu=nopt at boot time.
  */
+#ifdef CONFIG_IOMMU_DEFAULT_PASSTHROUGH
+int iommu_pass_through __read_mostly = 1;
+#else
 int iommu_pass_through __read_mostly;
+#endif
 
 extern struct iommu_table_entry __iommu_table[], __iommu_table_end[];
 
@@ -135,6 +141,8 @@ static __init int iommu_setup(char *p)
 #endif
                if (!strncmp(p, "pt", 2))
                        iommu_pass_through = 1;
+               if (!strncmp(p, "nopt", 4))
+                       iommu_pass_through = 0;
 
                gart_parse_options(p);
 
index 2924fd447e617dd6b4a2aaf1741fefe31c94b676..5046a3c9dec2feaa6761e38c9947e90ad4030efb 100644 (file)
@@ -59,7 +59,7 @@
 #include <asm/intel_rdt_sched.h>
 #include <asm/proto.h>
 
-void __show_regs(struct pt_regs *regs, int all)
+void __show_regs(struct pt_regs *regs, enum show_regs_mode mode)
 {
        unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
        unsigned long d0, d1, d2, d3, d6, d7;
@@ -85,7 +85,7 @@ void __show_regs(struct pt_regs *regs, int all)
        printk(KERN_DEFAULT "DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x EFLAGS: %08lx\n",
               (u16)regs->ds, (u16)regs->es, (u16)regs->fs, gs, ss, regs->flags);
 
-       if (!all)
+       if (mode != SHOW_REGS_ALL)
                return;
 
        cr0 = read_cr0();
index 476e3ddf88906d2df48bff128383306271bf14a6..ea5ea850348da94cafb85010c4ba123d83fbba57 100644 (file)
@@ -62,7 +62,7 @@
 __visible DEFINE_PER_CPU(unsigned long, rsp_scratch);
 
 /* Prints also some state that isn't saved in the pt_regs */
-void __show_regs(struct pt_regs *regs, int all)
+void __show_regs(struct pt_regs *regs, enum show_regs_mode mode)
 {
        unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs;
        unsigned long d0, d1, d2, d3, d6, d7;
@@ -87,9 +87,17 @@ void __show_regs(struct pt_regs *regs, int all)
        printk(KERN_DEFAULT "R13: %016lx R14: %016lx R15: %016lx\n",
               regs->r13, regs->r14, regs->r15);
 
-       if (!all)
+       if (mode == SHOW_REGS_SHORT)
                return;
 
+       if (mode == SHOW_REGS_USER) {
+               rdmsrl(MSR_FS_BASE, fs);
+               rdmsrl(MSR_KERNEL_GS_BASE, shadowgs);
+               printk(KERN_DEFAULT "FS:  %016lx GS:  %016lx\n",
+                      fs, shadowgs);
+               return;
+       }
+
        asm("movl %%ds,%0" : "=r" (ds));
        asm("movl %%cs,%0" : "=r" (cs));
        asm("movl %%es,%0" : "=r" (es));
@@ -384,6 +392,7 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
        start_thread_common(regs, new_ip, new_sp,
                            __USER_CS, __USER_DS, 0);
 }
+EXPORT_SYMBOL_GPL(start_thread);
 
 #ifdef CONFIG_COMPAT
 void compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp)
index 1463468ba9a0a5dc3914c92f88fffb491dc36d4f..6490f618e09696a7a407859037a0b1635cbb6f9f 100644 (file)
@@ -1415,7 +1415,7 @@ static bool __init determine_cpu_tsc_frequencies(bool early)
 
 static unsigned long __init get_loops_per_jiffy(void)
 {
-       unsigned long lpj = tsc_khz * KHZ;
+       u64 lpj = (u64)tsc_khz * KHZ;
 
        do_div(lpj, HZ);
        return lpj;
index 0cefba28c864a3a0925378ed9b438a05b554cff2..17c0472c5b344faaaac3153ff53c4600a3fcd81e 100644 (file)
@@ -548,7 +548,7 @@ int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq,
 }
 
 int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low,
-                   unsigned long ipi_bitmap_high, int min,
+                   unsigned long ipi_bitmap_high, u32 min,
                    unsigned long icr, int op_64_bit)
 {
        int i;
@@ -571,18 +571,31 @@ int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low,
        rcu_read_lock();
        map = rcu_dereference(kvm->arch.apic_map);
 
+       if (min > map->max_apic_id)
+               goto out;
        /* Bits above cluster_size are masked in the caller.  */
-       for_each_set_bit(i, &ipi_bitmap_low, BITS_PER_LONG) {
-               vcpu = map->phys_map[min + i]->vcpu;
-               count += kvm_apic_set_irq(vcpu, &irq, NULL);
+       for_each_set_bit(i, &ipi_bitmap_low,
+               min((u32)BITS_PER_LONG, (map->max_apic_id - min + 1))) {
+               if (map->phys_map[min + i]) {
+                       vcpu = map->phys_map[min + i]->vcpu;
+                       count += kvm_apic_set_irq(vcpu, &irq, NULL);
+               }
        }
 
        min += cluster_size;
-       for_each_set_bit(i, &ipi_bitmap_high, BITS_PER_LONG) {
-               vcpu = map->phys_map[min + i]->vcpu;
-               count += kvm_apic_set_irq(vcpu, &irq, NULL);
+
+       if (min > map->max_apic_id)
+               goto out;
+
+       for_each_set_bit(i, &ipi_bitmap_high,
+               min((u32)BITS_PER_LONG, (map->max_apic_id - min + 1))) {
+               if (map->phys_map[min + i]) {
+                       vcpu = map->phys_map[min + i]->vcpu;
+                       count += kvm_apic_set_irq(vcpu, &irq, NULL);
+               }
        }
 
+out:
        rcu_read_unlock();
        return count;
 }
index a282321329b51a10e7563b0d422bd9e38d57b530..e24ea7067373af69d258c46995007b0446a69fdc 100644 (file)
@@ -1853,11 +1853,6 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
        return kvm_handle_hva_range(kvm, hva, hva + 1, data, handler);
 }
 
-int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
-{
-       return kvm_handle_hva(kvm, hva, 0, kvm_unmap_rmapp);
-}
-
 int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end)
 {
        return kvm_handle_hva_range(kvm, start, end, 0, kvm_unmap_rmapp);
@@ -5217,7 +5212,7 @@ static int make_mmu_pages_available(struct kvm_vcpu *vcpu)
 int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u64 error_code,
                       void *insn, int insn_len)
 {
-       int r, emulation_type = EMULTYPE_RETRY;
+       int r, emulation_type = 0;
        enum emulation_result er;
        bool direct = vcpu->arch.mmu.direct_map;
 
@@ -5230,10 +5225,8 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u64 error_code,
        r = RET_PF_INVALID;
        if (unlikely(error_code & PFERR_RSVD_MASK)) {
                r = handle_mmio_page_fault(vcpu, cr2, direct);
-               if (r == RET_PF_EMULATE) {
-                       emulation_type = 0;
+               if (r == RET_PF_EMULATE)
                        goto emulate;
-               }
        }
 
        if (r == RET_PF_INVALID) {
@@ -5260,8 +5253,19 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u64 error_code,
                return 1;
        }
 
-       if (mmio_info_in_cache(vcpu, cr2, direct))
-               emulation_type = 0;
+       /*
+        * vcpu->arch.mmu.page_fault returned RET_PF_EMULATE, but we can still
+        * optimistically try to just unprotect the page and let the processor
+        * re-execute the instruction that caused the page fault.  Do not allow
+        * retrying MMIO emulation, as it's not only pointless but could also
+        * cause us to enter an infinite loop because the processor will keep
+        * faulting on the non-existent MMIO address.  Retrying an instruction
+        * from a nested guest is also pointless and dangerous as we are only
+        * explicitly shadowing L1's page tables, i.e. unprotecting something
+        * for L1 isn't going to magically fix whatever issue cause L2 to fail.
+        */
+       if (!mmio_info_in_cache(vcpu, cr2, direct) && !is_guest_mode(vcpu))
+               emulation_type = EMULTYPE_ALLOW_RETRY;
 emulate:
        /*
         * On AMD platforms, under certain conditions insn_len may be zero on #NPF.
index 73e27a98456fbd9cccf3bc1a2c7982cedb1302f0..89c4c5aa15f16c71af5404f302a627313a61fd96 100644 (file)
@@ -776,7 +776,7 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
        }
 
        if (!svm->next_rip) {
-               if (emulate_instruction(vcpu, EMULTYPE_SKIP) !=
+               if (kvm_emulate_instruction(vcpu, EMULTYPE_SKIP) !=
                                EMULATE_DONE)
                        printk(KERN_DEBUG "%s: NOP\n", __func__);
                return;
@@ -2715,7 +2715,7 @@ static int gp_interception(struct vcpu_svm *svm)
 
        WARN_ON_ONCE(!enable_vmware_backdoor);
 
-       er = emulate_instruction(vcpu,
+       er = kvm_emulate_instruction(vcpu,
                EMULTYPE_VMWARE | EMULTYPE_NO_UD_ON_FAIL);
        if (er == EMULATE_USER_EXIT)
                return 0;
@@ -2819,7 +2819,7 @@ static int io_interception(struct vcpu_svm *svm)
        string = (io_info & SVM_IOIO_STR_MASK) != 0;
        in = (io_info & SVM_IOIO_TYPE_MASK) != 0;
        if (string)
-               return emulate_instruction(vcpu, 0) == EMULATE_DONE;
+               return kvm_emulate_instruction(vcpu, 0) == EMULATE_DONE;
 
        port = io_info >> 16;
        size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT;
@@ -3861,7 +3861,7 @@ static int iret_interception(struct vcpu_svm *svm)
 static int invlpg_interception(struct vcpu_svm *svm)
 {
        if (!static_cpu_has(X86_FEATURE_DECODEASSISTS))
-               return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE;
+               return kvm_emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE;
 
        kvm_mmu_invlpg(&svm->vcpu, svm->vmcb->control.exit_info_1);
        return kvm_skip_emulated_instruction(&svm->vcpu);
@@ -3869,13 +3869,13 @@ static int invlpg_interception(struct vcpu_svm *svm)
 
 static int emulate_on_interception(struct vcpu_svm *svm)
 {
-       return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE;
+       return kvm_emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE;
 }
 
 static int rsm_interception(struct vcpu_svm *svm)
 {
-       return x86_emulate_instruction(&svm->vcpu, 0, 0,
-                                      rsm_ins_bytes, 2) == EMULATE_DONE;
+       return kvm_emulate_instruction_from_buffer(&svm->vcpu,
+                                       rsm_ins_bytes, 2) == EMULATE_DONE;
 }
 
 static int rdpmc_interception(struct vcpu_svm *svm)
@@ -4700,7 +4700,7 @@ static int avic_unaccelerated_access_interception(struct vcpu_svm *svm)
                ret = avic_unaccel_trap_write(svm);
        } else {
                /* Handling Fault */
-               ret = (emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE);
+               ret = (kvm_emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE);
        }
 
        return ret;
@@ -5586,8 +5586,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
 
        clgi();
 
-       local_irq_enable();
-
        /*
         * If this vCPU has touched SPEC_CTRL, restore the guest's value if
         * it's non-zero. Since vmentry is serialising on affected CPUs, there
@@ -5596,6 +5594,8 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
         */
        x86_spec_ctrl_set_guest(svm->spec_ctrl, svm->virt_spec_ctrl);
 
+       local_irq_enable();
+
        asm volatile (
                "push %%" _ASM_BP "; \n\t"
                "mov %c[rbx](%[svm]), %%" _ASM_BX " \n\t"
@@ -5718,12 +5718,12 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
        if (unlikely(!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL)))
                svm->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL);
 
-       x86_spec_ctrl_restore_host(svm->spec_ctrl, svm->virt_spec_ctrl);
-
        reload_tss(vcpu);
 
        local_irq_disable();
 
+       x86_spec_ctrl_restore_host(svm->spec_ctrl, svm->virt_spec_ctrl);
+
        vcpu->arch.cr2 = svm->vmcb->save.cr2;
        vcpu->arch.regs[VCPU_REGS_RAX] = svm->vmcb->save.rax;
        vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
@@ -6747,7 +6747,7 @@ e_free:
 static int sev_dbg_crypt(struct kvm *kvm, struct kvm_sev_cmd *argp, bool dec)
 {
        unsigned long vaddr, vaddr_end, next_vaddr;
-       unsigned long dst_vaddr, dst_vaddr_end;
+       unsigned long dst_vaddr;
        struct page **src_p, **dst_p;
        struct kvm_sev_dbg debug;
        unsigned long n;
@@ -6763,7 +6763,6 @@ static int sev_dbg_crypt(struct kvm *kvm, struct kvm_sev_cmd *argp, bool dec)
        size = debug.len;
        vaddr_end = vaddr + size;
        dst_vaddr = debug.dst_uaddr;
-       dst_vaddr_end = dst_vaddr + size;
 
        for (; vaddr < vaddr_end; vaddr = next_vaddr) {
                int len, s_off, d_off;
index 1519f030fd73198a2dbac4a6a050cf79b587c2cf..533a327372c876df0b1c2b99ea3558e2aaa92df4 100644 (file)
@@ -198,12 +198,14 @@ static enum vmx_l1d_flush_state __read_mostly vmentry_l1d_flush_param = VMENTER_
 
 static const struct {
        const char *option;
-       enum vmx_l1d_flush_state cmd;
+       bool for_parse;
 } vmentry_l1d_param[] = {
-       {"auto",        VMENTER_L1D_FLUSH_AUTO},
-       {"never",       VMENTER_L1D_FLUSH_NEVER},
-       {"cond",        VMENTER_L1D_FLUSH_COND},
-       {"always",      VMENTER_L1D_FLUSH_ALWAYS},
+       [VMENTER_L1D_FLUSH_AUTO]         = {"auto", true},
+       [VMENTER_L1D_FLUSH_NEVER]        = {"never", true},
+       [VMENTER_L1D_FLUSH_COND]         = {"cond", true},
+       [VMENTER_L1D_FLUSH_ALWAYS]       = {"always", true},
+       [VMENTER_L1D_FLUSH_EPT_DISABLED] = {"EPT disabled", false},
+       [VMENTER_L1D_FLUSH_NOT_REQUIRED] = {"not required", false},
 };
 
 #define L1D_CACHE_ORDER 4
@@ -219,15 +221,15 @@ static int vmx_setup_l1d_flush(enum vmx_l1d_flush_state l1tf)
                return 0;
        }
 
-       if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES)) {
-              u64 msr;
+       if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES)) {
+               u64 msr;
 
-              rdmsrl(MSR_IA32_ARCH_CAPABILITIES, msr);
-              if (msr & ARCH_CAP_SKIP_VMENTRY_L1DFLUSH) {
-                      l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_NOT_REQUIRED;
-                      return 0;
-              }
-       }
+               rdmsrl(MSR_IA32_ARCH_CAPABILITIES, msr);
+               if (msr & ARCH_CAP_SKIP_VMENTRY_L1DFLUSH) {
+                       l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_NOT_REQUIRED;
+                       return 0;
+               }
+       }
 
        /* If set to auto use the default l1tf mitigation method */
        if (l1tf == VMENTER_L1D_FLUSH_AUTO) {
@@ -287,8 +289,9 @@ static int vmentry_l1d_flush_parse(const char *s)
 
        if (s) {
                for (i = 0; i < ARRAY_SIZE(vmentry_l1d_param); i++) {
-                       if (sysfs_streq(s, vmentry_l1d_param[i].option))
-                               return vmentry_l1d_param[i].cmd;
+                       if (vmentry_l1d_param[i].for_parse &&
+                           sysfs_streq(s, vmentry_l1d_param[i].option))
+                               return i;
                }
        }
        return -EINVAL;
@@ -298,13 +301,13 @@ static int vmentry_l1d_flush_set(const char *s, const struct kernel_param *kp)
 {
        int l1tf, ret;
 
-       if (!boot_cpu_has(X86_BUG_L1TF))
-               return 0;
-
        l1tf = vmentry_l1d_flush_parse(s);
        if (l1tf < 0)
                return l1tf;
 
+       if (!boot_cpu_has(X86_BUG_L1TF))
+               return 0;
+
        /*
         * Has vmx_init() run already? If not then this is the pre init
         * parameter parsing. In that case just store the value and let
@@ -324,6 +327,9 @@ static int vmentry_l1d_flush_set(const char *s, const struct kernel_param *kp)
 
 static int vmentry_l1d_flush_get(char *s, const struct kernel_param *kp)
 {
+       if (WARN_ON_ONCE(l1tf_vmx_mitigation >= ARRAY_SIZE(vmentry_l1d_param)))
+               return sprintf(s, "???\n");
+
        return sprintf(s, "%s\n", vmentry_l1d_param[l1tf_vmx_mitigation].option);
 }
 
@@ -1684,6 +1690,12 @@ static inline bool cpu_has_vmx_virtual_intr_delivery(void)
                SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY;
 }
 
+static inline bool cpu_has_vmx_encls_vmexit(void)
+{
+       return vmcs_config.cpu_based_2nd_exec_ctrl &
+               SECONDARY_EXEC_ENCLS_EXITING;
+}
+
 /*
  * Comment's format: document - errata name - stepping - processor name.
  * Refer from
@@ -4551,7 +4563,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
                        SECONDARY_EXEC_RDRAND_EXITING |
                        SECONDARY_EXEC_ENABLE_PML |
                        SECONDARY_EXEC_TSC_SCALING |
-                       SECONDARY_EXEC_ENABLE_VMFUNC;
+                       SECONDARY_EXEC_ENABLE_VMFUNC |
+                       SECONDARY_EXEC_ENCLS_EXITING;
                if (adjust_vmx_controls(min2, opt2,
                                        MSR_IA32_VMX_PROCBASED_CTLS2,
                                        &_cpu_based_2nd_exec_control) < 0)
@@ -6648,6 +6661,9 @@ static void vmx_vcpu_setup(struct vcpu_vmx *vmx)
                vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg));
                vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
        }
+
+       if (cpu_has_vmx_encls_vmexit())
+               vmcs_write64(ENCLS_EXITING_BITMAP, -1ull);
 }
 
 static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
@@ -6967,7 +6983,7 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu,
         * Cause the #SS fault with 0 error code in VM86 mode.
         */
        if (((vec == GP_VECTOR) || (vec == SS_VECTOR)) && err_code == 0) {
-               if (emulate_instruction(vcpu, 0) == EMULATE_DONE) {
+               if (kvm_emulate_instruction(vcpu, 0) == EMULATE_DONE) {
                        if (vcpu->arch.halt_request) {
                                vcpu->arch.halt_request = 0;
                                return kvm_vcpu_halt(vcpu);
@@ -7038,7 +7054,7 @@ static int handle_exception(struct kvm_vcpu *vcpu)
 
        if (!vmx->rmode.vm86_active && is_gp_fault(intr_info)) {
                WARN_ON_ONCE(!enable_vmware_backdoor);
-               er = emulate_instruction(vcpu,
+               er = kvm_emulate_instruction(vcpu,
                        EMULTYPE_VMWARE | EMULTYPE_NO_UD_ON_FAIL);
                if (er == EMULATE_USER_EXIT)
                        return 0;
@@ -7141,7 +7157,7 @@ static int handle_io(struct kvm_vcpu *vcpu)
        ++vcpu->stat.io_exits;
 
        if (string)
-               return emulate_instruction(vcpu, 0) == EMULATE_DONE;
+               return kvm_emulate_instruction(vcpu, 0) == EMULATE_DONE;
 
        port = exit_qualification >> 16;
        size = (exit_qualification & 7) + 1;
@@ -7215,7 +7231,7 @@ static int handle_set_cr4(struct kvm_vcpu *vcpu, unsigned long val)
 static int handle_desc(struct kvm_vcpu *vcpu)
 {
        WARN_ON(!(vcpu->arch.cr4 & X86_CR4_UMIP));
-       return emulate_instruction(vcpu, 0) == EMULATE_DONE;
+       return kvm_emulate_instruction(vcpu, 0) == EMULATE_DONE;
 }
 
 static int handle_cr(struct kvm_vcpu *vcpu)
@@ -7464,7 +7480,7 @@ static int handle_vmcall(struct kvm_vcpu *vcpu)
 
 static int handle_invd(struct kvm_vcpu *vcpu)
 {
-       return emulate_instruction(vcpu, 0) == EMULATE_DONE;
+       return kvm_emulate_instruction(vcpu, 0) == EMULATE_DONE;
 }
 
 static int handle_invlpg(struct kvm_vcpu *vcpu)
@@ -7531,7 +7547,7 @@ static int handle_apic_access(struct kvm_vcpu *vcpu)
                        return kvm_skip_emulated_instruction(vcpu);
                }
        }
-       return emulate_instruction(vcpu, 0) == EMULATE_DONE;
+       return kvm_emulate_instruction(vcpu, 0) == EMULATE_DONE;
 }
 
 static int handle_apic_eoi_induced(struct kvm_vcpu *vcpu)
@@ -7688,8 +7704,8 @@ static int handle_ept_misconfig(struct kvm_vcpu *vcpu)
                if (!static_cpu_has(X86_FEATURE_HYPERVISOR))
                        return kvm_skip_emulated_instruction(vcpu);
                else
-                       return x86_emulate_instruction(vcpu, gpa, EMULTYPE_SKIP,
-                                                      NULL, 0) == EMULATE_DONE;
+                       return kvm_emulate_instruction(vcpu, EMULTYPE_SKIP) ==
+                                                               EMULATE_DONE;
        }
 
        return kvm_mmu_page_fault(vcpu, gpa, PFERR_RSVD_MASK, NULL, 0);
@@ -7732,7 +7748,7 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
                if (kvm_test_request(KVM_REQ_EVENT, vcpu))
                        return 1;
 
-               err = emulate_instruction(vcpu, 0);
+               err = kvm_emulate_instruction(vcpu, 0);
 
                if (err == EMULATE_USER_EXIT) {
                        ++vcpu->stat.mmio_exits;
@@ -9314,6 +9330,17 @@ fail:
        return 1;
 }
 
+static int handle_encls(struct kvm_vcpu *vcpu)
+{
+       /*
+        * SGX virtualization is not yet supported.  There is no software
+        * enable bit for SGX, so we have to trap ENCLS and inject a #UD
+        * to prevent the guest from executing ENCLS.
+        */
+       kvm_queue_exception(vcpu, UD_VECTOR);
+       return 1;
+}
+
 /*
  * The exit handlers return 1 if the exit was handled fully and guest execution
  * may resume.  Otherwise they set the kvm_run parameter to indicate what needs
@@ -9371,6 +9398,7 @@ static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
        [EXIT_REASON_INVPCID]                 = handle_invpcid,
        [EXIT_REASON_VMFUNC]                  = handle_vmfunc,
        [EXIT_REASON_PREEMPTION_TIMER]        = handle_preemption_timer,
+       [EXIT_REASON_ENCLS]                   = handle_encls,
 };
 
 static const int kvm_vmx_max_exit_handlers =
@@ -9741,6 +9769,9 @@ static bool nested_vmx_exit_reflected(struct kvm_vcpu *vcpu, u32 exit_reason)
        case EXIT_REASON_VMFUNC:
                /* VM functions are emulated through L2->L0 vmexits. */
                return false;
+       case EXIT_REASON_ENCLS:
+               /* SGX is never exposed to L1 */
+               return false;
        default:
                return true;
        }
@@ -10100,9 +10131,6 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
  * information but as all relevant affected CPUs have 32KiB L1D cache size
  * there is no point in doing so.
  */
-#define L1D_CACHE_ORDER 4
-static void *vmx_l1d_flush_pages;
-
 static void vmx_l1d_flush(struct kvm_vcpu *vcpu)
 {
        int size = PAGE_SIZE << L1D_CACHE_ORDER;
@@ -12101,6 +12129,9 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
                if (exec_control & SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)
                        vmcs_write64(APIC_ACCESS_ADDR, -1ull);
 
+               if (exec_control & SECONDARY_EXEC_ENCLS_EXITING)
+                       vmcs_write64(ENCLS_EXITING_BITMAP, -1ull);
+
                vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
        }
 
@@ -12506,8 +12537,11 @@ static int enter_vmx_non_root_mode(struct kvm_vcpu *vcpu, u32 *exit_qual)
        struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
        bool from_vmentry = !!exit_qual;
        u32 dummy_exit_qual;
+       u32 vmcs01_cpu_exec_ctrl;
        int r = 0;
 
+       vmcs01_cpu_exec_ctrl = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
+
        enter_guest_mode(vcpu);
 
        if (!(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS))
@@ -12543,6 +12577,25 @@ static int enter_vmx_non_root_mode(struct kvm_vcpu *vcpu, u32 *exit_qual)
                kvm_make_request(KVM_REQ_GET_VMCS12_PAGES, vcpu);
        }
 
+       /*
+        * If L1 had a pending IRQ/NMI until it executed
+        * VMLAUNCH/VMRESUME which wasn't delivered because it was
+        * disallowed (e.g. interrupts disabled), L0 needs to
+        * evaluate if this pending event should cause an exit from L2
+        * to L1 or delivered directly to L2 (e.g. In case L1 don't
+        * intercept EXTERNAL_INTERRUPT).
+        *
+        * Usually this would be handled by L0 requesting a
+        * IRQ/NMI window by setting VMCS accordingly. However,
+        * this setting was done on VMCS01 and now VMCS02 is active
+        * instead. Thus, we force L0 to perform pending event
+        * evaluation by requesting a KVM_REQ_EVENT.
+        */
+       if (vmcs01_cpu_exec_ctrl &
+               (CPU_BASED_VIRTUAL_INTR_PENDING | CPU_BASED_VIRTUAL_NMI_PENDING)) {
+               kvm_make_request(KVM_REQ_EVENT, vcpu);
+       }
+
        /*
         * Note no nested_vmx_succeed or nested_vmx_fail here. At this point
         * we are no longer running L1, and VMLAUNCH/VMRESUME has not yet
@@ -13957,9 +14010,6 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu,
            check_vmentry_postreqs(vcpu, vmcs12, &exit_qual))
                return -EINVAL;
 
-       if (kvm_state->flags & KVM_STATE_NESTED_RUN_PENDING)
-               vmx->nested.nested_run_pending = 1;
-
        vmx->nested.dirty_vmcs12 = true;
        ret = enter_vmx_non_root_mode(vcpu, NULL);
        if (ret)
index f7dff0457846474c6b1af5822674ffb7a64d2c9b..542f6315444d75aa365ca04dba4bddd7bfb369d3 100644 (file)
@@ -4987,7 +4987,7 @@ int handle_ud(struct kvm_vcpu *vcpu)
                emul_type = 0;
        }
 
-       er = emulate_instruction(vcpu, emul_type);
+       er = kvm_emulate_instruction(vcpu, emul_type);
        if (er == EMULATE_USER_EXIT)
                return 0;
        if (er != EMULATE_DONE)
@@ -5870,7 +5870,10 @@ static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t cr2,
        gpa_t gpa = cr2;
        kvm_pfn_t pfn;
 
-       if (emulation_type & EMULTYPE_NO_REEXECUTE)
+       if (!(emulation_type & EMULTYPE_ALLOW_RETRY))
+               return false;
+
+       if (WARN_ON_ONCE(is_guest_mode(vcpu)))
                return false;
 
        if (!vcpu->arch.mmu.direct_map) {
@@ -5958,7 +5961,10 @@ static bool retry_instruction(struct x86_emulate_ctxt *ctxt,
         */
        vcpu->arch.last_retry_eip = vcpu->arch.last_retry_addr = 0;
 
-       if (!(emulation_type & EMULTYPE_RETRY))
+       if (!(emulation_type & EMULTYPE_ALLOW_RETRY))
+               return false;
+
+       if (WARN_ON_ONCE(is_guest_mode(vcpu)))
                return false;
 
        if (x86_page_table_writing_insn(ctxt))
@@ -6276,7 +6282,19 @@ restart:
 
        return r;
 }
-EXPORT_SYMBOL_GPL(x86_emulate_instruction);
+
+int kvm_emulate_instruction(struct kvm_vcpu *vcpu, int emulation_type)
+{
+       return x86_emulate_instruction(vcpu, 0, emulation_type, NULL, 0);
+}
+EXPORT_SYMBOL_GPL(kvm_emulate_instruction);
+
+int kvm_emulate_instruction_from_buffer(struct kvm_vcpu *vcpu,
+                                       void *insn, int insn_len)
+{
+       return x86_emulate_instruction(vcpu, 0, 0, insn, insn_len);
+}
+EXPORT_SYMBOL_GPL(kvm_emulate_instruction_from_buffer);
 
 static int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size,
                            unsigned short port)
@@ -6576,14 +6594,12 @@ static void kvm_set_mmio_spte_mask(void)
        /* Set the present bit. */
        mask |= 1ull;
 
-#ifdef CONFIG_X86_64
        /*
         * If reserved bit is not supported, clear the present bit to disable
         * mmio page fault.
         */
-       if (maxphyaddr == 52)
+       if (IS_ENABLED(CONFIG_X86_64) && maxphyaddr == 52)
                mask &= ~1ull;
-#endif
 
        kvm_mmu_set_mmio_spte_mask(mask, mask);
 }
@@ -7305,8 +7321,9 @@ static void vcpu_load_eoi_exitmap(struct kvm_vcpu *vcpu)
        kvm_x86_ops->load_eoi_exitmap(vcpu, eoi_exit_bitmap);
 }
 
-void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
-               unsigned long start, unsigned long end)
+int kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
+               unsigned long start, unsigned long end,
+               bool blockable)
 {
        unsigned long apic_address;
 
@@ -7317,6 +7334,8 @@ void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
        apic_address = gfn_to_hva(kvm, APIC_DEFAULT_PHYS_BASE >> PAGE_SHIFT);
        if (start <= apic_address && apic_address < end)
                kvm_make_all_cpus_request(kvm, KVM_REQ_APIC_PAGE_RELOAD);
+
+       return 0;
 }
 
 void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu)
@@ -7733,7 +7752,7 @@ static inline int complete_emulated_io(struct kvm_vcpu *vcpu)
 {
        int r;
        vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
-       r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE);
+       r = kvm_emulate_instruction(vcpu, EMULTYPE_NO_DECODE);
        srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
        if (r != EMULATE_DONE)
                return 0;
index 257f27620bc272e3312295714a120de07963441f..67b9568613f34abdcacc208b4f23ef1414a512eb 100644 (file)
@@ -274,6 +274,8 @@ int kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
 bool kvm_mtrr_check_gfn_range_consistency(struct kvm_vcpu *vcpu, gfn_t gfn,
                                          int page_num);
 bool kvm_vector_hashing_enabled(void);
+int x86_emulate_instruction(struct kvm_vcpu *vcpu, unsigned long cr2,
+                           int emulation_type, void *insn, int insn_len);
 
 #define KVM_SUPPORTED_XCR0     (XFEATURE_MASK_FP | XFEATURE_MASK_SSE \
                                | XFEATURE_MASK_YMM | XFEATURE_MASK_BNDREGS \
index c8c6ad0d58b89c3621d0fcf11f45e00442ebf2a2..3f435d7fca5e62bc999e48c6a4f3e1c0fc86def9 100644 (file)
@@ -7,6 +7,8 @@
 #include <linux/uaccess.h>
 #include <linux/export.h>
 
+#include <asm/tlbflush.h>
+
 /*
  * We rely on the nested NMI work to allow atomic faults from the NMI path; the
  * nested NMI paths are careful to preserve CR2.
@@ -19,6 +21,9 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
        if (__range_not_ok(from, n, TASK_SIZE))
                return n;
 
+       if (!nmi_uaccess_okay())
+               return n;
+
        /*
         * Even though this function is typically called from NMI/IRQ context
         * disable pagefaults so that its behaviour is consistent even when
index b45f5aaefd7496e1af36037908efa8af3fccede5..076ebdce9bd4307945bf9d1ecfc54476686663fc 100644 (file)
@@ -2,6 +2,8 @@
 
 #include <linux/spinlock.h>
 #include <linux/percpu.h>
+#include <linux/kallsyms.h>
+#include <linux/kcore.h>
 
 #include <asm/cpu_entry_area.h>
 #include <asm/pgtable.h>
@@ -13,6 +15,7 @@ static DEFINE_PER_CPU_PAGE_ALIGNED(struct entry_stack_page, entry_stack_storage)
 #ifdef CONFIG_X86_64
 static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks
        [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]);
+static DEFINE_PER_CPU(struct kcore_list, kcore_entry_trampoline);
 #endif
 
 struct cpu_entry_area *get_cpu_entry_area(int cpu)
@@ -146,10 +149,40 @@ static void __init setup_cpu_entry_area(int cpu)
 
        cea_set_pte(&get_cpu_entry_area(cpu)->entry_trampoline,
                     __pa_symbol(_entry_trampoline), PAGE_KERNEL_RX);
+       /*
+        * The cpu_entry_area alias addresses are not in the kernel binary
+        * so they do not show up in /proc/kcore normally.  This adds entries
+        * for them manually.
+        */
+       kclist_add_remap(&per_cpu(kcore_entry_trampoline, cpu),
+                        _entry_trampoline,
+                        &get_cpu_entry_area(cpu)->entry_trampoline, PAGE_SIZE);
 #endif
        percpu_setup_debug_store(cpu);
 }
 
+#ifdef CONFIG_X86_64
+int arch_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
+                    char *name)
+{
+       unsigned int cpu, ncpu = 0;
+
+       if (symnum >= num_possible_cpus())
+               return -EINVAL;
+
+       for_each_possible_cpu(cpu) {
+               if (ncpu++ >= symnum)
+                       break;
+       }
+
+       *value = (unsigned long)&get_cpu_entry_area(cpu)->entry_trampoline;
+       *type = 't';
+       strlcpy(name, "__entry_SYSCALL_64_trampoline", KSYM_NAME_LEN);
+
+       return 0;
+}
+#endif
+
 static __init void setup_cpu_entry_area_ptes(void)
 {
 #ifdef CONFIG_X86_32
index b9123c497e0a7b20e25aa6608622118e6a00e3ea..47bebfe6efa70a316424934683f4302de33876a2 100644 (file)
@@ -837,7 +837,7 @@ show_signal_msg(struct pt_regs *regs, unsigned long error_code,
 
        printk(KERN_CONT "\n");
 
-       show_opcodes((u8 *)regs->ip, loglvl);
+       show_opcodes(regs, loglvl);
 }
 
 static void
index acfab322fbe062c24dee168f6b79e25e38290c68..7a8fc26c11155edac84372e2af7133e0bea07c36 100644 (file)
@@ -99,15 +99,22 @@ __ref void *alloc_low_pages(unsigned int num)
        }
 
        if ((pgt_buf_end + num) > pgt_buf_top || !can_use_brk_pgt) {
-               unsigned long ret;
-               if (min_pfn_mapped >= max_pfn_mapped)
-                       panic("alloc_low_pages: ran out of memory");
-               ret = memblock_find_in_range(min_pfn_mapped << PAGE_SHIFT,
+               unsigned long ret = 0;
+
+               if (min_pfn_mapped < max_pfn_mapped) {
+                       ret = memblock_find_in_range(
+                                       min_pfn_mapped << PAGE_SHIFT,
                                        max_pfn_mapped << PAGE_SHIFT,
                                        PAGE_SIZE * num , PAGE_SIZE);
+               }
+               if (ret)
+                       memblock_reserve(ret, PAGE_SIZE * num);
+               else if (can_use_brk_pgt)
+                       ret = __pa(extend_brk(PAGE_SIZE * num, PAGE_SIZE));
+
                if (!ret)
                        panic("alloc_low_pages: can not alloc memory");
-               memblock_reserve(ret, PAGE_SIZE * num);
+
                pfn = ret >> PAGE_SHIFT;
        } else {
                pfn = pgt_buf_end;
@@ -923,7 +930,7 @@ unsigned long max_swapfile_size(void)
 
        if (boot_cpu_has_bug(X86_BUG_L1TF)) {
                /* Limit the swap file size to MAX_PA/2 for L1TF workaround */
-               unsigned long l1tf_limit = l1tf_pfn_limit() + 1;
+               unsigned long long l1tf_limit = l1tf_pfn_limit();
                /*
                 * We encode swap offsets also with 3 bits below those for pfn
                 * which makes the usable limit higher.
@@ -931,7 +938,7 @@ unsigned long max_swapfile_size(void)
 #if CONFIG_PGTABLE_LEVELS > 2
                l1tf_limit <<= PAGE_SHIFT - SWP_OFFSET_FIRST_BIT;
 #endif
-               pages = min_t(unsigned long, l1tf_limit, pages);
+               pages = min_t(unsigned long long, l1tf_limit, pages);
        }
        return pages;
 }
index f40ab8185d9459d1712c702b10db48257a4866fe..1e95d57760cf79becf81c012df564e42ae7122e2 100644 (file)
@@ -257,7 +257,7 @@ bool pfn_modify_allowed(unsigned long pfn, pgprot_t prot)
        /* If it's real memory always allow */
        if (pfn_valid(pfn))
                return true;
-       if (pfn > l1tf_pfn_limit() && !capable(CAP_SYS_ADMIN))
+       if (pfn >= l1tf_pfn_limit() && !capable(CAP_SYS_ADMIN))
                return false;
        return true;
 }
index 8d6c34fe49be9567157b65fa69d8d1059f7779ee..51a5a69ecac9f24ab794ea6e86ea6d7fb39367a8 100644 (file)
@@ -1420,6 +1420,29 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias)
        return 0;
 }
 
+/*
+ * Machine check recovery code needs to change cache mode of poisoned
+ * pages to UC to avoid speculative access logging another error. But
+ * passing the address of the 1:1 mapping to set_memory_uc() is a fine
+ * way to encourage a speculative access. So we cheat and flip the top
+ * bit of the address. This works fine for the code that updates the
+ * page tables. But at the end of the process we need to flush the cache
+ * and the non-canonical address causes a #GP fault when used by the
+ * CLFLUSH instruction.
+ *
+ * But in the common case we already have a canonical address. This code
+ * will fix the top bit if needed and is a no-op otherwise.
+ */
+static inline unsigned long make_addr_canonical_again(unsigned long addr)
+{
+#ifdef CONFIG_X86_64
+       return (long)(addr << 1) >> 1;
+#else
+       return addr;
+#endif
+}
+
+
 static int change_page_attr_set_clr(unsigned long *addr, int numpages,
                                    pgprot_t mask_set, pgprot_t mask_clr,
                                    int force_split, int in_flag,
@@ -1465,7 +1488,7 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
                 * Save address for cache flush. *addr is modified in the call
                 * to __change_page_attr_set_clr() below.
                 */
-               baddr = *addr;
+               baddr = make_addr_canonical_again(*addr);
        }
 
        /* Must avoid aliasing mappings in the highmem code */
index 1555bd7d34493f972464e2df7e11a29f445ac600..3d0c83ef6aab98cde354b86f999eecfca3a38263 100644 (file)
@@ -512,6 +512,17 @@ static int free_ram_pages_type(u64 start, u64 end)
        return 0;
 }
 
+static u64 sanitize_phys(u64 address)
+{
+       /*
+        * When changing the memtype for pages containing poison allow
+        * for a "decoy" virtual address (bit 63 clear) passed to
+        * set_memory_X(). __pa() on a "decoy" address results in a
+        * physical address with bit 63 set.
+        */
+       return address & __PHYSICAL_MASK;
+}
+
 /*
  * req_type typically has one of the:
  * - _PAGE_CACHE_MODE_WB
@@ -533,6 +544,8 @@ int reserve_memtype(u64 start, u64 end, enum page_cache_mode req_type,
        int is_range_ram;
        int err = 0;
 
+       start = sanitize_phys(start);
+       end = sanitize_phys(end);
        BUG_ON(start >= end); /* end is exclusive */
 
        if (!pat_enabled()) {
@@ -609,6 +622,9 @@ int free_memtype(u64 start, u64 end)
        if (!pat_enabled())
                return 0;
 
+       start = sanitize_phys(start);
+       end = sanitize_phys(end);
+
        /* Low ISA region is always mapped WB. No need to track */
        if (x86_platform.is_untracked_pat_range(start, end))
                return 0;
index 3ef095c70ae31636fbecd185eac096ef5858d08b..ae394552fb945def068d2c877a153e9d7f040228 100644 (file)
@@ -63,7 +63,7 @@ void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
 {
        pgtable_page_dtor(pte);
        paravirt_release_pte(page_to_pfn(pte));
-       tlb_remove_table(tlb, pte);
+       paravirt_tlb_remove_table(tlb, pte);
 }
 
 #if CONFIG_PGTABLE_LEVELS > 2
@@ -79,21 +79,21 @@ void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
        tlb->need_flush_all = 1;
 #endif
        pgtable_pmd_page_dtor(page);
-       tlb_remove_table(tlb, page);
+       paravirt_tlb_remove_table(tlb, page);
 }
 
 #if CONFIG_PGTABLE_LEVELS > 3
 void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud)
 {
        paravirt_release_pud(__pa(pud) >> PAGE_SHIFT);
-       tlb_remove_table(tlb, virt_to_page(pud));
+       paravirt_tlb_remove_table(tlb, virt_to_page(pud));
 }
 
 #if CONFIG_PGTABLE_LEVELS > 4
 void ___p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d)
 {
        paravirt_release_p4d(__pa(p4d) >> PAGE_SHIFT);
-       tlb_remove_table(tlb, virt_to_page(p4d));
+       paravirt_tlb_remove_table(tlb, virt_to_page(p4d));
 }
 #endif /* CONFIG_PGTABLE_LEVELS > 4 */
 #endif /* CONFIG_PGTABLE_LEVELS > 3 */
@@ -269,7 +269,7 @@ static void mop_up_one_pmd(struct mm_struct *mm, pgd_t *pgdp)
        if (pgd_val(pgd) != 0) {
                pmd_t *pmd = (pmd_t *)pgd_page_vaddr(pgd);
 
-               *pgdp = native_make_pgd(0);
+               pgd_clear(pgdp);
 
                paravirt_release_pmd(pgd_val(pgd) >> PAGE_SHIFT);
                pmd_free(mm, pmd);
@@ -494,7 +494,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
        int changed = !pte_same(*ptep, entry);
 
        if (changed && dirty)
-               *ptep = entry;
+               set_pte(ptep, entry);
 
        return changed;
 }
@@ -509,7 +509,7 @@ int pmdp_set_access_flags(struct vm_area_struct *vma,
        VM_BUG_ON(address & ~HPAGE_PMD_MASK);
 
        if (changed && dirty) {
-               *pmdp = entry;
+               set_pmd(pmdp, entry);
                /*
                 * We had a write-protection fault here and changed the pmd
                 * to to more permissive. No need to flush the TLB for that,
@@ -529,7 +529,7 @@ int pudp_set_access_flags(struct vm_area_struct *vma, unsigned long address,
        VM_BUG_ON(address & ~HPAGE_PUD_MASK);
 
        if (changed && dirty) {
-               *pudp = entry;
+               set_pud(pudp, entry);
                /*
                 * We had a write-protection fault here and changed the pud
                 * to to more permissive. No need to flush the TLB for that,
index 31341ae7309f6b957e8fa8e7207bcd2c8433e6bb..c1fc1ae6b42947a9f6dece93efce6e4f843b7def 100644 (file)
@@ -248,7 +248,7 @@ static pmd_t *pti_user_pagetable_walk_pmd(unsigned long address)
  *
  * Returns a pointer to a PTE on success, or NULL on failure.
  */
-static __init pte_t *pti_user_pagetable_walk_pte(unsigned long address)
+static pte_t *pti_user_pagetable_walk_pte(unsigned long address)
 {
        gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO);
        pmd_t *pmd;
index 752dbf4e0e5071b9a71908822231ceda5940dabf..e96b99eb800ccd5f170f7539efaaf99720d192b4 100644 (file)
@@ -7,7 +7,6 @@
 #include <linux/export.h>
 #include <linux/cpu.h>
 #include <linux/debugfs.h>
-#include <linux/gfp.h>
 
 #include <asm/tlbflush.h>
 #include <asm/mmu_context.h>
@@ -186,11 +185,8 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
 {
        struct mm_struct *real_prev = this_cpu_read(cpu_tlbstate.loaded_mm);
        u16 prev_asid = this_cpu_read(cpu_tlbstate.loaded_mm_asid);
-       bool was_lazy = this_cpu_read(cpu_tlbstate.is_lazy);
        unsigned cpu = smp_processor_id();
        u64 next_tlb_gen;
-       bool need_flush;
-       u16 new_asid;
 
        /*
         * NB: The scheduler will call us with prev == next when switching
@@ -244,41 +240,20 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
                           next->context.ctx_id);
 
                /*
-                * Even in lazy TLB mode, the CPU should stay set in the
-                * mm_cpumask. The TLB shootdown code can figure out from
-                * from cpu_tlbstate.is_lazy whether or not to send an IPI.
+                * We don't currently support having a real mm loaded without
+                * our cpu set in mm_cpumask().  We have all the bookkeeping
+                * in place to figure out whether we would need to flush
+                * if our cpu were cleared in mm_cpumask(), but we don't
+                * currently use it.
                 */
                if (WARN_ON_ONCE(real_prev != &init_mm &&
                                 !cpumask_test_cpu(cpu, mm_cpumask(next))))
                        cpumask_set_cpu(cpu, mm_cpumask(next));
 
-               /*
-                * If the CPU is not in lazy TLB mode, we are just switching
-                * from one thread in a process to another thread in the same
-                * process. No TLB flush required.
-                */
-               if (!was_lazy)
-                       return;
-
-               /*
-                * Read the tlb_gen to check whether a flush is needed.
-                * If the TLB is up to date, just use it.
-                * The barrier synchronizes with the tlb_gen increment in
-                * the TLB shootdown code.
-                */
-               smp_mb();
-               next_tlb_gen = atomic64_read(&next->context.tlb_gen);
-               if (this_cpu_read(cpu_tlbstate.ctxs[prev_asid].tlb_gen) ==
-                               next_tlb_gen)
-                       return;
-
-               /*
-                * TLB contents went out of date while we were in lazy
-                * mode. Fall through to the TLB switching code below.
-                */
-               new_asid = prev_asid;
-               need_flush = true;
+               return;
        } else {
+               u16 new_asid;
+               bool need_flush;
                u64 last_ctx_id = this_cpu_read(cpu_tlbstate.last_ctx_id);
 
                /*
@@ -329,40 +304,47 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
                next_tlb_gen = atomic64_read(&next->context.tlb_gen);
 
                choose_new_asid(next, next_tlb_gen, &new_asid, &need_flush);
-       }
 
-       if (need_flush) {
-               this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id);
-               this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen);
-               load_new_mm_cr3(next->pgd, new_asid, true);
+               /* Let nmi_uaccess_okay() know that we're changing CR3. */
+               this_cpu_write(cpu_tlbstate.loaded_mm, LOADED_MM_SWITCHING);
+               barrier();
+
+               if (need_flush) {
+                       this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id);
+                       this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen);
+                       load_new_mm_cr3(next->pgd, new_asid, true);
+
+                       /*
+                        * NB: This gets called via leave_mm() in the idle path
+                        * where RCU functions differently.  Tracing normally
+                        * uses RCU, so we need to use the _rcuidle variant.
+                        *
+                        * (There is no good reason for this.  The idle code should
+                        *  be rearranged to call this before rcu_idle_enter().)
+                        */
+                       trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
+               } else {
+                       /* The new ASID is already up to date. */
+                       load_new_mm_cr3(next->pgd, new_asid, false);
+
+                       /* See above wrt _rcuidle. */
+                       trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, 0);
+               }
 
                /*
-                * NB: This gets called via leave_mm() in the idle path
-                * where RCU functions differently.  Tracing normally
-                * uses RCU, so we need to use the _rcuidle variant.
-                *
-                * (There is no good reason for this.  The idle code should
-                *  be rearranged to call this before rcu_idle_enter().)
+                * Record last user mm's context id, so we can avoid
+                * flushing branch buffer with IBPB if we switch back
+                * to the same user.
                 */
-               trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
-       } else {
-               /* The new ASID is already up to date. */
-               load_new_mm_cr3(next->pgd, new_asid, false);
-
-               /* See above wrt _rcuidle. */
-               trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, 0);
-       }
+               if (next != &init_mm)
+                       this_cpu_write(cpu_tlbstate.last_ctx_id, next->context.ctx_id);
 
-       /*
-        * Record last user mm's context id, so we can avoid
-        * flushing branch buffer with IBPB if we switch back
-        * to the same user.
-        */
-       if (next != &init_mm)
-               this_cpu_write(cpu_tlbstate.last_ctx_id, next->context.ctx_id);
+               /* Make sure we write CR3 before loaded_mm. */
+               barrier();
 
-       this_cpu_write(cpu_tlbstate.loaded_mm, next);
-       this_cpu_write(cpu_tlbstate.loaded_mm_asid, new_asid);
+               this_cpu_write(cpu_tlbstate.loaded_mm, next);
+               this_cpu_write(cpu_tlbstate.loaded_mm_asid, new_asid);
+       }
 
        load_mm_cr4(next);
        switch_ldt(real_prev, next);
@@ -386,7 +368,20 @@ void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
        if (this_cpu_read(cpu_tlbstate.loaded_mm) == &init_mm)
                return;
 
-       this_cpu_write(cpu_tlbstate.is_lazy, true);
+       if (tlb_defer_switch_to_init_mm()) {
+               /*
+                * There's a significant optimization that may be possible
+                * here.  We have accurate enough TLB flush tracking that we
+                * don't need to maintain coherence of TLB per se when we're
+                * lazy.  We do, however, need to maintain coherence of
+                * paging-structure caches.  We could, in principle, leave our
+                * old mm loaded and only switch to init_mm when
+                * tlb_remove_page() happens.
+                */
+               this_cpu_write(cpu_tlbstate.is_lazy, true);
+       } else {
+               switch_mm(NULL, &init_mm, NULL);
+       }
 }
 
 /*
@@ -473,9 +468,6 @@ static void flush_tlb_func_common(const struct flush_tlb_info *f,
                 * paging-structure cache to avoid speculatively reading
                 * garbage into our TLB.  Since switching to init_mm is barely
                 * slower than a minimal flush, just switch to init_mm.
-                *
-                * This should be rare, with native_flush_tlb_others skipping
-                * IPIs to lazy TLB mode CPUs.
                 */
                switch_mm_irqs_off(NULL, &init_mm, NULL);
                return;
@@ -582,9 +574,6 @@ static void flush_tlb_func_remote(void *info)
 void native_flush_tlb_others(const struct cpumask *cpumask,
                             const struct flush_tlb_info *info)
 {
-       cpumask_var_t lazymask;
-       unsigned int cpu;
-
        count_vm_tlb_event(NR_TLB_REMOTE_FLUSH);
        if (info->end == TLB_FLUSH_ALL)
                trace_tlb_flush(TLB_REMOTE_SEND_IPI, TLB_FLUSH_ALL);
@@ -608,6 +597,8 @@ void native_flush_tlb_others(const struct cpumask *cpumask,
                 * that UV should be updated so that smp_call_function_many(),
                 * etc, are optimal on UV.
                 */
+               unsigned int cpu;
+
                cpu = smp_processor_id();
                cpumask = uv_flush_tlb_others(cpumask, info);
                if (cpumask)
@@ -615,29 +606,8 @@ void native_flush_tlb_others(const struct cpumask *cpumask,
                                               (void *)info, 1);
                return;
        }
-
-       /*
-        * A temporary cpumask is used in order to skip sending IPIs
-        * to CPUs in lazy TLB state, while keeping them in mm_cpumask(mm).
-        * If the allocation fails, simply IPI every CPU in mm_cpumask.
-        */
-       if (!alloc_cpumask_var(&lazymask, GFP_ATOMIC)) {
-               smp_call_function_many(cpumask, flush_tlb_func_remote,
-                              (void *)info, 1);
-               return;
-       }
-
-       cpumask_copy(lazymask, cpumask);
-
-       for_each_cpu(cpu, lazymask) {
-               if (per_cpu(cpu_tlbstate.is_lazy, cpu))
-                       cpumask_clear_cpu(cpu, lazymask);
-       }
-
-       smp_call_function_many(lazymask, flush_tlb_func_remote,
+       smp_call_function_many(cpumask, flush_tlb_func_remote,
                               (void *)info, 1);
-
-       free_cpumask_var(lazymask);
 }
 
 /*
@@ -690,68 +660,6 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
        put_cpu();
 }
 
-void tlb_flush_remove_tables_local(void *arg)
-{
-       struct mm_struct *mm = arg;
-
-       if (this_cpu_read(cpu_tlbstate.loaded_mm) == mm &&
-                       this_cpu_read(cpu_tlbstate.is_lazy)) {
-               /*
-                * We're in lazy mode.  We need to at least flush our
-                * paging-structure cache to avoid speculatively reading
-                * garbage into our TLB.  Since switching to init_mm is barely
-                * slower than a minimal flush, just switch to init_mm.
-                */
-               switch_mm_irqs_off(NULL, &init_mm, NULL);
-       }
-}
-
-static void mm_fill_lazy_tlb_cpu_mask(struct mm_struct *mm,
-                                     struct cpumask *lazy_cpus)
-{
-       int cpu;
-
-       for_each_cpu(cpu, mm_cpumask(mm)) {
-               if (!per_cpu(cpu_tlbstate.is_lazy, cpu))
-                       cpumask_set_cpu(cpu, lazy_cpus);
-       }
-}
-
-void tlb_flush_remove_tables(struct mm_struct *mm)
-{
-       int cpu = get_cpu();
-       cpumask_var_t lazy_cpus;
-
-       if (cpumask_any_but(mm_cpumask(mm), cpu) >= nr_cpu_ids) {
-               put_cpu();
-               return;
-       }
-
-       if (!zalloc_cpumask_var(&lazy_cpus, GFP_ATOMIC)) {
-               /*
-                * If the cpumask allocation fails, do a brute force flush
-                * on all the CPUs that have this mm loaded.
-                */
-               smp_call_function_many(mm_cpumask(mm),
-                               tlb_flush_remove_tables_local, (void *)mm, 1);
-               put_cpu();
-               return;
-       }
-
-       /*
-        * CPUs with !is_lazy either received a TLB flush IPI while the user
-        * pages in this address range were unmapped, or have context switched
-        * and reloaded %CR3 since then.
-        *
-        * Shootdown IPIs at page table freeing time only need to be sent to
-        * CPUs that may have out of date TLB contents.
-        */
-       mm_fill_lazy_tlb_cpu_mask(mm, lazy_cpus);
-       smp_call_function_many(lazy_cpus,
-                               tlb_flush_remove_tables_local, (void *)mm, 1);
-       free_cpumask_var(lazy_cpus);
-       put_cpu();
-}
 
 static void do_flush_tlb_all(void *info)
 {
index 324b93328b3746f4bb8010780ee85915707b8095..05ca1422246336c6d3c923c22f06ad87113ac1d3 100644 (file)
@@ -85,14 +85,10 @@ pgd_t * __init efi_call_phys_prolog(void)
 
 void __init efi_call_phys_epilog(pgd_t *save_pgd)
 {
-       struct desc_ptr gdt_descr;
-
-       gdt_descr.address = (unsigned long)get_cpu_gdt_rw(0);
-       gdt_descr.size = GDT_SIZE - 1;
-       load_gdt(&gdt_descr);
-
        load_cr3(save_pgd);
        __flush_tlb_all();
+
+       load_fixmap_gdt(0);
 }
 
 void __init efi_runtime_update_mappings(void)
index ee3b00c7acda6d75035c916606ec27e0dcc58450..52a7c3faee0ccf88f840110093111e22bc7b30ad 100644 (file)
@@ -122,6 +122,8 @@ static void __init xen_banner(void)
 
 static void __init xen_pv_init_platform(void)
 {
+       populate_extra_pte(fix_to_virt(FIX_PARAVIRT_BOOTMAP));
+
        set_fixmap(FIX_PARAVIRT_BOOTMAP, xen_start_info->shared_info);
        HYPERVISOR_shared_info = (void *)fix_to_virt(FIX_PARAVIRT_BOOTMAP);
 
@@ -1170,13 +1172,13 @@ static void __init xen_boot_params_init_edd(void)
  * we do this, we have to be careful not to call any stack-protected
  * function, which is most of the kernel.
  */
-static void xen_setup_gdt(int cpu)
+static void __init xen_setup_gdt(int cpu)
 {
        pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry_boot;
        pv_cpu_ops.load_gdt = xen_load_gdt_boot;
 
-       setup_stack_canary_segment(0);
-       switch_to_new_gdt(0);
+       setup_stack_canary_segment(cpu);
+       switch_to_new_gdt(cpu);
 
        pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry;
        pv_cpu_ops.load_gdt = xen_load_gdt;
@@ -1385,8 +1387,11 @@ asmlinkage __visible void __init xen_start_kernel(void)
                xen_boot_params_init_edd();
        }
 
-       add_preferred_console("tty", 0, NULL);
+       if (!boot_params.screen_info.orig_video_isVGA)
+               add_preferred_console("tty", 0, NULL);
        add_preferred_console("hvc", 0, NULL);
+       if (boot_params.screen_info.orig_video_isVGA)
+               add_preferred_console("tty", 0, NULL);
 
 #ifdef CONFIG_PCI
        /* PCI BIOS service won't work from a PV guest. */
index 52206ad81e4bcabe5d1173781397fdfa7c6d2b3a..2fe5c9b1816bbd5e6f0adcc9385bcdf09b173154 100644 (file)
@@ -67,6 +67,7 @@
 #include <asm/init.h>
 #include <asm/pat.h>
 #include <asm/smp.h>
+#include <asm/tlb.h>
 
 #include <asm/xen/hypercall.h>
 #include <asm/xen/hypervisor.h>
@@ -434,14 +435,13 @@ static void xen_set_pud(pud_t *ptr, pud_t val)
 static void xen_set_pte_atomic(pte_t *ptep, pte_t pte)
 {
        trace_xen_mmu_set_pte_atomic(ptep, pte);
-       set_64bit((u64 *)ptep, native_pte_val(pte));
+       __xen_set_pte(ptep, pte);
 }
 
 static void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
        trace_xen_mmu_pte_clear(mm, addr, ptep);
-       if (!xen_batched_set_pte(ptep, native_make_pte(0)))
-               native_pte_clear(mm, addr, ptep);
+       __xen_set_pte(ptep, native_make_pte(0));
 }
 
 static void xen_pmd_clear(pmd_t *pmdp)
@@ -1569,7 +1569,7 @@ static void __init xen_set_pte_init(pte_t *ptep, pte_t pte)
                pte = __pte_ma(((pte_val_ma(*ptep) & _PAGE_RW) | ~_PAGE_RW) &
                               pte_val_ma(pte));
 #endif
-       native_set_pte(ptep, pte);
+       __xen_set_pte(ptep, pte);
 }
 
 /* Early in boot, while setting up the initial pagetable, assume
@@ -2060,7 +2060,6 @@ void __init xen_relocate_p2m(void)
        pud_t *pud;
        pgd_t *pgd;
        unsigned long *new_p2m;
-       int save_pud;
 
        size = PAGE_ALIGN(xen_start_info->nr_pages * sizeof(unsigned long));
        n_pte = roundup(size, PAGE_SIZE) >> PAGE_SHIFT;
@@ -2090,7 +2089,6 @@ void __init xen_relocate_p2m(void)
 
        pgd = __va(read_cr3_pa());
        new_p2m = (unsigned long *)(2 * PGDIR_SIZE);
-       save_pud = n_pud;
        for (idx_pud = 0; idx_pud < n_pud; idx_pud++) {
                pud = early_memremap(pud_phys, PAGE_SIZE);
                clear_page(pud);
@@ -2171,6 +2169,8 @@ void __init xen_relocate_p2m(void)
 #else  /* !CONFIG_X86_64 */
 static RESERVE_BRK_ARRAY(pmd_t, initial_kernel_pmd, PTRS_PER_PMD);
 static RESERVE_BRK_ARRAY(pmd_t, swapper_kernel_pmd, PTRS_PER_PMD);
+RESERVE_BRK(fixup_kernel_pmd, PAGE_SIZE);
+RESERVE_BRK(fixup_kernel_pte, PAGE_SIZE);
 
 static void __init xen_write_cr3_init(unsigned long cr3)
 {
@@ -2397,6 +2397,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
        .flush_tlb_kernel = xen_flush_tlb,
        .flush_tlb_one_user = xen_flush_tlb_one_user,
        .flush_tlb_others = xen_flush_tlb_others,
+       .tlb_remove_table = tlb_remove_table,
 
        .pgd_alloc = xen_pgd_alloc,
        .pgd_free = xen_pgd_free,
index 6e0d2086eacbf37326467b5142e59750151a5328..1163e33121fb39af673743b0eda9de5007629c63 100644 (file)
@@ -905,37 +905,6 @@ char * __init xen_memory_setup(void)
        return "Xen";
 }
 
-/*
- * Machine specific memory setup for auto-translated guests.
- */
-char * __init xen_auto_xlated_memory_setup(void)
-{
-       struct xen_memory_map memmap;
-       int i;
-       int rc;
-
-       memmap.nr_entries = ARRAY_SIZE(xen_e820_table.entries);
-       set_xen_guest_handle(memmap.buffer, xen_e820_table.entries);
-
-       rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
-       if (rc < 0)
-               panic("No memory map (%d)\n", rc);
-
-       xen_e820_table.nr_entries = memmap.nr_entries;
-
-       e820__update_table(&xen_e820_table);
-
-       for (i = 0; i < xen_e820_table.nr_entries; i++)
-               e820__range_add(xen_e820_table.entries[i].addr, xen_e820_table.entries[i].size, xen_e820_table.entries[i].type);
-
-       /* Remove p2m info, it is not needed. */
-       xen_start_info->mfn_list = 0;
-       xen_start_info->first_p2m_pfn = 0;
-       xen_start_info->nr_p2m_frames = 0;
-
-       return "Xen";
-}
-
 /*
  * Set the bit indicating "nosegneg" library variants should be used.
  * We only need to bother in pure 32-bit mode; compat 32-bit processes
index e78684597f579ae0d5d90d952dbd1f46188f2f73..0e60bd91869548a950b32550f26883ef5c4965f6 100644 (file)
@@ -50,7 +50,6 @@ void __init xen_inv_extra_mem(void);
 void __init xen_remap_memory(void);
 phys_addr_t __init xen_find_free_area(phys_addr_t size);
 char * __init xen_memory_setup(void);
-char * xen_auto_xlated_memory_setup(void);
 void __init xen_arch_setup(void);
 void xen_enable_sysenter(void);
 void xen_enable_syscall(void);
index 801491e9889037d77b620763c3aa254c6455bb89..04d038f3b6fab86fed6e458b136f8fc46c05feeb 100644 (file)
@@ -4,12 +4,15 @@ config ZONE_DMA
 
 config XTENSA
        def_bool y
+       select ARCH_HAS_SYNC_DMA_FOR_CPU
+       select ARCH_HAS_SYNC_DMA_FOR_DEVICE
        select ARCH_NO_COHERENT_DMA_MMAP if !MMU
        select ARCH_WANT_FRAME_POINTERS
        select ARCH_WANT_IPC_PARSE_VERSION
        select BUILDTIME_EXTABLE_SORT
        select CLONE_BACKWARDS
        select COMMON_CLK
+       select DMA_NONCOHERENT_OPS
        select GENERIC_ATOMIC64
        select GENERIC_CLOCKEVENTS
        select GENERIC_IRQ_SHOW
@@ -72,9 +75,6 @@ config TRACE_IRQFLAGS_SUPPORT
 config MMU
        def_bool n
 
-config VARIANT_IRQ_SWITCH
-       def_bool n
-
 config HAVE_XTENSA_GPIO32
        def_bool n
 
@@ -244,6 +244,23 @@ config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
 
          If in doubt, say Y.
 
+config MEMMAP_CACHEATTR
+       hex "Cache attributes for the memory address space"
+       depends on !MMU
+       default 0x22222222
+       help
+         These cache attributes are set up for noMMU systems. Each hex digit
+         specifies cache attributes for the corresponding 512MB memory
+         region: bits 0..3 -- for addresses 0x00000000..0x1fffffff,
+         bits 4..7 -- for addresses 0x20000000..0x3fffffff, and so on.
+
+         Cache attribute values are specific for the MMU type, so e.g.
+         for region protection MMUs: 2 is cache bypass, 4 is WB cached,
+         1 is WT cached, f is illegal. For ful MMU: bit 0 makes it executable,
+         bit 1 makes it writable, bits 2..3 meaning is 0: cache bypass,
+         1: WB cache, 2: WT cache, 3: special (c and e are illegal, f is
+         reserved).
+
 config KSEG_PADDR
        hex "Physical address of the KSEG mapping"
        depends on INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX && MMU
@@ -413,6 +430,10 @@ config XTENSA_PLATFORM_XTFPGA
 
 endchoice
 
+config PLATFORM_NR_IRQS
+       int
+       default 3 if XTENSA_PLATFORM_XT2000
+       default 0
 
 config XTENSA_CPU_CLOCK
        int "CPU clock rate [MHz]"
@@ -450,6 +471,15 @@ config BUILTIN_DTB
        string "DTB to build into the kernel image"
        depends on OF
 
+config PARSE_BOOTPARAM
+       bool "Parse bootparam block"
+       default y
+       help
+         Parse parameters passed to the kernel from the bootloader. It may
+         be disabled if the kernel is known to run without the bootloader.
+
+         If unsure, say Y.
+
 config BLK_DEV_SIMDISK
        tristate "Host file-based simulated block device support"
        default n
@@ -506,25 +536,13 @@ config PLATFORM_WANT_DEFAULT_MEM
        def_bool n
 
 config DEFAULT_MEM_START
-       hex "Physical address of the default memory area start"
-       depends on PLATFORM_WANT_DEFAULT_MEM
-       default 0x00000000 if MMU
-       default 0x60000000 if !MMU
-       help
-         This is the base address of the default memory area.
-         Default memory area has platform-specific meaning, it may be used
-         for e.g. early cache initialization.
-
-         If unsure, leave the default value here.
-
-config DEFAULT_MEM_SIZE
-       hex "Maximal size of the default memory area"
-       depends on PLATFORM_WANT_DEFAULT_MEM
-       default 0x04000000
+       hex
+       prompt "PAGE_OFFSET/PHYS_OFFSET" if !MMU && PLATFORM_WANT_DEFAULT_MEM
+       default 0x60000000 if PLATFORM_WANT_DEFAULT_MEM
+       default 0x00000000
        help
-         This is the size of the default memory area.
-         Default memory area has platform-specific meaning, it may be used
-         for e.g. early cache initialization.
+         This is the base address used for both PAGE_OFFSET and PHYS_OFFSET
+         in noMMU configurations.
 
          If unsure, leave the default value here.
 
index 3a934b72a2728948a0009ca3a92faf63c0b4a1ed..295c120ed099d26f198b32342ba1bfb59f59075e 100644 (file)
@@ -49,7 +49,7 @@ KBUILD_CFLAGS += $(call cc-option,-mno-serialize-volatile,)
 KBUILD_AFLAGS += -mlongcalls -mtext-section-literals
 
 ifneq ($(CONFIG_LD_NO_RELAX),)
-LDFLAGS := --no-relax
+KBUILD_LDFLAGS := --no-relax
 endif
 
 ifeq ($(shell echo __XTENSA_EB__ | $(CC) -E - | grep -v "\#"),1)
index 52147198135635b7c9d6e98d01dda95e7f59e755..12ae1e91cb75fbcb729491fef73ec0a4736a7fee 100644 (file)
@@ -25,7 +25,7 @@ $(obj)/Image.o: vmlinux.bin $(OBJS)
                $(OBJS) $@
 
 $(obj)/../Image.elf: $(obj)/Image.o $(obj)/boot.lds
-       $(Q)$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
+       $(Q)$(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_vmlinux) \
                -T $(obj)/boot.lds \
                --build-id=none \
                -o $@ $(obj)/Image.o
index b6aa85328ac0ccc05936bcf9b477499e7bbbbfe7..29c68426ab56a15ad7bfc8f1794692e5b3b3b1f4 100644 (file)
  */
 
 #include <asm/bootparam.h>
-#include <asm/processor.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/cacheasm.h>
 #include <asm/initialize_mmu.h>
 #include <asm/vectors.h>
 #include <linux/linkage.h>
@@ -33,16 +29,18 @@ _ResetVector:
        .begin  no-absolute-literals
        .literal_position
 
-       .align 4
-RomInitAddr:
 #if defined(CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX) && \
        XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
-       .word   CONFIG_KERNEL_LOAD_ADDRESS
+       .literal RomInitAddr, CONFIG_KERNEL_LOAD_ADDRESS
 #else
-       .word   KERNELOFFSET
+       .literal RomInitAddr, KERNELOFFSET
 #endif
-RomBootParam:
-       .word _bootparam
+#ifndef CONFIG_PARSE_BOOTPARAM
+       .literal RomBootParam, 0
+#else
+       .literal RomBootParam, _bootparam
+
+       .align 4
 _bootparam:
        .short  BP_TAG_FIRST
        .short  4
@@ -50,6 +48,7 @@ _bootparam:
        .short  BP_TAG_LAST
        .short  0
        .long   0
+#endif
 
        .align  4
 _SetupMMU:
index 624f9b3a3878dbfb38f4ded07e7988e6f2b6c50a..f3fc4f970ca8e22b0f7c271bced6235640e787af 100644 (file)
@@ -33,13 +33,13 @@ CONFIG_XTENSA_VARIANT_CUSTOM_NAME="de212"
 # CONFIG_XTENSA_VARIANT_MMU is not set
 CONFIG_XTENSA_UNALIGNED_USER=y
 CONFIG_PREEMPT=y
+CONFIG_MEMMAP_CACHEATTR=0xfff2442f
 # CONFIG_PCI is not set
 CONFIG_XTENSA_PLATFORM_XTFPGA=y
 CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="earlycon=uart8250,mmio32native,0x9d050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=256M@0x60000000"
 CONFIG_USE_OF=y
 CONFIG_BUILTIN_DTB="kc705_nommu"
-CONFIG_DEFAULT_MEM_SIZE=0x10000000
 CONFIG_BINFMT_FLAT=y
 CONFIG_NET=y
 CONFIG_PACKET=y
index e5e1e61c538c3dc06e49d7868f538bb4e01a9f3e..82c756431b49bc37aa1a5a8b8ea837bf01315e2b 100644 (file)
@@ -3,6 +3,7 @@ generic-y += compat.h
 generic-y += device.h
 generic-y += div64.h
 generic-y += dma-contiguous.h
+generic-y += dma-mapping.h
 generic-y += emergency-restart.h
 generic-y += exec.h
 generic-y += extable.h
index 2041abb10a2352a4b1f4323f3e1f0d9bdfff36ec..34545ecfdd6b7332df7fb486930f1f35c5532640 100644 (file)
  *
  */
 
-       .macro  __loop_cache_all ar at insn size line_width
 
-       movi    \ar, 0
+       .macro  __loop_cache_unroll ar at insn size line_width max_immed
+
+       .if     (1 << (\line_width)) > (\max_immed)
+       .set    _reps, 1
+       .elseif (2 << (\line_width)) > (\max_immed)
+       .set    _reps, 2
+       .else
+       .set    _reps, 4
+       .endif
+
+       __loopi \ar, \at, \size, (_reps << (\line_width))
+       .set    _index, 0
+       .rep    _reps
+       \insn   \ar, _index << (\line_width)
+       .set    _index, _index + 1
+       .endr
+       __endla \ar, \at, _reps << (\line_width)
+
+       .endm
+
 
-       __loopi \ar, \at, \size, (4 << (\line_width))
-       \insn   \ar, 0 << (\line_width)
-       \insn   \ar, 1 << (\line_width)
-       \insn   \ar, 2 << (\line_width)
-       \insn   \ar, 3 << (\line_width)
-       __endla \ar, \at, 4 << (\line_width)
+       .macro  __loop_cache_all ar at insn size line_width max_immed
+
+       movi    \ar, 0
+       __loop_cache_unroll \ar, \at, \insn, \size, \line_width, \max_immed
 
        .endm
 
        .endm
 
 
-       .macro  __loop_cache_page ar at insn line_width
+       .macro  __loop_cache_page ar at insn line_width max_immed
 
-       __loopi \ar, \at, PAGE_SIZE, 4 << (\line_width)
-       \insn   \ar, 0 << (\line_width)
-       \insn   \ar, 1 << (\line_width)
-       \insn   \ar, 2 << (\line_width)
-       \insn   \ar, 3 << (\line_width)
-       __endla \ar, \at, 4 << (\line_width)
+       __loop_cache_unroll \ar, \at, \insn, PAGE_SIZE, \line_width, \max_immed
 
        .endm
 
@@ -72,7 +83,8 @@
        .macro  ___unlock_dcache_all ar at
 
 #if XCHAL_DCACHE_LINE_LOCKABLE && XCHAL_DCACHE_SIZE
-       __loop_cache_all \ar \at diu XCHAL_DCACHE_SIZE XCHAL_DCACHE_LINEWIDTH
+       __loop_cache_all \ar \at diu XCHAL_DCACHE_SIZE \
+               XCHAL_DCACHE_LINEWIDTH 240
 #endif
 
        .endm
@@ -81,7 +93,8 @@
        .macro  ___unlock_icache_all ar at
 
 #if XCHAL_ICACHE_LINE_LOCKABLE && XCHAL_ICACHE_SIZE
-       __loop_cache_all \ar \at iiu XCHAL_ICACHE_SIZE XCHAL_ICACHE_LINEWIDTH
+       __loop_cache_all \ar \at iiu XCHAL_ICACHE_SIZE \
+               XCHAL_ICACHE_LINEWIDTH 240
 #endif
 
        .endm
        .macro  ___flush_invalidate_dcache_all ar at
 
 #if XCHAL_DCACHE_SIZE
-       __loop_cache_all \ar \at diwbi XCHAL_DCACHE_SIZE XCHAL_DCACHE_LINEWIDTH
+       __loop_cache_all \ar \at diwbi XCHAL_DCACHE_SIZE \
+               XCHAL_DCACHE_LINEWIDTH 240
 #endif
 
        .endm
        .macro  ___flush_dcache_all ar at
 
 #if XCHAL_DCACHE_SIZE
-       __loop_cache_all \ar \at diwb XCHAL_DCACHE_SIZE XCHAL_DCACHE_LINEWIDTH
+       __loop_cache_all \ar \at diwb XCHAL_DCACHE_SIZE \
+               XCHAL_DCACHE_LINEWIDTH 240
 #endif
 
        .endm
        .macro  ___invalidate_dcache_all ar at
 
 #if XCHAL_DCACHE_SIZE
-       __loop_cache_all \ar \at dii __stringify(DCACHE_WAY_SIZE) \
-                        XCHAL_DCACHE_LINEWIDTH
+       __loop_cache_all \ar \at dii XCHAL_DCACHE_SIZE \
+                        XCHAL_DCACHE_LINEWIDTH 1020
 #endif
 
        .endm
        .macro  ___invalidate_icache_all ar at
 
 #if XCHAL_ICACHE_SIZE
-       __loop_cache_all \ar \at iii __stringify(ICACHE_WAY_SIZE) \
-                        XCHAL_ICACHE_LINEWIDTH
+       __loop_cache_all \ar \at iii XCHAL_ICACHE_SIZE \
+                        XCHAL_ICACHE_LINEWIDTH 1020
 #endif
 
        .endm
        .macro  ___flush_invalidate_dcache_page ar as
 
 #if XCHAL_DCACHE_SIZE
-       __loop_cache_page \ar \as dhwbi XCHAL_DCACHE_LINEWIDTH
+       __loop_cache_page \ar \as dhwbi XCHAL_DCACHE_LINEWIDTH 1020
 #endif
 
        .endm
        .macro ___flush_dcache_page ar as
 
 #if XCHAL_DCACHE_SIZE
-       __loop_cache_page \ar \as dhwb XCHAL_DCACHE_LINEWIDTH
+       __loop_cache_page \ar \as dhwb XCHAL_DCACHE_LINEWIDTH 1020
 #endif
 
        .endm
        .macro  ___invalidate_dcache_page ar as
 
 #if XCHAL_DCACHE_SIZE
-       __loop_cache_page \ar \as dhi XCHAL_DCACHE_LINEWIDTH
+       __loop_cache_page \ar \as dhi XCHAL_DCACHE_LINEWIDTH 1020
 #endif
 
        .endm
        .macro  ___invalidate_icache_page ar as
 
 #if XCHAL_ICACHE_SIZE
-       __loop_cache_page \ar \as ihi XCHAL_ICACHE_LINEWIDTH
+       __loop_cache_page \ar \as ihi XCHAL_ICACHE_LINEWIDTH 1020
 #endif
 
        .endm
diff --git a/arch/xtensa/include/asm/dma-mapping.h b/arch/xtensa/include/asm/dma-mapping.h
deleted file mode 100644 (file)
index 4409880..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2003 - 2005 Tensilica Inc.
- * Copyright (C) 2015 Cadence Design Systems Inc.
- */
-
-#ifndef _XTENSA_DMA_MAPPING_H
-#define _XTENSA_DMA_MAPPING_H
-
-#include <asm/cache.h>
-#include <asm/io.h>
-
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
-
-extern const struct dma_map_ops xtensa_dma_map_ops;
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-       return &xtensa_dma_map_ops;
-}
-
-#endif /* _XTENSA_DMA_MAPPING_H */
index 42410f253597d5e772da628df4d042ed485cde4f..10e9852b2fb474d18ba8e5401592792fefe3504f 100644 (file)
 #endif /* defined(CONFIG_MMU) && XCHAL_HAVE_PTP_MMU &&
          XCHAL_HAVE_SPANNING_WAY */
 
-#if !defined(CONFIG_MMU) && XCHAL_HAVE_TLBS && \
-               (XCHAL_DCACHE_SIZE || XCHAL_ICACHE_SIZE)
-       /* Enable data and instruction cache in the DEFAULT_MEMORY region
-        * if the processor has DTLB and ITLB.
-        */
+       .endm
+
+       .macro  initialize_cacheattr
 
-       movi    a5, PLATFORM_DEFAULT_MEM_START | XCHAL_SPANNING_WAY
+#if !defined(CONFIG_MMU) && XCHAL_HAVE_TLBS
+#if CONFIG_MEMMAP_CACHEATTR == 0x22222222 && XCHAL_HAVE_PTP_MMU
+#error Default MEMMAP_CACHEATTR of 0x22222222 does not work with full MMU.
+#endif
+
+       movi    a5, XCHAL_SPANNING_WAY
        movi    a6, ~_PAGE_ATTRIB_MASK
-       movi    a7, CA_WRITEBACK
+       movi    a4, CONFIG_MEMMAP_CACHEATTR
        movi    a8, 0x20000000
-       movi    a9, PLATFORM_DEFAULT_MEM_SIZE
-       j       2f
 1:
-       sub     a9, a9, a8
-2:
-#if XCHAL_DCACHE_SIZE
        rdtlb1  a3, a5
+       xor     a3, a3, a4
        and     a3, a3, a6
-       or      a3, a3, a7
+       xor     a3, a3, a4
        wdtlb   a3, a5
-#endif
-#if XCHAL_ICACHE_SIZE
-       ritlb1  a4, a5
-       and     a4, a4, a6
-       or      a4, a4, a7
-       witlb   a4, a5
-#endif
+       ritlb1  a3, a5
+       xor     a3, a3, a4
+       and     a3, a3, a6
+       xor     a3, a3, a4
+       witlb   a3, a5
+
        add     a5, a5, a8
-       bltu    a8, a9, 1b
+       srli    a4, a4, 4
+       bgeu    a5, a8, 1b
 
+       isync
 #endif
 
        .endm
index 19707db966f1393017bcf9528ff64d2951089d20..6c6ed23e0c79c51875710e29a7e59ce59fe2ef7b 100644 (file)
 #define _XTENSA_IRQ_H
 
 #include <linux/init.h>
-#include <platform/hardware.h>
 #include <variant/core.h>
 
-#ifdef CONFIG_VARIANT_IRQ_SWITCH
-#include <variant/irq.h>
+#ifdef CONFIG_PLATFORM_NR_IRQS
+# define PLATFORM_NR_IRQS CONFIG_PLATFORM_NR_IRQS
 #else
-static inline void variant_irq_enable(unsigned int irq) { }
-static inline void variant_irq_disable(unsigned int irq) { }
-#endif
-
-#ifndef VARIANT_NR_IRQS
-# define VARIANT_NR_IRQS 0
-#endif
-#ifndef PLATFORM_NR_IRQS
 # define PLATFORM_NR_IRQS 0
 #endif
 #define XTENSA_NR_IRQS XCHAL_NUM_INTERRUPTS
-#define NR_IRQS (XTENSA_NR_IRQS + VARIANT_NR_IRQS + PLATFORM_NR_IRQS + 1)
+#define NR_IRQS (XTENSA_NR_IRQS + PLATFORM_NR_IRQS + 1)
 #define XTENSA_PIC_LINUX_IRQ(hwirq) ((hwirq) + 1)
 
-#if VARIANT_NR_IRQS == 0
-static inline void variant_init_irq(void) { }
-#else
-void variant_init_irq(void) __init;
-#endif
-
 static __inline__ int irq_canonicalize(int irq)
 {
        return (irq);
index 2317c835a4db3d2f6717ce130549d88bf0f6cfaf..9c12babc016cd996b1b9f27ff9ee0fb88b43b941 100644 (file)
 #error XCHAL_KSEG_PADDR is not properly aligned to XCHAL_KSEG_ALIGNMENT
 #endif
 
-#else
-
-#define XCHAL_KSEG_CACHED_VADDR        __XTENSA_UL_CONST(0xd0000000)
-#define XCHAL_KSEG_BYPASS_VADDR        __XTENSA_UL_CONST(0xd8000000)
-#define XCHAL_KSEG_SIZE                __XTENSA_UL_CONST(0x08000000)
-
 #endif
 
 #ifndef CONFIG_KASAN
index 5d69c11c01b8f991d0e2fc8f92a1b38d6091d835..09c56cba442e8b1718bc6fee5b2050d13f0cdd81 100644 (file)
@@ -14,7 +14,6 @@
 #include <asm/processor.h>
 #include <asm/types.h>
 #include <asm/cache.h>
-#include <platform/hardware.h>
 #include <asm/kmem_layout.h>
 
 /*
@@ -31,8 +30,8 @@
 #define MAX_LOW_PFN    (PHYS_PFN(XCHAL_KSEG_PADDR) + \
                         PHYS_PFN(XCHAL_KSEG_SIZE))
 #else
-#define PAGE_OFFSET    PLATFORM_DEFAULT_MEM_START
-#define PHYS_OFFSET    PLATFORM_DEFAULT_MEM_START
+#define PAGE_OFFSET    _AC(CONFIG_DEFAULT_MEM_START, UL)
+#define PHYS_OFFSET    _AC(CONFIG_DEFAULT_MEM_START, UL)
 #define MAX_LOW_PFN    PHYS_PFN(0xfffffffful)
 #endif
 
index 38802259978fd3fbaa571a3afdb425eaa52adde0..29cfe421cf41c4e58f3259bf4dc64b0771155884 100644 (file)
@@ -66,6 +66,7 @@
 #define FIRST_USER_ADDRESS     0UL
 #define FIRST_USER_PGD_NR      (FIRST_USER_ADDRESS >> PGDIR_SHIFT)
 
+#ifdef CONFIG_MMU
 /*
  * Virtual memory area. We keep a distance to other memory regions to be
  * on the safe side. We also use this area for cache aliasing.
 #define TLBTEMP_SIZE           ICACHE_WAY_SIZE
 #endif
 
+#else
+
+#define VMALLOC_START          __XTENSA_UL_CONST(0)
+#define VMALLOC_END            __XTENSA_UL_CONST(0xffffffff)
+
+#endif
+
 /*
  * For the Xtensa architecture, the PTE layout is as follows:
  *
index f8fbef67bc5f20590df28e635950faeecce521e2..560483356a06a2fcf9ad619bfd6c83602791dc72 100644 (file)
@@ -75,4 +75,31 @@ extern void platform_calibrate_ccount (void);
  */
 void cpu_reset(void) __attribute__((noreturn));
 
+/*
+ * Memory caching is platform-dependent in noMMU xtensa configurations.
+ * The following set of functions should be implemented in platform code
+ * in order to enable coherent DMA memory operations when CONFIG_MMU is not
+ * enabled. Default implementations do nothing and issue a warning.
+ */
+
+/*
+ * Check whether p points to a cached memory.
+ */
+bool platform_vaddr_cached(const void *p);
+
+/*
+ * Check whether p points to an uncached memory.
+ */
+bool platform_vaddr_uncached(const void *p);
+
+/*
+ * Return pointer to an uncached view of the cached sddress p.
+ */
+void *platform_vaddr_to_uncached(void *p);
+
+/*
+ * Return pointer to a cached view of the uncached sddress p.
+ */
+void *platform_vaddr_to_cached(void *p);
+
 #endif /* _XTENSA_PLATFORM_H */
index 5b0027d4ecc05cff651baec243a612d8deea20bc..e4ccb88b799631102185e21bda4b8a5193a5c5f4 100644 (file)
@@ -11,7 +11,6 @@
 #define _XTENSA_PROCESSOR_H
 
 #include <variant/core.h>
-#include <platform/hardware.h>
 
 #include <linux/compiler.h>
 #include <asm/ptrace.h>
index 65d3da9db19bebaff6120ca3544ad7c198e1af80..7111280c8842287fcc6a177d7c116b837c8974ec 100644 (file)
@@ -19,7 +19,6 @@
 #define _XTENSA_VECTORS_H
 
 #include <variant/core.h>
-#include <platform/hardware.h>
 #include <asm/kmem_layout.h>
 
 #if XCHAL_HAVE_PTP_MMU
index 9c4e9433e5362e097f70fd6cfe23616a02a9172f..2f76118ecf6230ff01fe0e43221269da7b208f46 100644 (file)
@@ -181,6 +181,8 @@ ENTRY(_startup)
 
        isync
 
+       initialize_cacheattr
+
 #ifdef CONFIG_HAVE_SMP
        movi    a2, CCON        # MX External Register to Configure Cache
        movi    a3, 1
index 18e4ef34ac4559a1afe105d93d480094d44f9667..a48bf2d10ac2d9fc71f677d1e516ebcb0aef2e65 100644 (file)
@@ -158,7 +158,6 @@ void __init init_IRQ(void)
 #ifdef CONFIG_SMP
        ipi_init();
 #endif
-       variant_init_irq();
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
index a02dc563d2904ff0e9eb4387b56792dce5c63fd0..1fc138b6bc0a8db4ba86732ebd9658ee0cb86d12 100644 (file)
  */
 
 #include <linux/dma-contiguous.h>
+#include <linux/dma-noncoherent.h>
 #include <linux/dma-direct.h>
 #include <linux/gfp.h>
 #include <linux/highmem.h>
 #include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/string.h>
 #include <linux/types.h>
 #include <asm/cacheflush.h>
 #include <asm/io.h>
+#include <asm/platform.h>
 
-static void do_cache_op(dma_addr_t dma_handle, size_t size,
+static void do_cache_op(phys_addr_t paddr, size_t size,
                        void (*fn)(unsigned long, unsigned long))
 {
-       unsigned long off = dma_handle & (PAGE_SIZE - 1);
-       unsigned long pfn = PFN_DOWN(dma_handle);
+       unsigned long off = paddr & (PAGE_SIZE - 1);
+       unsigned long pfn = PFN_DOWN(paddr);
        struct page *page = pfn_to_page(pfn);
 
        if (!PageHighMem(page))
-               fn((unsigned long)bus_to_virt(dma_handle), size);
+               fn((unsigned long)phys_to_virt(paddr), size);
        else
                while (size > 0) {
                        size_t sz = min_t(size_t, size, PAGE_SIZE - off);
@@ -49,14 +48,13 @@ static void do_cache_op(dma_addr_t dma_handle, size_t size,
                }
 }
 
-static void xtensa_sync_single_for_cpu(struct device *dev,
-                                      dma_addr_t dma_handle, size_t size,
-                                      enum dma_data_direction dir)
+void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
+               size_t size, enum dma_data_direction dir)
 {
        switch (dir) {
        case DMA_BIDIRECTIONAL:
        case DMA_FROM_DEVICE:
-               do_cache_op(dma_handle, size, __invalidate_dcache_range);
+               do_cache_op(paddr, size, __invalidate_dcache_range);
                break;
 
        case DMA_NONE:
@@ -68,15 +66,14 @@ static void xtensa_sync_single_for_cpu(struct device *dev,
        }
 }
 
-static void xtensa_sync_single_for_device(struct device *dev,
-                                         dma_addr_t dma_handle, size_t size,
-                                         enum dma_data_direction dir)
+void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
+               size_t size, enum dma_data_direction dir)
 {
        switch (dir) {
        case DMA_BIDIRECTIONAL:
        case DMA_TO_DEVICE:
                if (XCHAL_DCACHE_IS_WRITEBACK)
-                       do_cache_op(dma_handle, size, __flush_dcache_range);
+                       do_cache_op(paddr, size, __flush_dcache_range);
                break;
 
        case DMA_NONE:
@@ -88,43 +85,66 @@ static void xtensa_sync_single_for_device(struct device *dev,
        }
 }
 
-static void xtensa_sync_sg_for_cpu(struct device *dev,
-                                  struct scatterlist *sg, int nents,
-                                  enum dma_data_direction dir)
+#ifdef CONFIG_MMU
+bool platform_vaddr_cached(const void *p)
 {
-       struct scatterlist *s;
-       int i;
+       unsigned long addr = (unsigned long)p;
 
-       for_each_sg(sg, s, nents, i) {
-               xtensa_sync_single_for_cpu(dev, sg_dma_address(s),
-                                          sg_dma_len(s), dir);
-       }
+       return addr >= XCHAL_KSEG_CACHED_VADDR &&
+              addr - XCHAL_KSEG_CACHED_VADDR < XCHAL_KSEG_SIZE;
 }
 
-static void xtensa_sync_sg_for_device(struct device *dev,
-                                     struct scatterlist *sg, int nents,
-                                     enum dma_data_direction dir)
+bool platform_vaddr_uncached(const void *p)
 {
-       struct scatterlist *s;
-       int i;
+       unsigned long addr = (unsigned long)p;
 
-       for_each_sg(sg, s, nents, i) {
-               xtensa_sync_single_for_device(dev, sg_dma_address(s),
-                                             sg_dma_len(s), dir);
-       }
+       return addr >= XCHAL_KSEG_BYPASS_VADDR &&
+              addr - XCHAL_KSEG_BYPASS_VADDR < XCHAL_KSEG_SIZE;
+}
+
+void *platform_vaddr_to_uncached(void *p)
+{
+       return p + XCHAL_KSEG_BYPASS_VADDR - XCHAL_KSEG_CACHED_VADDR;
+}
+
+void *platform_vaddr_to_cached(void *p)
+{
+       return p + XCHAL_KSEG_CACHED_VADDR - XCHAL_KSEG_BYPASS_VADDR;
+}
+#else
+bool __attribute__((weak)) platform_vaddr_cached(const void *p)
+{
+       WARN_ONCE(1, "Default %s implementation is used\n", __func__);
+       return true;
+}
+
+bool __attribute__((weak)) platform_vaddr_uncached(const void *p)
+{
+       WARN_ONCE(1, "Default %s implementation is used\n", __func__);
+       return false;
+}
+
+void __attribute__((weak)) *platform_vaddr_to_uncached(void *p)
+{
+       WARN_ONCE(1, "Default %s implementation is used\n", __func__);
+       return p;
+}
+
+void __attribute__((weak)) *platform_vaddr_to_cached(void *p)
+{
+       WARN_ONCE(1, "Default %s implementation is used\n", __func__);
+       return p;
 }
+#endif
 
 /*
  * Note: We assume that the full memory space is always mapped to 'kseg'
  *      Otherwise we have to use page attributes (not implemented).
  */
 
-static void *xtensa_dma_alloc(struct device *dev, size_t size,
-                             dma_addr_t *handle, gfp_t flag,
-                             unsigned long attrs)
+void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+               gfp_t flag, unsigned long attrs)
 {
-       unsigned long ret;
-       unsigned long uncached;
        unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
        struct page *page = NULL;
 
@@ -147,6 +167,10 @@ static void *xtensa_dma_alloc(struct device *dev, size_t size,
 
        *handle = phys_to_dma(dev, page_to_phys(page));
 
+       if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) {
+               return page;
+       }
+
 #ifdef CONFIG_MMU
        if (PageHighMem(page)) {
                void *p;
@@ -161,27 +185,21 @@ static void *xtensa_dma_alloc(struct device *dev, size_t size,
                return p;
        }
 #endif
-       ret = (unsigned long)page_address(page);
-       BUG_ON(ret < XCHAL_KSEG_CACHED_VADDR ||
-              ret > XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_SIZE - 1);
-
-       uncached = ret + XCHAL_KSEG_BYPASS_VADDR - XCHAL_KSEG_CACHED_VADDR;
-       __invalidate_dcache_range(ret, size);
-
-       return (void *)uncached;
+       BUG_ON(!platform_vaddr_cached(page_address(page)));
+       __invalidate_dcache_range((unsigned long)page_address(page), size);
+       return platform_vaddr_to_uncached(page_address(page));
 }
 
-static void xtensa_dma_free(struct device *dev, size_t size, void *vaddr,
-                           dma_addr_t dma_handle, unsigned long attrs)
+void arch_dma_free(struct device *dev, size_t size, void *vaddr,
+               dma_addr_t dma_handle, unsigned long attrs)
 {
        unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
-       unsigned long addr = (unsigned long)vaddr;
        struct page *page;
 
-       if (addr >= XCHAL_KSEG_BYPASS_VADDR &&
-           addr - XCHAL_KSEG_BYPASS_VADDR < XCHAL_KSEG_SIZE) {
-               addr += XCHAL_KSEG_CACHED_VADDR - XCHAL_KSEG_BYPASS_VADDR;
-               page = virt_to_page(addr);
+       if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) {
+               page = vaddr;
+       } else if (platform_vaddr_uncached(vaddr)) {
+               page = virt_to_page(platform_vaddr_to_cached(vaddr));
        } else {
 #ifdef CONFIG_MMU
                dma_common_free_remap(vaddr, size, VM_MAP);
@@ -192,72 +210,3 @@ static void xtensa_dma_free(struct device *dev, size_t size, void *vaddr,
        if (!dma_release_from_contiguous(dev, page, count))
                __free_pages(page, get_order(size));
 }
-
-static dma_addr_t xtensa_map_page(struct device *dev, struct page *page,
-                                 unsigned long offset, size_t size,
-                                 enum dma_data_direction dir,
-                                 unsigned long attrs)
-{
-       dma_addr_t dma_handle = page_to_phys(page) + offset;
-
-       if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
-               xtensa_sync_single_for_device(dev, dma_handle, size, dir);
-
-       return dma_handle;
-}
-
-static void xtensa_unmap_page(struct device *dev, dma_addr_t dma_handle,
-                             size_t size, enum dma_data_direction dir,
-                             unsigned long attrs)
-{
-       if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
-               xtensa_sync_single_for_cpu(dev, dma_handle, size, dir);
-}
-
-static int xtensa_map_sg(struct device *dev, struct scatterlist *sg,
-                        int nents, enum dma_data_direction dir,
-                        unsigned long attrs)
-{
-       struct scatterlist *s;
-       int i;
-
-       for_each_sg(sg, s, nents, i) {
-               s->dma_address = xtensa_map_page(dev, sg_page(s), s->offset,
-                                                s->length, dir, attrs);
-       }
-       return nents;
-}
-
-static void xtensa_unmap_sg(struct device *dev,
-                           struct scatterlist *sg, int nents,
-                           enum dma_data_direction dir,
-                           unsigned long attrs)
-{
-       struct scatterlist *s;
-       int i;
-
-       for_each_sg(sg, s, nents, i) {
-               xtensa_unmap_page(dev, sg_dma_address(s),
-                                 sg_dma_len(s), dir, attrs);
-       }
-}
-
-int xtensa_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-       return 0;
-}
-
-const struct dma_map_ops xtensa_dma_map_ops = {
-       .alloc = xtensa_dma_alloc,
-       .free = xtensa_dma_free,
-       .map_page = xtensa_map_page,
-       .unmap_page = xtensa_unmap_page,
-       .map_sg = xtensa_map_sg,
-       .unmap_sg = xtensa_unmap_sg,
-       .sync_single_for_cpu = xtensa_sync_single_for_cpu,
-       .sync_single_for_device = xtensa_sync_single_for_device,
-       .sync_sg_for_cpu = xtensa_sync_sg_for_cpu,
-       .sync_sg_for_device = xtensa_sync_sg_for_device,
-       .mapping_error = xtensa_dma_mapping_error,
-};
-EXPORT_SYMBOL(xtensa_dma_map_ops);
index 686a27444bba24fcee3812b07c7c44becf93061e..351283b60df6174af90cfd789f991f58da68f131 100644 (file)
@@ -47,8 +47,6 @@
 #include <asm/smp.h>
 #include <asm/sysmem.h>
 
-#include <platform/hardware.h>
-
 #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
 struct screen_info screen_info = {
        .orig_x = 0,
@@ -81,6 +79,7 @@ static char __initdata command_line[COMMAND_LINE_SIZE];
 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
 #endif
 
+#ifdef CONFIG_PARSE_BOOTPARAM
 /*
  * Boot parameter parsing.
  *
@@ -178,6 +177,13 @@ static int __init parse_bootparam(const bp_tag_t* tag)
 
        return 0;
 }
+#else
+static int __init parse_bootparam(const bp_tag_t *tag)
+{
+       pr_info("Ignoring boot parameters at %p\n", tag);
+       return 0;
+}
+#endif
 
 #ifdef CONFIG_OF
 
index 70b731edc7b85259ab3a7af36831306fb99dc82f..a1c3edb8ad56c0d93e3c9a7d994dc0ffd9ad7351 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <asm/vectors.h>
 #include <variant/core.h>
-#include <platform/hardware.h>
+
 OUTPUT_ARCH(xtensa)
 ENTRY(_start)
 
diff --git a/arch/xtensa/platforms/iss/include/platform/hardware.h b/arch/xtensa/platforms/iss/include/platform/hardware.h
deleted file mode 100644 (file)
index 6930c12..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * include/asm-xtensa/platform-iss/hardware.h
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001 Tensilica Inc.
- */
-
-/*
- * This file contains the default configuration of ISS.
- */
-
-#ifndef _XTENSA_PLATFORM_ISS_HARDWARE_H
-#define _XTENSA_PLATFORM_ISS_HARDWARE_H
-
-/*
- * Memory configuration.
- */
-
-#define PLATFORM_DEFAULT_MEM_START     0x00000000
-#define PLATFORM_DEFAULT_MEM_SIZE      0x08000000
-
-/*
- * Interrupt configuration.
- */
-
-#endif /* _XTENSA_PLATFORM_ISS_HARDWARE_H */
index 886ef156ded3693ea49d00cf073d5121d17d18cd..8e5e0d6a81ec7868d0fa7bcb10ca5b37132048fa 100644 (file)
 
 #include <variant/core.h>
 
-/* 
- * Memory configuration.
- */
-
-#define PLATFORM_DEFAULT_MEM_START 0x00000000
-#define PLATFORM_DEFAULT_MEM_SIZE 0x08000000
-
-/*
- * Number of platform IRQs
- */
-#define PLATFORM_NR_IRQS 3
 /*
  * On-board components.
  */
index 1fda7e20dfcbff79849e5aae29ac8a6529c43e39..30d9cb6cf16881e22e7b5ddeeaf443d21fc45cad 100644 (file)
 #ifndef __XTENSA_XTAVNET_HARDWARE_H
 #define __XTENSA_XTAVNET_HARDWARE_H
 
-/* Memory configuration. */
-
-#define PLATFORM_DEFAULT_MEM_START __XTENSA_UL(CONFIG_DEFAULT_MEM_START)
-#define PLATFORM_DEFAULT_MEM_SIZE  __XTENSA_UL(CONFIG_DEFAULT_MEM_SIZE)
-
-/* Interrupt configuration. */
-
-#define PLATFORM_NR_IRQS       0
-
 /* Default assignment of LX60 devices to external interrupts. */
 
 #ifdef CONFIG_XTENSA_MX
diff --git a/arch/xtensa/variants/test_kc705_be/include/variant/core.h b/arch/xtensa/variants/test_kc705_be/include/variant/core.h
new file mode 100644 (file)
index 0000000..a4ebdf7
--- /dev/null
@@ -0,0 +1,575 @@
+/* 
+ * xtensa/config/core-isa.h -- HAL definitions that are dependent on Xtensa
+ *                             processor CORE configuration
+ *
+ *  See <xtensa/config/core.h>, which includes this file, for more details.
+ */
+
+/* Xtensa processor core configuration information.
+
+   Copyright (c) 1999-2015 Tensilica Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   "Software"), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef _XTENSA_CORE_CONFIGURATION_H
+#define _XTENSA_CORE_CONFIGURATION_H
+
+
+/****************************************************************************
+           Parameters Useful for Any Code, USER or PRIVILEGED
+ ****************************************************************************/
+
+/*
+ *  Note:  Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is
+ *  configured, and a value of 0 otherwise.  These macros are always defined.
+ */
+
+
+/*----------------------------------------------------------------------
+                               ISA
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_BE                  1       /* big-endian byte ordering */
+#define XCHAL_HAVE_WINDOWED            1       /* windowed registers option */
+#define XCHAL_NUM_AREGS                        32      /* num of physical addr regs */
+#define XCHAL_NUM_AREGS_LOG2           5       /* log2(XCHAL_NUM_AREGS) */
+#define XCHAL_MAX_INSTRUCTION_SIZE     8       /* max instr bytes (3..8) */
+#define XCHAL_HAVE_DEBUG               1       /* debug option */
+#define XCHAL_HAVE_DENSITY             1       /* 16-bit instructions */
+#define XCHAL_HAVE_LOOPS               1       /* zero-overhead loops */
+#define XCHAL_LOOP_BUFFER_SIZE         0       /* zero-ov. loop instr buffer size */
+#define XCHAL_HAVE_NSA                 1       /* NSA/NSAU instructions */
+#define XCHAL_HAVE_MINMAX              1       /* MIN/MAX instructions */
+#define XCHAL_HAVE_SEXT                        1       /* SEXT instruction */
+#define XCHAL_HAVE_DEPBITS             0       /* DEPBITS instruction */
+#define XCHAL_HAVE_CLAMPS              1       /* CLAMPS instruction */
+#define XCHAL_HAVE_MUL16               1       /* MUL16S/MUL16U instructions */
+#define XCHAL_HAVE_MUL32               1       /* MULL instruction */
+#define XCHAL_HAVE_MUL32_HIGH          1       /* MULUH/MULSH instructions */
+#define XCHAL_HAVE_DIV32               1       /* QUOS/QUOU/REMS/REMU instructions */
+#define XCHAL_HAVE_L32R                        1       /* L32R instruction */
+#define XCHAL_HAVE_ABSOLUTE_LITERALS   0       /* non-PC-rel (extended) L32R */
+#define XCHAL_HAVE_CONST16             0       /* CONST16 instruction */
+#define XCHAL_HAVE_ADDX                        1       /* ADDX#/SUBX# instructions */
+#define XCHAL_HAVE_WIDE_BRANCHES       0       /* B*.W18 or B*.W15 instr's */
+#define XCHAL_HAVE_PREDICTED_BRANCHES  0       /* B[EQ/EQZ/NE/NEZ]T instr's */
+#define XCHAL_HAVE_CALL4AND12          1       /* (obsolete option) */
+#define XCHAL_HAVE_ABS                 1       /* ABS instruction */
+/*#define XCHAL_HAVE_POPC              0*/     /* POPC instruction */
+/*#define XCHAL_HAVE_CRC               0*/     /* CRC instruction */
+#define XCHAL_HAVE_RELEASE_SYNC                1       /* L32AI/S32RI instructions */
+#define XCHAL_HAVE_S32C1I              1       /* S32C1I instruction */
+#define XCHAL_HAVE_SPECULATION         0       /* speculation */
+#define XCHAL_HAVE_FULL_RESET          1       /* all regs/state reset */
+#define XCHAL_NUM_CONTEXTS             1       /* */
+#define XCHAL_NUM_MISC_REGS            2       /* num of scratch regs (0..4) */
+#define XCHAL_HAVE_TAP_MASTER          0       /* JTAG TAP control instr's */
+#define XCHAL_HAVE_PRID                        1       /* processor ID register */
+#define XCHAL_HAVE_EXTERN_REGS         1       /* WER/RER instructions */
+#define XCHAL_HAVE_MX                  0       /* MX core (Tensilica internal) */
+#define XCHAL_HAVE_MP_INTERRUPTS       0       /* interrupt distributor port */
+#define XCHAL_HAVE_MP_RUNSTALL         0       /* core RunStall control port */
+#define XCHAL_HAVE_PSO                 0       /* Power Shut-Off */
+#define XCHAL_HAVE_PSO_CDM             0       /* core/debug/mem pwr domains */
+#define XCHAL_HAVE_PSO_FULL_RETENTION  0       /* all regs preserved on PSO */
+#define XCHAL_HAVE_THREADPTR           1       /* THREADPTR register */
+#define XCHAL_HAVE_BOOLEANS            1       /* boolean registers */
+#define XCHAL_HAVE_CP                  1       /* CPENABLE reg (coprocessor) */
+#define XCHAL_CP_MAXCFG                        8       /* max allowed cp id plus one */
+#define XCHAL_HAVE_MAC16               1       /* MAC16 package */
+
+#define XCHAL_HAVE_FUSION               0      /* Fusion*/
+#define XCHAL_HAVE_FUSION_FP    0              /* Fusion FP option */
+#define XCHAL_HAVE_FUSION_LOW_POWER 0  /* Fusion Low Power option */
+#define XCHAL_HAVE_FUSION_AES   0              /* Fusion BLE/Wifi AES-128 CCM option */
+#define XCHAL_HAVE_FUSION_CONVENC       0       /* Fusion Conv Encode option */
+#define XCHAL_HAVE_FUSION_LFSR_CRC      0      /* Fusion LFSR-CRC option */
+#define XCHAL_HAVE_FUSION_BITOPS        0      /* Fusion Bit Operations Support option */
+#define XCHAL_HAVE_FUSION_AVS   0      /* Fusion AVS option */
+#define XCHAL_HAVE_FUSION_16BIT_BASEBAND        0      /* Fusion 16-bit Baseband option */
+#define XCHAL_HAVE_HIFIPRO             0       /* HiFiPro Audio Engine pkg */
+#define XCHAL_HAVE_HIFI4               0       /* HiFi4 Audio Engine pkg */
+#define XCHAL_HAVE_HIFI4_VFPU          0       /* HiFi4 Audio Engine VFPU option */
+#define XCHAL_HAVE_HIFI3               0       /* HiFi3 Audio Engine pkg */
+#define XCHAL_HAVE_HIFI3_VFPU          0       /* HiFi3 Audio Engine VFPU option */
+#define XCHAL_HAVE_HIFI2               1       /* HiFi2 Audio Engine pkg */
+#define XCHAL_HAVE_HIFI2_MUL32X24      1       /* HiFi2 and 32x24 MACs */
+#define XCHAL_HAVE_HIFI2EP             1       /* HiFi2EP */
+#define XCHAL_HAVE_HIFI_MINI           0       
+
+
+#define XCHAL_HAVE_VECTORFPU2005       0       /* vector or user floating-point pkg */
+#define XCHAL_HAVE_USER_DPFPU         0       /* user DP floating-point pkg */
+#define XCHAL_HAVE_USER_SPFPU         0       /* user DP floating-point pkg */
+#define XCHAL_HAVE_FP                 0      /* single prec floating point */
+#define XCHAL_HAVE_FP_DIV             0  /* FP with DIV instructions */
+#define XCHAL_HAVE_FP_RECIP           0        /* FP with RECIP instructions */
+#define XCHAL_HAVE_FP_SQRT            0 /* FP with SQRT instructions */
+#define XCHAL_HAVE_FP_RSQRT           0        /* FP with RSQRT instructions */
+#define XCHAL_HAVE_DFP                        0     /* double precision FP pkg */
+#define XCHAL_HAVE_DFP_DIV            0 /* DFP with DIV instructions */
+#define XCHAL_HAVE_DFP_RECIP          0       /* DFP with RECIP instructions*/
+#define XCHAL_HAVE_DFP_SQRT           0        /* DFP with SQRT instructions */
+#define XCHAL_HAVE_DFP_RSQRT          0       /* DFP with RSQRT instructions*/
+#define XCHAL_HAVE_DFP_ACCEL           0       /* double precision FP acceleration pkg */
+#define XCHAL_HAVE_DFP_accel           XCHAL_HAVE_DFP_ACCEL                            /* for backward compatibility */
+
+#define XCHAL_HAVE_DFPU_SINGLE_ONLY    0                       /* DFPU Coprocessor, single precision only */
+#define XCHAL_HAVE_DFPU_SINGLE_DOUBLE  0                       /* DFPU Coprocessor, single and double precision */
+#define XCHAL_HAVE_VECTRA1             0       /* Vectra I  pkg */
+#define XCHAL_HAVE_VECTRALX            0       /* Vectra LX pkg */
+#define XCHAL_HAVE_PDX4                        0       /* PDX4 */
+#define XCHAL_HAVE_CONNXD2             0       /* ConnX D2 pkg */
+#define XCHAL_HAVE_CONNXD2_DUALLSFLIX   0      /* ConnX D2 & Dual LoadStore Flix */
+#define XCHAL_HAVE_BBE16               0       /* ConnX BBE16 pkg */
+#define XCHAL_HAVE_BBE16_RSQRT         0       /* BBE16 & vector recip sqrt */
+#define XCHAL_HAVE_BBE16_VECDIV                0       /* BBE16 & vector divide */
+#define XCHAL_HAVE_BBE16_DESPREAD      0       /* BBE16 & despread */
+#define XCHAL_HAVE_BBENEP              0       /* ConnX BBENEP pkgs */
+#define XCHAL_HAVE_BSP3                        0       /* ConnX BSP3 pkg */
+#define XCHAL_HAVE_BSP3_TRANSPOSE      0       /* BSP3 & transpose32x32 */
+#define XCHAL_HAVE_SSP16               0       /* ConnX SSP16 pkg */
+#define XCHAL_HAVE_SSP16_VITERBI       0       /* SSP16 & viterbi */
+#define XCHAL_HAVE_TURBO16             0       /* ConnX Turbo16 pkg */
+#define XCHAL_HAVE_BBP16               0       /* ConnX BBP16 pkg */
+#define XCHAL_HAVE_FLIX3               0       /* basic 3-way FLIX option */
+#define XCHAL_HAVE_GRIVPEP              0   /*  GRIVPEP is General Release of IVPEP */
+#define XCHAL_HAVE_GRIVPEP_HISTOGRAM    0   /* Histogram option on GRIVPEP */
+
+
+/*----------------------------------------------------------------------
+                               MISC
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_LOADSTORE_UNITS      1       /* load/store units */
+#define XCHAL_NUM_WRITEBUFFER_ENTRIES  8       /* size of write buffer */
+#define XCHAL_INST_FETCH_WIDTH         8       /* instr-fetch width in bytes */
+#define XCHAL_DATA_WIDTH               8       /* data width in bytes */
+#define XCHAL_DATA_PIPE_DELAY          1       /* d-side pipeline delay
+                                                  (1 = 5-stage, 2 = 7-stage) */
+#define XCHAL_CLOCK_GATING_GLOBAL      0       /* global clock gating */
+#define XCHAL_CLOCK_GATING_FUNCUNIT    0       /* funct. unit clock gating */
+/*  In T1050, applies to selected core load and store instructions (see ISA): */
+#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1       /* unaligned loads cause exc. */
+#define XCHAL_UNALIGNED_STORE_EXCEPTION        1       /* unaligned stores cause exc.*/
+#define XCHAL_UNALIGNED_LOAD_HW                0       /* unaligned loads work in hw */
+#define XCHAL_UNALIGNED_STORE_HW       0       /* unaligned stores work in hw*/
+
+#define XCHAL_SW_VERSION               1100002 /* sw version of this header */
+
+#define XCHAL_CORE_ID                  "test_kc705_be" /* alphanum core name
+                                                  (CoreID) set in the Xtensa
+                                                  Processor Generator */
+
+#define XCHAL_BUILD_UNIQUE_ID          0x00058D8C      /* 22-bit sw build ID */
+
+/*
+ *  These definitions describe the hardware targeted by this software.
+ */
+#define XCHAL_HW_CONFIGID0             0xC1B3FFFF      /* ConfigID hi 32 bits*/
+#define XCHAL_HW_CONFIGID1             0x1C858D8C      /* ConfigID lo 32 bits*/
+#define XCHAL_HW_VERSION_NAME          "LX6.0.2"       /* full version name */
+#define XCHAL_HW_VERSION_MAJOR         2600    /* major ver# of targeted hw */
+#define XCHAL_HW_VERSION_MINOR         2       /* minor ver# of targeted hw */
+#define XCHAL_HW_VERSION               260002  /* major*100+minor */
+#define XCHAL_HW_REL_LX6               1
+#define XCHAL_HW_REL_LX6_0             1
+#define XCHAL_HW_REL_LX6_0_2           1
+#define XCHAL_HW_CONFIGID_RELIABLE     1
+/*  If software targets a *range* of hardware versions, these are the bounds: */
+#define XCHAL_HW_MIN_VERSION_MAJOR     2600    /* major v of earliest tgt hw */
+#define XCHAL_HW_MIN_VERSION_MINOR     2       /* minor v of earliest tgt hw */
+#define XCHAL_HW_MIN_VERSION           260002  /* earliest targeted hw */
+#define XCHAL_HW_MAX_VERSION_MAJOR     2600    /* major v of latest tgt hw */
+#define XCHAL_HW_MAX_VERSION_MINOR     2       /* minor v of latest tgt hw */
+#define XCHAL_HW_MAX_VERSION           260002  /* latest targeted hw */
+
+
+/*----------------------------------------------------------------------
+                               CACHE
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_ICACHE_LINESIZE          32      /* I-cache line size in bytes */
+#define XCHAL_DCACHE_LINESIZE          32      /* D-cache line size in bytes */
+#define XCHAL_ICACHE_LINEWIDTH         5       /* log2(I line size in bytes) */
+#define XCHAL_DCACHE_LINEWIDTH         5       /* log2(D line size in bytes) */
+
+#define XCHAL_ICACHE_SIZE              16384   /* I-cache size in bytes or 0 */
+#define XCHAL_DCACHE_SIZE              16384   /* D-cache size in bytes or 0 */
+
+#define XCHAL_DCACHE_IS_WRITEBACK      1       /* writeback feature */
+#define XCHAL_DCACHE_IS_COHERENT       0       /* MP coherence feature */
+
+#define XCHAL_HAVE_PREFETCH            1       /* PREFCTL register */
+#define XCHAL_HAVE_PREFETCH_L1         0       /* prefetch to L1 dcache */
+#define XCHAL_PREFETCH_CASTOUT_LINES   1       /* dcache pref. castout bufsz */
+#define XCHAL_PREFETCH_ENTRIES         8       /* cache prefetch entries */
+#define XCHAL_PREFETCH_BLOCK_ENTRIES   0       /* prefetch block streams */
+#define XCHAL_HAVE_CACHE_BLOCKOPS      0       /* block prefetch for caches */
+#define XCHAL_HAVE_ICACHE_TEST         1       /* Icache test instructions */
+#define XCHAL_HAVE_DCACHE_TEST         1       /* Dcache test instructions */
+#define XCHAL_HAVE_ICACHE_DYN_WAYS     0       /* Icache dynamic way support */
+#define XCHAL_HAVE_DCACHE_DYN_WAYS     0       /* Dcache dynamic way support */
+
+
+
+
+/****************************************************************************
+    Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code
+ ****************************************************************************/
+
+
+#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY
+
+/*----------------------------------------------------------------------
+                               CACHE
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_PIF                 1       /* any outbound PIF present */
+
+/*  If present, cache size in bytes == (ways * 2^(linewidth + setwidth)).  */
+
+/*  Number of cache sets in log2(lines per way):  */
+#define XCHAL_ICACHE_SETWIDTH          7
+#define XCHAL_DCACHE_SETWIDTH          7
+
+/*  Cache set associativity (number of ways):  */
+#define XCHAL_ICACHE_WAYS              4
+#define XCHAL_DCACHE_WAYS              4
+
+/*  Cache features:  */
+#define XCHAL_ICACHE_LINE_LOCKABLE     1
+#define XCHAL_DCACHE_LINE_LOCKABLE     1
+#define XCHAL_ICACHE_ECC_PARITY                0
+#define XCHAL_DCACHE_ECC_PARITY                0
+
+/*  Cache access size in bytes (affects operation of SICW instruction):  */
+#define XCHAL_ICACHE_ACCESS_SIZE       8
+#define XCHAL_DCACHE_ACCESS_SIZE       8
+
+#define XCHAL_DCACHE_BANKS             1       /* number of banks */
+
+/*  Number of encoded cache attr bits (see <xtensa/hal.h> for decoded bits):  */
+#define XCHAL_CA_BITS                  4
+
+/*  Whether MEMCTL register has anything useful  */
+#define XCHAL_USE_MEMCTL               (((XCHAL_LOOP_BUFFER_SIZE > 0)  ||      \
+                                          XCHAL_DCACHE_IS_COHERENT     ||      \
+                                          XCHAL_HAVE_ICACHE_DYN_WAYS   ||      \
+                                          XCHAL_HAVE_DCACHE_DYN_WAYS)  &&      \
+                                          (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RE_2012_0))
+
+
+/*----------------------------------------------------------------------
+                       INTERNAL I/D RAM/ROMs and XLMI
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_INSTROM              0       /* number of core instr. ROMs */
+#define XCHAL_NUM_INSTRAM              0       /* number of core instr. RAMs */
+#define XCHAL_NUM_DATAROM              0       /* number of core data ROMs */
+#define XCHAL_NUM_DATARAM              0       /* number of core data RAMs */
+#define XCHAL_NUM_URAM                 0       /* number of core unified RAMs*/
+#define XCHAL_NUM_XLMI                 0       /* number of core XLMI ports */
+
+#define XCHAL_HAVE_IMEM_LOADSTORE      1       /* can load/store to IROM/IRAM*/
+
+
+/*----------------------------------------------------------------------
+                       INTERRUPTS and TIMERS
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_INTERRUPTS          1       /* interrupt option */
+#define XCHAL_HAVE_HIGHPRI_INTERRUPTS  1       /* med/high-pri. interrupts */
+#define XCHAL_HAVE_NMI                 1       /* non-maskable interrupt */
+#define XCHAL_HAVE_CCOUNT              1       /* CCOUNT reg. (timer option) */
+#define XCHAL_NUM_TIMERS               3       /* number of CCOMPAREn regs */
+#define XCHAL_NUM_INTERRUPTS           22      /* number of interrupts */
+#define XCHAL_NUM_INTERRUPTS_LOG2      5       /* ceil(log2(NUM_INTERRUPTS)) */
+#define XCHAL_NUM_EXTINTERRUPTS                16      /* num of external interrupts */
+#define XCHAL_NUM_INTLEVELS            6       /* number of interrupt levels
+                                                  (not including level zero) */
+#define XCHAL_EXCM_LEVEL               4       /* level masked by PS.EXCM */
+       /* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */
+
+/*  Masks of interrupts at each interrupt level:  */
+#define XCHAL_INTLEVEL1_MASK           0x001F00BF
+#define XCHAL_INTLEVEL2_MASK           0x00000140
+#define XCHAL_INTLEVEL3_MASK           0x00200E00
+#define XCHAL_INTLEVEL4_MASK           0x00008000
+#define XCHAL_INTLEVEL5_MASK           0x00003000
+#define XCHAL_INTLEVEL6_MASK           0x00000000
+#define XCHAL_INTLEVEL7_MASK           0x00004000
+
+/*  Masks of interrupts at each range 1..n of interrupt levels:  */
+#define XCHAL_INTLEVEL1_ANDBELOW_MASK  0x001F00BF
+#define XCHAL_INTLEVEL2_ANDBELOW_MASK  0x001F01FF
+#define XCHAL_INTLEVEL3_ANDBELOW_MASK  0x003F0FFF
+#define XCHAL_INTLEVEL4_ANDBELOW_MASK  0x003F8FFF
+#define XCHAL_INTLEVEL5_ANDBELOW_MASK  0x003FBFFF
+#define XCHAL_INTLEVEL6_ANDBELOW_MASK  0x003FBFFF
+#define XCHAL_INTLEVEL7_ANDBELOW_MASK  0x003FFFFF
+
+/*  Level of each interrupt:  */
+#define XCHAL_INT0_LEVEL               1
+#define XCHAL_INT1_LEVEL               1
+#define XCHAL_INT2_LEVEL               1
+#define XCHAL_INT3_LEVEL               1
+#define XCHAL_INT4_LEVEL               1
+#define XCHAL_INT5_LEVEL               1
+#define XCHAL_INT6_LEVEL               2
+#define XCHAL_INT7_LEVEL               1
+#define XCHAL_INT8_LEVEL               2
+#define XCHAL_INT9_LEVEL               3
+#define XCHAL_INT10_LEVEL              3
+#define XCHAL_INT11_LEVEL              3
+#define XCHAL_INT12_LEVEL              5
+#define XCHAL_INT13_LEVEL              5
+#define XCHAL_INT14_LEVEL              7
+#define XCHAL_INT15_LEVEL              4
+#define XCHAL_INT16_LEVEL              1
+#define XCHAL_INT17_LEVEL              1
+#define XCHAL_INT18_LEVEL              1
+#define XCHAL_INT19_LEVEL              1
+#define XCHAL_INT20_LEVEL              1
+#define XCHAL_INT21_LEVEL              3
+#define XCHAL_DEBUGLEVEL               6       /* debug interrupt level */
+#define XCHAL_HAVE_DEBUG_EXTERN_INT    1       /* OCD external db interrupt */
+#define XCHAL_NMILEVEL                 7       /* NMI "level" (for use with
+                                                  EXCSAVE/EPS/EPC_n, RFI n) */
+
+/*  Type of each interrupt:  */
+#define XCHAL_INT0_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT1_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT2_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT3_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT4_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT5_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT6_TYPE        XTHAL_INTTYPE_TIMER
+#define XCHAL_INT7_TYPE        XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT8_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT9_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT10_TYPE       XTHAL_INTTYPE_TIMER
+#define XCHAL_INT11_TYPE       XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT12_TYPE       XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT13_TYPE       XTHAL_INTTYPE_TIMER
+#define XCHAL_INT14_TYPE       XTHAL_INTTYPE_NMI
+#define XCHAL_INT15_TYPE       XTHAL_INTTYPE_PROFILING
+#define XCHAL_INT16_TYPE       XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT17_TYPE       XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT18_TYPE       XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT19_TYPE       XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT20_TYPE       XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT21_TYPE       XTHAL_INTTYPE_EXTERN_EDGE
+
+/*  Masks of interrupts for each type of interrupt:  */
+#define XCHAL_INTTYPE_MASK_UNCONFIGURED        0xFFC00000
+#define XCHAL_INTTYPE_MASK_SOFTWARE    0x00000880
+#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x003F0000
+#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL        0x0000133F
+#define XCHAL_INTTYPE_MASK_TIMER       0x00002440
+#define XCHAL_INTTYPE_MASK_NMI         0x00004000
+#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000000
+#define XCHAL_INTTYPE_MASK_PROFILING   0x00008000
+
+/*  Interrupt numbers assigned to specific interrupt sources:  */
+#define XCHAL_TIMER0_INTERRUPT         6       /* CCOMPARE0 */
+#define XCHAL_TIMER1_INTERRUPT         10      /* CCOMPARE1 */
+#define XCHAL_TIMER2_INTERRUPT         13      /* CCOMPARE2 */
+#define XCHAL_TIMER3_INTERRUPT         XTHAL_TIMER_UNCONFIGURED
+#define XCHAL_NMI_INTERRUPT            14      /* non-maskable interrupt */
+#define XCHAL_PROFILING_INTERRUPT      15      /* profiling interrupt */
+
+/*  Interrupt numbers for levels at which only one interrupt is configured:  */
+#define XCHAL_INTLEVEL4_NUM            15
+#define XCHAL_INTLEVEL7_NUM            14
+/*  (There are many interrupts each at level(s) 1, 2, 3, 5.)  */
+
+
+/*
+ *  External interrupt mapping.
+ *  These macros describe how Xtensa processor interrupt numbers
+ *  (as numbered internally, eg. in INTERRUPT and INTENABLE registers)
+ *  map to external BInterrupt<n> pins, for those interrupts
+ *  configured as external (level-triggered, edge-triggered, or NMI).
+ *  See the Xtensa processor databook for more details.
+ */
+
+/*  Core interrupt numbers mapped to each EXTERNAL BInterrupt pin number:  */
+#define XCHAL_EXTINT0_NUM              0       /* (intlevel 1) */
+#define XCHAL_EXTINT1_NUM              1       /* (intlevel 1) */
+#define XCHAL_EXTINT2_NUM              2       /* (intlevel 1) */
+#define XCHAL_EXTINT3_NUM              3       /* (intlevel 1) */
+#define XCHAL_EXTINT4_NUM              4       /* (intlevel 1) */
+#define XCHAL_EXTINT5_NUM              5       /* (intlevel 1) */
+#define XCHAL_EXTINT6_NUM              8       /* (intlevel 2) */
+#define XCHAL_EXTINT7_NUM              9       /* (intlevel 3) */
+#define XCHAL_EXTINT8_NUM              12      /* (intlevel 5) */
+#define XCHAL_EXTINT9_NUM              14      /* (intlevel 7) */
+#define XCHAL_EXTINT10_NUM             16      /* (intlevel 1) */
+#define XCHAL_EXTINT11_NUM             17      /* (intlevel 1) */
+#define XCHAL_EXTINT12_NUM             18      /* (intlevel 1) */
+#define XCHAL_EXTINT13_NUM             19      /* (intlevel 1) */
+#define XCHAL_EXTINT14_NUM             20      /* (intlevel 1) */
+#define XCHAL_EXTINT15_NUM             21      /* (intlevel 3) */
+/*  EXTERNAL BInterrupt pin numbers mapped to each core interrupt number:  */
+#define XCHAL_INT0_EXTNUM              0       /* (intlevel 1) */
+#define XCHAL_INT1_EXTNUM              1       /* (intlevel 1) */
+#define XCHAL_INT2_EXTNUM              2       /* (intlevel 1) */
+#define XCHAL_INT3_EXTNUM              3       /* (intlevel 1) */
+#define XCHAL_INT4_EXTNUM              4       /* (intlevel 1) */
+#define XCHAL_INT5_EXTNUM              5       /* (intlevel 1) */
+#define XCHAL_INT8_EXTNUM              6       /* (intlevel 2) */
+#define XCHAL_INT9_EXTNUM              7       /* (intlevel 3) */
+#define XCHAL_INT12_EXTNUM             8       /* (intlevel 5) */
+#define XCHAL_INT14_EXTNUM             9       /* (intlevel 7) */
+#define XCHAL_INT16_EXTNUM             10      /* (intlevel 1) */
+#define XCHAL_INT17_EXTNUM             11      /* (intlevel 1) */
+#define XCHAL_INT18_EXTNUM             12      /* (intlevel 1) */
+#define XCHAL_INT19_EXTNUM             13      /* (intlevel 1) */
+#define XCHAL_INT20_EXTNUM             14      /* (intlevel 1) */
+#define XCHAL_INT21_EXTNUM             15      /* (intlevel 3) */
+
+
+/*----------------------------------------------------------------------
+                       EXCEPTIONS and VECTORS
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_XEA_VERSION              2       /* Xtensa Exception Architecture
+                                                  number: 1 == XEA1 (old)
+                                                          2 == XEA2 (new)
+                                                          0 == XEAX (extern) or TX */
+#define XCHAL_HAVE_XEA1                        0       /* Exception Architecture 1 */
+#define XCHAL_HAVE_XEA2                        1       /* Exception Architecture 2 */
+#define XCHAL_HAVE_XEAX                        0       /* External Exception Arch. */
+#define XCHAL_HAVE_EXCEPTIONS          1       /* exception option */
+#define XCHAL_HAVE_HALT                        0       /* halt architecture option */
+#define XCHAL_HAVE_BOOTLOADER          0       /* boot loader (for TX) */
+#define XCHAL_HAVE_MEM_ECC_PARITY      0       /* local memory ECC/parity */
+#define XCHAL_HAVE_VECTOR_SELECT       1       /* relocatable vectors */
+#define XCHAL_HAVE_VECBASE             1       /* relocatable vectors */
+#define XCHAL_VECBASE_RESET_VADDR      0x00002000  /* VECBASE reset value */
+#define XCHAL_VECBASE_RESET_PADDR      0x00002000
+#define XCHAL_RESET_VECBASE_OVERLAP    0
+
+#define XCHAL_RESET_VECTOR0_VADDR      0xFE000000
+#define XCHAL_RESET_VECTOR0_PADDR      0xFE000000
+#define XCHAL_RESET_VECTOR1_VADDR      0x00001000
+#define XCHAL_RESET_VECTOR1_PADDR      0x00001000
+#define XCHAL_RESET_VECTOR_VADDR       0xFE000000
+#define XCHAL_RESET_VECTOR_PADDR       0xFE000000
+#define XCHAL_USER_VECOFS              0x00000340
+#define XCHAL_USER_VECTOR_VADDR                0x00002340
+#define XCHAL_USER_VECTOR_PADDR                0x00002340
+#define XCHAL_KERNEL_VECOFS            0x00000300
+#define XCHAL_KERNEL_VECTOR_VADDR      0x00002300
+#define XCHAL_KERNEL_VECTOR_PADDR      0x00002300
+#define XCHAL_DOUBLEEXC_VECOFS         0x000003C0
+#define XCHAL_DOUBLEEXC_VECTOR_VADDR   0x000023C0
+#define XCHAL_DOUBLEEXC_VECTOR_PADDR   0x000023C0
+#define XCHAL_WINDOW_OF4_VECOFS                0x00000000
+#define XCHAL_WINDOW_UF4_VECOFS                0x00000040
+#define XCHAL_WINDOW_OF8_VECOFS                0x00000080
+#define XCHAL_WINDOW_UF8_VECOFS                0x000000C0
+#define XCHAL_WINDOW_OF12_VECOFS       0x00000100
+#define XCHAL_WINDOW_UF12_VECOFS       0x00000140
+#define XCHAL_WINDOW_VECTORS_VADDR     0x00002000
+#define XCHAL_WINDOW_VECTORS_PADDR     0x00002000
+#define XCHAL_INTLEVEL2_VECOFS         0x00000180
+#define XCHAL_INTLEVEL2_VECTOR_VADDR   0x00002180
+#define XCHAL_INTLEVEL2_VECTOR_PADDR   0x00002180
+#define XCHAL_INTLEVEL3_VECOFS         0x000001C0
+#define XCHAL_INTLEVEL3_VECTOR_VADDR   0x000021C0
+#define XCHAL_INTLEVEL3_VECTOR_PADDR   0x000021C0
+#define XCHAL_INTLEVEL4_VECOFS         0x00000200
+#define XCHAL_INTLEVEL4_VECTOR_VADDR   0x00002200
+#define XCHAL_INTLEVEL4_VECTOR_PADDR   0x00002200
+#define XCHAL_INTLEVEL5_VECOFS         0x00000240
+#define XCHAL_INTLEVEL5_VECTOR_VADDR   0x00002240
+#define XCHAL_INTLEVEL5_VECTOR_PADDR   0x00002240
+#define XCHAL_INTLEVEL6_VECOFS         0x00000280
+#define XCHAL_INTLEVEL6_VECTOR_VADDR   0x00002280
+#define XCHAL_INTLEVEL6_VECTOR_PADDR   0x00002280
+#define XCHAL_DEBUG_VECOFS             XCHAL_INTLEVEL6_VECOFS
+#define XCHAL_DEBUG_VECTOR_VADDR       XCHAL_INTLEVEL6_VECTOR_VADDR
+#define XCHAL_DEBUG_VECTOR_PADDR       XCHAL_INTLEVEL6_VECTOR_PADDR
+#define XCHAL_NMI_VECOFS               0x000002C0
+#define XCHAL_NMI_VECTOR_VADDR         0x000022C0
+#define XCHAL_NMI_VECTOR_PADDR         0x000022C0
+#define XCHAL_INTLEVEL7_VECOFS         XCHAL_NMI_VECOFS
+#define XCHAL_INTLEVEL7_VECTOR_VADDR   XCHAL_NMI_VECTOR_VADDR
+#define XCHAL_INTLEVEL7_VECTOR_PADDR   XCHAL_NMI_VECTOR_PADDR
+
+
+/*----------------------------------------------------------------------
+                               DEBUG MODULE
+  ----------------------------------------------------------------------*/
+
+/*  Misc  */
+#define XCHAL_HAVE_DEBUG_ERI           1       /* ERI to debug module */
+#define XCHAL_HAVE_DEBUG_APB           0       /* APB to debug module */
+#define XCHAL_HAVE_DEBUG_JTAG          1       /* JTAG to debug module */
+
+/*  On-Chip Debug (OCD)  */
+#define XCHAL_HAVE_OCD                 1       /* OnChipDebug option */
+#define XCHAL_NUM_IBREAK               2       /* number of IBREAKn regs */
+#define XCHAL_NUM_DBREAK               2       /* number of DBREAKn regs */
+#define XCHAL_HAVE_OCD_DIR_ARRAY       0       /* faster OCD option (to LX4) */
+#define XCHAL_HAVE_OCD_LS32DDR         1       /* L32DDR/S32DDR (faster OCD) */
+
+/*  TRAX (in core)  */
+#define XCHAL_HAVE_TRAX                        1       /* TRAX in debug module */
+#define XCHAL_TRAX_MEM_SIZE            262144  /* TRAX memory size in bytes */
+#define XCHAL_TRAX_MEM_SHAREABLE       1       /* start/end regs; ready sig. */
+#define XCHAL_TRAX_ATB_WIDTH           0       /* ATB width (bits), 0=no ATB */
+#define XCHAL_TRAX_TIME_WIDTH          0       /* timestamp bitwidth, 0=none */
+
+/*  Perf counters  */
+#define XCHAL_NUM_PERF_COUNTERS                8       /* performance counters */
+
+
+/*----------------------------------------------------------------------
+                               MMU
+  ----------------------------------------------------------------------*/
+
+/*  See core-matmap.h header file for more details.  */
+
+#define XCHAL_HAVE_TLBS                        1       /* inverse of HAVE_CACHEATTR */
+#define XCHAL_HAVE_SPANNING_WAY                1       /* one way maps I+D 4GB vaddr */
+#define XCHAL_SPANNING_WAY             6       /* TLB spanning way number */
+#define XCHAL_HAVE_IDENTITY_MAP                0       /* vaddr == paddr always */
+#define XCHAL_HAVE_CACHEATTR           0       /* CACHEATTR register present */
+#define XCHAL_HAVE_MIMIC_CACHEATTR     0       /* region protection */
+#define XCHAL_HAVE_XLT_CACHEATTR       0       /* region prot. w/translation */
+#define XCHAL_HAVE_PTP_MMU             1       /* full MMU (with page table
+                                                  [autorefill] and protection)
+                                                  usable for an MMU-based OS */
+/*  If none of the above last 4 are set, it's a custom TLB configuration.  */
+#define XCHAL_ITLB_ARF_ENTRIES_LOG2    2       /* log2(autorefill way size) */
+#define XCHAL_DTLB_ARF_ENTRIES_LOG2    2       /* log2(autorefill way size) */
+
+#define XCHAL_MMU_ASID_BITS            8       /* number of bits in ASIDs */
+#define XCHAL_MMU_RINGS                        4       /* number of rings (1..4) */
+#define XCHAL_MMU_RING_BITS            2       /* num of bits in RING field */
+
+#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */
+
+
+#endif /* _XTENSA_CORE_CONFIGURATION_H */
+
diff --git a/arch/xtensa/variants/test_kc705_be/include/variant/tie-asm.h b/arch/xtensa/variants/test_kc705_be/include/variant/tie-asm.h
new file mode 100644 (file)
index 0000000..b87fe1a
--- /dev/null
@@ -0,0 +1,308 @@
+/* 
+ * tie-asm.h -- compile-time HAL assembler definitions dependent on CORE & TIE
+ *
+ *  NOTE:  This header file is not meant to be included directly.
+ */
+
+/* This header file contains assembly-language definitions (assembly
+   macros, etc.) for this specific Xtensa processor's TIE extensions
+   and options.  It is customized to this Xtensa processor configuration.
+
+   Copyright (c) 1999-2015 Cadence Design Systems Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   "Software"), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef _XTENSA_CORE_TIE_ASM_H
+#define _XTENSA_CORE_TIE_ASM_H
+
+/*  Selection parameter values for save-area save/restore macros:  */
+/*  Option vs. TIE:  */
+#define XTHAL_SAS_TIE  0x0001  /* custom extension or coprocessor */
+#define XTHAL_SAS_OPT  0x0002  /* optional (and not a coprocessor) */
+#define XTHAL_SAS_ANYOT        0x0003  /* both of the above */
+/*  Whether used automatically by compiler:  */
+#define XTHAL_SAS_NOCC 0x0004  /* not used by compiler w/o special opts/code */
+#define XTHAL_SAS_CC   0x0008  /* used by compiler without special opts/code */
+#define XTHAL_SAS_ANYCC        0x000C  /* both of the above */
+/*  ABI handling across function calls:  */
+#define XTHAL_SAS_CALR 0x0010  /* caller-saved */
+#define XTHAL_SAS_CALE 0x0020  /* callee-saved */
+#define XTHAL_SAS_GLOB 0x0040  /* global across function calls (in thread) */
+#define XTHAL_SAS_ANYABI       0x0070  /* all of the above three */
+/*  Misc  */
+#define XTHAL_SAS_ALL  0xFFFF  /* include all default NCP contents */
+#define XTHAL_SAS3(optie,ccuse,abi)    ( ((optie) & XTHAL_SAS_ANYOT)  \
+                                       | ((ccuse) & XTHAL_SAS_ANYCC)  \
+                                       | ((abi)   & XTHAL_SAS_ANYABI) )
+
+
+    /*
+      *  Macro to store all non-coprocessor (extra) custom TIE and optional state
+      *  (not including zero-overhead loop registers).
+      *  Required parameters:
+      *      ptr         Save area pointer address register (clobbered)
+      *                  (register must contain a 4 byte aligned address).
+      *      at1..at4    Four temporary address registers (first XCHAL_NCP_NUM_ATMPS
+      *                  registers are clobbered, the remaining are unused).
+      *  Optional parameters:
+      *      continue    If macro invoked as part of a larger store sequence, set to 1
+      *                  if this is not the first in the sequence.  Defaults to 0.
+      *      ofs         Offset from start of larger sequence (from value of first ptr
+      *                  in sequence) at which to store.  Defaults to next available space
+      *                  (or 0 if <continue> is 0).
+      *      select      Select what category(ies) of registers to store, as a bitmask
+      *                  (see XTHAL_SAS_xxx constants).  Defaults to all registers.
+      *      alloc       Select what category(ies) of registers to allocate; if any
+      *                  category is selected here that is not in <select>, space for
+      *                  the corresponding registers is skipped without doing any store.
+      */
+    .macro xchal_ncp_store  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0
+       xchal_sa_start  \continue, \ofs
+       // Optional global registers used by default by the compiler:
+       .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~(\select)
+       xchal_sa_align  \ptr, 0, 1020, 4, 4
+       rur.THREADPTR   \at1            // threadptr option
+       s32i    \at1, \ptr, .Lxchal_ofs_+0
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 4
+       .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~(\alloc)) == 0
+       xchal_sa_align  \ptr, 0, 1020, 4, 4
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 4
+       .endif
+       // Optional caller-saved registers used by default by the compiler:
+       .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~(\select)
+       xchal_sa_align  \ptr, 0, 1016, 4, 4
+       rsr.ACCLO       \at1            // MAC16 option
+       s32i    \at1, \ptr, .Lxchal_ofs_+0
+       rsr.ACCHI       \at1            // MAC16 option
+       s32i    \at1, \ptr, .Lxchal_ofs_+4
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 8
+       .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~(\alloc)) == 0
+       xchal_sa_align  \ptr, 0, 1016, 4, 4
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 8
+       .endif
+       // Optional caller-saved registers not used by default by the compiler:
+       .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select)
+       xchal_sa_align  \ptr, 0, 1000, 4, 4
+       rsr.BR  \at1            // boolean option
+       s32i    \at1, \ptr, .Lxchal_ofs_+0
+       rsr.SCOMPARE1   \at1            // conditional store option
+       s32i    \at1, \ptr, .Lxchal_ofs_+4
+       rsr.M0  \at1            // MAC16 option
+       s32i    \at1, \ptr, .Lxchal_ofs_+8
+       rsr.M1  \at1            // MAC16 option
+       s32i    \at1, \ptr, .Lxchal_ofs_+12
+       rsr.M2  \at1            // MAC16 option
+       s32i    \at1, \ptr, .Lxchal_ofs_+16
+       rsr.M3  \at1            // MAC16 option
+       s32i    \at1, \ptr, .Lxchal_ofs_+20
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 24
+       .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0
+       xchal_sa_align  \ptr, 0, 1000, 4, 4
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 24
+       .endif
+    .endm      // xchal_ncp_store
+
+    /*
+      *  Macro to load all non-coprocessor (extra) custom TIE and optional state
+      *  (not including zero-overhead loop registers).
+      *  Required parameters:
+      *      ptr         Save area pointer address register (clobbered)
+      *                  (register must contain a 4 byte aligned address).
+      *      at1..at4    Four temporary address registers (first XCHAL_NCP_NUM_ATMPS
+      *                  registers are clobbered, the remaining are unused).
+      *  Optional parameters:
+      *      continue    If macro invoked as part of a larger load sequence, set to 1
+      *                  if this is not the first in the sequence.  Defaults to 0.
+      *      ofs         Offset from start of larger sequence (from value of first ptr
+      *                  in sequence) at which to load.  Defaults to next available space
+      *                  (or 0 if <continue> is 0).
+      *      select      Select what category(ies) of registers to load, as a bitmask
+      *                  (see XTHAL_SAS_xxx constants).  Defaults to all registers.
+      *      alloc       Select what category(ies) of registers to allocate; if any
+      *                  category is selected here that is not in <select>, space for
+      *                  the corresponding registers is skipped without doing any load.
+      */
+    .macro xchal_ncp_load  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0
+       xchal_sa_start  \continue, \ofs
+       // Optional global registers used by default by the compiler:
+       .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~(\select)
+       xchal_sa_align  \ptr, 0, 1020, 4, 4
+       l32i    \at1, \ptr, .Lxchal_ofs_+0
+       wur.THREADPTR   \at1            // threadptr option
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 4
+       .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~(\alloc)) == 0
+       xchal_sa_align  \ptr, 0, 1020, 4, 4
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 4
+       .endif
+       // Optional caller-saved registers used by default by the compiler:
+       .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~(\select)
+       xchal_sa_align  \ptr, 0, 1016, 4, 4
+       l32i    \at1, \ptr, .Lxchal_ofs_+0
+       wsr.ACCLO       \at1            // MAC16 option
+       l32i    \at1, \ptr, .Lxchal_ofs_+4
+       wsr.ACCHI       \at1            // MAC16 option
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 8
+       .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~(\alloc)) == 0
+       xchal_sa_align  \ptr, 0, 1016, 4, 4
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 8
+       .endif
+       // Optional caller-saved registers not used by default by the compiler:
+       .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select)
+       xchal_sa_align  \ptr, 0, 1000, 4, 4
+       l32i    \at1, \ptr, .Lxchal_ofs_+0
+       wsr.BR  \at1            // boolean option
+       l32i    \at1, \ptr, .Lxchal_ofs_+4
+       wsr.SCOMPARE1   \at1            // conditional store option
+       l32i    \at1, \ptr, .Lxchal_ofs_+8
+       wsr.M0  \at1            // MAC16 option
+       l32i    \at1, \ptr, .Lxchal_ofs_+12
+       wsr.M1  \at1            // MAC16 option
+       l32i    \at1, \ptr, .Lxchal_ofs_+16
+       wsr.M2  \at1            // MAC16 option
+       l32i    \at1, \ptr, .Lxchal_ofs_+20
+       wsr.M3  \at1            // MAC16 option
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 24
+       .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0
+       xchal_sa_align  \ptr, 0, 1000, 4, 4
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 24
+       .endif
+    .endm      // xchal_ncp_load
+
+
+#define XCHAL_NCP_NUM_ATMPS    1
+
+    /* 
+     *  Macro to store the state of TIE coprocessor AudioEngineLX.
+     *  Required parameters:
+     *      ptr         Save area pointer address register (clobbered)
+     *                  (register must contain a 8 byte aligned address).
+     *      at1..at4    Four temporary address registers (first XCHAL_CP1_NUM_ATMPS
+     *                  registers are clobbered, the remaining are unused).
+     *  Optional parameters are the same as for xchal_ncp_store.
+     */
+#define xchal_cp_AudioEngineLX_store   xchal_cp1_store
+    .macro     xchal_cp1_store  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0
+       xchal_sa_start \continue, \ofs
+       // Custom caller-saved registers not used by default by the compiler:
+       .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select)
+       xchal_sa_align  \ptr, 0, 0, 8, 8
+       rur.AE_OVF_SAR  \at1            // ureg 240
+       s32i    \at1, \ptr, .Lxchal_ofs_+0
+       rur.AE_BITHEAD  \at1            // ureg 241
+       s32i    \at1, \ptr, .Lxchal_ofs_+4
+       rur.AE_TS_FTS_BU_BP     \at1            // ureg 242
+       s32i    \at1, \ptr, .Lxchal_ofs_+8
+       rur.AE_SD_NO    \at1            // ureg 243
+       s32i    \at1, \ptr, .Lxchal_ofs_+12
+       rur.AE_CBEGIN0  \at1            // ureg 246
+       s32i    \at1, \ptr, .Lxchal_ofs_+16
+       rur.AE_CEND0    \at1            // ureg 247
+       s32i    \at1, \ptr, .Lxchal_ofs_+20
+       ae_sp24x2s.i    aep0, \ptr, .Lxchal_ofs_+24
+       ae_sp24x2s.i    aep1, \ptr, .Lxchal_ofs_+32
+       ae_sp24x2s.i    aep2, \ptr, .Lxchal_ofs_+40
+       ae_sp24x2s.i    aep3, \ptr, .Lxchal_ofs_+48
+       ae_sp24x2s.i    aep4, \ptr, .Lxchal_ofs_+56
+       addi    \ptr, \ptr, 64
+       ae_sp24x2s.i    aep5, \ptr, .Lxchal_ofs_+0
+       ae_sp24x2s.i    aep6, \ptr, .Lxchal_ofs_+8
+       ae_sp24x2s.i    aep7, \ptr, .Lxchal_ofs_+16
+       ae_sq56s.i      aeq0, \ptr, .Lxchal_ofs_+24
+       ae_sq56s.i      aeq1, \ptr, .Lxchal_ofs_+32
+       ae_sq56s.i      aeq2, \ptr, .Lxchal_ofs_+40
+       ae_sq56s.i      aeq3, \ptr, .Lxchal_ofs_+48
+       .set    .Lxchal_pofs_, .Lxchal_pofs_ + 64
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 56
+       .elseif ((XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0
+       xchal_sa_align  \ptr, 0, 0, 8, 8
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 120
+       .endif
+    .endm      // xchal_cp1_store
+
+    /* 
+     *  Macro to load the state of TIE coprocessor AudioEngineLX.
+     *  Required parameters:
+     *      ptr         Save area pointer address register (clobbered)
+     *                  (register must contain a 8 byte aligned address).
+     *      at1..at4    Four temporary address registers (first XCHAL_CP1_NUM_ATMPS
+     *                  registers are clobbered, the remaining are unused).
+     *  Optional parameters are the same as for xchal_ncp_load.
+     */
+#define xchal_cp_AudioEngineLX_load    xchal_cp1_load
+    .macro     xchal_cp1_load  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0
+       xchal_sa_start \continue, \ofs
+       // Custom caller-saved registers not used by default by the compiler:
+       .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select)
+       xchal_sa_align  \ptr, 0, 0, 8, 8
+       l32i    \at1, \ptr, .Lxchal_ofs_+0
+       wur.AE_OVF_SAR  \at1            // ureg 240
+       l32i    \at1, \ptr, .Lxchal_ofs_+4
+       wur.AE_BITHEAD  \at1            // ureg 241
+       l32i    \at1, \ptr, .Lxchal_ofs_+8
+       wur.AE_TS_FTS_BU_BP     \at1            // ureg 242
+       l32i    \at1, \ptr, .Lxchal_ofs_+12
+       wur.AE_SD_NO    \at1            // ureg 243
+       l32i    \at1, \ptr, .Lxchal_ofs_+16
+       wur.AE_CBEGIN0  \at1            // ureg 246
+       l32i    \at1, \ptr, .Lxchal_ofs_+20
+       wur.AE_CEND0    \at1            // ureg 247
+       ae_lp24x2.i     aep0, \ptr, .Lxchal_ofs_+24
+       ae_lp24x2.i     aep1, \ptr, .Lxchal_ofs_+32
+       ae_lp24x2.i     aep2, \ptr, .Lxchal_ofs_+40
+       ae_lp24x2.i     aep3, \ptr, .Lxchal_ofs_+48
+       ae_lp24x2.i     aep4, \ptr, .Lxchal_ofs_+56
+       addi    \ptr, \ptr, 64
+       ae_lp24x2.i     aep5, \ptr, .Lxchal_ofs_+0
+       ae_lp24x2.i     aep6, \ptr, .Lxchal_ofs_+8
+       ae_lp24x2.i     aep7, \ptr, .Lxchal_ofs_+16
+       addi    \ptr, \ptr, 24
+       ae_lq56.i       aeq0, \ptr, .Lxchal_ofs_+0
+       ae_lq56.i       aeq1, \ptr, .Lxchal_ofs_+8
+       ae_lq56.i       aeq2, \ptr, .Lxchal_ofs_+16
+       ae_lq56.i       aeq3, \ptr, .Lxchal_ofs_+24
+       .set    .Lxchal_pofs_, .Lxchal_pofs_ + 88
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 32
+       .elseif ((XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0
+       xchal_sa_align  \ptr, 0, 0, 8, 8
+       .set    .Lxchal_ofs_, .Lxchal_ofs_ + 120
+       .endif
+    .endm      // xchal_cp1_load
+
+#define XCHAL_CP1_NUM_ATMPS    1
+#define XCHAL_SA_NUM_ATMPS     1
+
+       /*  Empty macros for unconfigured coprocessors:  */
+       .macro xchal_cp0_store  p a b c d continue=0 ofs=-1 select=-1 ; .endm
+       .macro xchal_cp0_load   p a b c d continue=0 ofs=-1 select=-1 ; .endm
+       .macro xchal_cp2_store  p a b c d continue=0 ofs=-1 select=-1 ; .endm
+       .macro xchal_cp2_load   p a b c d continue=0 ofs=-1 select=-1 ; .endm
+       .macro xchal_cp3_store  p a b c d continue=0 ofs=-1 select=-1 ; .endm
+       .macro xchal_cp3_load   p a b c d continue=0 ofs=-1 select=-1 ; .endm
+       .macro xchal_cp4_store  p a b c d continue=0 ofs=-1 select=-1 ; .endm
+       .macro xchal_cp4_load   p a b c d continue=0 ofs=-1 select=-1 ; .endm
+       .macro xchal_cp5_store  p a b c d continue=0 ofs=-1 select=-1 ; .endm
+       .macro xchal_cp5_load   p a b c d continue=0 ofs=-1 select=-1 ; .endm
+       .macro xchal_cp6_store  p a b c d continue=0 ofs=-1 select=-1 ; .endm
+       .macro xchal_cp6_load   p a b c d continue=0 ofs=-1 select=-1 ; .endm
+       .macro xchal_cp7_store  p a b c d continue=0 ofs=-1 select=-1 ; .endm
+       .macro xchal_cp7_load   p a b c d continue=0 ofs=-1 select=-1 ; .endm
+
+#endif /*_XTENSA_CORE_TIE_ASM_H*/
+
diff --git a/arch/xtensa/variants/test_kc705_be/include/variant/tie.h b/arch/xtensa/variants/test_kc705_be/include/variant/tie.h
new file mode 100644 (file)
index 0000000..4e1b4ba
--- /dev/null
@@ -0,0 +1,182 @@
+/* 
+ * tie.h -- compile-time HAL definitions dependent on CORE & TIE configuration
+ *
+ *  NOTE:  This header file is not meant to be included directly.
+ */
+
+/* This header file describes this specific Xtensa processor's TIE extensions
+   that extend basic Xtensa core functionality.  It is customized to this
+   Xtensa processor configuration.
+
+   Copyright (c) 1999-2015 Cadence Design Systems Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   "Software"), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef _XTENSA_CORE_TIE_H
+#define _XTENSA_CORE_TIE_H
+
+#define XCHAL_CP_NUM                   2       /* number of coprocessors */
+#define XCHAL_CP_MAX                   8       /* max CP ID + 1 (0 if none) */
+#define XCHAL_CP_MASK                  0x82    /* bitmask of all CPs by ID */
+#define XCHAL_CP_PORT_MASK             0x80    /* bitmask of only port CPs */
+
+/*  Basic parameters of each coprocessor:  */
+#define XCHAL_CP1_NAME                 "AudioEngineLX"
+#define XCHAL_CP1_IDENT                        AudioEngineLX
+#define XCHAL_CP1_SA_SIZE              120     /* size of state save area */
+#define XCHAL_CP1_SA_ALIGN             8       /* min alignment of save area */
+#define XCHAL_CP_ID_AUDIOENGINELX      1       /* coprocessor ID (0..7) */
+#define XCHAL_CP7_NAME                 "XTIOP"
+#define XCHAL_CP7_IDENT                        XTIOP
+#define XCHAL_CP7_SA_SIZE              0       /* size of state save area */
+#define XCHAL_CP7_SA_ALIGN             1       /* min alignment of save area */
+#define XCHAL_CP_ID_XTIOP              7       /* coprocessor ID (0..7) */
+
+/*  Filler info for unassigned coprocessors, to simplify arrays etc:  */
+#define XCHAL_CP0_SA_SIZE              0
+#define XCHAL_CP0_SA_ALIGN             1
+#define XCHAL_CP2_SA_SIZE              0
+#define XCHAL_CP2_SA_ALIGN             1
+#define XCHAL_CP3_SA_SIZE              0
+#define XCHAL_CP3_SA_ALIGN             1
+#define XCHAL_CP4_SA_SIZE              0
+#define XCHAL_CP4_SA_ALIGN             1
+#define XCHAL_CP5_SA_SIZE              0
+#define XCHAL_CP5_SA_ALIGN             1
+#define XCHAL_CP6_SA_SIZE              0
+#define XCHAL_CP6_SA_ALIGN             1
+
+/*  Save area for non-coprocessor optional and custom (TIE) state:  */
+#define XCHAL_NCP_SA_SIZE              36
+#define XCHAL_NCP_SA_ALIGN             4
+
+/*  Total save area for optional and custom state (NCP + CPn):  */
+#define XCHAL_TOTAL_SA_SIZE            160     /* with 16-byte align padding */
+#define XCHAL_TOTAL_SA_ALIGN           8       /* actual minimum alignment */
+
+/*
+ * Detailed contents of save areas.
+ * NOTE:  caller must define the XCHAL_SA_REG macro (not defined here)
+ * before expanding the XCHAL_xxx_SA_LIST() macros.
+ *
+ * XCHAL_SA_REG(s,ccused,abikind,kind,opt,name,galign,align,asize,
+ *             dbnum,base,regnum,bitsz,gapsz,reset,x...)
+ *
+ *     s = passed from XCHAL_*_LIST(s), eg. to select how to expand
+ *     ccused = set if used by compiler without special options or code
+ *     abikind = 0 (caller-saved), 1 (callee-saved), or 2 (thread-global)
+ *     kind = 0 (special reg), 1 (TIE user reg), or 2 (TIE regfile reg)
+ *     opt = 0 (custom TIE extension or coprocessor), or 1 (optional reg)
+ *     name = lowercase reg name (no quotes)
+ *     galign = group byte alignment (power of 2) (galign >= align)
+ *     align = register byte alignment (power of 2)
+ *     asize = allocated size in bytes (asize*8 == bitsz + gapsz + padsz)
+ *       (not including any pad bytes required to galign this or next reg)
+ *     dbnum = unique target number f/debug (see <xtensa-libdb-macros.h>)
+ *     base = reg shortname w/o index (or sr=special, ur=TIE user reg)
+ *     regnum = reg index in regfile, or special/TIE-user reg number
+ *     bitsz = number of significant bits (regfile width, or ur/sr mask bits)
+ *     gapsz = intervening bits, if bitsz bits not stored contiguously
+ *     (padsz = pad bits at end [TIE regfile] or at msbits [ur,sr] of asize)
+ *     reset = register reset value (or 0 if undefined at reset)
+ *     x = reserved for future use (0 until then)
+ *
+ *  To filter out certain registers, e.g. to expand only the non-global
+ *  registers used by the compiler, you can do something like this:
+ *
+ *  #define XCHAL_SA_REG(s,ccused,p...)        SELCC##ccused(p)
+ *  #define SELCC0(p...)
+ *  #define SELCC1(abikind,p...)       SELAK##abikind(p)
+ *  #define SELAK0(p...)               REG(p)
+ *  #define SELAK1(p...)               REG(p)
+ *  #define SELAK2(p...)
+ *  #define REG(kind,tie,name,galn,aln,asz,csz,dbnum,base,rnum,bsz,rst,x...) \
+ *             ...what you want to expand...
+ */
+
+#define XCHAL_NCP_SA_NUM       9
+#define XCHAL_NCP_SA_LIST(s)   \
+ XCHAL_SA_REG(s,1,2,1,1,      threadptr, 4, 4, 4,0x03E7,  ur,231, 32,0,0,0) \
+ XCHAL_SA_REG(s,1,0,0,1,          acclo, 4, 4, 4,0x0210,  sr,16 , 32,0,0,0) \
+ XCHAL_SA_REG(s,1,0,0,1,          acchi, 4, 4, 4,0x0211,  sr,17 ,  8,0,0,0) \
+ XCHAL_SA_REG(s,0,0,0,1,             br, 4, 4, 4,0x0204,  sr,4  , 16,0,0,0) \
+ XCHAL_SA_REG(s,0,0,0,1,      scompare1, 4, 4, 4,0x020C,  sr,12 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,0,1,             m0, 4, 4, 4,0x0220,  sr,32 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,0,1,             m1, 4, 4, 4,0x0221,  sr,33 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,0,1,             m2, 4, 4, 4,0x0222,  sr,34 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,0,1,             m3, 4, 4, 4,0x0223,  sr,35 , 32,0,0,0)
+
+#define XCHAL_CP0_SA_NUM       0
+#define XCHAL_CP0_SA_LIST(s)   /* empty */
+
+#define XCHAL_CP1_SA_NUM       18
+#define XCHAL_CP1_SA_LIST(s)   \
+ XCHAL_SA_REG(s,0,0,1,0,     ae_ovf_sar, 8, 4, 4,0x03F0,  ur,240,  7,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,     ae_bithead, 4, 4, 4,0x03F1,  ur,241, 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,ae_ts_fts_bu_bp, 4, 4, 4,0x03F2,  ur,242, 16,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,       ae_sd_no, 4, 4, 4,0x03F3,  ur,243, 28,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,     ae_cbegin0, 4, 4, 4,0x03F6,  ur,246, 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,       ae_cend0, 4, 4, 4,0x03F7,  ur,247, 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           aep0, 8, 8, 8,0x0060, aep,0  , 48,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           aep1, 8, 8, 8,0x0061, aep,1  , 48,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           aep2, 8, 8, 8,0x0062, aep,2  , 48,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           aep3, 8, 8, 8,0x0063, aep,3  , 48,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           aep4, 8, 8, 8,0x0064, aep,4  , 48,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           aep5, 8, 8, 8,0x0065, aep,5  , 48,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           aep6, 8, 8, 8,0x0066, aep,6  , 48,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           aep7, 8, 8, 8,0x0067, aep,7  , 48,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           aeq0, 8, 8, 8,0x0068, aeq,0  , 56,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           aeq1, 8, 8, 8,0x0069, aeq,1  , 56,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           aeq2, 8, 8, 8,0x006A, aeq,2  , 56,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           aeq3, 8, 8, 8,0x006B, aeq,3  , 56,0,0,0)
+
+#define XCHAL_CP2_SA_NUM       0
+#define XCHAL_CP2_SA_LIST(s)   /* empty */
+
+#define XCHAL_CP3_SA_NUM       0
+#define XCHAL_CP3_SA_LIST(s)   /* empty */
+
+#define XCHAL_CP4_SA_NUM       0
+#define XCHAL_CP4_SA_LIST(s)   /* empty */
+
+#define XCHAL_CP5_SA_NUM       0
+#define XCHAL_CP5_SA_LIST(s)   /* empty */
+
+#define XCHAL_CP6_SA_NUM       0
+#define XCHAL_CP6_SA_LIST(s)   /* empty */
+
+#define XCHAL_CP7_SA_NUM       0
+#define XCHAL_CP7_SA_LIST(s)   /* empty */
+
+/* Byte length of instruction from its first nibble (op0 field), per FLIX.  */
+#define XCHAL_OP0_FORMAT_LENGTHS       3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,8
+/* Byte length of instruction from its first byte, per FLIX.  */
+#define XCHAL_BYTE0_FORMAT_LENGTHS     \
+       3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,\
+       3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,\
+       3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,\
+       3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,\
+       2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,\
+       2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,\
+       2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,\
+       3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
+
+#endif /*_XTENSA_CORE_TIE_H*/
+
index a9e8633388f40985a0a49246a1e95c37def3cc8f..9fe5952d117d553f12f32055fde8683c554b06a8 100644 (file)
@@ -275,9 +275,9 @@ static void bfqg_and_blkg_get(struct bfq_group *bfqg)
 
 void bfqg_and_blkg_put(struct bfq_group *bfqg)
 {
-       bfqg_put(bfqg);
-
        blkg_put(bfqg_to_blkg(bfqg));
+
+       bfqg_put(bfqg);
 }
 
 /* @stats = 0 */
@@ -913,7 +913,8 @@ static ssize_t bfq_io_set_weight(struct kernfs_open_file *of,
        if (ret)
                return ret;
 
-       return bfq_io_set_weight_legacy(of_css(of), NULL, weight);
+       ret = bfq_io_set_weight_legacy(of_css(of), NULL, weight);
+       return ret ?: nbytes;
 }
 
 #ifdef CONFIG_DEBUG_BLK_CGROUP
index 41d9036b182249e8aff1e5e270e0d599baaf9445..653100fb719eb80e1bb11e9ef7761f14f960623f 100644 (file)
@@ -187,11 +187,25 @@ static const int bfq_stats_min_budgets = 194;
 static const int bfq_default_max_budget = 16 * 1024;
 
 /*
- * Async to sync throughput distribution is controlled as follows:
- * when an async request is served, the entity is charged the number
- * of sectors of the request, multiplied by the factor below
+ * When a sync request is dispatched, the queue that contains that
+ * request, and all the ancestor entities of that queue, are charged
+ * with the number of sectors of the request. In constrast, if the
+ * request is async, then the queue and its ancestor entities are
+ * charged with the number of sectors of the request, multiplied by
+ * the factor below. This throttles the bandwidth for async I/O,
+ * w.r.t. to sync I/O, and it is done to counter the tendency of async
+ * writes to steal I/O throughput to reads.
+ *
+ * The current value of this parameter is the result of a tuning with
+ * several hardware and software configurations. We tried to find the
+ * lowest value for which writes do not cause noticeable problems to
+ * reads. In fact, the lower this parameter, the stabler I/O control,
+ * in the following respect.  The lower this parameter is, the less
+ * the bandwidth enjoyed by a group decreases
+ * - when the group does writes, w.r.t. to when it does reads;
+ * - when other groups do reads, w.r.t. to when they do writes.
  */
-static const int bfq_async_charge_factor = 10;
+static const int bfq_async_charge_factor = 3;
 
 /* Default timeout values, in jiffies, approximating CFQ defaults. */
 const int bfq_timeout = HZ / 8;
@@ -853,16 +867,7 @@ static unsigned long bfq_serv_to_charge(struct request *rq,
        if (bfq_bfqq_sync(bfqq) || bfqq->wr_coeff > 1)
                return blk_rq_sectors(rq);
 
-       /*
-        * If there are no weight-raised queues, then amplify service
-        * by just the async charge factor; otherwise amplify service
-        * by twice the async charge factor, to further reduce latency
-        * for weight-raised queues.
-        */
-       if (bfqq->bfqd->wr_busy_queues == 0)
-               return blk_rq_sectors(rq) * bfq_async_charge_factor;
-
-       return blk_rq_sectors(rq) * 2 * bfq_async_charge_factor;
+       return blk_rq_sectors(rq) * bfq_async_charge_factor;
 }
 
 /**
@@ -3298,6 +3303,27 @@ void bfq_bfqq_expire(struct bfq_data *bfqd,
                 */
        } else
                entity->service = 0;
+
+       /*
+        * Reset the received-service counter for every parent entity.
+        * Differently from what happens with bfqq->entity.service,
+        * the resetting of this counter never needs to be postponed
+        * for parent entities. In fact, in case bfqq may have a
+        * chance to go on being served using the last, partially
+        * consumed budget, bfqq->entity.service needs to be kept,
+        * because if bfqq then actually goes on being served using
+        * the same budget, the last value of bfqq->entity.service is
+        * needed to properly decrement bfqq->entity.budget by the
+        * portion already consumed. In contrast, it is not necessary
+        * to keep entity->service for parent entities too, because
+        * the bubble up of the new value of bfqq->entity.budget will
+        * make sure that the budgets of parent entities are correct,
+        * even in case bfqq and thus parent entities go on receiving
+        * service with the same budget.
+        */
+       entity = entity->parent;
+       for_each_entity(entity)
+               entity->service = 0;
 }
 
 /*
index dbc07b4560598e3b3aceb5b4d53ebe6c69cafe87..ae52bff43ce4ff1697fdfdbc0c9c10fb4148c69e 100644 (file)
@@ -130,10 +130,14 @@ static bool bfq_update_next_in_service(struct bfq_sched_data *sd,
        if (!change_without_lookup) /* lookup needed */
                next_in_service = bfq_lookup_next_entity(sd, expiration);
 
-       if (next_in_service)
-               parent_sched_may_change = !sd->next_in_service ||
+       if (next_in_service) {
+               bool new_budget_triggers_change =
                        bfq_update_parent_budget(next_in_service);
 
+               parent_sched_may_change = !sd->next_in_service ||
+                       new_budget_triggers_change;
+       }
+
        sd->next_in_service = next_in_service;
 
        if (!next_in_service)
@@ -877,15 +881,11 @@ void bfq_bfqq_charge_time(struct bfq_data *bfqd, struct bfq_queue *bfqq,
                          unsigned long time_ms)
 {
        struct bfq_entity *entity = &bfqq->entity;
-       int tot_serv_to_charge = entity->service;
-       unsigned int timeout_ms = jiffies_to_msecs(bfq_timeout);
-
-       if (time_ms > 0 && time_ms < timeout_ms)
-               tot_serv_to_charge =
-                       (bfqd->bfq_max_budget * time_ms) / timeout_ms;
-
-       if (tot_serv_to_charge < entity->service)
-               tot_serv_to_charge = entity->service;
+       unsigned long timeout_ms = jiffies_to_msecs(bfq_timeout);
+       unsigned long bounded_time_ms = min(time_ms, timeout_ms);
+       int serv_to_charge_for_time =
+               (bfqd->bfq_max_budget * bounded_time_ms) / timeout_ms;
+       int tot_serv_to_charge = max(serv_to_charge_for_time, entity->service);
 
        /* Increase budget to avoid inconsistencies */
        if (tot_serv_to_charge > entity->budget)
index b12966e415d3f807d0ac27bab9b5e010f771d0b0..8c680a776171c8c1bc7dcbefee2d4b6bb9cc5ebc 100644 (file)
@@ -2015,7 +2015,8 @@ int bio_associate_blkg(struct bio *bio, struct blkcg_gq *blkg)
 {
        if (unlikely(bio->bi_blkg))
                return -EBUSY;
-       blkg_get(blkg);
+       if (!blkg_try_get(blkg))
+               return -ENODEV;
        bio->bi_blkg = blkg;
        return 0;
 }
index 694595b29b8fd2faac52ac79cf9e6e4540e7dcd6..c19f9078da1ed9b17295eb4fcce108b1d5658c93 100644 (file)
@@ -310,28 +310,11 @@ struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg,
        }
 }
 
-static void blkg_pd_offline(struct blkcg_gq *blkg)
-{
-       int i;
-
-       lockdep_assert_held(blkg->q->queue_lock);
-       lockdep_assert_held(&blkg->blkcg->lock);
-
-       for (i = 0; i < BLKCG_MAX_POLS; i++) {
-               struct blkcg_policy *pol = blkcg_policy[i];
-
-               if (blkg->pd[i] && !blkg->pd[i]->offline &&
-                   pol->pd_offline_fn) {
-                       pol->pd_offline_fn(blkg->pd[i]);
-                       blkg->pd[i]->offline = true;
-               }
-       }
-}
-
 static void blkg_destroy(struct blkcg_gq *blkg)
 {
        struct blkcg *blkcg = blkg->blkcg;
        struct blkcg_gq *parent = blkg->parent;
+       int i;
 
        lockdep_assert_held(blkg->q->queue_lock);
        lockdep_assert_held(&blkcg->lock);
@@ -340,6 +323,13 @@ static void blkg_destroy(struct blkcg_gq *blkg)
        WARN_ON_ONCE(list_empty(&blkg->q_node));
        WARN_ON_ONCE(hlist_unhashed(&blkg->blkcg_node));
 
+       for (i = 0; i < BLKCG_MAX_POLS; i++) {
+               struct blkcg_policy *pol = blkcg_policy[i];
+
+               if (blkg->pd[i] && pol->pd_offline_fn)
+                       pol->pd_offline_fn(blkg->pd[i]);
+       }
+
        if (parent) {
                blkg_rwstat_add_aux(&parent->stat_bytes, &blkg->stat_bytes);
                blkg_rwstat_add_aux(&parent->stat_ios, &blkg->stat_ios);
@@ -382,7 +372,6 @@ static void blkg_destroy_all(struct request_queue *q)
                struct blkcg *blkcg = blkg->blkcg;
 
                spin_lock(&blkcg->lock);
-               blkg_pd_offline(blkg);
                blkg_destroy(blkg);
                spin_unlock(&blkcg->lock);
        }
@@ -1053,59 +1042,64 @@ static struct cftype blkcg_legacy_files[] = {
        { }     /* terminate */
 };
 
+/*
+ * blkcg destruction is a three-stage process.
+ *
+ * 1. Destruction starts.  The blkcg_css_offline() callback is invoked
+ *    which offlines writeback.  Here we tie the next stage of blkg destruction
+ *    to the completion of writeback associated with the blkcg.  This lets us
+ *    avoid punting potentially large amounts of outstanding writeback to root
+ *    while maintaining any ongoing policies.  The next stage is triggered when
+ *    the nr_cgwbs count goes to zero.
+ *
+ * 2. When the nr_cgwbs count goes to zero, blkcg_destroy_blkgs() is called
+ *    and handles the destruction of blkgs.  Here the css reference held by
+ *    the blkg is put back eventually allowing blkcg_css_free() to be called.
+ *    This work may occur in cgwb_release_workfn() on the cgwb_release
+ *    workqueue.  Any submitted ios that fail to get the blkg ref will be
+ *    punted to the root_blkg.
+ *
+ * 3. Once the blkcg ref count goes to zero, blkcg_css_free() is called.
+ *    This finally frees the blkcg.
+ */
+
 /**
  * blkcg_css_offline - cgroup css_offline callback
  * @css: css of interest
  *
- * This function is called when @css is about to go away and responsible
- * for offlining all blkgs pd and killing all wbs associated with @css.
- * blkgs pd offline should be done while holding both q and blkcg locks.
- * As blkcg lock is nested inside q lock, this function performs reverse
- * double lock dancing.
- *
- * This is the blkcg counterpart of ioc_release_fn().
+ * This function is called when @css is about to go away.  Here the cgwbs are
+ * offlined first and only once writeback associated with the blkcg has
+ * finished do we start step 2 (see above).
  */
 static void blkcg_css_offline(struct cgroup_subsys_state *css)
 {
        struct blkcg *blkcg = css_to_blkcg(css);
-       struct blkcg_gq *blkg;
-
-       spin_lock_irq(&blkcg->lock);
-
-       hlist_for_each_entry(blkg, &blkcg->blkg_list, blkcg_node) {
-               struct request_queue *q = blkg->q;
-
-               if (spin_trylock(q->queue_lock)) {
-                       blkg_pd_offline(blkg);
-                       spin_unlock(q->queue_lock);
-               } else {
-                       spin_unlock_irq(&blkcg->lock);
-                       cpu_relax();
-                       spin_lock_irq(&blkcg->lock);
-               }
-       }
-
-       spin_unlock_irq(&blkcg->lock);
 
+       /* this prevents anyone from attaching or migrating to this blkcg */
        wb_blkcg_offline(blkcg);
+
+       /* put the base cgwb reference allowing step 2 to be triggered */
+       blkcg_cgwb_put(blkcg);
 }
 
 /**
- * blkcg_destroy_all_blkgs - destroy all blkgs associated with a blkcg
+ * blkcg_destroy_blkgs - responsible for shooting down blkgs
  * @blkcg: blkcg of interest
  *
- * This function is called when blkcg css is about to free and responsible for
- * destroying all blkgs associated with @blkcg.
- * blkgs should be removed while holding both q and blkcg locks. As blkcg lock
+ * blkgs should be removed while holding both q and blkcg locks.  As blkcg lock
  * is nested inside q lock, this function performs reverse double lock dancing.
+ * Destroying the blkgs releases the reference held on the blkcg's css allowing
+ * blkcg_css_free to eventually be called.
+ *
+ * This is the blkcg counterpart of ioc_release_fn().
  */
-static void blkcg_destroy_all_blkgs(struct blkcg *blkcg)
+void blkcg_destroy_blkgs(struct blkcg *blkcg)
 {
        spin_lock_irq(&blkcg->lock);
+
        while (!hlist_empty(&blkcg->blkg_list)) {
                struct blkcg_gq *blkg = hlist_entry(blkcg->blkg_list.first,
-                                                   struct blkcg_gq,
-                                                   blkcg_node);
+                                               struct blkcg_gq, blkcg_node);
                struct request_queue *q = blkg->q;
 
                if (spin_trylock(q->queue_lock)) {
@@ -1117,6 +1111,7 @@ static void blkcg_destroy_all_blkgs(struct blkcg *blkcg)
                        spin_lock_irq(&blkcg->lock);
                }
        }
+
        spin_unlock_irq(&blkcg->lock);
 }
 
@@ -1125,8 +1120,6 @@ static void blkcg_css_free(struct cgroup_subsys_state *css)
        struct blkcg *blkcg = css_to_blkcg(css);
        int i;
 
-       blkcg_destroy_all_blkgs(blkcg);
-
        mutex_lock(&blkcg_pol_mutex);
 
        list_del(&blkcg->all_blkcgs_node);
@@ -1189,6 +1182,7 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css)
        INIT_HLIST_HEAD(&blkcg->blkg_list);
 #ifdef CONFIG_CGROUP_WRITEBACK
        INIT_LIST_HEAD(&blkcg->cgwb_list);
+       refcount_set(&blkcg->cgwb_refcnt, 1);
 #endif
        list_add_tail(&blkcg->all_blkcgs_node, &all_blkcgs);
 
@@ -1480,11 +1474,8 @@ void blkcg_deactivate_policy(struct request_queue *q,
 
        list_for_each_entry(blkg, &q->blkg_list, q_node) {
                if (blkg->pd[pol->plid]) {
-                       if (!blkg->pd[pol->plid]->offline &&
-                           pol->pd_offline_fn) {
+                       if (pol->pd_offline_fn)
                                pol->pd_offline_fn(blkg->pd[pol->plid]);
-                               blkg->pd[pol->plid]->offline = true;
-                       }
                        pol->pd_free_fn(blkg->pd[pol->plid]);
                        blkg->pd[pol->plid] = NULL;
                }
index 12550340418d950dccc3e27b615a6dace19b8b48..4dbc93f43b38231657ec2c97e836b5063a7265cf 100644 (file)
@@ -1036,7 +1036,6 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id,
                    laptop_mode_timer_fn, 0);
        timer_setup(&q->timeout, blk_rq_timed_out_timer, 0);
        INIT_WORK(&q->timeout_work, NULL);
-       INIT_LIST_HEAD(&q->queue_head);
        INIT_LIST_HEAD(&q->timeout_list);
        INIT_LIST_HEAD(&q->icq_list);
 #ifdef CONFIG_BLK_CGROUP
@@ -2162,9 +2161,14 @@ static inline bool should_fail_request(struct hd_struct *part,
 
 static inline bool bio_check_ro(struct bio *bio, struct hd_struct *part)
 {
-       if (part->policy && op_is_write(bio_op(bio))) {
+       const int op = bio_op(bio);
+
+       if (part->policy && op_is_write(op)) {
                char b[BDEVNAME_SIZE];
 
+               if (op_is_flush(bio->bi_opf) && !bio_sectors(bio))
+                       return false;
+
                WARN_ONCE(1,
                       "generic_make_request: Trying to write "
                        "to read-only block-device %s (partno %d)\n",
index cf9c66c6d35a866c63a8a1785eeab769ec3298d4..29bfe8017a2d8e6cbadeab6b9d1d63d293f656a5 100644 (file)
@@ -462,50 +462,6 @@ static void blk_mq_sched_tags_teardown(struct request_queue *q)
                blk_mq_sched_free_tags(set, hctx, i);
 }
 
-int blk_mq_sched_init_hctx(struct request_queue *q, struct blk_mq_hw_ctx *hctx,
-                          unsigned int hctx_idx)
-{
-       struct elevator_queue *e = q->elevator;
-       int ret;
-
-       if (!e)
-               return 0;
-
-       ret = blk_mq_sched_alloc_tags(q, hctx, hctx_idx);
-       if (ret)
-               return ret;
-
-       if (e->type->ops.mq.init_hctx) {
-               ret = e->type->ops.mq.init_hctx(hctx, hctx_idx);
-               if (ret) {
-                       blk_mq_sched_free_tags(q->tag_set, hctx, hctx_idx);
-                       return ret;
-               }
-       }
-
-       blk_mq_debugfs_register_sched_hctx(q, hctx);
-
-       return 0;
-}
-
-void blk_mq_sched_exit_hctx(struct request_queue *q, struct blk_mq_hw_ctx *hctx,
-                           unsigned int hctx_idx)
-{
-       struct elevator_queue *e = q->elevator;
-
-       if (!e)
-               return;
-
-       blk_mq_debugfs_unregister_sched_hctx(hctx);
-
-       if (e->type->ops.mq.exit_hctx && hctx->sched_data) {
-               e->type->ops.mq.exit_hctx(hctx, hctx_idx);
-               hctx->sched_data = NULL;
-       }
-
-       blk_mq_sched_free_tags(q->tag_set, hctx, hctx_idx);
-}
-
 int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e)
 {
        struct blk_mq_hw_ctx *hctx;
index 0cb8f938dff9d6a9b2fd3f6b519790c6f9f7b805..4e028ee4243014ff8eed44627f8e0cc5068217ca 100644 (file)
@@ -28,11 +28,6 @@ void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx);
 int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e);
 void blk_mq_exit_sched(struct request_queue *q, struct elevator_queue *e);
 
-int blk_mq_sched_init_hctx(struct request_queue *q, struct blk_mq_hw_ctx *hctx,
-                          unsigned int hctx_idx);
-void blk_mq_sched_exit_hctx(struct request_queue *q, struct blk_mq_hw_ctx *hctx,
-                           unsigned int hctx_idx);
-
 static inline bool
 blk_mq_sched_bio_merge(struct request_queue *q, struct bio *bio)
 {
index 816923bf874d7c8eb55ed640735caab5131022a4..94e1ed667b6ea383a99f1cd76d6917af0d2a1ba6 100644 (file)
@@ -320,6 +320,18 @@ void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_iter_fn *fn,
        struct blk_mq_hw_ctx *hctx;
        int i;
 
+       /*
+        * __blk_mq_update_nr_hw_queues will update the nr_hw_queues and
+        * queue_hw_ctx after freeze the queue. So we could use q_usage_counter
+        * to avoid race with it. __blk_mq_update_nr_hw_queues will users
+        * synchronize_rcu to ensure all of the users go out of the critical
+        * section below and see zeroed q_usage_counter.
+        */
+       rcu_read_lock();
+       if (percpu_ref_is_zero(&q->q_usage_counter)) {
+               rcu_read_unlock();
+               return;
+       }
 
        queue_for_each_hw_ctx(q, hctx, i) {
                struct blk_mq_tags *tags = hctx->tags;
@@ -335,7 +347,7 @@ void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_iter_fn *fn,
                        bt_for_each(hctx, &tags->breserved_tags, fn, priv, true);
                bt_for_each(hctx, &tags->bitmap_tags, fn, priv, false);
        }
-
+       rcu_read_unlock();
 }
 
 static int bt_alloc(struct sbitmap_queue *bt, unsigned int depth,
index 72a0033ccee92af029ccc1219fbeb4fc7c127455..85a1c1a59c72716ce2e31c280d7fd43d5c6e61e9 100644 (file)
@@ -2145,8 +2145,6 @@ static void blk_mq_exit_hctx(struct request_queue *q,
        if (set->ops->exit_request)
                set->ops->exit_request(set, hctx->fq->flush_rq, hctx_idx);
 
-       blk_mq_sched_exit_hctx(q, hctx, hctx_idx);
-
        if (set->ops->exit_hctx)
                set->ops->exit_hctx(hctx, hctx_idx);
 
@@ -2214,12 +2212,9 @@ static int blk_mq_init_hctx(struct request_queue *q,
            set->ops->init_hctx(hctx, set->driver_data, hctx_idx))
                goto free_bitmap;
 
-       if (blk_mq_sched_init_hctx(q, hctx, hctx_idx))
-               goto exit_hctx;
-
        hctx->fq = blk_alloc_flush_queue(q, hctx->numa_node, set->cmd_size);
        if (!hctx->fq)
-               goto sched_exit_hctx;
+               goto exit_hctx;
 
        if (blk_mq_init_request(set, hctx->fq->flush_rq, hctx_idx, node))
                goto free_fq;
@@ -2233,8 +2228,6 @@ static int blk_mq_init_hctx(struct request_queue *q,
 
  free_fq:
        kfree(hctx->fq);
- sched_exit_hctx:
-       blk_mq_sched_exit_hctx(q, hctx, hctx_idx);
  exit_hctx:
        if (set->ops->exit_hctx)
                set->ops->exit_hctx(hctx, hctx_idx);
@@ -2896,10 +2889,81 @@ int blk_mq_update_nr_requests(struct request_queue *q, unsigned int nr)
        return ret;
 }
 
+/*
+ * request_queue and elevator_type pair.
+ * It is just used by __blk_mq_update_nr_hw_queues to cache
+ * the elevator_type associated with a request_queue.
+ */
+struct blk_mq_qe_pair {
+       struct list_head node;
+       struct request_queue *q;
+       struct elevator_type *type;
+};
+
+/*
+ * Cache the elevator_type in qe pair list and switch the
+ * io scheduler to 'none'
+ */
+static bool blk_mq_elv_switch_none(struct list_head *head,
+               struct request_queue *q)
+{
+       struct blk_mq_qe_pair *qe;
+
+       if (!q->elevator)
+               return true;
+
+       qe = kmalloc(sizeof(*qe), GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY);
+       if (!qe)
+               return false;
+
+       INIT_LIST_HEAD(&qe->node);
+       qe->q = q;
+       qe->type = q->elevator->type;
+       list_add(&qe->node, head);
+
+       mutex_lock(&q->sysfs_lock);
+       /*
+        * After elevator_switch_mq, the previous elevator_queue will be
+        * released by elevator_release. The reference of the io scheduler
+        * module get by elevator_get will also be put. So we need to get
+        * a reference of the io scheduler module here to prevent it to be
+        * removed.
+        */
+       __module_get(qe->type->elevator_owner);
+       elevator_switch_mq(q, NULL);
+       mutex_unlock(&q->sysfs_lock);
+
+       return true;
+}
+
+static void blk_mq_elv_switch_back(struct list_head *head,
+               struct request_queue *q)
+{
+       struct blk_mq_qe_pair *qe;
+       struct elevator_type *t = NULL;
+
+       list_for_each_entry(qe, head, node)
+               if (qe->q == q) {
+                       t = qe->type;
+                       break;
+               }
+
+       if (!t)
+               return;
+
+       list_del(&qe->node);
+       kfree(qe);
+
+       mutex_lock(&q->sysfs_lock);
+       elevator_switch_mq(q, t);
+       mutex_unlock(&q->sysfs_lock);
+}
+
 static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
                                                        int nr_hw_queues)
 {
        struct request_queue *q;
+       LIST_HEAD(head);
 
        lockdep_assert_held(&set->tag_list_lock);
 
@@ -2910,6 +2974,18 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
 
        list_for_each_entry(q, &set->tag_list, tag_set_list)
                blk_mq_freeze_queue(q);
+       /*
+        * Sync with blk_mq_queue_tag_busy_iter.
+        */
+       synchronize_rcu();
+       /*
+        * Switch IO scheduler to 'none', cleaning up the data associated
+        * with the previous scheduler. We will switch back once we are done
+        * updating the new sw to hw queue mappings.
+        */
+       list_for_each_entry(q, &set->tag_list, tag_set_list)
+               if (!blk_mq_elv_switch_none(&head, q))
+                       goto switch_back;
 
        set->nr_hw_queues = nr_hw_queues;
        blk_mq_update_queue_map(set);
@@ -2918,6 +2994,10 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
                blk_mq_queue_reinit(q);
        }
 
+switch_back:
+       list_for_each_entry(q, &set->tag_list, tag_set_list)
+               blk_mq_elv_switch_back(&head, q);
+
        list_for_each_entry(q, &set->tag_list, tag_set_list)
                blk_mq_unfreeze_queue(q);
 }
index bb109bb0a055378fb412269d9795b50b629946a4..3772671cf2bc5ad6322786b9531e9eb8bb6c7edd 100644 (file)
@@ -453,9 +453,26 @@ static ssize_t queue_wb_lat_store(struct request_queue *q, const char *page,
        else if (val >= 0)
                val *= 1000ULL;
 
-       wbt_set_min_lat(q, val);
+       /*
+        * Ensure that the queue is idled, in case the latency update
+        * ends up either enabling or disabling wbt completely. We can't
+        * have IO inflight if that happens.
+        */
+       if (q->mq_ops) {
+               blk_mq_freeze_queue(q);
+               blk_mq_quiesce_queue(q);
+       } else
+               blk_queue_bypass_start(q);
 
+       wbt_set_min_lat(q, val);
        wbt_update_limits(q);
+
+       if (q->mq_ops) {
+               blk_mq_unquiesce_queue(q);
+               blk_mq_unfreeze_queue(q);
+       } else
+               blk_queue_bypass_end(q);
+
        return count;
 }
 
index a3eede00d3020b7edc84915caf6dae52a726df21..01d0620a4e4a5e829c9de5c2dec0ac5e0b2b3ab3 100644 (file)
@@ -2129,8 +2129,9 @@ static inline void throtl_update_latency_buckets(struct throtl_data *td)
 static void blk_throtl_assoc_bio(struct throtl_grp *tg, struct bio *bio)
 {
 #ifdef CONFIG_BLK_DEV_THROTTLING_LOW
-       if (bio->bi_css)
-               bio_associate_blkg(bio, tg_to_blkg(tg));
+       /* fallback to root_blkg if we fail to get a blkg ref */
+       if (bio->bi_css && (bio_associate_blkg(bio, tg_to_blkg(tg)) == -ENODEV))
+               bio_associate_blkg(bio, bio->bi_disk->queue->root_blkg);
        bio_issue_init(&bio->bi_issue, bio_sectors(bio));
 #endif
 }
index 1d94a20374fcbf2108edd4d54927ad4b0d5c4647..8e20a0677dcf69b6e523b571099fede8c9904d78 100644 (file)
@@ -118,21 +118,16 @@ static void rwb_wake_all(struct rq_wb *rwb)
        for (i = 0; i < WBT_NUM_RWQ; i++) {
                struct rq_wait *rqw = &rwb->rq_wait[i];
 
-               if (waitqueue_active(&rqw->wait))
+               if (wq_has_sleeper(&rqw->wait))
                        wake_up_all(&rqw->wait);
        }
 }
 
-static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct)
+static void wbt_rqw_done(struct rq_wb *rwb, struct rq_wait *rqw,
+                        enum wbt_flags wb_acct)
 {
-       struct rq_wb *rwb = RQWB(rqos);
-       struct rq_wait *rqw;
        int inflight, limit;
 
-       if (!(wb_acct & WBT_TRACKED))
-               return;
-
-       rqw = get_rq_wait(rwb, wb_acct);
        inflight = atomic_dec_return(&rqw->inflight);
 
        /*
@@ -162,14 +157,26 @@ static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct)
        if (inflight && inflight >= limit)
                return;
 
-       if (waitqueue_active(&rqw->wait)) {
+       if (wq_has_sleeper(&rqw->wait)) {
                int diff = limit - inflight;
 
                if (!inflight || diff >= rwb->wb_background / 2)
-                       wake_up(&rqw->wait);
+                       wake_up_all(&rqw->wait);
        }
 }
 
+static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct)
+{
+       struct rq_wb *rwb = RQWB(rqos);
+       struct rq_wait *rqw;
+
+       if (!(wb_acct & WBT_TRACKED))
+               return;
+
+       rqw = get_rq_wait(rwb, wb_acct);
+       wbt_rqw_done(rwb, rqw, wb_acct);
+}
+
 /*
  * Called on completion of a request. Note that it's also called when
  * a request is merged, when the request gets freed.
@@ -449,6 +456,13 @@ static inline unsigned int get_limit(struct rq_wb *rwb, unsigned long rw)
 {
        unsigned int limit;
 
+       /*
+        * If we got disabled, just return UINT_MAX. This ensures that
+        * we'll properly inc a new IO, and dec+wakeup at the end.
+        */
+       if (!rwb_enabled(rwb))
+               return UINT_MAX;
+
        if ((rw & REQ_OP_MASK) == REQ_OP_DISCARD)
                return rwb->wb_background;
 
@@ -474,6 +488,34 @@ static inline unsigned int get_limit(struct rq_wb *rwb, unsigned long rw)
        return limit;
 }
 
+struct wbt_wait_data {
+       struct wait_queue_entry wq;
+       struct task_struct *task;
+       struct rq_wb *rwb;
+       struct rq_wait *rqw;
+       unsigned long rw;
+       bool got_token;
+};
+
+static int wbt_wake_function(struct wait_queue_entry *curr, unsigned int mode,
+                            int wake_flags, void *key)
+{
+       struct wbt_wait_data *data = container_of(curr, struct wbt_wait_data,
+                                                       wq);
+
+       /*
+        * If we fail to get a budget, return -1 to interrupt the wake up
+        * loop in __wake_up_common.
+        */
+       if (!rq_wait_inc_below(data->rqw, get_limit(data->rwb, data->rw)))
+               return -1;
+
+       data->got_token = true;
+       list_del_init(&curr->entry);
+       wake_up_process(data->task);
+       return 1;
+}
+
 /*
  * Block if we will exceed our limit, or if we are currently waiting for
  * the timer to kick off queuing again.
@@ -484,33 +526,40 @@ static void __wbt_wait(struct rq_wb *rwb, enum wbt_flags wb_acct,
        __acquires(lock)
 {
        struct rq_wait *rqw = get_rq_wait(rwb, wb_acct);
-       DECLARE_WAITQUEUE(wait, current);
-
-       /*
-       * inc it here even if disabled, since we'll dec it at completion.
-       * this only happens if the task was sleeping in __wbt_wait(),
-       * and someone turned it off at the same time.
-       */
-       if (!rwb_enabled(rwb)) {
-               atomic_inc(&rqw->inflight);
-               return;
-       }
-
-       if (!waitqueue_active(&rqw->wait)
-               && rq_wait_inc_below(rqw, get_limit(rwb, rw)))
+       struct wbt_wait_data data = {
+               .wq = {
+                       .func   = wbt_wake_function,
+                       .entry  = LIST_HEAD_INIT(data.wq.entry),
+               },
+               .task = current,
+               .rwb = rwb,
+               .rqw = rqw,
+               .rw = rw,
+       };
+       bool has_sleeper;
+
+       has_sleeper = wq_has_sleeper(&rqw->wait);
+       if (!has_sleeper && rq_wait_inc_below(rqw, get_limit(rwb, rw)))
                return;
 
-       add_wait_queue_exclusive(&rqw->wait, &wait);
+       prepare_to_wait_exclusive(&rqw->wait, &data.wq, TASK_UNINTERRUPTIBLE);
        do {
-               set_current_state(TASK_UNINTERRUPTIBLE);
-
-               if (!rwb_enabled(rwb)) {
-                       atomic_inc(&rqw->inflight);
+               if (data.got_token)
                        break;
-               }
 
-               if (rq_wait_inc_below(rqw, get_limit(rwb, rw)))
+               if (!has_sleeper &&
+                   rq_wait_inc_below(rqw, get_limit(rwb, rw))) {
+                       finish_wait(&rqw->wait, &data.wq);
+
+                       /*
+                        * We raced with wbt_wake_function() getting a token,
+                        * which means we now have two. Put our local token
+                        * and wake anyone else potentially waiting for one.
+                        */
+                       if (data.got_token)
+                               wbt_rqw_done(rwb, rqw, wb_acct);
                        break;
+               }
 
                if (lock) {
                        spin_unlock_irq(lock);
@@ -518,10 +567,11 @@ static void __wbt_wait(struct rq_wb *rwb, enum wbt_flags wb_acct,
                        spin_lock_irq(lock);
                } else
                        io_schedule();
+
+               has_sleeper = false;
        } while (1);
 
-       __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&rqw->wait, &wait);
+       finish_wait(&rqw->wait, &data.wq);
 }
 
 static inline bool wbt_should_throttle(struct rq_wb *rwb, struct bio *bio)
@@ -546,6 +596,9 @@ static enum wbt_flags bio_to_wbt_flags(struct rq_wb *rwb, struct bio *bio)
 {
        enum wbt_flags flags = 0;
 
+       if (!rwb_enabled(rwb))
+               return 0;
+
        if (bio_op(bio) == REQ_OP_READ) {
                flags = WBT_READ;
        } else if (wbt_should_throttle(rwb, bio)) {
@@ -576,22 +629,13 @@ static void wbt_wait(struct rq_qos *rqos, struct bio *bio, spinlock_t *lock)
        struct rq_wb *rwb = RQWB(rqos);
        enum wbt_flags flags;
 
-       if (!rwb_enabled(rwb))
-               return;
-
        flags = bio_to_wbt_flags(rwb, bio);
-
-       if (!wbt_should_throttle(rwb, bio)) {
+       if (!(flags & WBT_TRACKED)) {
                if (flags & WBT_READ)
                        wb_timestamp(rwb, &rwb->last_issue);
                return;
        }
 
-       if (current_is_kswapd())
-               flags |= WBT_KSWAPD;
-       if (bio_op(bio) == REQ_OP_DISCARD)
-               flags |= WBT_DISCARD;
-
        __wbt_wait(rwb, flags, bio->bi_opf, lock);
 
        if (!blk_stat_is_active(rwb->cb))
index d4d67e94892042d4faefa12484438020af1edd9c..9db4e389582c8da7848d458a9d4f12d64a1aecae 100644 (file)
@@ -234,6 +234,8 @@ static inline void elv_deactivate_rq(struct request_queue *q, struct request *rq
 
 int elevator_init(struct request_queue *);
 int elevator_init_mq(struct request_queue *q);
+int elevator_switch_mq(struct request_queue *q,
+                             struct elevator_type *new_e);
 void elevator_exit(struct request_queue *, struct elevator_queue *);
 int elv_register_queue(struct request_queue *q);
 void elv_unregister_queue(struct request_queue *q);
@@ -297,7 +299,7 @@ extern int blk_update_nr_requests(struct request_queue *, unsigned int);
  *     b) the queue had IO stats enabled when this request was started, and
  *     c) it's a file system request
  */
-static inline int blk_do_io_stat(struct request *rq)
+static inline bool blk_do_io_stat(struct request *rq)
 {
        return rq->rq_disk &&
               (rq->rq_flags & RQF_IO_STAT) &&
index db588add6ba6622b1495446b05f19ce0e5720bf8..9a442c23a715e2f8b53b8bb4209af912a3f45af3 100644 (file)
@@ -37,7 +37,7 @@ struct bsg_device {
        struct request_queue *queue;
        spinlock_t lock;
        struct hlist_node dev_list;
-       atomic_t ref_count;
+       refcount_t ref_count;
        char name[20];
        int max_queue;
 };
@@ -252,7 +252,7 @@ static int bsg_put_device(struct bsg_device *bd)
 
        mutex_lock(&bsg_mutex);
 
-       if (!atomic_dec_and_test(&bd->ref_count)) {
+       if (!refcount_dec_and_test(&bd->ref_count)) {
                mutex_unlock(&bsg_mutex);
                return 0;
        }
@@ -290,7 +290,7 @@ static struct bsg_device *bsg_add_device(struct inode *inode,
 
        bd->queue = rq;
 
-       atomic_set(&bd->ref_count, 1);
+       refcount_set(&bd->ref_count, 1);
        hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(iminor(inode)));
 
        strncpy(bd->name, dev_name(rq->bsg_dev.class_dev), sizeof(bd->name) - 1);
@@ -308,7 +308,7 @@ static struct bsg_device *__bsg_get_device(int minor, struct request_queue *q)
 
        hlist_for_each_entry(bd, bsg_dev_idx_hash(minor), dev_list) {
                if (bd->queue == q) {
-                       atomic_inc(&bd->ref_count);
+                       refcount_inc(&bd->ref_count);
                        goto found;
                }
        }
index fa828b5bfd4b14c977b2d3cdea41ff12f1573344..6a06b5d040e5dd8ffab230a3f3ae74bfa6935233 100644 (file)
@@ -895,8 +895,7 @@ int elv_register(struct elevator_type *e)
        spin_lock(&elv_list_lock);
        if (elevator_find(e->elevator_name, e->uses_mq)) {
                spin_unlock(&elv_list_lock);
-               if (e->icq_cache)
-                       kmem_cache_destroy(e->icq_cache);
+               kmem_cache_destroy(e->icq_cache);
                return -EBUSY;
        }
        list_add_tail(&e->list, &elv_list);
@@ -933,16 +932,13 @@ void elv_unregister(struct elevator_type *e)
 }
 EXPORT_SYMBOL_GPL(elv_unregister);
 
-static int elevator_switch_mq(struct request_queue *q,
+int elevator_switch_mq(struct request_queue *q,
                              struct elevator_type *new_e)
 {
        int ret;
 
        lockdep_assert_held(&q->sysfs_lock);
 
-       blk_mq_freeze_queue(q);
-       blk_mq_quiesce_queue(q);
-
        if (q->elevator) {
                if (q->elevator->registered)
                        elv_unregister_queue(q);
@@ -968,8 +964,6 @@ static int elevator_switch_mq(struct request_queue *q,
                blk_add_trace_msg(q, "elv switch: none");
 
 out:
-       blk_mq_unquiesce_queue(q);
-       blk_mq_unfreeze_queue(q);
        return ret;
 }
 
@@ -1021,8 +1015,17 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
 
        lockdep_assert_held(&q->sysfs_lock);
 
-       if (q->mq_ops)
-               return elevator_switch_mq(q, new_e);
+       if (q->mq_ops) {
+               blk_mq_freeze_queue(q);
+               blk_mq_quiesce_queue(q);
+
+               err = elevator_switch_mq(q, new_e);
+
+               blk_mq_unquiesce_queue(q);
+               blk_mq_unfreeze_queue(q);
+
+               return err;
+       }
 
        /*
         * Turn on BYPASS and drain all requests w/ elevator private data.
index 3918ff7235ed8bfb1425269a867cd3133ec58730..8f29058adf93c9f30b53035e6784cd337a2c0a12 100644 (file)
@@ -5,8 +5,8 @@
        __INITRODATA
 
        .align 8
-       .globl VMLINUX_SYMBOL(system_certificate_list)
-VMLINUX_SYMBOL(system_certificate_list):
+       .globl system_certificate_list
+system_certificate_list:
 __cert_list_start:
 #ifdef CONFIG_MODULE_SIG
        .incbin "certs/signing_key.x509"
@@ -15,21 +15,21 @@ __cert_list_start:
 __cert_list_end:
 
 #ifdef CONFIG_SYSTEM_EXTRA_CERTIFICATE
-       .globl VMLINUX_SYMBOL(system_extra_cert)
+       .globl system_extra_cert
        .size system_extra_cert, CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE
-VMLINUX_SYMBOL(system_extra_cert):
+system_extra_cert:
        .fill CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE, 1, 0
 
        .align 4
-       .globl VMLINUX_SYMBOL(system_extra_cert_used)
-VMLINUX_SYMBOL(system_extra_cert_used):
+       .globl system_extra_cert_used
+system_extra_cert_used:
        .int 0
 
 #endif /* CONFIG_SYSTEM_EXTRA_CERTIFICATE */
 
        .align 8
-       .globl VMLINUX_SYMBOL(system_certificate_list_size)
-VMLINUX_SYMBOL(system_certificate_list_size):
+       .globl system_certificate_list_size
+system_certificate_list_size:
 #ifdef CONFIG_64BIT
        .quad __cert_list_end - __cert_list_start
 #else
index 4a46344bf0e3f3dc1178320563dfb3d2411202ed..dd1eea90f67f1c9c998fd00941b4cb6c9b2e7fef 100644 (file)
@@ -3,6 +3,9 @@
 # ACPI Configuration
 #
 
+config ARCH_SUPPORTS_ACPI
+       bool
+
 menuconfig ACPI
        bool "ACPI (Advanced Configuration and Power Interface) Support"
        depends on ARCH_SUPPORTS_ACPI
@@ -40,9 +43,6 @@ menuconfig ACPI
          <http://www.acpi.info>
          <http://www.uefi.org/acpi/specs>
 
-config ARCH_SUPPORTS_ACPI
-       bool
-
 if ACPI
 
 config ACPI_LEGACY_TABLES_LOOKUP
index 9706613eecf9e2320209225b41d4856fecbf3ae1..bf64cfa30febf173640729db80f9a567ce50b4b0 100644 (file)
@@ -879,7 +879,7 @@ static void acpi_lpss_dismiss(struct device *dev)
 #define LPSS_GPIODEF0_DMA_LLP          BIT(13)
 
 static DEFINE_MUTEX(lpss_iosf_mutex);
-static bool lpss_iosf_d3_entered;
+static bool lpss_iosf_d3_entered = true;
 
 static void lpss_iosf_enter_d3_state(void)
 {
index c5367bf5487fcf3a1ac466e990675871a7af16ae..0f28a38a43ea1dadaeafbbefa478637deb1de90d 100644 (file)
@@ -164,6 +164,7 @@ struct acpi_namespace_node {
 #define ANOBJ_SUBTREE_HAS_INI           0x10   /* Used to optimize device initialization */
 #define ANOBJ_EVALUATED                 0x20   /* Set on first evaluation of node */
 #define ANOBJ_ALLOCATED_BUFFER          0x40   /* Method AML buffer is dynamic (install_method) */
+#define ANOBJ_NODE_EARLY_INIT           0x80   /* acpi_exec only: Node was create via init file (-fi) */
 
 #define ANOBJ_IS_EXTERNAL               0x08   /* iASL only: This object created via External() */
 #define ANOBJ_METHOD_NO_RETVAL          0x10   /* iASL only: Method has no return value */
index 3825df9234803a84cd5bc9ddd6892452eb87160f..bbb3b4d1e796cef48aad9362ca7d3022d3acab17 100644 (file)
 /* Flags for acpi_ns_lookup, acpi_ns_search_and_enter */
 
 #define ACPI_NS_NO_UPSEARCH         0
-#define ACPI_NS_SEARCH_PARENT       0x01
-#define ACPI_NS_DONT_OPEN_SCOPE     0x02
-#define ACPI_NS_NO_PEER_SEARCH      0x04
-#define ACPI_NS_ERROR_IF_FOUND      0x08
-#define ACPI_NS_PREFIX_IS_SCOPE     0x10
-#define ACPI_NS_EXTERNAL            0x20
-#define ACPI_NS_TEMPORARY           0x40
-#define ACPI_NS_OVERRIDE_IF_FOUND   0x80
+#define ACPI_NS_SEARCH_PARENT       0x0001
+#define ACPI_NS_DONT_OPEN_SCOPE     0x0002
+#define ACPI_NS_NO_PEER_SEARCH      0x0004
+#define ACPI_NS_ERROR_IF_FOUND      0x0008
+#define ACPI_NS_PREFIX_IS_SCOPE     0x0010
+#define ACPI_NS_EXTERNAL            0x0020
+#define ACPI_NS_TEMPORARY           0x0040
+#define ACPI_NS_OVERRIDE_IF_FOUND   0x0080
+#define ACPI_NS_EARLY_INIT          0x0100
 
 /* Flags for acpi_ns_walk_namespace */
 
index 2733cd4e418c49beb051f895a1b17037e65b37d0..3374d41582b53aaafec4334484f4085de2c4db76 100644 (file)
@@ -180,6 +180,8 @@ char acpi_ut_remove_leading_zeros(char **string);
 
 u8 acpi_ut_detect_hex_prefix(char **string);
 
+void acpi_ut_remove_hex_prefix(char **string);
+
 u8 acpi_ut_detect_octal_prefix(char **string);
 
 /*
index 556ff59bbbfcce71fa5c37b530c0dcb931d2c442..3e5f95390f0dd8a179c7e23751cf30a1d960e958 100644 (file)
@@ -763,7 +763,12 @@ acpi_db_command_dispatch(char *input_buffer,
        case CMD_DISASSEMBLE:
        case CMD_DISASM:
 
+#ifdef ACPI_DISASSEMBLER
                (void)acpi_db_disassemble_method(acpi_gbl_db_args[1]);
+#else
+               acpi_os_printf
+                   ("The AML Disassembler is not configured/present\n");
+#endif
                break;
 
        case CMD_DUMP:
@@ -872,7 +877,12 @@ acpi_db_command_dispatch(char *input_buffer,
 
        case CMD_LIST:
 
+#ifdef ACPI_DISASSEMBLER
                acpi_db_disassemble_aml(acpi_gbl_db_args[1], op);
+#else
+               acpi_os_printf
+                   ("The AML Disassembler is not configured/present\n");
+#endif
                break;
 
        case CMD_LOCKS:
index 9fcecf104ba001106de75f0dbc24d18c7163e305..d8b7a0fe92ecd07bca1547ac26f58ea2a5e5e28e 100644 (file)
@@ -216,6 +216,7 @@ cleanup:
        acpi_ut_remove_reference(obj_desc);
 }
 
+#ifdef ACPI_DISASSEMBLER
 /*******************************************************************************
  *
  * FUNCTION:    acpi_db_disassemble_aml
@@ -242,9 +243,8 @@ void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op)
        if (statements) {
                num_statements = strtoul(statements, NULL, 0);
        }
-#ifdef ACPI_DISASSEMBLER
+
        acpi_dm_disassemble(NULL, op, num_statements);
-#endif
 }
 
 /*******************************************************************************
@@ -317,8 +317,6 @@ acpi_status acpi_db_disassemble_method(char *name)
        walk_state->parse_flags |= ACPI_PARSE_DISASSEMBLE;
 
        status = acpi_ps_parse_aml(walk_state);
-
-#ifdef ACPI_DISASSEMBLER
        (void)acpi_dm_parse_deferred_ops(op);
 
        /* Now we can disassemble the method */
@@ -326,7 +324,6 @@ acpi_status acpi_db_disassemble_method(char *name)
        acpi_gbl_dm_opt_verbose = FALSE;
        acpi_dm_disassemble(NULL, op, 0);
        acpi_gbl_dm_opt_verbose = TRUE;
-#endif
 
        acpi_ps_delete_parse_tree(op);
 
@@ -337,6 +334,7 @@ acpi_status acpi_db_disassemble_method(char *name)
        acpi_ut_release_owner_id(&obj_desc->method.owner_id);
        return (AE_OK);
 }
+#endif
 
 /*******************************************************************************
  *
index 4647aa8efecbb79772102ace42ecc1aed73bd198..f2526726daf6cbf7c2c72e7697aaab398ba0beca 100644 (file)
@@ -10,6 +10,7 @@
 #include "amlcode.h"
 #include "acdebug.h"
 #include "acinterp.h"
+#include "acparser.h"
 
 #define _COMPONENT          ACPI_CA_DEBUGGER
 ACPI_MODULE_NAME("dbxface")
@@ -262,10 +263,17 @@ acpi_db_single_step(struct acpi_walk_state *walk_state,
                        }
                }
 
-               /* Now we can display it */
+               /* Now we can disassemble and display it */
 
 #ifdef ACPI_DISASSEMBLER
                acpi_dm_disassemble(walk_state, display_op, ACPI_UINT32_MAX);
+#else
+               /*
+                * The AML Disassembler is not configured - at least we can
+                * display the opcode value and name
+                */
+               acpi_os_printf("AML Opcode: %4.4X %s\n", op->common.aml_opcode,
+                              acpi_ps_get_opcode_name(op->common.aml_opcode));
 #endif
 
                if ((op->common.aml_opcode == AML_IF_OP) ||
index 7c937595dfcbd5d594a13eb9233851bdda0527b4..30fe89545d6ab614a32d8d563e2d335dc25613b2 100644 (file)
 #include "acnamesp.h"
 #include "acparser.h"
 
+#ifdef ACPI_EXEC_APP
+#include "aecommon.h"
+#endif
+
 #define _COMPONENT          ACPI_DISPATCHER
 ACPI_MODULE_NAME("dsfield")
 
@@ -259,6 +263,13 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
        u64 position;
        union acpi_parse_object *child;
 
+#ifdef ACPI_EXEC_APP
+       u64 value = 0;
+       union acpi_operand_object *result_desc;
+       union acpi_operand_object *obj_desc;
+       char *name_path;
+#endif
+
        ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info);
 
        /* First field starts at bit zero */
@@ -391,6 +402,25 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
                                        if (ACPI_FAILURE(status)) {
                                                return_ACPI_STATUS(status);
                                        }
+#ifdef ACPI_EXEC_APP
+                                       name_path =
+                                           acpi_ns_get_external_pathname(info->
+                                                                         field_node);
+                                       obj_desc =
+                                           acpi_ut_create_integer_object
+                                           (value);
+                                       if (ACPI_SUCCESS
+                                           (ae_lookup_init_file_entry
+                                            (name_path, &value))) {
+                                               acpi_ex_write_data_to_field
+                                                   (obj_desc,
+                                                    acpi_ns_get_attached_object
+                                                    (info->field_node),
+                                                    &result_desc);
+                                       }
+                                       acpi_ut_remove_reference(obj_desc);
+                                       ACPI_FREE(name_path);
+#endif
                                }
                        }
 
@@ -573,7 +603,9 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
            !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
                flags |= ACPI_NS_TEMPORARY;
        }
-
+#ifdef ACPI_EXEC_APP
+       flags |= ACPI_NS_OVERRIDE_IF_FOUND;
+#endif
        /*
         * Walk the list of entries in the field_list
         * Note: field_list can be of zero length. In this case, Arg will be NULL.
index 3de794bcf8fa8c1bf906ca5ac6f4d422ec5e0faa..69603ba52a3accc41d71b35ac863d6d4c7498f0d 100644 (file)
@@ -528,13 +528,18 @@ acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value)
 
                status =
                    acpi_hw_read(&value64, &acpi_gbl_FADT.xpm2_control_block);
-               value = (u32)value64;
+               if (ACPI_SUCCESS(status)) {
+                       value = (u32)value64;
+               }
                break;
 
        case ACPI_REGISTER_PM_TIMER:    /* 32-bit access */
 
                status = acpi_hw_read(&value64, &acpi_gbl_FADT.xpm_timer_block);
-               value = (u32)value64;
+               if (ACPI_SUCCESS(status)) {
+                       value = (u32)value64;
+               }
+
                break;
 
        case ACPI_REGISTER_SMI_COMMAND_BLOCK:   /* 8-bit access */
index fe9d46d81750792350270c4f6c1920a77e236a05..d8b8fc2ff5633e7406c256fc6fff3e0ee6b16f2a 100644 (file)
@@ -56,14 +56,9 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state)
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
-       /*
-        * If the target sleep state is S5, clear all GPEs and fixed events too
-        */
-       if (sleep_state == ACPI_STATE_S5) {
-               status = acpi_hw_clear_acpi_status();
-               if (ACPI_FAILURE(status)) {
-                       return_ACPI_STATUS(status);
-               }
+       status = acpi_hw_clear_acpi_status();
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
        }
        acpi_gbl_system_awake_and_running = FALSE;
 
index 83a593e2155d7a71db823ab341acf903fb30cbea..e3f10afde5ffae47deb166544cf8f5ded393f726 100644 (file)
@@ -558,6 +558,14 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
                                                  (char *)&current_node->name,
                                                  current_node));
                        }
+#ifdef ACPI_EXEC_APP
+                       if ((status == AE_ALREADY_EXISTS) &&
+                           (this_node->flags & ANOBJ_NODE_EARLY_INIT)) {
+                               this_node->flags &= ~ANOBJ_NODE_EARLY_INIT;
+                               status = AE_OK;
+                       }
+#endif
+
 #ifdef ACPI_ASL_COMPILER
                        /*
                         * If this ACPI name already exists within the namespace as an
@@ -676,6 +684,11 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
                        }
                }
        }
+#ifdef ACPI_EXEC_APP
+       if (flags & ACPI_NS_EARLY_INIT) {
+               this_node->flags |= ANOBJ_NODE_EARLY_INIT;
+       }
+#endif
 
        *return_node = this_node;
        return_ACPI_STATUS(AE_OK);
index 44f35ab3347d1a57aded2402e6e386c4d792d759..34fc2f7476eddadf678a85000a0c0023c9f3bb64 100644 (file)
@@ -22,6 +22,7 @@
 #include "acdispat.h"
 #include "amlcode.h"
 #include "acconvert.h"
+#include "acnamesp.h"
 
 #define _COMPONENT          ACPI_PARSER
 ACPI_MODULE_NAME("psloop")
@@ -527,12 +528,18 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
                                if (ACPI_FAILURE(status)) {
                                        return_ACPI_STATUS(status);
                                }
-                               if (walk_state->opcode == AML_SCOPE_OP) {
+                               if (acpi_ns_opens_scope
+                                   (acpi_ps_get_opcode_info
+                                    (walk_state->opcode)->object_type)) {
                                        /*
-                                        * If the scope op fails to parse, skip the body of the
-                                        * scope op because the parse failure indicates that the
-                                        * device may not exist.
+                                        * If the scope/device op fails to parse, skip the body of
+                                        * the scope op because the parse failure indicates that
+                                        * the device may not exist.
                                         */
+                                       ACPI_ERROR((AE_INFO,
+                                                   "Skip parsing opcode %s",
+                                                   acpi_ps_get_opcode_name
+                                                   (walk_state->opcode)));
                                        walk_state->parser_state.aml =
                                            walk_state->aml + 1;
                                        walk_state->parser_state.aml =
@@ -540,8 +547,6 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
                                            (&walk_state->parser_state);
                                        walk_state->aml =
                                            walk_state->parser_state.aml;
-                                       ACPI_ERROR((AE_INFO,
-                                                   "Skipping Scope block"));
                                }
 
                                continue;
@@ -709,20 +714,20 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
                        } else
                            if ((walk_state->
                                 parse_flags & ACPI_PARSE_MODULE_LEVEL)
-                               && status != AE_CTRL_TRANSFER
-                               && ACPI_FAILURE(status)) {
+                               && (ACPI_AML_EXCEPTION(status)
+                                   || status == AE_ALREADY_EXISTS
+                                   || status == AE_NOT_FOUND)) {
                                /*
-                                * ACPI_PARSE_MODULE_LEVEL flag means that we are currently
-                                * loading a table by executing it as a control method.
-                                * However, if we encounter an error while loading the table,
-                                * we need to keep trying to load the table rather than
-                                * aborting the table load (setting the status to AE_OK
-                                * continues the table load). If we get a failure at this
-                                * point, it means that the dispatcher got an error while
-                                * processing Op (most likely an AML operand error) or a
-                                * control method was called from module level and the
-                                * dispatcher returned AE_CTRL_TRANSFER. In the latter case,
-                                * leave the status alone, there's nothing wrong with it.
+                                * ACPI_PARSE_MODULE_LEVEL flag means that we
+                                * are currently loading a table by executing
+                                * it as a control method. However, if we
+                                * encounter an error while loading the table,
+                                * we need to keep trying to load the table
+                                * rather than aborting the table load (setting
+                                * the status to AE_OK continues the table
+                                * load). If we get a failure at this point, it
+                                * means that the dispatcher got an error while
+                                * trying to execute the Op.
                                 */
                                status = AE_OK;
                        }
index 51891f9fb05709ca9084c2d95afd7117b6575450..862149c8a208e6fdc3be390bdacfa5aefd44b1c0 100644 (file)
@@ -516,9 +516,9 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
                            acpi_tb_check_duplication(table_desc, table_index);
                        if (ACPI_FAILURE(status)) {
                                if (status != AE_CTRL_TERMINATE) {
-                                       ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
+                                       ACPI_EXCEPTION((AE_INFO, status,
                                                        "%4.4s 0x%8.8X%8.8X"
-                                                       " Table is duplicated",
+                                                       " Table is already loaded",
                                                        acpi_ut_valid_nameseg
                                                        (table_desc->signature.
                                                         ascii) ? table_desc->
index 118f3ff1fbb55bd9a1f98ac19c455f299fd38cde..8cc4392c61f33aea636251426e263b7017613498 100644 (file)
@@ -355,6 +355,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
        u16 original_count;
        u16 new_count = 0;
        acpi_cpu_flags lock_flags;
+       char *message;
 
        ACPI_FUNCTION_NAME(ut_update_ref_count);
 
@@ -391,6 +392,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
                                  object, object->common.type,
                                  acpi_ut_get_object_type_name(object),
                                  new_count));
+               message = "Incremement";
                break;
 
        case REF_DECREMENT:
@@ -420,6 +422,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
                if (new_count == 0) {
                        acpi_ut_delete_internal_obj(object);
                }
+               message = "Decrement";
                break;
 
        default:
@@ -436,8 +439,8 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
         */
        if (new_count > ACPI_MAX_REFERENCE_COUNT) {
                ACPI_WARNING((AE_INFO,
-                             "Large Reference Count (0x%X) in object %p, Type=0x%.2X",
-                             new_count, object, object->common.type));
+                             "Large Reference Count (0x%X) in object %p, Type=0x%.2X Operation=%s",
+                             new_count, object, object->common.type, message));
        }
 }
 
index 954f8e3e35cda87e2f5aa95b247555b1f9f92354..05ff20049b875f2c0a504a7dd64bb7decc0a9919 100644 (file)
@@ -231,14 +231,34 @@ char acpi_ut_remove_whitespace(char **string)
 
 u8 acpi_ut_detect_hex_prefix(char **string)
 {
+       char *initial_position = *string;
 
+       acpi_ut_remove_hex_prefix(string);
+       if (*string != initial_position) {
+               return (TRUE);  /* String is past leading 0x */
+       }
+
+       return (FALSE);         /* Not a hex string */
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_remove_hex_prefix
+ *
+ * PARAMETERS:  string                  - Pointer to input ASCII string
+ *
+ * RETURN:      none
+ *
+ * DESCRIPTION: Remove a hex "0x" prefix
+ *
+ ******************************************************************************/
+
+void acpi_ut_remove_hex_prefix(char **string)
+{
        if ((**string == ACPI_ASCII_ZERO) &&
            (tolower((int)*(*string + 1)) == 'x')) {
                *string += 2;   /* Go past the leading 0x */
-               return (TRUE);
        }
-
-       return (FALSE);         /* Not a hex string */
 }
 
 /*******************************************************************************
index 8fadad242db6dc54587383f51fd82e578ddcfa5a..5fde619a8bbdde9a8f0bb3f97c70d77461559463 100644 (file)
@@ -218,7 +218,7 @@ u64 acpi_ut_implicit_strtoul64(char *string)
         * implicit conversions, and the "0x" prefix is "not allowed".
         * However, allow a "0x" prefix as an ACPI extension.
         */
-       acpi_ut_detect_hex_prefix(&string);
+       acpi_ut_remove_hex_prefix(&string);
 
        if (!acpi_ut_remove_leading_zeros(&string)) {
                return_VALUE(0);
index 292088fcc6245ba2a683f02899750a1a70249701..d2e29a19890d14db1a9e6fd85f207d558c6a3c6e 100644 (file)
 #include <linux/delay.h>
 #ifdef CONFIG_X86
 #include <asm/mpspec.h>
+#include <linux/dmi.h>
 #endif
 #include <linux/acpi_iort.h>
 #include <linux/pci.h>
 #include <acpi/apei.h>
-#include <linux/dmi.h>
 #include <linux/suspend.h>
 
 #include "internal.h"
@@ -82,10 +82,6 @@ static const struct dmi_system_id dsdt_dmi_table[] __initconst = {
        },
        {}
 };
-#else
-static const struct dmi_system_id dsdt_dmi_table[] __initconst = {
-       {}
-};
 #endif
 
 /* --------------------------------------------------------------------------
@@ -1033,11 +1029,16 @@ void __init acpi_early_init(void)
 
        acpi_permanent_mmap = true;
 
+#ifdef CONFIG_X86
        /*
         * If the machine falls into the DMI check table,
-        * DSDT will be copied to memory
+        * DSDT will be copied to memory.
+        * Note that calling dmi_check_system() here on other architectures
+        * would not be OK because only x86 initializes dmi early enough.
+        * Thankfully only x86 systems need such quirks for now.
         */
        dmi_check_system(dsdt_dmi_table);
+#endif
 
        status = acpi_reallocate_root_table();
        if (ACPI_FAILURE(status)) {
index 7c479002e798bf92f3dc58263c3c2064182922bb..b072cfc5f20ee0ec47ba83532a58eafdfcbd2534 100644 (file)
@@ -1699,7 +1699,7 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
 {
        struct acpi_device *adev, *adev_dimm;
        struct device *dev = acpi_desc->dev;
-       unsigned long dsm_mask;
+       unsigned long dsm_mask, label_mask;
        const guid_t *guid;
        int i;
        int family = -1;
@@ -1771,6 +1771,16 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
                                        1ULL << i))
                        set_bit(i, &nfit_mem->dsm_mask);
 
+       /*
+        * Prefer the NVDIMM_FAMILY_INTEL label read commands if present
+        * due to their better semantics handling locked capacity.
+        */
+       label_mask = 1 << ND_CMD_GET_CONFIG_SIZE | 1 << ND_CMD_GET_CONFIG_DATA
+               | 1 << ND_CMD_SET_CONFIG_DATA;
+       if (family == NVDIMM_FAMILY_INTEL
+                       && (dsm_mask & label_mask) == label_mask)
+               return 0;
+
        if (acpi_nvdimm_has_method(adev_dimm, "_LSI")
                        && acpi_nvdimm_has_method(adev_dimm, "_LSR")) {
                dev_dbg(dev, "%s: has _LSR\n", dev_name(&adev_dimm->dev));
@@ -2559,7 +2569,12 @@ static void ars_complete(struct acpi_nfit_desc *acpi_desc,
                        test_bit(ARS_SHORT, &nfit_spa->ars_state)
                        ? "short" : "long");
        clear_bit(ARS_SHORT, &nfit_spa->ars_state);
-       set_bit(ARS_DONE, &nfit_spa->ars_state);
+       if (test_and_clear_bit(ARS_REQ_REDO, &nfit_spa->ars_state)) {
+               set_bit(ARS_SHORT, &nfit_spa->ars_state);
+               set_bit(ARS_REQ, &nfit_spa->ars_state);
+               dev_dbg(dev, "ARS: processing scrub request received while in progress\n");
+       } else
+               set_bit(ARS_DONE, &nfit_spa->ars_state);
 }
 
 static int ars_status_process_records(struct acpi_nfit_desc *acpi_desc)
@@ -3256,9 +3271,10 @@ int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, unsigned long flags)
                if (test_bit(ARS_FAILED, &nfit_spa->ars_state))
                        continue;
 
-               if (test_and_set_bit(ARS_REQ, &nfit_spa->ars_state))
+               if (test_and_set_bit(ARS_REQ, &nfit_spa->ars_state)) {
                        busy++;
-               else {
+                       set_bit(ARS_REQ_REDO, &nfit_spa->ars_state);
+               } else {
                        if (test_bit(ARS_SHORT, &flags))
                                set_bit(ARS_SHORT, &nfit_spa->ars_state);
                        scheduled++;
index a97ff42fe311bfa5041f54d67124aed4b85deb4d..d1274ea2d251636115a645ff4ba4ed8eddb12798 100644 (file)
@@ -119,6 +119,7 @@ enum nfit_dimm_notifiers {
 
 enum nfit_ars_state {
        ARS_REQ,
+       ARS_REQ_REDO,
        ARS_DONE,
        ARS_SHORT,
        ARS_FAILED,
index 7ffa74048107ae3c69bd1b79bb056e7aebca2c55..22c9e374c9233fda78d9cd4b067f96a43bdd2039 100644 (file)
 #define PMIC_A0LOCK_REG                0xc5
 
 static struct pmic_table power_table[] = {
+/*     {
+               .address = 0x00,
+               .reg = ??,
+               .bit = ??,
+       }, ** VSYS */
+       {
+               .address = 0x04,
+               .reg = 0x63,
+               .bit = 0x00,
+       }, /* SYSX -> VSYS_SX */
+       {
+               .address = 0x08,
+               .reg = 0x62,
+               .bit = 0x00,
+       }, /* SYSU -> VSYS_U */
+       {
+               .address = 0x0c,
+               .reg = 0x64,
+               .bit = 0x00,
+       }, /* SYSS -> VSYS_S */
+       {
+               .address = 0x10,
+               .reg = 0x6a,
+               .bit = 0x00,
+       }, /* V50S -> V5P0S */
+       {
+               .address = 0x14,
+               .reg = 0x6b,
+               .bit = 0x00,
+       }, /* HOST -> VHOST, USB2/3 host */
+       {
+               .address = 0x18,
+               .reg = 0x6c,
+               .bit = 0x00,
+       }, /* VBUS -> VBUS, USB2/3 OTG */
+       {
+               .address = 0x1c,
+               .reg = 0x6d,
+               .bit = 0x00,
+       }, /* HDMI -> VHDMI */
+/*     {
+               .address = 0x20,
+               .reg = ??,
+               .bit = ??,
+       }, ** S285 */
        {
                .address = 0x24,
                .reg = 0x66,
                .bit = 0x00,
-       },
+       }, /* X285 -> V2P85SX, camera */
+/*     {
+               .address = 0x28,
+               .reg = ??,
+               .bit = ??,
+       }, ** V33A */
+       {
+               .address = 0x2c,
+               .reg = 0x69,
+               .bit = 0x00,
+       }, /* V33S -> V3P3S, display/ssd/audio */
+       {
+               .address = 0x30,
+               .reg = 0x68,
+               .bit = 0x00,
+       }, /* V33U -> V3P3U, SDIO wifi&bt */
+/*     {
+               .address = 0x34 .. 0x40,
+               .reg = ??,
+               .bit = ??,
+       }, ** V33I, V18A, REFQ, V12A */
+       {
+               .address = 0x44,
+               .reg = 0x5c,
+               .bit = 0x00,
+       }, /* V18S -> V1P8S, SOC/USB PHY/SIM */
        {
                .address = 0x48,
                .reg = 0x5d,
                .bit = 0x00,
-       },
+       }, /* V18X -> V1P8SX, eMMC/camara/audio */
+       {
+               .address = 0x4c,
+               .reg = 0x5b,
+               .bit = 0x00,
+       }, /* V18U -> V1P8U, LPDDR */
+       {
+               .address = 0x50,
+               .reg = 0x61,
+               .bit = 0x00,
+       }, /* V12X -> V1P2SX, SOC SFR */
+       {
+               .address = 0x54,
+               .reg = 0x60,
+               .bit = 0x00,
+       }, /* V12S -> V1P2S, MIPI */
+/*     {
+               .address = 0x58,
+               .reg = ??,
+               .bit = ??,
+       }, ** V10A */
+       {
+               .address = 0x5c,
+               .reg = 0x56,
+               .bit = 0x00,
+       }, /* V10S -> V1P0S, SOC GFX */
+       {
+               .address = 0x60,
+               .reg = 0x57,
+               .bit = 0x00,
+       }, /* V10X -> V1P0SX, SOC display/DDR IO/PCIe */
+       {
+               .address = 0x64,
+               .reg = 0x59,
+               .bit = 0x00,
+       }, /* V105 -> V1P05S, L2 SRAM */
 };
 
 static struct pmic_table thermal_table[] = {
index b933061b6b607c467e20317412c63c78728396fc..8c0a54d50d0e9b90eb7b7bf4d7e0ed2e9f97ee9b 100644 (file)
@@ -205,6 +205,7 @@ phys_cpuid_t acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id)
 
        return phys_id;
 }
+EXPORT_SYMBOL_GPL(acpi_get_phys_id);
 
 int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id)
 {
index b2b9eba1d214765723165f1d3d7c1bda64720207..021ce46e2e57343b181976a980abef2e16e798d5 100644 (file)
@@ -610,7 +610,7 @@ static int marvell_enable = 1;
 module_param(marvell_enable, int, 0644);
 MODULE_PARM_DESC(marvell_enable, "Marvell SATA via AHCI (1 = enabled)");
 
-static int mobile_lpm_policy = CONFIG_SATA_MOBILE_LPM_POLICY;
+static int mobile_lpm_policy = -1;
 module_param(mobile_lpm_policy, int, 0644);
 MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets");
 
@@ -1604,6 +1604,37 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
        return pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
 }
 
+static void ahci_update_initial_lpm_policy(struct ata_port *ap,
+                                          struct ahci_host_priv *hpriv)
+{
+       int policy = CONFIG_SATA_MOBILE_LPM_POLICY;
+
+
+       /* Ignore processing for non mobile platforms */
+       if (!(hpriv->flags & AHCI_HFLAG_IS_MOBILE))
+               return;
+
+       /* user modified policy via module param */
+       if (mobile_lpm_policy != -1) {
+               policy = mobile_lpm_policy;
+               goto update_policy;
+       }
+
+#ifdef CONFIG_ACPI
+       if (policy > ATA_LPM_MED_POWER &&
+           (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) {
+               if (hpriv->cap & HOST_CAP_PART)
+                       policy = ATA_LPM_MIN_POWER_WITH_PARTIAL;
+               else if (hpriv->cap & HOST_CAP_SSC)
+                       policy = ATA_LPM_MIN_POWER;
+       }
+#endif
+
+update_policy:
+       if (policy >= ATA_LPM_UNKNOWN && policy <= ATA_LPM_MIN_POWER)
+               ap->target_lpm_policy = policy;
+}
+
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        unsigned int board_id = ent->driver_data;
@@ -1807,10 +1838,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                if (ap->flags & ATA_FLAG_EM)
                        ap->em_message_type = hpriv->em_msg_type;
 
-               if ((hpriv->flags & AHCI_HFLAG_IS_MOBILE) &&
-                   mobile_lpm_policy >= ATA_LPM_UNKNOWN &&
-                   mobile_lpm_policy <= ATA_LPM_MIN_POWER)
-                       ap->target_lpm_policy = mobile_lpm_policy;
+               ahci_update_initial_lpm_policy(ap, hpriv);
 
                /* disabled/not-implemented port */
                if (!(hpriv->port_map & (1 << i)))
index 1609ebab4e230e885040a0b4582c4b09c789fa7f..6a1515f0da4021d755d433bf618cc423487fe930 100644 (file)
@@ -350,6 +350,7 @@ struct ahci_host_priv {
        u32                     em_msg_type;    /* EM message type */
        bool                    got_runtime_pm; /* Did we do pm_runtime_get? */
        struct clk              *clks[AHCI_MAX_CLKS]; /* Optional */
+       struct reset_control    *rsts;          /* Optional */
        struct regulator        **target_pwrs;  /* Optional */
        /*
         * If platform uses PHYs. There is a 1:1 relation between the port number and
index ea430819c80b9793657652775edda0b7131c08ae..f3d557777d8292bd7739a477b70cc47f5df802e0 100644 (file)
@@ -425,7 +425,7 @@ static int brcm_ahci_probe(struct platform_device *pdev)
 
        brcm_sata_phys_enable(priv);
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
        hpriv->plat_data = priv;
index 5ecc9d46cb54474f50132dd781e2b5da96fe893a..dc78c98cb9f102caf651ac36bbe794fcdf0ac960 100644 (file)
@@ -213,7 +213,7 @@ static int ceva_ahci_probe(struct platform_device *pdev)
 
        cevapriv->ahci_pdev = pdev;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index 9b34dff6453633fcc9cf63393eb6fe553af29dbe..ebaa657f28c40c039ff5f6bbaee6f426fd3571fc 100644 (file)
@@ -171,7 +171,7 @@ static int ahci_da850_probe(struct platform_device *pdev)
        u32 mpy;
        int rc;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index fbd827c3a75c79fac65daae8716d023b7df88520..89509c3efb014f76139c98fb282fdb13156a1a3d 100644 (file)
@@ -148,7 +148,7 @@ static int ahci_dm816_probe(struct platform_device *pdev)
        struct ahci_host_priv *hpriv;
        int rc;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index 6822e2f33f7e801a53d3dfe423ceaf756e40a06f..b00799d208f509740cdd84bb1743625c7a9f6b62 100644 (file)
@@ -1127,7 +1127,7 @@ static int imx_ahci_probe(struct platform_device *pdev)
                        return ret;
        }
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index 0ae6971c2a4cfcd3bba93856335f4a031137385c..8bc1a26ffc31e67073a7ba8154a071ca23d29305 100644 (file)
@@ -142,7 +142,7 @@ static int mtk_ahci_probe(struct platform_device *pdev)
        if (!plat)
                return -ENOMEM;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index 72d90b4c3aaefa4b9051d02383b55c9e3899072b..f9cb51be38ebfd099940c1836d34e6933275ec54 100644 (file)
@@ -158,7 +158,7 @@ static int ahci_mvebu_probe(struct platform_device *pdev)
        const struct mbus_dram_target_info *dram;
        int rc;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index 99f9a895a459a673d753bce6a3c00f912c5a7437..46f0bd75eff7984f9709d431aaa874fa951c3724 100644 (file)
@@ -43,7 +43,8 @@ static int ahci_probe(struct platform_device *pdev)
        struct ahci_host_priv *hpriv;
        int rc;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev,
+                                           AHCI_PLATFORM_GET_RESETS);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
@@ -75,7 +76,6 @@ static const struct of_device_id ahci_of_match[] = {
        { .compatible = "generic-ahci", },
        /* Keep the following compatibles for device tree compatibility */
        { .compatible = "snps,spear-ahci", },
-       { .compatible = "snps,exynos5440-ahci", },
        { .compatible = "ibm,476gtr-ahci", },
        { .compatible = "snps,dwc-ahci", },
        { .compatible = "hisilicon,hisi-ahci", },
index cfdef4d44ae92cdf5a335c99a7d049df8a8cb5ae..ce59253ec158e1765570892b017e662c98eb0a59 100644 (file)
@@ -250,7 +250,7 @@ static int ahci_qoriq_probe(struct platform_device *pdev)
        struct resource *res;
        int rc;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index 1d31c0c0fc20b48c287d2df293776cf9c1e52329..e57b6f92c288574b557b06614275b05dbdcd1ad9 100644 (file)
@@ -164,7 +164,7 @@ static int ahci_seattle_probe(struct platform_device *pdev)
        int rc;
        struct ahci_host_priv *hpriv;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index bc345f24955531fba69e36e1bc0233da3bb6fc88..21c5c44832ef3b6466ce4e0f81189d490ee7c6cf 100644 (file)
@@ -156,7 +156,7 @@ static int st_ahci_probe(struct platform_device *pdev)
        if (!drv_data)
                return -ENOMEM;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
        hpriv->plat_data = drv_data;
index b26437430163e89f2c9a81e725df51d5c6c777f3..631610b72aa5843431e05b1f709abedcc1df3efb 100644 (file)
@@ -181,7 +181,7 @@ static int ahci_sunxi_probe(struct platform_device *pdev)
        struct ahci_host_priv *hpriv;
        int rc;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index 64d848409fe23d4c457f57f8b26d39769199caed..004f2608818ed85da701451a02da23dd02d78259 100644 (file)
@@ -494,7 +494,7 @@ static int tegra_ahci_probe(struct platform_device *pdev)
        int ret;
        unsigned int i;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index ad58da7c9affd8e4ec381d8bb0fd7f23d6fa0310..7e157e1bf65e47f160a10b9e8a6a335bbaaa8d5c 100644 (file)
@@ -759,7 +759,7 @@ static int xgene_ahci_probe(struct platform_device *pdev)
                                              &xgene_ahci_v2_port_info };
        int rc;
 
-       hpriv = ahci_platform_get_resources(pdev);
+       hpriv = ahci_platform_get_resources(pdev, 0);
        if (IS_ERR(hpriv))
                return PTR_ERR(hpriv);
 
index 09620c2ffa0f72e1a696d10d3e4480818b101e51..b5f57c69c48786e7b795b399b8a828a111534ec9 100644 (file)
@@ -801,6 +801,8 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
                        cmd |= PORT_CMD_ALPE;
                        if (policy == ATA_LPM_MIN_POWER)
                                cmd |= PORT_CMD_ASP;
+                       else if (policy == ATA_LPM_MIN_POWER_WITH_PARTIAL)
+                               cmd &= ~PORT_CMD_ASP;
 
                        /* write out new cmd value */
                        writel(cmd, port_mmio + PORT_CMD);
@@ -811,7 +813,8 @@ static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
        if ((hpriv->cap2 & HOST_CAP2_SDS) &&
            (hpriv->cap2 & HOST_CAP2_SADM) &&
            (link->device->flags & ATA_DFLAG_DEVSLP)) {
-               if (policy == ATA_LPM_MIN_POWER)
+               if (policy == ATA_LPM_MIN_POWER ||
+                   policy == ATA_LPM_MIN_POWER_WITH_PARTIAL)
                        ahci_set_aggressive_devslp(ap, true);
                else
                        ahci_set_aggressive_devslp(ap, false);
@@ -2107,7 +2110,7 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
        struct ahci_host_priv *hpriv = ap->host->private_data;
        void __iomem *port_mmio = ahci_port_base(ap);
        struct ata_device *dev = ap->link.device;
-       u32 devslp, dm, dito, mdat, deto;
+       u32 devslp, dm, dito, mdat, deto, dito_conf;
        int rc;
        unsigned int err_mask;
 
@@ -2131,8 +2134,15 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
                return;
        }
 
-       /* device sleep was already enabled */
-       if (devslp & PORT_DEVSLP_ADSE)
+       dm = (devslp & PORT_DEVSLP_DM_MASK) >> PORT_DEVSLP_DM_OFFSET;
+       dito = devslp_idle_timeout / (dm + 1);
+       if (dito > 0x3ff)
+               dito = 0x3ff;
+
+       dito_conf = (devslp >> PORT_DEVSLP_DITO_OFFSET) & 0x3FF;
+
+       /* device sleep was already enabled and same dito */
+       if ((devslp & PORT_DEVSLP_ADSE) && (dito_conf == dito))
                return;
 
        /* set DITO, MDAT, DETO and enable DevSlp, need to stop engine first */
@@ -2140,11 +2150,6 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
        if (rc)
                return;
 
-       dm = (devslp & PORT_DEVSLP_DM_MASK) >> PORT_DEVSLP_DM_OFFSET;
-       dito = devslp_idle_timeout / (dm + 1);
-       if (dito > 0x3ff)
-               dito = 0x3ff;
-
        /* Use the nominal value 10 ms if the read MDAT is zero,
         * the nominal value of DETO is 20 ms.
         */
@@ -2162,6 +2167,8 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
                deto = 20;
        }
 
+       /* Make dito, mdat, deto bits to 0s */
+       devslp &= ~GENMASK_ULL(24, 2);
        devslp |= ((dito << PORT_DEVSLP_DITO_OFFSET) |
                   (mdat << PORT_DEVSLP_MDAT_OFFSET) |
                   (deto << PORT_DEVSLP_DETO_OFFSET) |
@@ -2439,6 +2446,8 @@ static void ahci_port_stop(struct ata_port *ap)
         * re-enabling INTx.
         */
        writel(1 << ap->port_no, host_mmio + HOST_IRQ_STAT);
+
+       ahci_rpm_put_port(ap);
 }
 
 void ahci_print_info(struct ata_host *host, const char *scc_s)
index 30cc8f1a31e1299f3cc68659a5be959492249382..c92c10d553746da95702677b9b380a0da099b242 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/phy/phy.h>
 #include <linux/pm_runtime.h>
 #include <linux/of_platform.h>
+#include <linux/reset.h>
 #include "ahci.h"
 
 static void ahci_host_stop(struct ata_host *host);
@@ -195,7 +196,8 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators);
  * following order:
  * 1) Regulator
  * 2) Clocks (through ahci_platform_enable_clks)
- * 3) Phys
+ * 3) Resets
+ * 4) Phys
  *
  * If resource enabling fails at any point the previous enabled resources
  * are disabled in reverse order.
@@ -215,12 +217,19 @@ int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
        if (rc)
                goto disable_regulator;
 
-       rc = ahci_platform_enable_phys(hpriv);
+       rc = reset_control_deassert(hpriv->rsts);
        if (rc)
                goto disable_clks;
 
+       rc = ahci_platform_enable_phys(hpriv);
+       if (rc)
+               goto disable_resets;
+
        return 0;
 
+disable_resets:
+       reset_control_assert(hpriv->rsts);
+
 disable_clks:
        ahci_platform_disable_clks(hpriv);
 
@@ -238,13 +247,16 @@ EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
  * This function disables all ahci_platform managed resources in the
  * following order:
  * 1) Phys
- * 2) Clocks (through ahci_platform_disable_clks)
- * 3) Regulator
+ * 2) Resets
+ * 3) Clocks (through ahci_platform_disable_clks)
+ * 4) Regulator
  */
 void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
 {
        ahci_platform_disable_phys(hpriv);
 
+       reset_control_assert(hpriv->rsts);
+
        ahci_platform_disable_clks(hpriv);
 
        ahci_platform_disable_regulators(hpriv);
@@ -332,6 +344,7 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port,
 /**
  * ahci_platform_get_resources - Get platform resources
  * @pdev: platform device to get resources for
+ * @flags: bitmap representing the resource to get
  *
  * This function allocates an ahci_host_priv struct, and gets the following
  * resources, storing a reference to them inside the returned struct:
@@ -340,18 +353,20 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port,
  * 2) regulator for controlling the targets power (optional)
  * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
  *    or for non devicetree enabled platforms a single clock
- * 4) phys (optional)
+ * 4) resets, if flags has AHCI_PLATFORM_GET_RESETS (optional)
+ * 5) phys (optional)
  *
  * RETURNS:
  * The allocated ahci_host_priv on success, otherwise an ERR_PTR value
  */
-struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
+struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev,
+                                                  unsigned int flags)
 {
        struct device *dev = &pdev->dev;
        struct ahci_host_priv *hpriv;
        struct clk *clk;
        struct device_node *child;
-       int i, sz, enabled_ports = 0, rc = -ENOMEM, child_nodes;
+       int i, enabled_ports = 0, rc = -ENOMEM, child_nodes;
        u32 mask_port_map = 0;
 
        if (!devres_open_group(dev, NULL, GFP_KERNEL))
@@ -393,6 +408,14 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
                hpriv->clks[i] = clk;
        }
 
+       if (flags & AHCI_PLATFORM_GET_RESETS) {
+               hpriv->rsts = devm_reset_control_array_get_optional_shared(dev);
+               if (IS_ERR(hpriv->rsts)) {
+                       rc = PTR_ERR(hpriv->rsts);
+                       goto err_out;
+               }
+       }
+
        hpriv->nports = child_nodes = of_get_child_count(dev->of_node);
 
        /*
@@ -403,14 +426,16 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
        if (!child_nodes)
                hpriv->nports = 1;
 
-       sz = hpriv->nports * sizeof(*hpriv->phys);
-       hpriv->phys = devm_kzalloc(dev, sz, GFP_KERNEL);
+       hpriv->phys = devm_kcalloc(dev, hpriv->nports, sizeof(*hpriv->phys), GFP_KERNEL);
        if (!hpriv->phys) {
                rc = -ENOMEM;
                goto err_out;
        }
-       sz = hpriv->nports * sizeof(*hpriv->target_pwrs);
-       hpriv->target_pwrs = kzalloc(sz, GFP_KERNEL);
+       /*
+        * We cannot use devm_ here, since ahci_platform_put_resources() uses
+        * target_pwrs after devm_ have freed memory
+        */
+       hpriv->target_pwrs = kcalloc(hpriv->nports, sizeof(*hpriv->target_pwrs), GFP_KERNEL);
        if (!hpriv->target_pwrs) {
                rc = -ENOMEM;
                goto err_out;
@@ -605,7 +630,7 @@ static void ahci_host_stop(struct ata_host *host)
 
 /**
  * ahci_platform_shutdown - Disable interrupts and stop DMA for host ports
- * @dev: platform device pointer for the host
+ * @pdev: platform device pointer for the host
  *
  * This function is called during system shutdown and performs the minimal
  * deconfiguration required to ensure that an ahci_platform host cannot
index 984b37647b2f025c1a43ffda8e6d38f825099c5c..599e01bcdef22b7064853b30b31ad5f3e6a9b432 100644 (file)
@@ -3970,6 +3970,7 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy,
                scontrol |= (0x6 << 8);
                break;
        case ATA_LPM_MED_POWER_WITH_DIPM:
+       case ATA_LPM_MIN_POWER_WITH_PARTIAL:
        case ATA_LPM_MIN_POWER:
                if (ata_link_nr_enabled(link) > 0)
                        /* no restrictions on LPM transitions */
@@ -5066,7 +5067,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
        if (n_elem < 1)
                return -1;
 
-       DPRINTK("%d sg elements mapped\n", n_elem);
+       VPRINTK("%d sg elements mapped\n", n_elem);
        qc->orig_n_elem = qc->n_elem;
        qc->n_elem = n_elem;
        qc->flags |= ATA_QCFLAG_DMAMAP;
@@ -7393,4 +7394,4 @@ EXPORT_SYMBOL_GPL(ata_cable_unknown);
 EXPORT_SYMBOL_GPL(ata_cable_ignore);
 EXPORT_SYMBOL_GPL(ata_cable_sata);
 EXPORT_SYMBOL_GPL(ata_host_get);
-EXPORT_SYMBOL_GPL(ata_host_put);
\ No newline at end of file
+EXPORT_SYMBOL_GPL(ata_host_put);
index 8e270962b2f31431f9185d9da30410897e9fb950..1984fc78c750b42505a5178761366dce33fa4089 100644 (file)
@@ -110,6 +110,7 @@ static const char *ata_lpm_policy_names[] = {
        [ATA_LPM_MAX_POWER]             = "max_performance",
        [ATA_LPM_MED_POWER]             = "medium_power",
        [ATA_LPM_MED_POWER_WITH_DIPM]   = "med_power_with_dipm",
+       [ATA_LPM_MIN_POWER_WITH_PARTIAL] = "min_power_with_partial",
        [ATA_LPM_MIN_POWER]             = "min_power",
 };
 
@@ -4288,10 +4289,10 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
 static inline void ata_scsi_dump_cdb(struct ata_port *ap,
                                     struct scsi_cmnd *cmd)
 {
-#ifdef ATA_DEBUG
+#ifdef ATA_VERBOSE_DEBUG
        struct scsi_device *scsidev = cmd->device;
 
-       DPRINTK("CDB (%u:%d,%d,%lld) %9ph\n",
+       VPRINTK("CDB (%u:%d,%d,%lld) %9ph\n",
                ap->print_id,
                scsidev->channel, scsidev->id, scsidev->lun,
                cmd->cmnd);
index cc2f2e35f4c2e4ee49a67ef8df5da34cfb182a4e..c5ea0fc635e54eb800cb12d8812ea5e508c388cc 100644 (file)
@@ -657,36 +657,6 @@ unsigned int ata_sff_data_xfer32(struct ata_queued_cmd *qc, unsigned char *buf,
 }
 EXPORT_SYMBOL_GPL(ata_sff_data_xfer32);
 
-/**
- *     ata_sff_data_xfer_noirq - Transfer data by PIO
- *     @qc: queued command
- *     @buf: data buffer
- *     @buflen: buffer length
- *     @rw: read/write
- *
- *     Transfer data from/to the device data register by PIO. Do the
- *     transfer with interrupts disabled.
- *
- *     LOCKING:
- *     Inherited from caller.
- *
- *     RETURNS:
- *     Bytes consumed.
- */
-unsigned int ata_sff_data_xfer_noirq(struct ata_queued_cmd *qc, unsigned char *buf,
-                                    unsigned int buflen, int rw)
-{
-       unsigned long flags;
-       unsigned int consumed;
-
-       local_irq_save(flags);
-       consumed = ata_sff_data_xfer32(qc, buf, buflen, rw);
-       local_irq_restore(flags);
-
-       return consumed;
-}
-EXPORT_SYMBOL_GPL(ata_sff_data_xfer_noirq);
-
 /**
  *     ata_pio_sector - Transfer a sector of data.
  *     @qc: Command on going
index c47caa807fa933d370e91720ca99df253216c803..e3532eda7b058d41a16500c9b6d6dc7a0d6b1059 100644 (file)
@@ -178,7 +178,7 @@ static struct scsi_host_template cmd640_sht = {
 static struct ata_port_operations cmd640_port_ops = {
        .inherits       = &ata_sff_port_ops,
        /* In theory xfer_noirq is not needed once we kill the prefetcher */
-       .sff_data_xfer  = ata_sff_data_xfer_noirq,
+       .sff_data_xfer  = ata_sff_data_xfer32,
        .sff_irq_check  = cmd640_sff_irq_check,
        .qc_issue       = cmd640_qc_issue,
        .cable_detect   = ata_cable_40wire,
index 5d4b72e21161a888c44997b448f602cef99a6709..569a4a662dcd4deb9d9edb0dbca4001f798bcab5 100644 (file)
@@ -256,14 +256,12 @@ static struct ata_port_operations pata_ftide010_port_ops = {
        .qc_issue       = ftide010_qc_issue,
 };
 
-static struct ata_port_info ftide010_port_info[] = {
-       {
-               .flags          = ATA_FLAG_SLAVE_POSS,
-               .mwdma_mask     = ATA_MWDMA2,
-               .udma_mask      = ATA_UDMA6,
-               .pio_mask       = ATA_PIO4,
-               .port_ops       = &pata_ftide010_port_ops,
-       },
+static struct ata_port_info ftide010_port_info = {
+       .flags          = ATA_FLAG_SLAVE_POSS,
+       .mwdma_mask     = ATA_MWDMA2,
+       .udma_mask      = ATA_UDMA6,
+       .pio_mask       = ATA_PIO4,
+       .port_ops       = &pata_ftide010_port_ops,
 };
 
 #if IS_ENABLED(CONFIG_SATA_GEMINI)
@@ -349,6 +347,7 @@ static int pata_ftide010_gemini_cable_detect(struct ata_port *ap)
 }
 
 static int pata_ftide010_gemini_init(struct ftide010 *ftide,
+                                    struct ata_port_info *pi,
                                     bool is_ata1)
 {
        struct device *dev = ftide->dev;
@@ -373,7 +372,13 @@ static int pata_ftide010_gemini_init(struct ftide010 *ftide,
 
        /* Flag port as SATA-capable */
        if (gemini_sata_bridge_enabled(sg, is_ata1))
-               ftide010_port_info[0].flags |= ATA_FLAG_SATA;
+               pi->flags |= ATA_FLAG_SATA;
+
+       /* This device has broken DMA, only PIO works */
+       if (of_machine_is_compatible("itian,sq201")) {
+               pi->mwdma_mask = 0;
+               pi->udma_mask = 0;
+       }
 
        /*
         * We assume that a simple 40-wire cable is used in the PATA mode.
@@ -435,6 +440,7 @@ static int pata_ftide010_gemini_init(struct ftide010 *ftide,
 }
 #else
 static int pata_ftide010_gemini_init(struct ftide010 *ftide,
+                                    struct ata_port_info *pi,
                                     bool is_ata1)
 {
        return -ENOTSUPP;
@@ -446,7 +452,7 @@ static int pata_ftide010_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct device_node *np = dev->of_node;
-       const struct ata_port_info pi = ftide010_port_info[0];
+       struct ata_port_info pi = ftide010_port_info;
        const struct ata_port_info *ppi[] = { &pi, NULL };
        struct ftide010 *ftide;
        struct resource *res;
@@ -490,6 +496,7 @@ static int pata_ftide010_probe(struct platform_device *pdev)
                 * are ATA0. This will also set up the cable types.
                 */
                ret = pata_ftide010_gemini_init(ftide,
+                               &pi,
                                (res->start == 0x63400000));
                if (ret)
                        goto err_dis_clk;
index 188f2f2eb21fe54ad5b62675864cb97ea31f9c32..c272f2cbb47c5872fae9d17a29ff7bfe0d79e48f 100644 (file)
@@ -324,7 +324,7 @@ static struct ata_port_operations pata_icside_port_ops = {
        .inherits               = &ata_bmdma_port_ops,
        /* no need to build any PRD tables for DMA */
        .qc_prep                = ata_noop_qc_prep,
-       .sff_data_xfer          = ata_sff_data_xfer_noirq,
+       .sff_data_xfer          = ata_sff_data_xfer32,
        .bmdma_setup            = pata_icside_bmdma_setup,
        .bmdma_start            = pata_icside_bmdma_start,
        .bmdma_stop             = pata_icside_bmdma_stop,
index 6f0534047c6d748fa2879937944556aebbef755b..2e538726802b68674f172a7c76e459f743ed5e91 100644 (file)
@@ -103,7 +103,7 @@ static struct scsi_host_template pata_imx_sht = {
 
 static struct ata_port_operations pata_imx_port_ops = {
        .inherits               = &ata_sff_port_ops,
-       .sff_data_xfer          = ata_sff_data_xfer_noirq,
+       .sff_data_xfer          = ata_sff_data_xfer32,
        .cable_detect           = ata_cable_unknown,
        .set_piomode            = pata_imx_set_piomode,
 };
index 53828b6c30441735b62a36103d42d67df58794b6..8ea4b8431fc822855f79ad2853b1ab4832ec6da4 100644 (file)
@@ -246,12 +246,12 @@ static const struct ata_port_operations legacy_base_port_ops = {
 
 static struct ata_port_operations simple_port_ops = {
        .inherits       = &legacy_base_port_ops,
-       .sff_data_xfer  = ata_sff_data_xfer_noirq,
+       .sff_data_xfer  = ata_sff_data_xfer32,
 };
 
 static struct ata_port_operations legacy_port_ops = {
        .inherits       = &legacy_base_port_ops,
-       .sff_data_xfer  = ata_sff_data_xfer_noirq,
+       .sff_data_xfer  = ata_sff_data_xfer32,
        .set_mode       = legacy_set_mode,
 };
 
@@ -341,7 +341,7 @@ static unsigned int pdc_data_xfer_vlb(struct ata_queued_cmd *qc,
                }
                local_irq_restore(flags);
        } else
-               buflen = ata_sff_data_xfer_noirq(qc, buf, buflen, rw);
+               buflen = ata_sff_data_xfer32(qc, buf, buflen, rw);
 
        return buflen;
 }
index 8c0d7d736b7afd81b1146536527efc3b46bab42e..d071ab6864a8a82cafd2befcfefbfaba93952dd8 100644 (file)
@@ -44,7 +44,7 @@ static struct scsi_host_template palmld_sht = {
 
 static struct ata_port_operations palmld_port_ops = {
        .inherits               = &ata_sff_port_ops,
-       .sff_data_xfer          = ata_sff_data_xfer_noirq,
+       .sff_data_xfer          = ata_sff_data_xfer32,
        .cable_detect           = ata_cable_40wire,
 };
 
index a541eacc5e95c3278598c4b849146280b1f6cc87..9b0e6c72e3f96c3cf55a7cc438c25f20b2f8ba6d 100644 (file)
@@ -151,7 +151,7 @@ static struct scsi_host_template pcmcia_sht = {
 
 static struct ata_port_operations pcmcia_port_ops = {
        .inherits       = &ata_sff_port_ops,
-       .sff_data_xfer  = ata_sff_data_xfer_noirq,
+       .sff_data_xfer  = ata_sff_data_xfer32,
        .cable_detect   = ata_cable_40wire,
        .set_mode       = pcmcia_set_mode,
 };
index c503ded87bb88a341cb0c2d1f9e22e0fb9ddd60f..d6f8f540644243fa8accf10b59e145982295b10b 100644 (file)
@@ -49,7 +49,7 @@ static struct scsi_host_template pata_platform_sht = {
 
 static struct ata_port_operations pata_platform_port_ops = {
        .inherits               = &ata_sff_port_ops,
-       .sff_data_xfer          = ata_sff_data_xfer_noirq,
+       .sff_data_xfer          = ata_sff_data_xfer32,
        .cable_detect           = ata_cable_unknown,
        .set_mode               = pata_platform_set_mode,
 };
index 1ca6bcab369f015dffc43718b985d58717eabce5..fd19f1ce83aa16dffd2e23cb6e8d9ae54c2129b7 100644 (file)
@@ -471,7 +471,7 @@ static struct ata_port_operations via_port_ops = {
 
 static struct ata_port_operations via_port_ops_noirq = {
        .inherits       = &via_port_ops,
-       .sff_data_xfer  = ata_sff_data_xfer_noirq,
+       .sff_data_xfer  = ata_sff_data_xfer32,
 };
 
 /**
index 6456e07db72a7ea4e5cf2bcb1110dec9db42e946..10ecb232245db8c617ee808966db432ece834358 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/libata.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
 #include <linux/err.h>
 
 #define DRV_NAME "sata_rcar"
 #define SATAINTMASK_ERRMSK             BIT(2)
 #define SATAINTMASK_ERRCRTMSK          BIT(1)
 #define SATAINTMASK_ATAMSK             BIT(0)
+#define SATAINTMASK_ALL_GEN1           0x7ff
+#define SATAINTMASK_ALL_GEN2           0xfff
 
 #define SATA_RCAR_INT_MASK             (SATAINTMASK_SERRMSK | \
                                         SATAINTMASK_ATAMSK)
@@ -152,7 +154,7 @@ enum sata_rcar_type {
 
 struct sata_rcar_priv {
        void __iomem *base;
-       struct clk *clk;
+       u32 sataint_mask;
        enum sata_rcar_type type;
 };
 
@@ -226,7 +228,7 @@ static void sata_rcar_freeze(struct ata_port *ap)
        struct sata_rcar_priv *priv = ap->host->private_data;
 
        /* mask */
-       iowrite32(0x7ff, priv->base + SATAINTMASK_REG);
+       iowrite32(priv->sataint_mask, priv->base + SATAINTMASK_REG);
 
        ata_sff_freeze(ap);
 }
@@ -242,7 +244,7 @@ static void sata_rcar_thaw(struct ata_port *ap)
        ata_sff_thaw(ap);
 
        /* unmask */
-       iowrite32(0x7ff & ~SATA_RCAR_INT_MASK, base + SATAINTMASK_REG);
+       iowrite32(priv->sataint_mask & ~SATA_RCAR_INT_MASK, base + SATAINTMASK_REG);
 }
 
 static void sata_rcar_ioread16_rep(void __iomem *reg, void *buffer, int count)
@@ -736,7 +738,7 @@ static irqreturn_t sata_rcar_interrupt(int irq, void *dev_instance)
        if (!sataintstat)
                goto done;
        /* ack */
-       iowrite32(~sataintstat & 0x7ff, base + SATAINTSTAT_REG);
+       iowrite32(~sataintstat & priv->sataint_mask, base + SATAINTSTAT_REG);
 
        ap = host->ports[0];
 
@@ -809,7 +811,7 @@ static void sata_rcar_init_module(struct sata_rcar_priv *priv)
 
        /* ack and mask */
        iowrite32(0, base + SATAINTSTAT_REG);
-       iowrite32(0x7ff, base + SATAINTMASK_REG);
+       iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
 
        /* enable interrupts */
        iowrite32(ATAPI_INT_ENABLE_SATAINT, base + ATAPI_INT_ENABLE_REG);
@@ -819,16 +821,20 @@ static void sata_rcar_init_controller(struct ata_host *host)
 {
        struct sata_rcar_priv *priv = host->private_data;
 
+       priv->sataint_mask = SATAINTMASK_ALL_GEN2;
+
        /* reset and setup phy */
        switch (priv->type) {
        case RCAR_GEN1_SATA:
+               priv->sataint_mask = SATAINTMASK_ALL_GEN1;
                sata_rcar_gen1_phy_init(priv);
                break;
        case RCAR_GEN2_SATA:
-       case RCAR_GEN3_SATA:
        case RCAR_R8A7790_ES1_SATA:
                sata_rcar_gen2_phy_init(priv);
                break;
+       case RCAR_GEN3_SATA:
+               break;
        default:
                dev_warn(host->dev, "SATA phy is not initialized\n");
                break;
@@ -881,6 +887,7 @@ MODULE_DEVICE_TABLE(of, sata_rcar_match);
 
 static int sata_rcar_probe(struct platform_device *pdev)
 {
+       struct device *dev = &pdev->dev;
        struct ata_host *host;
        struct sata_rcar_priv *priv;
        struct resource *mem;
@@ -891,36 +898,31 @@ static int sata_rcar_probe(struct platform_device *pdev)
        if (irq <= 0)
                return -EINVAL;
 
-       priv = devm_kzalloc(&pdev->dev, sizeof(struct sata_rcar_priv),
-                          GFP_KERNEL);
+       priv = devm_kzalloc(dev, sizeof(struct sata_rcar_priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
-       priv->type = (enum sata_rcar_type)of_device_get_match_data(&pdev->dev);
-       priv->clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(priv->clk)) {
-               dev_err(&pdev->dev, "failed to get access to sata clock\n");
-               return PTR_ERR(priv->clk);
-       }
+       priv->type = (enum sata_rcar_type)of_device_get_match_data(dev);
 
-       ret = clk_prepare_enable(priv->clk);
-       if (ret)
-               return ret;
+       pm_runtime_enable(dev);
+       ret = pm_runtime_get_sync(dev);
+       if (ret < 0)
+               goto err_pm_disable;
 
-       host = ata_host_alloc(&pdev->dev, 1);
+       host = ata_host_alloc(dev, 1);
        if (!host) {
-               dev_err(&pdev->dev, "ata_host_alloc failed\n");
+               dev_err(dev, "ata_host_alloc failed\n");
                ret = -ENOMEM;
-               goto cleanup;
+               goto err_pm_put;
        }
 
        host->private_data = priv;
 
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       priv->base = devm_ioremap_resource(&pdev->dev, mem);
+       priv->base = devm_ioremap_resource(dev, mem);
        if (IS_ERR(priv->base)) {
                ret = PTR_ERR(priv->base);
-               goto cleanup;
+               goto err_pm_put;
        }
 
        /* setup port */
@@ -934,9 +936,10 @@ static int sata_rcar_probe(struct platform_device *pdev)
        if (!ret)
                return 0;
 
-cleanup:
-       clk_disable_unprepare(priv->clk);
-
+err_pm_put:
+       pm_runtime_put(dev);
+err_pm_disable:
+       pm_runtime_disable(dev);
        return ret;
 }
 
@@ -952,9 +955,10 @@ static int sata_rcar_remove(struct platform_device *pdev)
        iowrite32(0, base + ATAPI_INT_ENABLE_REG);
        /* ack and mask */
        iowrite32(0, base + SATAINTSTAT_REG);
-       iowrite32(0x7ff, base + SATAINTMASK_REG);
+       iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
 
-       clk_disable_unprepare(priv->clk);
+       pm_runtime_put(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
 
        return 0;
 }
@@ -972,9 +976,9 @@ static int sata_rcar_suspend(struct device *dev)
                /* disable interrupts */
                iowrite32(0, base + ATAPI_INT_ENABLE_REG);
                /* mask */
-               iowrite32(0x7ff, base + SATAINTMASK_REG);
+               iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
 
-               clk_disable_unprepare(priv->clk);
+               pm_runtime_put(dev);
        }
 
        return ret;
@@ -987,17 +991,16 @@ static int sata_rcar_resume(struct device *dev)
        void __iomem *base = priv->base;
        int ret;
 
-       ret = clk_prepare_enable(priv->clk);
-       if (ret)
+       ret = pm_runtime_get_sync(dev);
+       if (ret < 0)
                return ret;
 
        if (priv->type == RCAR_GEN3_SATA) {
-               sata_rcar_gen2_phy_init(priv);
                sata_rcar_init_module(priv);
        } else {
                /* ack and mask */
                iowrite32(0, base + SATAINTSTAT_REG);
-               iowrite32(0x7ff, base + SATAINTMASK_REG);
+               iowrite32(priv->sataint_mask, base + SATAINTMASK_REG);
 
                /* enable interrupts */
                iowrite32(ATAPI_INT_ENABLE_SATAINT,
@@ -1012,11 +1015,10 @@ static int sata_rcar_resume(struct device *dev)
 static int sata_rcar_restore(struct device *dev)
 {
        struct ata_host *host = dev_get_drvdata(dev);
-       struct sata_rcar_priv *priv = host->private_data;
        int ret;
 
-       ret = clk_prepare_enable(priv->clk);
-       if (ret)
+       ret = pm_runtime_get_sync(dev);
+       if (ret < 0)
                return ret;
 
        sata_rcar_setup_port(host);
index c8a1cb0b61361f63088ecb940c0ca8dc7dee67cf..817320c7c4c1b72cf248b73a184bc8dee6ef28ac 100644 (file)
@@ -416,26 +416,24 @@ static ssize_t show_valid_zones(struct device *dev,
        struct zone *default_zone;
        int nid;
 
-       /*
-        * The block contains more than one zone can not be offlined.
-        * This can happen e.g. for ZONE_DMA and ZONE_DMA32
-        */
-       if (!test_pages_in_a_zone(start_pfn, start_pfn + nr_pages, &valid_start_pfn, &valid_end_pfn))
-               return sprintf(buf, "none\n");
-
-       start_pfn = valid_start_pfn;
-       nr_pages = valid_end_pfn - start_pfn;
-
        /*
         * Check the existing zone. Make sure that we do that only on the
         * online nodes otherwise the page_zone is not reliable
         */
        if (mem->state == MEM_ONLINE) {
+               /*
+                * The block contains more than one zone can not be offlined.
+                * This can happen e.g. for ZONE_DMA and ZONE_DMA32
+                */
+               if (!test_pages_in_a_zone(start_pfn, start_pfn + nr_pages,
+                                         &valid_start_pfn, &valid_end_pfn))
+                       return sprintf(buf, "none\n");
+               start_pfn = valid_start_pfn;
                strcat(buf, page_zone(pfn_to_page(start_pfn))->name);
                goto out;
        }
 
-       nid = pfn_to_nid(start_pfn);
+       nid = mem->nid;
        default_zone = zone_for_pfn_range(MMOP_ONLINE_KEEP, nid, start_pfn, nr_pages);
        strcat(buf, default_zone->name);
 
index 8e2e4757adcb02c9cd07a0b868a45e0bb3baa3eb..5a42ae4078c27febf8194901d8fa0e30b43bd1aa 100644 (file)
@@ -185,7 +185,7 @@ EXPORT_SYMBOL_GPL(of_pm_clk_add_clk);
 int of_pm_clk_add_clks(struct device *dev)
 {
        struct clk **clks;
-       unsigned int i, count;
+       int i, count;
        int ret;
 
        if (!dev || !dev->of_node)
index f99e5c883368a7eeca339c4bf47e0a10b2842aee..581312ac375ff46516dd4504a515da43c9e283ae 100644 (file)
@@ -2428,16 +2428,20 @@ static bool DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
     {
       DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
        Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
-      unsigned char *ReadCacheStatus[] = { "Read Cache Disabled",
-                                          "Read Cache Enabled",
-                                          "Read Ahead Enabled",
-                                          "Intelligent Read Ahead Enabled",
-                                          "-", "-", "-", "-" };
-      unsigned char *WriteCacheStatus[] = { "Write Cache Disabled",
-                                           "Logical Device Read Only",
-                                           "Write Cache Enabled",
-                                           "Intelligent Write Cache Enabled",
-                                           "-", "-", "-", "-" };
+      static const unsigned char *ReadCacheStatus[] = {
+        "Read Cache Disabled",
+        "Read Cache Enabled",
+        "Read Ahead Enabled",
+        "Intelligent Read Ahead Enabled",
+        "-", "-", "-", "-"
+      };
+      static const unsigned char *WriteCacheStatus[] = {
+        "Write Cache Disabled",
+        "Logical Device Read Only",
+        "Write Cache Enabled",
+        "Intelligent Write Cache Enabled",
+        "-", "-", "-", "-"
+      };
       unsigned char *GeometryTranslation;
       if (LogicalDeviceInfo == NULL) continue;
       switch (LogicalDeviceInfo->DriveGeometry)
@@ -4339,14 +4343,16 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
 static void DAC960_V2_ReadWriteError(DAC960_Command_T *Command)
 {
   DAC960_Controller_T *Controller = Command->Controller;
-  unsigned char *SenseErrors[] = { "NO SENSE", "RECOVERED ERROR",
-                                  "NOT READY", "MEDIUM ERROR",
-                                  "HARDWARE ERROR", "ILLEGAL REQUEST",
-                                  "UNIT ATTENTION", "DATA PROTECT",
-                                  "BLANK CHECK", "VENDOR-SPECIFIC",
-                                  "COPY ABORTED", "ABORTED COMMAND",
-                                  "EQUAL", "VOLUME OVERFLOW",
-                                  "MISCOMPARE", "RESERVED" };
+  static const unsigned char *SenseErrors[] = {
+    "NO SENSE", "RECOVERED ERROR",
+    "NOT READY", "MEDIUM ERROR",
+    "HARDWARE ERROR", "ILLEGAL REQUEST",
+    "UNIT ATTENTION", "DATA PROTECT",
+    "BLANK CHECK", "VENDOR-SPECIFIC",
+    "COPY ABORTED", "ABORTED COMMAND",
+    "EQUAL", "VOLUME OVERFLOW",
+    "MISCOMPARE", "RESERVED"
+  };
   unsigned char *CommandName = "UNKNOWN";
   switch (Command->CommandType)
     {
index db253cd5b32af2d8920934aaaa49bf806c922a8f..d0666f5ce0036aea97404cdfd76a515b5bd49da2 100644 (file)
@@ -118,7 +118,6 @@ static struct dentry *dfs_device_status;
 
 static u32 cpu_use[NR_CPUS];
 
-static DEFINE_SPINLOCK(rssd_index_lock);
 static DEFINE_IDA(rssd_index_ida);
 
 static int mtip_block_initialize(struct driver_data *dd);
@@ -3767,20 +3766,10 @@ static int mtip_block_initialize(struct driver_data *dd)
                goto alloc_disk_error;
        }
 
-       /* Generate the disk name, implemented same as in sd.c */
-       do {
-               if (!ida_pre_get(&rssd_index_ida, GFP_KERNEL)) {
-                       rv = -ENOMEM;
-                       goto ida_get_error;
-               }
-
-               spin_lock(&rssd_index_lock);
-               rv = ida_get_new(&rssd_index_ida, &index);
-               spin_unlock(&rssd_index_lock);
-       } while (rv == -EAGAIN);
-
-       if (rv)
+       rv = ida_alloc(&rssd_index_ida, GFP_KERNEL);
+       if (rv < 0)
                goto ida_get_error;
+       index = rv;
 
        rv = rssd_disk_name_format("rssd",
                                index,
@@ -3922,9 +3911,7 @@ block_queue_alloc_init_error:
 block_queue_alloc_tag_error:
        mtip_hw_debugfs_exit(dd);
 disk_index_error:
-       spin_lock(&rssd_index_lock);
-       ida_remove(&rssd_index_ida, index);
-       spin_unlock(&rssd_index_lock);
+       ida_free(&rssd_index_ida, index);
 
 ida_get_error:
        put_disk(dd->disk);
@@ -4012,9 +3999,7 @@ static int mtip_block_remove(struct driver_data *dd)
        }
        dd->disk  = NULL;
 
-       spin_lock(&rssd_index_lock);
-       ida_remove(&rssd_index_ida, dd->index);
-       spin_unlock(&rssd_index_lock);
+       ida_free(&rssd_index_ida, dd->index);
 
        /* De-initialize the protocol layer. */
        mtip_hw_exit(dd);
@@ -4054,9 +4039,7 @@ static int mtip_block_shutdown(struct driver_data *dd)
                dd->queue = NULL;
        }
 
-       spin_lock(&rssd_index_lock);
-       ida_remove(&rssd_index_ida, dd->index);
-       spin_unlock(&rssd_index_lock);
+       ida_free(&rssd_index_ida, dd->index);
        return 0;
 }
 
index 3863c00372bb9ed9b68fa41f3e692736d779b81c..14a51254c3db7f19c94cdab62e1d9e192c7ae02f 100644 (file)
@@ -1239,6 +1239,9 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
        case NBD_SET_SOCK:
                return nbd_add_socket(nbd, arg, false);
        case NBD_SET_BLKSIZE:
+               if (!arg || !is_power_of_2(arg) || arg < 512 ||
+                   arg > PAGE_SIZE)
+                       return -EINVAL;
                nbd_size_set(nbd, arg,
                             div_s64(config->bytesize, arg));
                return 0;
index e285413d4a7510f63ad670921628cab8e904a6a6..6f1d25c1eb640b8a0cffe94c3bd7e0cfa0ea691b 100644 (file)
@@ -2740,6 +2740,7 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
        pd->write_congestion_on  = write_congestion_on;
        pd->write_congestion_off = write_congestion_off;
 
+       ret = -ENOMEM;
        disk = alloc_disk(1);
        if (!disk)
                goto out_mem;
index d81c653b9bf61587db1684305dc296a85d05818a..73ed5f3a862dfcde598227671d55c2491d33408b 100644 (file)
@@ -181,6 +181,7 @@ struct rbd_image_header {
 struct rbd_spec {
        u64             pool_id;
        const char      *pool_name;
+       const char      *pool_ns;       /* NULL if default, never "" */
 
        const char      *image_id;
        const char      *image_name;
@@ -735,6 +736,7 @@ enum {
        Opt_lock_timeout,
        Opt_last_int,
        /* int args above */
+       Opt_pool_ns,
        Opt_last_string,
        /* string args above */
        Opt_read_only,
@@ -749,6 +751,7 @@ static match_table_t rbd_opts_tokens = {
        {Opt_queue_depth, "queue_depth=%d"},
        {Opt_lock_timeout, "lock_timeout=%d"},
        /* int args above */
+       {Opt_pool_ns, "_pool_ns=%s"},
        /* string args above */
        {Opt_read_only, "read_only"},
        {Opt_read_only, "ro"},          /* Alternate spelling */
@@ -776,9 +779,14 @@ struct rbd_options {
 #define RBD_EXCLUSIVE_DEFAULT  false
 #define RBD_TRIM_DEFAULT       true
 
+struct parse_rbd_opts_ctx {
+       struct rbd_spec         *spec;
+       struct rbd_options      *opts;
+};
+
 static int parse_rbd_opts_token(char *c, void *private)
 {
-       struct rbd_options *rbd_opts = private;
+       struct parse_rbd_opts_ctx *pctx = private;
        substring_t argstr[MAX_OPT_ARGS];
        int token, intval, ret;
 
@@ -786,7 +794,7 @@ static int parse_rbd_opts_token(char *c, void *private)
        if (token < Opt_last_int) {
                ret = match_int(&argstr[0], &intval);
                if (ret < 0) {
-                       pr_err("bad mount option arg (not int) at '%s'\n", c);
+                       pr_err("bad option arg (not int) at '%s'\n", c);
                        return ret;
                }
                dout("got int token %d val %d\n", token, intval);
@@ -802,7 +810,7 @@ static int parse_rbd_opts_token(char *c, void *private)
                        pr_err("queue_depth out of range\n");
                        return -EINVAL;
                }
-               rbd_opts->queue_depth = intval;
+               pctx->opts->queue_depth = intval;
                break;
        case Opt_lock_timeout:
                /* 0 is "wait forever" (i.e. infinite timeout) */
@@ -810,22 +818,28 @@ static int parse_rbd_opts_token(char *c, void *private)
                        pr_err("lock_timeout out of range\n");
                        return -EINVAL;
                }
-               rbd_opts->lock_timeout = msecs_to_jiffies(intval * 1000);
+               pctx->opts->lock_timeout = msecs_to_jiffies(intval * 1000);
+               break;
+       case Opt_pool_ns:
+               kfree(pctx->spec->pool_ns);
+               pctx->spec->pool_ns = match_strdup(argstr);
+               if (!pctx->spec->pool_ns)
+                       return -ENOMEM;
                break;
        case Opt_read_only:
-               rbd_opts->read_only = true;
+               pctx->opts->read_only = true;
                break;
        case Opt_read_write:
-               rbd_opts->read_only = false;
+               pctx->opts->read_only = false;
                break;
        case Opt_lock_on_read:
-               rbd_opts->lock_on_read = true;
+               pctx->opts->lock_on_read = true;
                break;
        case Opt_exclusive:
-               rbd_opts->exclusive = true;
+               pctx->opts->exclusive = true;
                break;
        case Opt_notrim:
-               rbd_opts->trim = false;
+               pctx->opts->trim = false;
                break;
        default:
                /* libceph prints "bad option" msg */
@@ -1452,7 +1466,7 @@ static void rbd_osd_req_format_write(struct rbd_obj_request *obj_request)
        struct ceph_osd_request *osd_req = obj_request->osd_req;
 
        osd_req->r_flags = CEPH_OSD_FLAG_WRITE;
-       ktime_get_real_ts(&osd_req->r_mtime);
+       ktime_get_real_ts64(&osd_req->r_mtime);
        osd_req->r_data_offset = obj_request->ex.oe_off;
 }
 
@@ -1475,7 +1489,13 @@ rbd_osd_req_create(struct rbd_obj_request *obj_req, unsigned int num_ops)
        req->r_callback = rbd_osd_req_callback;
        req->r_priv = obj_req;
 
+       /*
+        * Data objects may be stored in a separate pool, but always in
+        * the same namespace in that pool as the header in its pool.
+        */
+       ceph_oloc_copy(&req->r_base_oloc, &rbd_dev->header_oloc);
        req->r_base_oloc.pool = rbd_dev->layout.pool_id;
+
        if (ceph_oid_aprintf(&req->r_base_oid, GFP_NOIO, name_format,
                        rbd_dev->header.object_prefix, obj_req->ex.oe_objno))
                goto err_req;
@@ -4119,6 +4139,14 @@ static ssize_t rbd_pool_id_show(struct device *dev,
                        (unsigned long long) rbd_dev->spec->pool_id);
 }
 
+static ssize_t rbd_pool_ns_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
+
+       return sprintf(buf, "%s\n", rbd_dev->spec->pool_ns ?: "");
+}
+
 static ssize_t rbd_name_show(struct device *dev,
                             struct device_attribute *attr, char *buf)
 {
@@ -4179,11 +4207,13 @@ static ssize_t rbd_parent_show(struct device *dev,
 
                count += sprintf(&buf[count], "%s"
                            "pool_id %llu\npool_name %s\n"
+                           "pool_ns %s\n"
                            "image_id %s\nimage_name %s\n"
                            "snap_id %llu\nsnap_name %s\n"
                            "overlap %llu\n",
                            !count ? "" : "\n", /* first? */
                            spec->pool_id, spec->pool_name,
+                           spec->pool_ns ?: "",
                            spec->image_id, spec->image_name ?: "(unknown)",
                            spec->snap_id, spec->snap_name,
                            rbd_dev->parent_overlap);
@@ -4217,6 +4247,7 @@ static DEVICE_ATTR(cluster_fsid, 0444, rbd_cluster_fsid_show, NULL);
 static DEVICE_ATTR(config_info, 0400, rbd_config_info_show, NULL);
 static DEVICE_ATTR(pool, 0444, rbd_pool_show, NULL);
 static DEVICE_ATTR(pool_id, 0444, rbd_pool_id_show, NULL);
+static DEVICE_ATTR(pool_ns, 0444, rbd_pool_ns_show, NULL);
 static DEVICE_ATTR(name, 0444, rbd_name_show, NULL);
 static DEVICE_ATTR(image_id, 0444, rbd_image_id_show, NULL);
 static DEVICE_ATTR(refresh, 0200, NULL, rbd_image_refresh);
@@ -4235,6 +4266,7 @@ static struct attribute *rbd_attrs[] = {
        &dev_attr_config_info.attr,
        &dev_attr_pool.attr,
        &dev_attr_pool_id.attr,
+       &dev_attr_pool_ns.attr,
        &dev_attr_name.attr,
        &dev_attr_image_id.attr,
        &dev_attr_current_snap.attr,
@@ -4295,6 +4327,7 @@ static void rbd_spec_free(struct kref *kref)
        struct rbd_spec *spec = container_of(kref, struct rbd_spec, kref);
 
        kfree(spec->pool_name);
+       kfree(spec->pool_ns);
        kfree(spec->image_id);
        kfree(spec->image_name);
        kfree(spec->snap_name);
@@ -4353,6 +4386,12 @@ static struct rbd_device *__rbd_dev_create(struct rbd_client *rbdc,
        rbd_dev->header.data_pool_id = CEPH_NOPOOL;
        ceph_oid_init(&rbd_dev->header_oid);
        rbd_dev->header_oloc.pool = spec->pool_id;
+       if (spec->pool_ns) {
+               WARN_ON(!*spec->pool_ns);
+               rbd_dev->header_oloc.pool_ns =
+                   ceph_find_or_create_string(spec->pool_ns,
+                                              strlen(spec->pool_ns));
+       }
 
        mutex_init(&rbd_dev->watch_mutex);
        rbd_dev->watch_state = RBD_WATCH_STATE_UNREGISTERED;
@@ -4547,47 +4586,177 @@ static int rbd_dev_v2_features(struct rbd_device *rbd_dev)
                                                &rbd_dev->header.features);
 }
 
+struct parent_image_info {
+       u64             pool_id;
+       const char      *pool_ns;
+       const char      *image_id;
+       u64             snap_id;
+
+       bool            has_overlap;
+       u64             overlap;
+};
+
+/*
+ * The caller is responsible for @pii.
+ */
+static int decode_parent_image_spec(void **p, void *end,
+                                   struct parent_image_info *pii)
+{
+       u8 struct_v;
+       u32 struct_len;
+       int ret;
+
+       ret = ceph_start_decoding(p, end, 1, "ParentImageSpec",
+                                 &struct_v, &struct_len);
+       if (ret)
+               return ret;
+
+       ceph_decode_64_safe(p, end, pii->pool_id, e_inval);
+       pii->pool_ns = ceph_extract_encoded_string(p, end, NULL, GFP_KERNEL);
+       if (IS_ERR(pii->pool_ns)) {
+               ret = PTR_ERR(pii->pool_ns);
+               pii->pool_ns = NULL;
+               return ret;
+       }
+       pii->image_id = ceph_extract_encoded_string(p, end, NULL, GFP_KERNEL);
+       if (IS_ERR(pii->image_id)) {
+               ret = PTR_ERR(pii->image_id);
+               pii->image_id = NULL;
+               return ret;
+       }
+       ceph_decode_64_safe(p, end, pii->snap_id, e_inval);
+       return 0;
+
+e_inval:
+       return -EINVAL;
+}
+
+static int __get_parent_info(struct rbd_device *rbd_dev,
+                            struct page *req_page,
+                            struct page *reply_page,
+                            struct parent_image_info *pii)
+{
+       struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
+       size_t reply_len = PAGE_SIZE;
+       void *p, *end;
+       int ret;
+
+       ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc,
+                            "rbd", "parent_get", CEPH_OSD_FLAG_READ,
+                            req_page, sizeof(u64), reply_page, &reply_len);
+       if (ret)
+               return ret == -EOPNOTSUPP ? 1 : ret;
+
+       p = page_address(reply_page);
+       end = p + reply_len;
+       ret = decode_parent_image_spec(&p, end, pii);
+       if (ret)
+               return ret;
+
+       ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc,
+                            "rbd", "parent_overlap_get", CEPH_OSD_FLAG_READ,
+                            req_page, sizeof(u64), reply_page, &reply_len);
+       if (ret)
+               return ret;
+
+       p = page_address(reply_page);
+       end = p + reply_len;
+       ceph_decode_8_safe(&p, end, pii->has_overlap, e_inval);
+       if (pii->has_overlap)
+               ceph_decode_64_safe(&p, end, pii->overlap, e_inval);
+
+       return 0;
+
+e_inval:
+       return -EINVAL;
+}
+
+/*
+ * The caller is responsible for @pii.
+ */
+static int __get_parent_info_legacy(struct rbd_device *rbd_dev,
+                                   struct page *req_page,
+                                   struct page *reply_page,
+                                   struct parent_image_info *pii)
+{
+       struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
+       size_t reply_len = PAGE_SIZE;
+       void *p, *end;
+       int ret;
+
+       ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc,
+                            "rbd", "get_parent", CEPH_OSD_FLAG_READ,
+                            req_page, sizeof(u64), reply_page, &reply_len);
+       if (ret)
+               return ret;
+
+       p = page_address(reply_page);
+       end = p + reply_len;
+       ceph_decode_64_safe(&p, end, pii->pool_id, e_inval);
+       pii->image_id = ceph_extract_encoded_string(&p, end, NULL, GFP_KERNEL);
+       if (IS_ERR(pii->image_id)) {
+               ret = PTR_ERR(pii->image_id);
+               pii->image_id = NULL;
+               return ret;
+       }
+       ceph_decode_64_safe(&p, end, pii->snap_id, e_inval);
+       pii->has_overlap = true;
+       ceph_decode_64_safe(&p, end, pii->overlap, e_inval);
+
+       return 0;
+
+e_inval:
+       return -EINVAL;
+}
+
+static int get_parent_info(struct rbd_device *rbd_dev,
+                          struct parent_image_info *pii)
+{
+       struct page *req_page, *reply_page;
+       void *p;
+       int ret;
+
+       req_page = alloc_page(GFP_KERNEL);
+       if (!req_page)
+               return -ENOMEM;
+
+       reply_page = alloc_page(GFP_KERNEL);
+       if (!reply_page) {
+               __free_page(req_page);
+               return -ENOMEM;
+       }
+
+       p = page_address(req_page);
+       ceph_encode_64(&p, rbd_dev->spec->snap_id);
+       ret = __get_parent_info(rbd_dev, req_page, reply_page, pii);
+       if (ret > 0)
+               ret = __get_parent_info_legacy(rbd_dev, req_page, reply_page,
+                                              pii);
+
+       __free_page(req_page);
+       __free_page(reply_page);
+       return ret;
+}
+
 static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
 {
        struct rbd_spec *parent_spec;
-       size_t size;
-       void *reply_buf = NULL;
-       __le64 snapid;
-       void *p;
-       void *end;
-       u64 pool_id;
-       char *image_id;
-       u64 snap_id;
-       u64 overlap;
+       struct parent_image_info pii = { 0 };
        int ret;
 
        parent_spec = rbd_spec_alloc();
        if (!parent_spec)
                return -ENOMEM;
 
-       size = sizeof (__le64) +                                /* pool_id */
-               sizeof (__le32) + RBD_IMAGE_ID_LEN_MAX +        /* image_id */
-               sizeof (__le64) +                               /* snap_id */
-               sizeof (__le64);                                /* overlap */
-       reply_buf = kmalloc(size, GFP_KERNEL);
-       if (!reply_buf) {
-               ret = -ENOMEM;
+       ret = get_parent_info(rbd_dev, &pii);
+       if (ret)
                goto out_err;
-       }
 
-       snapid = cpu_to_le64(rbd_dev->spec->snap_id);
-       ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid,
-                                 &rbd_dev->header_oloc, "get_parent",
-                                 &snapid, sizeof(snapid), reply_buf, size);
-       dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret);
-       if (ret < 0)
-               goto out_err;
+       dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n",
+            __func__, pii.pool_id, pii.pool_ns, pii.image_id, pii.snap_id,
+            pii.has_overlap, pii.overlap);
 
-       p = reply_buf;
-       end = reply_buf + ret;
-       ret = -ERANGE;
-       ceph_decode_64_safe(&p, end, pool_id, out_err);
-       if (pool_id == CEPH_NOPOOL) {
+       if (pii.pool_id == CEPH_NOPOOL || !pii.has_overlap) {
                /*
                 * Either the parent never existed, or we have
                 * record of it but the image got flattened so it no
@@ -4596,6 +4765,10 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
                 * overlap to 0.  The effect of this is that all new
                 * requests will be treated as if the image had no
                 * parent.
+                *
+                * If !pii.has_overlap, the parent image spec is not
+                * applicable.  It's there to avoid duplication in each
+                * snapshot record.
                 */
                if (rbd_dev->parent_overlap) {
                        rbd_dev->parent_overlap = 0;
@@ -4610,19 +4783,11 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
        /* The ceph file layout needs to fit pool id in 32 bits */
 
        ret = -EIO;
-       if (pool_id > (u64)U32_MAX) {
+       if (pii.pool_id > (u64)U32_MAX) {
                rbd_warn(NULL, "parent pool id too large (%llu > %u)",
-                       (unsigned long long)pool_id, U32_MAX);
-               goto out_err;
-       }
-
-       image_id = ceph_extract_encoded_string(&p, end, NULL, GFP_KERNEL);
-       if (IS_ERR(image_id)) {
-               ret = PTR_ERR(image_id);
+                       (unsigned long long)pii.pool_id, U32_MAX);
                goto out_err;
        }
-       ceph_decode_64_safe(&p, end, snap_id, out_err);
-       ceph_decode_64_safe(&p, end, overlap, out_err);
 
        /*
         * The parent won't change (except when the clone is
@@ -4630,20 +4795,24 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
         * record the parent spec we have not already done so.
         */
        if (!rbd_dev->parent_spec) {
-               parent_spec->pool_id = pool_id;
-               parent_spec->image_id = image_id;
-               parent_spec->snap_id = snap_id;
+               parent_spec->pool_id = pii.pool_id;
+               if (pii.pool_ns && *pii.pool_ns) {
+                       parent_spec->pool_ns = pii.pool_ns;
+                       pii.pool_ns = NULL;
+               }
+               parent_spec->image_id = pii.image_id;
+               pii.image_id = NULL;
+               parent_spec->snap_id = pii.snap_id;
+
                rbd_dev->parent_spec = parent_spec;
                parent_spec = NULL;     /* rbd_dev now owns this */
-       } else {
-               kfree(image_id);
        }
 
        /*
         * We always update the parent overlap.  If it's zero we issue
         * a warning, as we will proceed as if there was no parent.
         */
-       if (!overlap) {
+       if (!pii.overlap) {
                if (parent_spec) {
                        /* refresh, careful to warn just once */
                        if (rbd_dev->parent_overlap)
@@ -4654,14 +4823,14 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
                        rbd_warn(rbd_dev, "clone is standalone (overlap 0)");
                }
        }
-       rbd_dev->parent_overlap = overlap;
+       rbd_dev->parent_overlap = pii.overlap;
 
 out:
        ret = 0;
 out_err:
-       kfree(reply_buf);
+       kfree(pii.pool_ns);
+       kfree(pii.image_id);
        rbd_spec_put(parent_spec);
-
        return ret;
 }
 
@@ -5146,8 +5315,7 @@ static int rbd_add_parse_args(const char *buf,
        const char *mon_addrs;
        char *snap_name;
        size_t mon_addrs_size;
-       struct rbd_spec *spec = NULL;
-       struct rbd_options *rbd_opts = NULL;
+       struct parse_rbd_opts_ctx pctx = { 0 };
        struct ceph_options *copts;
        int ret;
 
@@ -5171,22 +5339,22 @@ static int rbd_add_parse_args(const char *buf,
                goto out_err;
        }
 
-       spec = rbd_spec_alloc();
-       if (!spec)
+       pctx.spec = rbd_spec_alloc();
+       if (!pctx.spec)
                goto out_mem;
 
-       spec->pool_name = dup_token(&buf, NULL);
-       if (!spec->pool_name)
+       pctx.spec->pool_name = dup_token(&buf, NULL);
+       if (!pctx.spec->pool_name)
                goto out_mem;
-       if (!*spec->pool_name) {
+       if (!*pctx.spec->pool_name) {
                rbd_warn(NULL, "no pool name provided");
                goto out_err;
        }
 
-       spec->image_name = dup_token(&buf, NULL);
-       if (!spec->image_name)
+       pctx.spec->image_name = dup_token(&buf, NULL);
+       if (!pctx.spec->image_name)
                goto out_mem;
-       if (!*spec->image_name) {
+       if (!*pctx.spec->image_name) {
                rbd_warn(NULL, "no image name provided");
                goto out_err;
        }
@@ -5207,24 +5375,24 @@ static int rbd_add_parse_args(const char *buf,
        if (!snap_name)
                goto out_mem;
        *(snap_name + len) = '\0';
-       spec->snap_name = snap_name;
+       pctx.spec->snap_name = snap_name;
 
        /* Initialize all rbd options to the defaults */
 
-       rbd_opts = kzalloc(sizeof (*rbd_opts), GFP_KERNEL);
-       if (!rbd_opts)
+       pctx.opts = kzalloc(sizeof(*pctx.opts), GFP_KERNEL);
+       if (!pctx.opts)
                goto out_mem;
 
-       rbd_opts->read_only = RBD_READ_ONLY_DEFAULT;
-       rbd_opts->queue_depth = RBD_QUEUE_DEPTH_DEFAULT;
-       rbd_opts->lock_timeout = RBD_LOCK_TIMEOUT_DEFAULT;
-       rbd_opts->lock_on_read = RBD_LOCK_ON_READ_DEFAULT;
-       rbd_opts->exclusive = RBD_EXCLUSIVE_DEFAULT;
-       rbd_opts->trim = RBD_TRIM_DEFAULT;
+       pctx.opts->read_only = RBD_READ_ONLY_DEFAULT;
+       pctx.opts->queue_depth = RBD_QUEUE_DEPTH_DEFAULT;
+       pctx.opts->lock_timeout = RBD_LOCK_TIMEOUT_DEFAULT;
+       pctx.opts->lock_on_read = RBD_LOCK_ON_READ_DEFAULT;
+       pctx.opts->exclusive = RBD_EXCLUSIVE_DEFAULT;
+       pctx.opts->trim = RBD_TRIM_DEFAULT;
 
        copts = ceph_parse_options(options, mon_addrs,
-                                       mon_addrs + mon_addrs_size - 1,
-                                       parse_rbd_opts_token, rbd_opts);
+                                  mon_addrs + mon_addrs_size - 1,
+                                  parse_rbd_opts_token, &pctx);
        if (IS_ERR(copts)) {
                ret = PTR_ERR(copts);
                goto out_err;
@@ -5232,15 +5400,15 @@ static int rbd_add_parse_args(const char *buf,
        kfree(options);
 
        *ceph_opts = copts;
-       *opts = rbd_opts;
-       *rbd_spec = spec;
+       *opts = pctx.opts;
+       *rbd_spec = pctx.spec;
 
        return 0;
 out_mem:
        ret = -ENOMEM;
 out_err:
-       kfree(rbd_opts);
-       rbd_spec_put(spec);
+       kfree(pctx.opts);
+       rbd_spec_put(pctx.spec);
        kfree(options);
 
        return ret;
@@ -5586,8 +5754,10 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
                ret = rbd_register_watch(rbd_dev);
                if (ret) {
                        if (ret == -ENOENT)
-                               pr_info("image %s/%s does not exist\n",
+                               pr_info("image %s/%s%s%s does not exist\n",
                                        rbd_dev->spec->pool_name,
+                                       rbd_dev->spec->pool_ns ?: "",
+                                       rbd_dev->spec->pool_ns ? "/" : "",
                                        rbd_dev->spec->image_name);
                        goto err_out_format;
                }
@@ -5609,8 +5779,10 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)
                ret = rbd_spec_fill_names(rbd_dev);
        if (ret) {
                if (ret == -ENOENT)
-                       pr_info("snap %s/%s@%s does not exist\n",
+                       pr_info("snap %s/%s%s%s@%s does not exist\n",
                                rbd_dev->spec->pool_name,
+                               rbd_dev->spec->pool_ns ?: "",
+                               rbd_dev->spec->pool_ns ? "/" : "",
                                rbd_dev->spec->image_name,
                                rbd_dev->spec->snap_name);
                goto err_out_probe;
index b7d71914a32a8b66541fb308a9cd4aa95056fdd2..f2c631ce793cc8a342b44381592824bf902282f7 100644 (file)
@@ -58,7 +58,6 @@ MODULE_PARM_DESC(sync_start, "On by Default: Driver load will not complete "
                             "until the card startup has completed.");
 
 static DEFINE_IDA(rsxx_disk_ida);
-static DEFINE_SPINLOCK(rsxx_ida_lock);
 
 /* --------------------Debugfs Setup ------------------- */
 
@@ -771,19 +770,10 @@ static int rsxx_pci_probe(struct pci_dev *dev,
        card->dev = dev;
        pci_set_drvdata(dev, card);
 
-       do {
-               if (!ida_pre_get(&rsxx_disk_ida, GFP_KERNEL)) {
-                       st = -ENOMEM;
-                       goto failed_ida_get;
-               }
-
-               spin_lock(&rsxx_ida_lock);
-               st = ida_get_new(&rsxx_disk_ida, &card->disk_id);
-               spin_unlock(&rsxx_ida_lock);
-       } while (st == -EAGAIN);
-
-       if (st)
+       st = ida_alloc(&rsxx_disk_ida, GFP_KERNEL);
+       if (st < 0)
                goto failed_ida_get;
+       card->disk_id = st;
 
        st = pci_enable_device(dev);
        if (st)
@@ -985,9 +975,7 @@ failed_request_regions:
 failed_dma_mask:
        pci_disable_device(dev);
 failed_enable:
-       spin_lock(&rsxx_ida_lock);
-       ida_remove(&rsxx_disk_ida, card->disk_id);
-       spin_unlock(&rsxx_ida_lock);
+       ida_free(&rsxx_disk_ida, card->disk_id);
 failed_ida_get:
        kfree(card);
 
@@ -1050,6 +1038,7 @@ static void rsxx_pci_remove(struct pci_dev *dev)
        pci_disable_device(dev);
        pci_release_regions(dev);
 
+       ida_free(&rsxx_disk_ida, card->disk_id);
        kfree(card);
 }
 
index b55b245e805205a07266c9d745b96e4716ed3009..fd1e19f1a49f5803ca6dd5d939ec41ec592af077 100644 (file)
@@ -83,6 +83,18 @@ module_param_named(max_persistent_grants, xen_blkif_max_pgrants, int, 0644);
 MODULE_PARM_DESC(max_persistent_grants,
                  "Maximum number of grants to map persistently");
 
+/*
+ * How long a persistent grant is allowed to remain allocated without being in
+ * use. The time is in seconds, 0 means indefinitely long.
+ */
+
+static unsigned int xen_blkif_pgrant_timeout = 60;
+module_param_named(persistent_grant_unused_seconds, xen_blkif_pgrant_timeout,
+                  uint, 0644);
+MODULE_PARM_DESC(persistent_grant_unused_seconds,
+                "Time in seconds an unused persistent grant is allowed to "
+                "remain allocated. Default is 60, 0 means unlimited.");
+
 /*
  * Maximum number of rings/queues blkback supports, allow as many queues as there
  * are CPUs if user has not specified a value.
@@ -123,6 +135,13 @@ module_param(log_stats, int, 0644);
 /* Number of free pages to remove on each call to gnttab_free_pages */
 #define NUM_BATCH_FREE_PAGES 10
 
+static inline bool persistent_gnt_timeout(struct persistent_gnt *persistent_gnt)
+{
+       return xen_blkif_pgrant_timeout &&
+              (jiffies - persistent_gnt->last_used >=
+               HZ * xen_blkif_pgrant_timeout);
+}
+
 static inline int get_free_page(struct xen_blkif_ring *ring, struct page **page)
 {
        unsigned long flags;
@@ -236,8 +255,7 @@ static int add_persistent_gnt(struct xen_blkif_ring *ring,
                }
        }
 
-       bitmap_zero(persistent_gnt->flags, PERSISTENT_GNT_FLAGS_SIZE);
-       set_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags);
+       persistent_gnt->active = true;
        /* Add new node and rebalance tree. */
        rb_link_node(&(persistent_gnt->node), parent, new);
        rb_insert_color(&(persistent_gnt->node), &ring->persistent_gnts);
@@ -261,11 +279,11 @@ static struct persistent_gnt *get_persistent_gnt(struct xen_blkif_ring *ring,
                else if (gref > data->gnt)
                        node = node->rb_right;
                else {
-                       if(test_bit(PERSISTENT_GNT_ACTIVE, data->flags)) {
+                       if (data->active) {
                                pr_alert_ratelimited("requesting a grant already in use\n");
                                return NULL;
                        }
-                       set_bit(PERSISTENT_GNT_ACTIVE, data->flags);
+                       data->active = true;
                        atomic_inc(&ring->persistent_gnt_in_use);
                        return data;
                }
@@ -276,10 +294,10 @@ static struct persistent_gnt *get_persistent_gnt(struct xen_blkif_ring *ring,
 static void put_persistent_gnt(struct xen_blkif_ring *ring,
                                struct persistent_gnt *persistent_gnt)
 {
-       if(!test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags))
+       if (!persistent_gnt->active)
                pr_alert_ratelimited("freeing a grant already unused\n");
-       set_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags);
-       clear_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags);
+       persistent_gnt->last_used = jiffies;
+       persistent_gnt->active = false;
        atomic_dec(&ring->persistent_gnt_in_use);
 }
 
@@ -371,26 +389,26 @@ static void purge_persistent_gnt(struct xen_blkif_ring *ring)
        struct persistent_gnt *persistent_gnt;
        struct rb_node *n;
        unsigned int num_clean, total;
-       bool scan_used = false, clean_used = false;
+       bool scan_used = false;
        struct rb_root *root;
 
-       if (ring->persistent_gnt_c < xen_blkif_max_pgrants ||
-           (ring->persistent_gnt_c == xen_blkif_max_pgrants &&
-           !ring->blkif->vbd.overflow_max_grants)) {
-               goto out;
-       }
-
        if (work_busy(&ring->persistent_purge_work)) {
                pr_alert_ratelimited("Scheduled work from previous purge is still busy, cannot purge list\n");
                goto out;
        }
 
-       num_clean = (xen_blkif_max_pgrants / 100) * LRU_PERCENT_CLEAN;
-       num_clean = ring->persistent_gnt_c - xen_blkif_max_pgrants + num_clean;
-       num_clean = min(ring->persistent_gnt_c, num_clean);
-       if ((num_clean == 0) ||
-           (num_clean > (ring->persistent_gnt_c - atomic_read(&ring->persistent_gnt_in_use))))
-               goto out;
+       if (ring->persistent_gnt_c < xen_blkif_max_pgrants ||
+           (ring->persistent_gnt_c == xen_blkif_max_pgrants &&
+           !ring->blkif->vbd.overflow_max_grants)) {
+               num_clean = 0;
+       } else {
+               num_clean = (xen_blkif_max_pgrants / 100) * LRU_PERCENT_CLEAN;
+               num_clean = ring->persistent_gnt_c - xen_blkif_max_pgrants +
+                           num_clean;
+               num_clean = min(ring->persistent_gnt_c, num_clean);
+               pr_debug("Going to purge at least %u persistent grants\n",
+                        num_clean);
+       }
 
        /*
         * At this point, we can assure that there will be no calls
@@ -401,9 +419,7 @@ static void purge_persistent_gnt(struct xen_blkif_ring *ring)
          * number of grants.
         */
 
-       total = num_clean;
-
-       pr_debug("Going to purge %u persistent grants\n", num_clean);
+       total = 0;
 
        BUG_ON(!list_empty(&ring->persistent_purge_list));
        root = &ring->persistent_gnts;
@@ -412,46 +428,37 @@ purge_list:
                BUG_ON(persistent_gnt->handle ==
                        BLKBACK_INVALID_HANDLE);
 
-               if (clean_used) {
-                       clear_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags);
+               if (persistent_gnt->active)
                        continue;
-               }
-
-               if (test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags))
+               if (!scan_used && !persistent_gnt_timeout(persistent_gnt))
                        continue;
-               if (!scan_used &&
-                   (test_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags)))
+               if (scan_used && total >= num_clean)
                        continue;
 
                rb_erase(&persistent_gnt->node, root);
                list_add(&persistent_gnt->remove_node,
                         &ring->persistent_purge_list);
-               if (--num_clean == 0)
-                       goto finished;
+               total++;
        }
        /*
-        * If we get here it means we also need to start cleaning
+        * Check whether we also need to start cleaning
         * grants that were used since last purge in order to cope
         * with the requested num
         */
-       if (!scan_used && !clean_used) {
-               pr_debug("Still missing %u purged frames\n", num_clean);
+       if (!scan_used && total < num_clean) {
+               pr_debug("Still missing %u purged frames\n", num_clean - total);
                scan_used = true;
                goto purge_list;
        }
-finished:
-       if (!clean_used) {
-               pr_debug("Finished scanning for grants to clean, removing used flag\n");
-               clean_used = true;
-               goto purge_list;
-       }
 
-       ring->persistent_gnt_c -= (total - num_clean);
-       ring->blkif->vbd.overflow_max_grants = 0;
+       if (total) {
+               ring->persistent_gnt_c -= total;
+               ring->blkif->vbd.overflow_max_grants = 0;
 
-       /* We can defer this work */
-       schedule_work(&ring->persistent_purge_work);
-       pr_debug("Purged %u/%u\n", (total - num_clean), total);
+               /* We can defer this work */
+               schedule_work(&ring->persistent_purge_work);
+               pr_debug("Purged %u/%u\n", num_clean, total);
+       }
 
 out:
        return;
index ecb35fe8ca8dbb54f36a85513a09064819acd67a..1d3002d773f7adb151dcf79adf18f919e461290a 100644 (file)
@@ -233,16 +233,6 @@ struct xen_vbd {
 
 struct backend_info;
 
-/* Number of available flags */
-#define PERSISTENT_GNT_FLAGS_SIZE      2
-/* This persistent grant is currently in use */
-#define PERSISTENT_GNT_ACTIVE          0
-/*
- * This persistent grant has been used, this flag is set when we remove the
- * PERSISTENT_GNT_ACTIVE, to know that this grant has been used recently.
- */
-#define PERSISTENT_GNT_WAS_ACTIVE      1
-
 /* Number of requests that we can fit in a ring */
 #define XEN_BLKIF_REQS_PER_PAGE                32
 
@@ -250,7 +240,8 @@ struct persistent_gnt {
        struct page *page;
        grant_ref_t gnt;
        grant_handle_t handle;
-       DECLARE_BITMAP(flags, PERSISTENT_GNT_FLAGS_SIZE);
+       unsigned long last_used;
+       bool active;
        struct rb_node node;
        struct list_head remove_node;
 };
@@ -278,7 +269,6 @@ struct xen_blkif_ring {
        wait_queue_head_t       pending_free_wq;
 
        /* Tree to store persistent grants. */
-       spinlock_t              pers_gnts_lock;
        struct rb_root          persistent_gnts;
        unsigned int            persistent_gnt_c;
        atomic_t                persistent_gnt_in_use;
index 8986adab9bf58540bd8d2ab0744d317fba6c23a0..a71d817e900ddc07ff45d240f0ae290ff408b6cd 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/scatterlist.h>
 #include <linux/bitmap.h>
 #include <linux/list.h>
+#include <linux/workqueue.h>
 
 #include <xen/xen.h>
 #include <xen/xenbus.h>
@@ -121,6 +122,8 @@ static inline struct blkif_req *blkif_req(struct request *rq)
 
 static DEFINE_MUTEX(blkfront_mutex);
 static const struct block_device_operations xlvbd_block_fops;
+static struct delayed_work blkfront_work;
+static LIST_HEAD(info_list);
 
 /*
  * Maximum number of segments in indirect requests, the actual value used by
@@ -216,6 +219,7 @@ struct blkfront_info
        /* Save uncomplete reqs and bios for migration. */
        struct list_head requests;
        struct bio_list bio_list;
+       struct list_head info_list;
 };
 
 static unsigned int nr_minors;
@@ -1759,6 +1763,12 @@ abort_transaction:
        return err;
 }
 
+static void free_info(struct blkfront_info *info)
+{
+       list_del(&info->info_list);
+       kfree(info);
+}
+
 /* Common code used when first setting up, and when resuming. */
 static int talk_to_blkback(struct xenbus_device *dev,
                           struct blkfront_info *info)
@@ -1880,7 +1890,10 @@ again:
  destroy_blkring:
        blkif_free(info, 0);
 
-       kfree(info);
+       mutex_lock(&blkfront_mutex);
+       free_info(info);
+       mutex_unlock(&blkfront_mutex);
+
        dev_set_drvdata(&dev->dev, NULL);
 
        return err;
@@ -1991,6 +2004,10 @@ static int blkfront_probe(struct xenbus_device *dev,
        info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0);
        dev_set_drvdata(&dev->dev, info);
 
+       mutex_lock(&blkfront_mutex);
+       list_add(&info->info_list, &info_list);
+       mutex_unlock(&blkfront_mutex);
+
        return 0;
 }
 
@@ -2301,6 +2318,12 @@ static void blkfront_gather_backend_features(struct blkfront_info *info)
        if (indirect_segments <= BLKIF_MAX_SEGMENTS_PER_REQUEST)
                indirect_segments = 0;
        info->max_indirect_segments = indirect_segments;
+
+       if (info->feature_persistent) {
+               mutex_lock(&blkfront_mutex);
+               schedule_delayed_work(&blkfront_work, HZ * 10);
+               mutex_unlock(&blkfront_mutex);
+       }
 }
 
 /*
@@ -2482,7 +2505,9 @@ static int blkfront_remove(struct xenbus_device *xbdev)
        mutex_unlock(&info->mutex);
 
        if (!bdev) {
-               kfree(info);
+               mutex_lock(&blkfront_mutex);
+               free_info(info);
+               mutex_unlock(&blkfront_mutex);
                return 0;
        }
 
@@ -2502,7 +2527,9 @@ static int blkfront_remove(struct xenbus_device *xbdev)
        if (info && !bdev->bd_openers) {
                xlvbd_release_gendisk(info);
                disk->private_data = NULL;
-               kfree(info);
+               mutex_lock(&blkfront_mutex);
+               free_info(info);
+               mutex_unlock(&blkfront_mutex);
        }
 
        mutex_unlock(&bdev->bd_mutex);
@@ -2585,7 +2612,7 @@ static void blkif_release(struct gendisk *disk, fmode_t mode)
                dev_info(disk_to_dev(bdev->bd_disk), "releasing disk\n");
                xlvbd_release_gendisk(info);
                disk->private_data = NULL;
-               kfree(info);
+               free_info(info);
        }
 
 out:
@@ -2618,6 +2645,61 @@ static struct xenbus_driver blkfront_driver = {
        .is_ready = blkfront_is_ready,
 };
 
+static void purge_persistent_grants(struct blkfront_info *info)
+{
+       unsigned int i;
+       unsigned long flags;
+
+       for (i = 0; i < info->nr_rings; i++) {
+               struct blkfront_ring_info *rinfo = &info->rinfo[i];
+               struct grant *gnt_list_entry, *tmp;
+
+               spin_lock_irqsave(&rinfo->ring_lock, flags);
+
+               if (rinfo->persistent_gnts_c == 0) {
+                       spin_unlock_irqrestore(&rinfo->ring_lock, flags);
+                       continue;
+               }
+
+               list_for_each_entry_safe(gnt_list_entry, tmp, &rinfo->grants,
+                                        node) {
+                       if (gnt_list_entry->gref == GRANT_INVALID_REF ||
+                           gnttab_query_foreign_access(gnt_list_entry->gref))
+                               continue;
+
+                       list_del(&gnt_list_entry->node);
+                       gnttab_end_foreign_access(gnt_list_entry->gref, 0, 0UL);
+                       rinfo->persistent_gnts_c--;
+                       __free_page(gnt_list_entry->page);
+                       kfree(gnt_list_entry);
+               }
+
+               spin_unlock_irqrestore(&rinfo->ring_lock, flags);
+       }
+}
+
+static void blkfront_delay_work(struct work_struct *work)
+{
+       struct blkfront_info *info;
+       bool need_schedule_work = false;
+
+       mutex_lock(&blkfront_mutex);
+
+       list_for_each_entry(info, &info_list, info_list) {
+               if (info->feature_persistent) {
+                       need_schedule_work = true;
+                       mutex_lock(&info->mutex);
+                       purge_persistent_grants(info);
+                       mutex_unlock(&info->mutex);
+               }
+       }
+
+       if (need_schedule_work)
+               schedule_delayed_work(&blkfront_work, HZ * 10);
+
+       mutex_unlock(&blkfront_mutex);
+}
+
 static int __init xlblk_init(void)
 {
        int ret;
@@ -2626,6 +2708,15 @@ static int __init xlblk_init(void)
        if (!xen_domain())
                return -ENODEV;
 
+       if (!xen_has_pv_disk_devices())
+               return -ENODEV;
+
+       if (register_blkdev(XENVBD_MAJOR, DEV_NAME)) {
+               pr_warn("xen_blk: can't get major %d with name %s\n",
+                       XENVBD_MAJOR, DEV_NAME);
+               return -ENODEV;
+       }
+
        if (xen_blkif_max_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST)
                xen_blkif_max_segments = BLKIF_MAX_SEGMENTS_PER_REQUEST;
 
@@ -2641,14 +2732,7 @@ static int __init xlblk_init(void)
                xen_blkif_max_queues = nr_cpus;
        }
 
-       if (!xen_has_pv_disk_devices())
-               return -ENODEV;
-
-       if (register_blkdev(XENVBD_MAJOR, DEV_NAME)) {
-               printk(KERN_WARNING "xen_blk: can't get major %d with name %s\n",
-                      XENVBD_MAJOR, DEV_NAME);
-               return -ENODEV;
-       }
+       INIT_DELAYED_WORK(&blkfront_work, blkfront_delay_work);
 
        ret = xenbus_register_frontend(&blkfront_driver);
        if (ret) {
@@ -2663,6 +2747,8 @@ module_init(xlblk_init);
 
 static void __exit xlblk_exit(void)
 {
+       cancel_delayed_work_sync(&blkfront_work);
+
        xenbus_unregister_driver(&blkfront_driver);
        unregister_blkdev(XENVBD_MAJOR, DEV_NAME);
        kfree(minors);
index c7acf74253a12e22fb9720b2c75966a68ea3eded..a1d6b5597c17bac113c062f7b3200e2926b9f0e5 100644 (file)
@@ -337,6 +337,7 @@ static ssize_t backing_dev_store(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t len)
 {
        char *file_name;
+       size_t sz;
        struct file *backing_dev = NULL;
        struct inode *inode;
        struct address_space *mapping;
@@ -357,7 +358,11 @@ static ssize_t backing_dev_store(struct device *dev,
                goto out;
        }
 
-       strlcpy(file_name, buf, len);
+       strlcpy(file_name, buf, PATH_MAX);
+       /* ignore trailing newline */
+       sz = strlen(file_name);
+       if (sz > 0 && file_name[sz - 1] == '\n')
+               file_name[sz - 1] = 0x00;
 
        backing_dev = filp_open(file_name, O_RDWR|O_LARGEFILE, 0);
        if (IS_ERR(backing_dev)) {
index 2df11cc08a460a893e2ebcb7af510f70bd6e792a..845b0314ce3a7f599360d6c7e3d73c14a5fc2bbb 100644 (file)
@@ -200,6 +200,7 @@ config BT_HCIUART_RTL
        depends on BT_HCIUART
        depends on BT_HCIUART_SERDEV
        depends on GPIOLIB
+       depends on ACPI
        select BT_HCIUART_3WIRE
        select BT_RTL
        help
index ed2a5c7cb77fa0304ed7f3639631c3b9c8eb597e..4593baff2bc944f5a003bb666520062f768f52e5 100644 (file)
@@ -144,8 +144,10 @@ static int mtk_setup_fw(struct hci_dev *hdev)
        fw_size = fw->size;
 
        /* The size of patch header is 30 bytes, should be skip */
-       if (fw_size < 30)
-               return -EINVAL;
+       if (fw_size < 30) {
+               err = -EINVAL;
+               goto free_fw;
+       }
 
        fw_size -= 30;
        fw_ptr += 30;
@@ -172,8 +174,8 @@ static int mtk_setup_fw(struct hci_dev *hdev)
                fw_ptr += dlen;
        }
 
+free_fw:
        release_firmware(fw);
-
        return err;
 }
 
index d1c0b60e9326f5f5a0b0db56ac7d328283f27506..1851112ccc294bcbd36d0fd8c016477c3f95d0cd 100644 (file)
@@ -103,6 +103,16 @@ config SIMPLE_PM_BUS
          Controller (BSC, sometimes called "LBSC within Bus Bridge", or
          "External Bus Interface") as found on several Renesas ARM SoCs.
 
+config SUN50I_DE2_BUS
+       bool "Allwinner A64 DE2 Bus Driver"
+         default ARM64
+         depends on ARCH_SUNXI
+         select SUNXI_SRAM
+         help
+         Say y here to enable support for Allwinner A64 DE2 bus driver. It's
+         mostly transparent, but a SRAM region needs to be claimed in the SRAM
+         controller to make the all blocks in the DE2 part accessible.
+
 config SUNXI_RSB
        tristate "Allwinner sunXi Reduced Serial Bus Driver"
          default MACH_SUN8I || MACH_SUN9I || ARM64
index b8f036cca7ff2c056399288ca011ab6c6bc6efbe..ca300b1914ce24170a4862ea422b526acfeafd4d 100644 (file)
@@ -21,6 +21,7 @@ obj-$(CONFIG_OMAP_INTERCONNECT)       += omap_l3_smx.o omap_l3_noc.o
 
 obj-$(CONFIG_OMAP_OCP2SCP)     += omap-ocp2scp.o
 obj-$(CONFIG_QCOM_EBI2)                += qcom-ebi2.o
+obj-$(CONFIG_SUN50I_DE2_BUS)   += sun50i-de2.o
 obj-$(CONFIG_SUNXI_RSB)                += sunxi-rsb.o
 obj-$(CONFIG_SIMPLE_PM_BUS)    += simple-pm-bus.o
 obj-$(CONFIG_TEGRA_ACONNECT)   += tegra-aconnect.o
diff --git a/drivers/bus/sun50i-de2.c b/drivers/bus/sun50i-de2.c
new file mode 100644 (file)
index 0000000..6725187
--- /dev/null
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Allwinner A64 Display Engine 2.0 Bus Driver
+ *
+ * Copyright (C) 2018 Icenowy Zheng <icenowy@aosc.io>
+ */
+
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/soc/sunxi/sunxi_sram.h>
+
+static int sun50i_de2_bus_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       int ret;
+
+       ret = sunxi_sram_claim(&pdev->dev);
+       if (ret) {
+               dev_err(&pdev->dev, "Error couldn't map SRAM to device\n");
+               return ret;
+       }
+
+       of_platform_populate(np, NULL, NULL, &pdev->dev);
+
+       return 0;
+}
+
+static int sun50i_de2_bus_remove(struct platform_device *pdev)
+{
+       sunxi_sram_release(&pdev->dev);
+       return 0;
+}
+
+static const struct of_device_id sun50i_de2_bus_of_match[] = {
+       { .compatible = "allwinner,sun50i-a64-de2", },
+       { /* sentinel */ }
+};
+
+static struct platform_driver sun50i_de2_bus_driver = {
+       .probe = sun50i_de2_bus_probe,
+       .remove = sun50i_de2_bus_remove,
+       .driver = {
+               .name = "sun50i-de2-bus",
+               .of_match_table = sun50i_de2_bus_of_match,
+       },
+};
+
+builtin_platform_driver(sun50i_de2_bus_driver);
index 80d60f43db56123076fed5ea2047da35af88af8f..e4fe954e63a9be53b74397c825bf4f57b06dcca5 100644 (file)
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/slab.h>
+#include <linux/iopoll.h>
 
 #include <linux/platform_data/ti-sysc.h>
 
 #include <dt-bindings/bus/ti-sysc.h>
 
+#define MAX_MODULE_SOFTRESET_WAIT              10000
+
 static const char * const reg_names[] = { "rev", "sysc", "syss", };
 
 enum sysc_clocks {
@@ -88,6 +91,11 @@ struct sysc {
        struct delayed_work idle_work;
 };
 
+void sysc_write(struct sysc *ddata, int offset, u32 value)
+{
+       writel_relaxed(value, ddata->module_va + offset);
+}
+
 static u32 sysc_read(struct sysc *ddata, int offset)
 {
        if (ddata->cfg.quirks & SYSC_QUIRK_16BIT) {
@@ -490,32 +498,29 @@ static int sysc_check_registers(struct sysc *ddata)
 
 /**
  * syc_ioremap - ioremap register space for the interconnect target module
- * @ddata: deviec driver data
+ * @ddata: device driver data
  *
  * Note that the interconnect target module registers can be anywhere
- * within the first child device address space. For example, SGX has
- * them at offset 0x1fc00 in the 32MB module address space. We just
- * what we need around the interconnect target module registers.
+ * within the interconnect target module range. For example, SGX has
+ * them at offset 0x1fc00 in the 32MB module address space. And cpsw
+ * has them at offset 0x1200 in the CPSW_WR child. Usually the
+ * the interconnect target module registers are at the beginning of
+ * the module range though.
  */
 static int sysc_ioremap(struct sysc *ddata)
 {
-       u32 size = 0;
-
-       if (ddata->offsets[SYSC_SYSSTATUS] >= 0)
-               size = ddata->offsets[SYSC_SYSSTATUS];
-       else if (ddata->offsets[SYSC_SYSCONFIG] >= 0)
-               size = ddata->offsets[SYSC_SYSCONFIG];
-       else if (ddata->offsets[SYSC_REVISION] >= 0)
-               size = ddata->offsets[SYSC_REVISION];
-       else
-               return -EINVAL;
+       int size;
+
+       size = max3(ddata->offsets[SYSC_REVISION],
+                   ddata->offsets[SYSC_SYSCONFIG],
+                   ddata->offsets[SYSC_SYSSTATUS]);
 
-       size &= 0xfff00;
-       size += SZ_256;
+       if (size < 0 || (size + sizeof(u32)) > ddata->module_size)
+               return -EINVAL;
 
        ddata->module_va = devm_ioremap(ddata->dev,
                                        ddata->module_pa,
-                                       size);
+                                       size + sizeof(u32));
        if (!ddata->module_va)
                return -EIO;
 
@@ -943,6 +948,36 @@ static void sysc_init_revision_quirks(struct sysc *ddata)
        }
 }
 
+static int sysc_reset(struct sysc *ddata)
+{
+       int offset = ddata->offsets[SYSC_SYSCONFIG];
+       int val;
+
+       if (ddata->legacy_mode || offset < 0 ||
+           ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)
+               return 0;
+
+       /*
+        * Currently only support reset status in sysstatus.
+        * Warn and return error in all other cases
+        */
+       if (!ddata->cfg.syss_mask) {
+               dev_err(ddata->dev, "No ti,syss-mask. Reset failed\n");
+               return -EINVAL;
+       }
+
+       val = sysc_read(ddata, offset);
+       val |= (0x1 << ddata->cap->regbits->srst_shift);
+       sysc_write(ddata, offset, val);
+
+       /* Poll on reset status */
+       offset = ddata->offsets[SYSC_SYSSTATUS];
+
+       return readl_poll_timeout(ddata->module_va + offset, val,
+                                 (val & ddata->cfg.syss_mask) == 0x0,
+                                 100, MAX_MODULE_SOFTRESET_WAIT);
+}
+
 /* At this point the module is configured enough to read the revision */
 static int sysc_init_module(struct sysc *ddata)
 {
@@ -960,6 +995,14 @@ static int sysc_init_module(struct sysc *ddata)
                return 0;
        }
 
+       error = sysc_reset(ddata);
+       if (error) {
+               dev_err(ddata->dev, "Reset failed with %d\n", error);
+               pm_runtime_put_sync(ddata->dev);
+
+               return error;
+       }
+
        ddata->revision = sysc_read_revision(ddata);
        pm_runtime_put_sync(ddata->dev);
 
@@ -1178,10 +1221,10 @@ static int sysc_child_suspend_noirq(struct device *dev)
        if (!pm_runtime_status_suspended(dev)) {
                error = pm_generic_runtime_suspend(dev);
                if (error) {
-                       dev_err(dev, "%s error at %i: %i\n",
-                               __func__, __LINE__, error);
+                       dev_warn(dev, "%s busy at %i: %i\n",
+                                __func__, __LINE__, error);
 
-                       return error;
+                       return 0;
                }
 
                error = sysc_runtime_suspend(ddata->dev);
@@ -1552,6 +1595,23 @@ static const struct sysc_capabilities sysc_omap4_usb_host_fs = {
        .regbits = &sysc_regbits_omap4_usb_host_fs,
 };
 
+static const struct sysc_regbits sysc_regbits_dra7_mcan = {
+       .dmadisable_shift = -ENODEV,
+       .midle_shift = -ENODEV,
+       .sidle_shift = -ENODEV,
+       .clkact_shift = -ENODEV,
+       .enwkup_shift = 4,
+       .srst_shift = 0,
+       .emufree_shift = -ENODEV,
+       .autoidle_shift = -ENODEV,
+};
+
+static const struct sysc_capabilities sysc_dra7_mcan = {
+       .type = TI_SYSC_DRA7_MCAN,
+       .sysc_mask = SYSC_DRA7_MCAN_ENAWAKEUP | SYSC_OMAP4_SOFTRESET,
+       .regbits = &sysc_regbits_dra7_mcan,
+};
+
 static int sysc_init_pdata(struct sysc *ddata)
 {
        struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev);
@@ -1743,6 +1803,7 @@ static const struct of_device_id sysc_match[] = {
        { .compatible = "ti,sysc-mcasp", .data = &sysc_omap4_mcasp, },
        { .compatible = "ti,sysc-usb-host-fs",
          .data = &sysc_omap4_usb_host_fs, },
+       { .compatible = "ti,sysc-dra7-mcan", .data = &sysc_dra7_mcan, },
        {  },
 };
 MODULE_DEVICE_TABLE(of, sysc_match);
index 113fc6edb2b03718166b2e42854d777a2f18f798..a5d5a96479bfe813449c7527024c52bf0d79c1b8 100644 (file)
@@ -2546,7 +2546,7 @@ static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi,
        if (!CDROM_CAN(CDC_SELECT_DISC) ||
            (arg == CDSL_CURRENT || arg == CDSL_NONE))
                return cdi->ops->drive_status(cdi, CDSL_CURRENT);
-       if (((int)arg >= cdi->capacity))
+       if (arg >= cdi->capacity)
                return -EINVAL;
        return cdrom_slot_status(cdi, arg);
 }
index ce277ee0a28a21a328bee687d6872842a1cda5cc..40728491f37b6a46be7e59399c6530263d2d40c1 100644 (file)
@@ -566,5 +566,5 @@ config RANDOM_TRUST_CPU
        that CPU manufacturer (perhaps with the insistence or mandate
        of a Nation State's intelligence or law enforcement agencies)
        has not installed a hidden back door to compromise the CPU's
-       random number generation facilities.
-
+       random number generation facilities. This can also be configured
+       at boot with "random.trust_cpu=on/off".
index bf5f99fc36f1b654aad2f4cfe196c9b66814be82..c75b6cdf00533ac82ec6fb957bc1669f1f44a34d 100644 (file)
@@ -779,6 +779,13 @@ static struct crng_state **crng_node_pool __read_mostly;
 
 static void invalidate_batched_entropy(void);
 
+static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU);
+static int __init parse_trust_cpu(char *arg)
+{
+       return kstrtobool(arg, &trust_cpu);
+}
+early_param("random.trust_cpu", parse_trust_cpu);
+
 static void crng_initialize(struct crng_state *crng)
 {
        int             i;
@@ -799,12 +806,10 @@ static void crng_initialize(struct crng_state *crng)
                }
                crng->state[i] ^= rv;
        }
-#ifdef CONFIG_RANDOM_TRUST_CPU
-       if (arch_init) {
+       if (trust_cpu && arch_init) {
                crng_init = 2;
                pr_notice("random: crng done (trusting CPU's manufacturer)\n");
        }
-#endif
        crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
 }
 
index 94fedeeec0356b7a9f818b72369cca1bd312379e..4948c8bda6b1fb7d5dc1dd734f52ebc11307aa99 100644 (file)
@@ -193,14 +193,6 @@ static unsigned long rtc_freq;             /* Current periodic IRQ rate    */
 static unsigned long rtc_irq_data;     /* our output to the world      */
 static unsigned long rtc_max_user_freq = 64; /* > this, need CAP_SYS_RESOURCE */
 
-#ifdef RTC_IRQ
-/*
- * rtc_task_lock nests inside rtc_lock.
- */
-static DEFINE_SPINLOCK(rtc_task_lock);
-static rtc_task_t *rtc_callback;
-#endif
-
 /*
  *     If this driver ever becomes modularised, it will be really nice
  *     to make the epoch retain its value across module reload...
@@ -264,11 +256,6 @@ static irqreturn_t rtc_interrupt(int irq, void *dev_id)
 
        spin_unlock(&rtc_lock);
 
-       /* Now do the rest of the actions */
-       spin_lock(&rtc_task_lock);
-       if (rtc_callback)
-               rtc_callback->func(rtc_callback->private_data);
-       spin_unlock(&rtc_task_lock);
        wake_up_interruptible(&rtc_wait);
 
        kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
index 740af90a950820055d9934f66e080c338f0cf143..c5edf8f2fd1969337b7803ef96884ee9164495fb 100644 (file)
@@ -558,8 +558,8 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np)
        if (!clk_base)
                goto npcm7xx_init_error;
 
-       npcm7xx_clk_data = kzalloc(sizeof(*npcm7xx_clk_data->hws) *
-               NPCM7XX_NUM_CLOCKS + sizeof(npcm7xx_clk_data), GFP_KERNEL);
+       npcm7xx_clk_data = kzalloc(struct_size(npcm7xx_clk_data, hws,
+                                  NPCM7XX_NUM_CLOCKS), GFP_KERNEL);
        if (!npcm7xx_clk_data)
                goto npcm7xx_init_np_err;
 
index 081b039fcb023383b62899c0acece3a82788e14b..6481337382a629d49dbab0d88ea27a7dbe988b61 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "psc.h"
 
+LPSC_CLKDEV1(aemif_clkdev,     NULL,   "ti-aemif");
 LPSC_CLKDEV1(spi0_clkdev,      NULL,   "spi_davinci.0");
 LPSC_CLKDEV1(mmcsd_clkdev,     NULL,   "da830-mmc.0");
 LPSC_CLKDEV1(uart0_clkdev,     NULL,   "serial8250.0");
@@ -22,7 +23,7 @@ static const struct davinci_lpsc_clk_info da830_psc0_info[] = {
        LPSC(0,  0, tpcc,     pll0_sysclk2, NULL,         LPSC_ALWAYS_ENABLED),
        LPSC(1,  0, tptc0,    pll0_sysclk2, NULL,         LPSC_ALWAYS_ENABLED),
        LPSC(2,  0, tptc1,    pll0_sysclk2, NULL,         LPSC_ALWAYS_ENABLED),
-       LPSC(3,  0, aemif,    pll0_sysclk3, NULL,         LPSC_ALWAYS_ENABLED),
+       LPSC(3,  0, aemif,    pll0_sysclk3, aemif_clkdev, LPSC_ALWAYS_ENABLED),
        LPSC(4,  0, spi0,     pll0_sysclk2, spi0_clkdev,  0),
        LPSC(5,  0, mmcsd,    pll0_sysclk2, mmcsd_clkdev, 0),
        LPSC(6,  0, aintc,    pll0_sysclk4, NULL,         LPSC_ALWAYS_ENABLED),
index d196dcbed56021cd43f7417286ca048573ac1d2d..5a18bca464cdaf3a0f3573cf9d70b79ca591cf28 100644 (file)
@@ -16,8 +16,7 @@
 
 #include "psc.h"
 
-LPSC_CLKDEV2(emifa_clkdev,     NULL,           "ti-aemif",
-                               "aemif",        "davinci_nand.0");
+LPSC_CLKDEV1(emifa_clkdev,     NULL,           "ti-aemif");
 LPSC_CLKDEV1(spi0_clkdev,      NULL,           "spi_davinci.0");
 LPSC_CLKDEV1(mmcsd0_clkdev,    NULL,           "da830-mmc.0");
 LPSC_CLKDEV1(uart0_clkdev,     NULL,           "serial8250.0");
index 8c73086cc6767ceb19ae4590b6242f0fd276dc6d..c75424f4ea3bf80b24773915d9590ed42403c166 100644 (file)
@@ -21,7 +21,8 @@ LPSC_CLKDEV1(mmcsd1_clkdev,           NULL,           "da830-mmc.1");
 LPSC_CLKDEV1(asp0_clkdev,              NULL,           "davinci-mcbsp");
 LPSC_CLKDEV1(usb_clkdev,               "usb",          NULL);
 LPSC_CLKDEV1(spi2_clkdev,              NULL,           "spi_davinci.2");
-LPSC_CLKDEV1(aemif_clkdev,             "aemif",        NULL);
+LPSC_CLKDEV2(aemif_clkdev,             "aemif",        NULL,
+                                       NULL,           "ti-aemif");
 LPSC_CLKDEV1(mmcsd0_clkdev,            NULL,           "da830-mmc.0");
 LPSC_CLKDEV1(i2c_clkdev,               NULL,           "i2c_davinci.1");
 LPSC_CLKDEV1(uart0_clkdev,             NULL,           "serial8250.0");
index fc0230e3a3d66995d92d83823ac45cdc328fe29b..0cea6e0bd5f06f0af4af7ba82559f261ddcfdd14 100644 (file)
@@ -21,7 +21,8 @@ LPSC_CLKDEV2(emac_clkdev,             NULL,           "davinci_emac.1",
                                        "fck",          "davinci_mdio.0");
 LPSC_CLKDEV1(usb_clkdev,               "usb",          NULL);
 LPSC_CLKDEV1(ide_clkdev,               NULL,           "palm_bk3710");
-LPSC_CLKDEV1(aemif_clkdev,             "aemif",        NULL);
+LPSC_CLKDEV2(aemif_clkdev,             "aemif",        NULL,
+                                       NULL,           "ti-aemif");
 LPSC_CLKDEV1(mmcsd_clkdev,             NULL,           "dm6441-mmc.0");
 LPSC_CLKDEV1(asp0_clkdev,              NULL,           "davinci-mcbsp");
 LPSC_CLKDEV1(i2c_clkdev,               NULL,           "i2c_davinci.1");
index c3f82ed70a80ee157a5f00c48e966fa5f8715d00..20012dc7471a2873e700190401c44ee715b475fd 100644 (file)
@@ -18,7 +18,8 @@
 LPSC_CLKDEV1(ide_clkdev,       NULL,           "palm_bk3710");
 LPSC_CLKDEV2(emac_clkdev,      NULL,           "davinci_emac.1",
                                "fck",          "davinci_mdio.0");
-LPSC_CLKDEV1(aemif_clkdev,     "aemif",        NULL);
+LPSC_CLKDEV2(aemif_clkdev,     "aemif",        NULL,
+                               NULL,           "ti-aemif");
 LPSC_CLKDEV1(mcasp0_clkdev,    NULL,           "davinci-mcasp.0");
 LPSC_CLKDEV1(mcasp1_clkdev,    NULL,           "davinci-mcasp.1");
 LPSC_CLKDEV1(uart0_clkdev,     NULL,           "serial8250.0");
index 513826393158d90f50f1adf62bdd111399cc1ebd..1a4e6b787978383ba44252a9e70cb587dea659fa 100644 (file)
@@ -14,7 +14,6 @@ obj-$(CONFIG_SOC_EXYNOS5410)  += clk-exynos5410.o
 obj-$(CONFIG_SOC_EXYNOS5420)   += clk-exynos5420.o
 obj-$(CONFIG_SOC_EXYNOS5420)   += clk-exynos5-subcmu.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)  += clk-exynos5433.o
-obj-$(CONFIG_SOC_EXYNOS5440)   += clk-exynos5440.o
 obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
 obj-$(CONFIG_ARCH_EXYNOS)      += clk-exynos-clkout.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)  += clk-exynos7.o
diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c
deleted file mode 100644 (file)
index b08bd54..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2013 Samsung Electronics Co., Ltd.
- * Author: Thomas Abraham <thomas.ab@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.
- *
- * Common Clock Framework support for Exynos5440 SoC.
-*/
-
-#include <dt-bindings/clock/exynos5440.h>
-#include <linux/clk-provider.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-
-#include "clk.h"
-#include "clk-pll.h"
-
-#define CLKEN_OV_VAL           0xf8
-#define CPU_CLK_STATUS         0xfc
-#define MISC_DOUT1             0x558
-
-static void __iomem *reg_base;
-
-/* parent clock name list */
-PNAME(mout_armclk_p)   = { "cplla", "cpllb" };
-PNAME(mout_spi_p)      = { "div125", "div200" };
-
-/* fixed rate clocks generated outside the soc */
-static struct samsung_fixed_rate_clock exynos5440_fixed_rate_ext_clks[] __initdata = {
-       FRATE(0, "xtal", NULL, 0, 0),
-};
-
-/* fixed rate clocks */
-static const struct samsung_fixed_rate_clock exynos5440_fixed_rate_clks[] __initconst = {
-       FRATE(0, "ppll", NULL, 0, 1000000000),
-       FRATE(0, "usb_phy0", NULL, 0, 60000000),
-       FRATE(0, "usb_phy1", NULL, 0, 60000000),
-       FRATE(0, "usb_ohci12", NULL, 0, 12000000),
-       FRATE(0, "usb_ohci48", NULL, 0, 48000000),
-};
-
-/* fixed factor clocks */
-static const struct samsung_fixed_factor_clock exynos5440_fixed_factor_clks[] __initconst = {
-       FFACTOR(0, "div250", "ppll", 1, 4, 0),
-       FFACTOR(0, "div200", "ppll", 1, 5, 0),
-       FFACTOR(0, "div125", "div250", 1, 2, 0),
-};
-
-/* mux clocks */
-static const struct samsung_mux_clock exynos5440_mux_clks[] __initconst = {
-       MUX(0, "mout_spi", mout_spi_p, MISC_DOUT1, 5, 1),
-       MUX(CLK_ARM_CLK, "arm_clk", mout_armclk_p, CPU_CLK_STATUS, 0, 1),
-};
-
-/* divider clocks */
-static const struct samsung_div_clock exynos5440_div_clks[] __initconst = {
-       DIV(CLK_SPI_BAUD, "div_spi", "mout_spi", MISC_DOUT1, 3, 2),
-};
-
-/* gate clocks */
-static const struct samsung_gate_clock exynos5440_gate_clks[] __initconst = {
-       GATE(CLK_PB0_250, "pb0_250", "div250", CLKEN_OV_VAL, 3, 0, 0),
-       GATE(CLK_PR0_250, "pr0_250", "div250", CLKEN_OV_VAL, 4, 0, 0),
-       GATE(CLK_PR1_250, "pr1_250", "div250", CLKEN_OV_VAL, 5, 0, 0),
-       GATE(CLK_B_250, "b_250", "div250", CLKEN_OV_VAL, 9, 0, 0),
-       GATE(CLK_B_125, "b_125", "div125", CLKEN_OV_VAL, 10, 0, 0),
-       GATE(CLK_B_200, "b_200", "div200", CLKEN_OV_VAL, 11, 0, 0),
-       GATE(CLK_SATA, "sata", "div200", CLKEN_OV_VAL, 12, 0, 0),
-       GATE(CLK_USB, "usb", "div200", CLKEN_OV_VAL, 13, 0, 0),
-       GATE(CLK_GMAC0, "gmac0", "div200", CLKEN_OV_VAL, 14, 0, 0),
-       GATE(CLK_CS250, "cs250", "div250", CLKEN_OV_VAL, 19, 0, 0),
-       GATE(CLK_PB0_250_O, "pb0_250_o", "pb0_250", CLKEN_OV_VAL, 3, 0, 0),
-       GATE(CLK_PR0_250_O, "pr0_250_o", "pr0_250", CLKEN_OV_VAL, 4, 0, 0),
-       GATE(CLK_PR1_250_O, "pr1_250_o", "pr1_250", CLKEN_OV_VAL, 5, 0, 0),
-       GATE(CLK_B_250_O, "b_250_o", "b_250", CLKEN_OV_VAL, 9, 0, 0),
-       GATE(CLK_B_125_O, "b_125_o", "b_125", CLKEN_OV_VAL, 10, 0, 0),
-       GATE(CLK_B_200_O, "b_200_o", "b_200", CLKEN_OV_VAL, 11, 0, 0),
-       GATE(CLK_SATA_O, "sata_o", "sata", CLKEN_OV_VAL, 12, 0, 0),
-       GATE(CLK_USB_O, "usb_o", "usb", CLKEN_OV_VAL, 13, 0, 0),
-       GATE(CLK_GMAC0_O, "gmac0_o", "gmac", CLKEN_OV_VAL, 14, 0, 0),
-       GATE(CLK_CS250_O, "cs250_o", "cs250", CLKEN_OV_VAL, 19, 0, 0),
-};
-
-static const struct of_device_id ext_clk_match[] __initconst = {
-       { .compatible = "samsung,clock-xtal", .data = (void *)0, },
-       {},
-};
-
-static int exynos5440_clk_restart_notify(struct notifier_block *this,
-               unsigned long code, void *unused)
-{
-       u32 val, status;
-
-       status = readl_relaxed(reg_base + 0xbc);
-       val = readl_relaxed(reg_base + 0xcc);
-       val = (val & 0xffff0000) | (status & 0xffff);
-       writel_relaxed(val, reg_base + 0xcc);
-
-       return NOTIFY_DONE;
-}
-
-/*
- * Exynos5440 Clock restart notifier, handles restart functionality
- */
-static struct notifier_block exynos5440_clk_restart_handler = {
-       .notifier_call = exynos5440_clk_restart_notify,
-       .priority = 128,
-};
-
-static const struct samsung_pll_clock exynos5440_plls[] __initconst = {
-       PLL(pll_2550x, CLK_CPLLA, "cplla", "xtal", 0, 0x4c, NULL),
-       PLL(pll_2550x, CLK_CPLLB, "cpllb", "xtal", 0, 0x50, NULL),
-};
-
-/*
- * Clock aliases for legacy clkdev look-up.
- */
-static const struct samsung_clock_alias exynos5440_aliases[] __initconst = {
-       ALIAS(CLK_ARM_CLK, NULL, "armclk"),
-};
-
-/* register exynos5440 clocks */
-static void __init exynos5440_clk_init(struct device_node *np)
-{
-       struct samsung_clk_provider *ctx;
-
-       reg_base = of_iomap(np, 0);
-       if (!reg_base) {
-               pr_err("%s: failed to map clock controller registers,"
-                       " aborting clock initialization\n", __func__);
-               return;
-       }
-
-       ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
-
-       samsung_clk_of_register_fixed_ext(ctx, exynos5440_fixed_rate_ext_clks,
-               ARRAY_SIZE(exynos5440_fixed_rate_ext_clks), ext_clk_match);
-
-       samsung_clk_register_pll(ctx, exynos5440_plls,
-                       ARRAY_SIZE(exynos5440_plls), ctx->reg_base);
-
-       samsung_clk_register_fixed_rate(ctx, exynos5440_fixed_rate_clks,
-                       ARRAY_SIZE(exynos5440_fixed_rate_clks));
-       samsung_clk_register_fixed_factor(ctx, exynos5440_fixed_factor_clks,
-                       ARRAY_SIZE(exynos5440_fixed_factor_clks));
-       samsung_clk_register_mux(ctx, exynos5440_mux_clks,
-                       ARRAY_SIZE(exynos5440_mux_clks));
-       samsung_clk_register_div(ctx, exynos5440_div_clks,
-                       ARRAY_SIZE(exynos5440_div_clks));
-       samsung_clk_register_gate(ctx, exynos5440_gate_clks,
-                       ARRAY_SIZE(exynos5440_gate_clks));
-       samsung_clk_register_alias(ctx, exynos5440_aliases,
-                                               ARRAY_SIZE(exynos5440_aliases));
-
-       samsung_clk_of_add_provider(np, ctx);
-
-       if (register_restart_handler(&exynos5440_clk_restart_handler))
-               pr_warn("exynos5440 clock can't register restart handler\n");
-
-       pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("arm_clk"));
-       pr_info("exynos5440 clock initialization complete\n");
-}
-CLK_OF_DECLARE(exynos5440_clk, "samsung,exynos5440-clock", exynos5440_clk_init);
index fb249a1637a59545acb0a44633407b8dcd23ac55..71a122b2dc67eb6c4324da73ea75860117067160 100644 (file)
@@ -708,6 +708,7 @@ static const struct omap_clkctrl_reg_data dra7_wkupaon_clkctrl_regs[] __initcons
        { DRA7_COUNTER_32K_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" },
        { DRA7_UART10_CLKCTRL, dra7_uart10_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0060:24" },
        { DRA7_DCAN1_CLKCTRL, dra7_dcan1_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0068:24" },
+       { DRA7_ADC_CLKCTRL, NULL, CLKF_SW_SUP, "mcan_clk"},
        { 0 },
 };
 
index fb62f393800825f1fa4433ea14a7931dfb6409d6..3a0996f2d5564054d782edf83224f425e3799059 100644 (file)
@@ -46,7 +46,7 @@ static int st_clk_probe(struct platform_device *pdev)
                clk_oscout1_parents, ARRAY_SIZE(clk_oscout1_parents),
                0, st_data->base + CLKDRVSTR2, OSCOUT1CLK25MHZ, 3, 0, NULL);
 
-       clk_set_parent(hws[ST_CLK_MUX]->clk, hws[ST_CLK_25M]->clk);
+       clk_set_parent(hws[ST_CLK_MUX]->clk, hws[ST_CLK_48M]->clk);
 
        hws[ST_CLK_GATE] = clk_hw_register_gate(NULL, "oscout1", "oscout1_mux",
                0, st_data->base + MISCCLKCNTL1, OSCCLKENB,
index 52f5f1a2040c38002885c1e804be3d8721bcac6f..0cd8eb76ad592b9e3c5531380c6f74e4d539b594 100644 (file)
@@ -71,20 +71,6 @@ config ARM_BRCMSTB_AVS_CPUFREQ
 
          Say Y, if you have a Broadcom SoC with AVS support for DFS or DVFS.
 
-config ARM_EXYNOS5440_CPUFREQ
-       tristate "SAMSUNG EXYNOS5440"
-       depends on SOC_EXYNOS5440
-       depends on HAVE_CLK && OF
-       select PM_OPP
-       default y
-       help
-         This adds the CPUFreq driver for Samsung EXYNOS5440
-         SoC. The nature of exynos5440 clock controller is
-         different than previous exynos controllers so not using
-         the common exynos framework.
-
-         If in doubt, say N.
-
 config ARM_HIGHBANK_CPUFREQ
        tristate "Calxeda Highbank-based"
        depends on ARCH_HIGHBANK && CPUFREQ_DT && REGULATOR
index fb4a2ecac43bf5bb360ba339bcb7924a482eb09d..c1ffeabe4ecfaf50cd56bf4981d3274c12f3d08a 100644 (file)
@@ -56,7 +56,6 @@ obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ) += armada-37xx-cpufreq.o
 obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ)  += brcmstb-avs-cpufreq.o
 obj-$(CONFIG_ACPI_CPPC_CPUFREQ)                += cppc_cpufreq.o
 obj-$(CONFIG_ARCH_DAVINCI)             += davinci-cpufreq.o
-obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ)   += exynos5440-cpufreq.o
 obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ)     += highbank-cpufreq.o
 obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)                += imx6q-cpufreq.o
 obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ)     += kirkwood-cpufreq.o
index 1d50e97d49f192cd8bf1c5eb0ce569e9641cf43e..6d53f7d9fc7a92d415b507f9b8facdb3f4143b17 100644 (file)
@@ -555,12 +555,20 @@ EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_stop);
 
 void cpufreq_dbs_governor_limits(struct cpufreq_policy *policy)
 {
-       struct policy_dbs_info *policy_dbs = policy->governor_data;
+       struct policy_dbs_info *policy_dbs;
+
+       /* Protect gov->gdbs_data against cpufreq_dbs_governor_exit() */
+       mutex_lock(&gov_dbs_data_mutex);
+       policy_dbs = policy->governor_data;
+       if (!policy_dbs)
+               goto out;
 
        mutex_lock(&policy_dbs->update_mutex);
        cpufreq_policy_apply_limits(policy);
        gov_update_sample_delay(policy_dbs, 0);
-
        mutex_unlock(&policy_dbs->update_mutex);
+
+out:
+       mutex_unlock(&gov_dbs_data_mutex);
 }
 EXPORT_SYMBOL_GPL(cpufreq_dbs_governor_limits);
diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c
deleted file mode 100644 (file)
index 932caa3..0000000
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * Copyright (c) 2013 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Amit Daniel Kachhap <amit.daniel@samsung.com>
- *
- * EXYNOS5440 - CPU frequency scaling 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/clk.h>
-#include <linux/cpu.h>
-#include <linux/cpufreq.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/pm_opp.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-/* Register definitions */
-#define XMU_DVFS_CTRL          0x0060
-#define XMU_PMU_P0_7           0x0064
-#define XMU_C0_3_PSTATE                0x0090
-#define XMU_P_LIMIT            0x00a0
-#define XMU_P_STATUS           0x00a4
-#define XMU_PMUEVTEN           0x00d0
-#define XMU_PMUIRQEN           0x00d4
-#define XMU_PMUIRQ             0x00d8
-
-/* PMU mask and shift definations */
-#define P_VALUE_MASK           0x7
-
-#define XMU_DVFS_CTRL_EN_SHIFT 0
-
-#define P0_7_CPUCLKDEV_SHIFT   21
-#define P0_7_CPUCLKDEV_MASK    0x7
-#define P0_7_ATBCLKDEV_SHIFT   18
-#define P0_7_ATBCLKDEV_MASK    0x7
-#define P0_7_CSCLKDEV_SHIFT    15
-#define P0_7_CSCLKDEV_MASK     0x7
-#define P0_7_CPUEMA_SHIFT      28
-#define P0_7_CPUEMA_MASK       0xf
-#define P0_7_L2EMA_SHIFT       24
-#define P0_7_L2EMA_MASK                0xf
-#define P0_7_VDD_SHIFT         8
-#define P0_7_VDD_MASK          0x7f
-#define P0_7_FREQ_SHIFT                0
-#define P0_7_FREQ_MASK         0xff
-
-#define C0_3_PSTATE_VALID_SHIFT        8
-#define C0_3_PSTATE_CURR_SHIFT 4
-#define C0_3_PSTATE_NEW_SHIFT  0
-
-#define PSTATE_CHANGED_EVTEN_SHIFT     0
-
-#define PSTATE_CHANGED_IRQEN_SHIFT     0
-
-#define PSTATE_CHANGED_SHIFT           0
-
-/* some constant values for clock divider calculation */
-#define CPU_DIV_FREQ_MAX       500
-#define CPU_DBG_FREQ_MAX       375
-#define CPU_ATB_FREQ_MAX       500
-
-#define PMIC_LOW_VOLT          0x30
-#define PMIC_HIGH_VOLT         0x28
-
-#define CPUEMA_HIGH            0x2
-#define CPUEMA_MID             0x4
-#define CPUEMA_LOW             0x7
-
-#define L2EMA_HIGH             0x1
-#define L2EMA_MID              0x3
-#define L2EMA_LOW              0x4
-
-#define DIV_TAB_MAX    2
-/* frequency unit is 20MHZ */
-#define FREQ_UNIT      20
-#define MAX_VOLTAGE    1550000 /* In microvolt */
-#define VOLTAGE_STEP   12500   /* In microvolt */
-
-#define CPUFREQ_NAME           "exynos5440_dvfs"
-#define DEF_TRANS_LATENCY      100000
-
-enum cpufreq_level_index {
-       L0, L1, L2, L3, L4,
-       L5, L6, L7, L8, L9,
-};
-#define CPUFREQ_LEVEL_END      (L7 + 1)
-
-struct exynos_dvfs_data {
-       void __iomem *base;
-       struct resource *mem;
-       int irq;
-       struct clk *cpu_clk;
-       unsigned int latency;
-       struct cpufreq_frequency_table *freq_table;
-       unsigned int freq_count;
-       struct device *dev;
-       bool dvfs_enabled;
-       struct work_struct irq_work;
-};
-
-static struct exynos_dvfs_data *dvfs_info;
-static DEFINE_MUTEX(cpufreq_lock);
-static struct cpufreq_freqs freqs;
-
-static int init_div_table(void)
-{
-       struct cpufreq_frequency_table *pos, *freq_tbl = dvfs_info->freq_table;
-       unsigned int tmp, clk_div, ema_div, freq, volt_id, idx;
-       struct dev_pm_opp *opp;
-
-       cpufreq_for_each_entry_idx(pos, freq_tbl, idx) {
-               opp = dev_pm_opp_find_freq_exact(dvfs_info->dev,
-                                       pos->frequency * 1000, true);
-               if (IS_ERR(opp)) {
-                       dev_err(dvfs_info->dev,
-                               "failed to find valid OPP for %u KHZ\n",
-                               pos->frequency);
-                       return PTR_ERR(opp);
-               }
-
-               freq = pos->frequency / 1000; /* In MHZ */
-               clk_div = ((freq / CPU_DIV_FREQ_MAX) & P0_7_CPUCLKDEV_MASK)
-                                       << P0_7_CPUCLKDEV_SHIFT;
-               clk_div |= ((freq / CPU_ATB_FREQ_MAX) & P0_7_ATBCLKDEV_MASK)
-                                       << P0_7_ATBCLKDEV_SHIFT;
-               clk_div |= ((freq / CPU_DBG_FREQ_MAX) & P0_7_CSCLKDEV_MASK)
-                                       << P0_7_CSCLKDEV_SHIFT;
-
-               /* Calculate EMA */
-               volt_id = dev_pm_opp_get_voltage(opp);
-
-               volt_id = (MAX_VOLTAGE - volt_id) / VOLTAGE_STEP;
-               if (volt_id < PMIC_HIGH_VOLT) {
-                       ema_div = (CPUEMA_HIGH << P0_7_CPUEMA_SHIFT) |
-                               (L2EMA_HIGH << P0_7_L2EMA_SHIFT);
-               } else if (volt_id > PMIC_LOW_VOLT) {
-                       ema_div = (CPUEMA_LOW << P0_7_CPUEMA_SHIFT) |
-                               (L2EMA_LOW << P0_7_L2EMA_SHIFT);
-               } else {
-                       ema_div = (CPUEMA_MID << P0_7_CPUEMA_SHIFT) |
-                               (L2EMA_MID << P0_7_L2EMA_SHIFT);
-               }
-
-               tmp = (clk_div | ema_div | (volt_id << P0_7_VDD_SHIFT)
-                       | ((freq / FREQ_UNIT) << P0_7_FREQ_SHIFT));
-
-               __raw_writel(tmp, dvfs_info->base + XMU_PMU_P0_7 + 4 * idx);
-               dev_pm_opp_put(opp);
-       }
-
-       return 0;
-}
-
-static void exynos_enable_dvfs(unsigned int cur_frequency)
-{
-       unsigned int tmp, cpu;
-       struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table;
-       struct cpufreq_frequency_table *pos;
-       /* Disable DVFS */
-       __raw_writel(0, dvfs_info->base + XMU_DVFS_CTRL);
-
-       /* Enable PSTATE Change Event */
-       tmp = __raw_readl(dvfs_info->base + XMU_PMUEVTEN);
-       tmp |= (1 << PSTATE_CHANGED_EVTEN_SHIFT);
-       __raw_writel(tmp, dvfs_info->base + XMU_PMUEVTEN);
-
-       /* Enable PSTATE Change IRQ */
-       tmp = __raw_readl(dvfs_info->base + XMU_PMUIRQEN);
-       tmp |= (1 << PSTATE_CHANGED_IRQEN_SHIFT);
-       __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQEN);
-
-       /* Set initial performance index */
-       cpufreq_for_each_entry(pos, freq_table)
-               if (pos->frequency == cur_frequency)
-                       break;
-
-       if (pos->frequency == CPUFREQ_TABLE_END) {
-               dev_crit(dvfs_info->dev, "Boot up frequency not supported\n");
-               /* Assign the highest frequency */
-               pos = freq_table;
-               cur_frequency = pos->frequency;
-       }
-
-       dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ",
-                                               cur_frequency);
-
-       for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) {
-               tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4);
-               tmp &= ~(P_VALUE_MASK << C0_3_PSTATE_NEW_SHIFT);
-               tmp |= ((pos - freq_table) << C0_3_PSTATE_NEW_SHIFT);
-               __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4);
-       }
-
-       /* Enable DVFS */
-       __raw_writel(1 << XMU_DVFS_CTRL_EN_SHIFT,
-                               dvfs_info->base + XMU_DVFS_CTRL);
-}
-
-static int exynos_target(struct cpufreq_policy *policy, unsigned int index)
-{
-       unsigned int tmp;
-       int i;
-       struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table;
-
-       mutex_lock(&cpufreq_lock);
-
-       freqs.old = policy->cur;
-       freqs.new = freq_table[index].frequency;
-
-       cpufreq_freq_transition_begin(policy, &freqs);
-
-       /* Set the target frequency in all C0_3_PSTATE register */
-       for_each_cpu(i, policy->cpus) {
-               tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + i * 4);
-               tmp &= ~(P_VALUE_MASK << C0_3_PSTATE_NEW_SHIFT);
-               tmp |= (index << C0_3_PSTATE_NEW_SHIFT);
-
-               __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + i * 4);
-       }
-       mutex_unlock(&cpufreq_lock);
-       return 0;
-}
-
-static void exynos_cpufreq_work(struct work_struct *work)
-{
-       unsigned int cur_pstate, index;
-       struct cpufreq_policy *policy = cpufreq_cpu_get(0); /* boot CPU */
-       struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table;
-
-       /* Ensure we can access cpufreq structures */
-       if (unlikely(dvfs_info->dvfs_enabled == false))
-               goto skip_work;
-
-       mutex_lock(&cpufreq_lock);
-       freqs.old = policy->cur;
-
-       cur_pstate = __raw_readl(dvfs_info->base + XMU_P_STATUS);
-       if (cur_pstate >> C0_3_PSTATE_VALID_SHIFT & 0x1)
-               index = (cur_pstate >> C0_3_PSTATE_CURR_SHIFT) & P_VALUE_MASK;
-       else
-               index = (cur_pstate >> C0_3_PSTATE_NEW_SHIFT) & P_VALUE_MASK;
-
-       if (likely(index < dvfs_info->freq_count)) {
-               freqs.new = freq_table[index].frequency;
-       } else {
-               dev_crit(dvfs_info->dev, "New frequency out of range\n");
-               freqs.new = freqs.old;
-       }
-       cpufreq_freq_transition_end(policy, &freqs, 0);
-
-       cpufreq_cpu_put(policy);
-       mutex_unlock(&cpufreq_lock);
-skip_work:
-       enable_irq(dvfs_info->irq);
-}
-
-static irqreturn_t exynos_cpufreq_irq(int irq, void *id)
-{
-       unsigned int tmp;
-
-       tmp = __raw_readl(dvfs_info->base + XMU_PMUIRQ);
-       if (tmp >> PSTATE_CHANGED_SHIFT & 0x1) {
-               __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQ);
-               disable_irq_nosync(irq);
-               schedule_work(&dvfs_info->irq_work);
-       }
-       return IRQ_HANDLED;
-}
-
-static void exynos_sort_descend_freq_table(void)
-{
-       struct cpufreq_frequency_table *freq_tbl = dvfs_info->freq_table;
-       int i = 0, index;
-       unsigned int tmp_freq;
-       /*
-        * Exynos5440 clock controller state logic expects the cpufreq table to
-        * be in descending order. But the OPP library constructs the table in
-        * ascending order. So to make the table descending we just need to
-        * swap the i element with the N - i element.
-        */
-       for (i = 0; i < dvfs_info->freq_count / 2; i++) {
-               index = dvfs_info->freq_count - i - 1;
-               tmp_freq = freq_tbl[i].frequency;
-               freq_tbl[i].frequency = freq_tbl[index].frequency;
-               freq_tbl[index].frequency = tmp_freq;
-       }
-}
-
-static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
-{
-       policy->clk = dvfs_info->cpu_clk;
-       return cpufreq_generic_init(policy, dvfs_info->freq_table,
-                       dvfs_info->latency);
-}
-
-static struct cpufreq_driver exynos_driver = {
-       .flags          = CPUFREQ_STICKY | CPUFREQ_ASYNC_NOTIFICATION |
-                               CPUFREQ_NEED_INITIAL_FREQ_CHECK,
-       .verify         = cpufreq_generic_frequency_table_verify,
-       .target_index   = exynos_target,
-       .get            = cpufreq_generic_get,
-       .init           = exynos_cpufreq_cpu_init,
-       .name           = CPUFREQ_NAME,
-       .attr           = cpufreq_generic_attr,
-};
-
-static const struct of_device_id exynos_cpufreq_match[] = {
-       {
-               .compatible = "samsung,exynos5440-cpufreq",
-       },
-       {},
-};
-MODULE_DEVICE_TABLE(of, exynos_cpufreq_match);
-
-static int exynos_cpufreq_probe(struct platform_device *pdev)
-{
-       int ret = -EINVAL;
-       struct device_node *np;
-       struct resource res;
-       unsigned int cur_frequency;
-
-       np = pdev->dev.of_node;
-       if (!np)
-               return -ENODEV;
-
-       dvfs_info = devm_kzalloc(&pdev->dev, sizeof(*dvfs_info), GFP_KERNEL);
-       if (!dvfs_info) {
-               ret = -ENOMEM;
-               goto err_put_node;
-       }
-
-       dvfs_info->dev = &pdev->dev;
-
-       ret = of_address_to_resource(np, 0, &res);
-       if (ret)
-               goto err_put_node;
-
-       dvfs_info->base = devm_ioremap_resource(dvfs_info->dev, &res);
-       if (IS_ERR(dvfs_info->base)) {
-               ret = PTR_ERR(dvfs_info->base);
-               goto err_put_node;
-       }
-
-       dvfs_info->irq = irq_of_parse_and_map(np, 0);
-       if (!dvfs_info->irq) {
-               dev_err(dvfs_info->dev, "No cpufreq irq found\n");
-               ret = -ENODEV;
-               goto err_put_node;
-       }
-
-       ret = dev_pm_opp_of_add_table(dvfs_info->dev);
-       if (ret) {
-               dev_err(dvfs_info->dev, "failed to init OPP table: %d\n", ret);
-               goto err_put_node;
-       }
-
-       ret = dev_pm_opp_init_cpufreq_table(dvfs_info->dev,
-                                           &dvfs_info->freq_table);
-       if (ret) {
-               dev_err(dvfs_info->dev,
-                       "failed to init cpufreq table: %d\n", ret);
-               goto err_free_opp;
-       }
-       dvfs_info->freq_count = dev_pm_opp_get_opp_count(dvfs_info->dev);
-       exynos_sort_descend_freq_table();
-
-       if (of_property_read_u32(np, "clock-latency", &dvfs_info->latency))
-               dvfs_info->latency = DEF_TRANS_LATENCY;
-
-       dvfs_info->cpu_clk = devm_clk_get(dvfs_info->dev, "armclk");
-       if (IS_ERR(dvfs_info->cpu_clk)) {
-               dev_err(dvfs_info->dev, "Failed to get cpu clock\n");
-               ret = PTR_ERR(dvfs_info->cpu_clk);
-               goto err_free_table;
-       }
-
-       cur_frequency = clk_get_rate(dvfs_info->cpu_clk);
-       if (!cur_frequency) {
-               dev_err(dvfs_info->dev, "Failed to get clock rate\n");
-               ret = -EINVAL;
-               goto err_free_table;
-       }
-       cur_frequency /= 1000;
-
-       INIT_WORK(&dvfs_info->irq_work, exynos_cpufreq_work);
-       ret = devm_request_irq(dvfs_info->dev, dvfs_info->irq,
-                               exynos_cpufreq_irq, IRQF_TRIGGER_NONE,
-                               CPUFREQ_NAME, dvfs_info);
-       if (ret) {
-               dev_err(dvfs_info->dev, "Failed to register IRQ\n");
-               goto err_free_table;
-       }
-
-       ret = init_div_table();
-       if (ret) {
-               dev_err(dvfs_info->dev, "Failed to initialise div table\n");
-               goto err_free_table;
-       }
-
-       exynos_enable_dvfs(cur_frequency);
-       ret = cpufreq_register_driver(&exynos_driver);
-       if (ret) {
-               dev_err(dvfs_info->dev,
-                       "%s: failed to register cpufreq driver\n", __func__);
-               goto err_free_table;
-       }
-
-       of_node_put(np);
-       dvfs_info->dvfs_enabled = true;
-       return 0;
-
-err_free_table:
-       dev_pm_opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table);
-err_free_opp:
-       dev_pm_opp_of_remove_table(dvfs_info->dev);
-err_put_node:
-       of_node_put(np);
-       dev_err(&pdev->dev, "%s: failed initialization\n", __func__);
-       return ret;
-}
-
-static int exynos_cpufreq_remove(struct platform_device *pdev)
-{
-       cpufreq_unregister_driver(&exynos_driver);
-       dev_pm_opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table);
-       dev_pm_opp_of_remove_table(dvfs_info->dev);
-       return 0;
-}
-
-static struct platform_driver exynos_cpufreq_platdrv = {
-       .driver = {
-               .name   = "exynos5440-cpufreq",
-               .of_match_table = exynos_cpufreq_match,
-       },
-       .probe          = exynos_cpufreq_probe,
-       .remove         = exynos_cpufreq_remove,
-};
-module_platform_driver(exynos_cpufreq_platdrv);
-
-MODULE_AUTHOR("Amit Daniel Kachhap <amit.daniel@samsung.com>");
-MODULE_DESCRIPTION("Exynos5440 cpufreq driver");
-MODULE_LICENSE("GPL");
index 1aef60d160eb0c6236bee855a9a2cdd244679418..e26a40971b263ed5f5cb113c938f4d9f84109862 100644 (file)
@@ -328,9 +328,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
                unsigned int polling_threshold;
 
                /*
-                * We want to default to C1 (hlt), not to busy polling
-                * unless the timer is happening really really soon, or
-                * C1's exit latency exceeds the user configured limit.
+                * Default to a physical idle state, not to busy polling, unless
+                * a timer is going to trigger really really soon.
                 */
                polling_threshold = max_t(unsigned int, 20, s->target_residency);
                if (data->next_timer_us > polling_threshold &&
@@ -349,14 +348,12 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
                 * If the tick is already stopped, the cost of possible short
                 * idle duration misprediction is much higher, because the CPU
                 * may be stuck in a shallow idle state for a long time as a
-                * result of it.  In that case say we might mispredict and try
-                * to force the CPU into a state for which we would have stopped
-                * the tick, unless a timer is going to expire really soon
-                * anyway.
+                * result of it.  In that case say we might mispredict and use
+                * the known time till the closest timer event for the idle
+                * state selection.
                 */
                if (data->predicted_us < TICK_USEC)
-                       data->predicted_us = min_t(unsigned int, TICK_USEC,
-                                                  ktime_to_us(delta_next));
+                       data->predicted_us = ktime_to_us(delta_next);
        } else {
                /*
                 * Use the performance multiplier and the user-configurable
@@ -381,8 +378,33 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
                        continue;
                if (idx == -1)
                        idx = i; /* first enabled state */
-               if (s->target_residency > data->predicted_us)
-                       break;
+               if (s->target_residency > data->predicted_us) {
+                       if (data->predicted_us < TICK_USEC)
+                               break;
+
+                       if (!tick_nohz_tick_stopped()) {
+                               /*
+                                * If the state selected so far is shallow,
+                                * waking up early won't hurt, so retain the
+                                * tick in that case and let the governor run
+                                * again in the next iteration of the loop.
+                                */
+                               expected_interval = drv->states[idx].target_residency;
+                               break;
+                       }
+
+                       /*
+                        * If the state selected so far is shallow and this
+                        * state's target residency matches the time till the
+                        * closest timer event, select this one to avoid getting
+                        * stuck in the shallow one for too long.
+                        */
+                       if (drv->states[idx].target_residency < TICK_USEC &&
+                           s->target_residency <= ktime_to_us(delta_next))
+                               idx = i;
+
+                       goto out;
+               }
                if (s->exit_latency > latency_req) {
                        /*
                         * If we break out of the loop for latency reasons, use
@@ -403,14 +425,13 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
         * Don't stop the tick if the selected state is a polling one or if the
         * expected idle duration is shorter than the tick period length.
         */
-       if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) ||
-           expected_interval < TICK_USEC) {
+       if (((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) ||
+            expected_interval < TICK_USEC) && !tick_nohz_tick_stopped()) {
                unsigned int delta_next_us = ktime_to_us(delta_next);
 
                *stop_tick = false;
 
-               if (!tick_nohz_tick_stopped() && idx > 0 &&
-                   drv->states[idx].target_residency > delta_next_us) {
+               if (idx > 0 && drv->states[idx].target_residency > delta_next_us) {
                        /*
                         * The tick is not going to be stopped and the target
                         * residency of the state to be returned is not within
@@ -418,8 +439,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
                         * tick, so try to correct that.
                         */
                        for (i = idx - 1; i >= 0; i--) {
-                           if (drv->states[i].disabled ||
-                               dev->states_usage[i].disable)
+                               if (drv->states[i].disabled ||
+                                   dev->states_usage[i].disable)
                                        continue;
 
                                idx = i;
@@ -429,6 +450,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
                }
        }
 
+out:
        data->last_state_idx = idx;
 
        return data->last_state_idx;
index 6e61cc93c2b0da3be9d2f68bf8e063deaf122054..d7aa7d7ff102fab24aa86bd1d13190348973a1bf 100644 (file)
@@ -679,10 +679,8 @@ static int xts_ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
        int ret = 0;
 
        if (keylen != 2 * AES_MIN_KEY_SIZE  && keylen != 2 * AES_MAX_KEY_SIZE) {
-               crypto_ablkcipher_set_flags(ablkcipher,
-                                           CRYPTO_TFM_RES_BAD_KEY_LEN);
                dev_err(jrdev, "key size mismatch\n");
-               return -EINVAL;
+               goto badkey;
        }
 
        ctx->cdata.keylen = keylen;
@@ -715,7 +713,7 @@ static int xts_ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
        return ret;
 badkey:
        crypto_ablkcipher_set_flags(ablkcipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
-       return 0;
+       return -EINVAL;
 }
 
 /*
index 578ea63a31098e46a7e32554f2c7acff5f8137cd..f26d62e5533a7a5a622d6e2f0661dcb3d0ebdc40 100644 (file)
@@ -71,8 +71,8 @@ static void rsa_priv_f2_unmap(struct device *dev, struct rsa_edesc *edesc,
        dma_unmap_single(dev, pdb->d_dma, key->d_sz, DMA_TO_DEVICE);
        dma_unmap_single(dev, pdb->p_dma, p_sz, DMA_TO_DEVICE);
        dma_unmap_single(dev, pdb->q_dma, q_sz, DMA_TO_DEVICE);
-       dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
-       dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_TO_DEVICE);
+       dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL);
+       dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_BIDIRECTIONAL);
 }
 
 static void rsa_priv_f3_unmap(struct device *dev, struct rsa_edesc *edesc,
@@ -90,8 +90,8 @@ static void rsa_priv_f3_unmap(struct device *dev, struct rsa_edesc *edesc,
        dma_unmap_single(dev, pdb->dp_dma, p_sz, DMA_TO_DEVICE);
        dma_unmap_single(dev, pdb->dq_dma, q_sz, DMA_TO_DEVICE);
        dma_unmap_single(dev, pdb->c_dma, p_sz, DMA_TO_DEVICE);
-       dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
-       dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_TO_DEVICE);
+       dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL);
+       dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_BIDIRECTIONAL);
 }
 
 /* RSA Job Completion handler */
@@ -417,13 +417,13 @@ static int set_rsa_priv_f2_pdb(struct akcipher_request *req,
                goto unmap_p;
        }
 
-       pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_TO_DEVICE);
+       pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_BIDIRECTIONAL);
        if (dma_mapping_error(dev, pdb->tmp1_dma)) {
                dev_err(dev, "Unable to map RSA tmp1 memory\n");
                goto unmap_q;
        }
 
-       pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_TO_DEVICE);
+       pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_BIDIRECTIONAL);
        if (dma_mapping_error(dev, pdb->tmp2_dma)) {
                dev_err(dev, "Unable to map RSA tmp2 memory\n");
                goto unmap_tmp1;
@@ -451,7 +451,7 @@ static int set_rsa_priv_f2_pdb(struct akcipher_request *req,
        return 0;
 
 unmap_tmp1:
-       dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
+       dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL);
 unmap_q:
        dma_unmap_single(dev, pdb->q_dma, q_sz, DMA_TO_DEVICE);
 unmap_p:
@@ -504,13 +504,13 @@ static int set_rsa_priv_f3_pdb(struct akcipher_request *req,
                goto unmap_dq;
        }
 
-       pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_TO_DEVICE);
+       pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_BIDIRECTIONAL);
        if (dma_mapping_error(dev, pdb->tmp1_dma)) {
                dev_err(dev, "Unable to map RSA tmp1 memory\n");
                goto unmap_qinv;
        }
 
-       pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_TO_DEVICE);
+       pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_BIDIRECTIONAL);
        if (dma_mapping_error(dev, pdb->tmp2_dma)) {
                dev_err(dev, "Unable to map RSA tmp2 memory\n");
                goto unmap_tmp1;
@@ -538,7 +538,7 @@ static int set_rsa_priv_f3_pdb(struct akcipher_request *req,
        return 0;
 
 unmap_tmp1:
-       dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
+       dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL);
 unmap_qinv:
        dma_unmap_single(dev, pdb->c_dma, p_sz, DMA_TO_DEVICE);
 unmap_dq:
index f4f258075b895a8c55fbd836d35b1b6b399beed8..acdd72016ffe154fab70f8de0ff43f6251b50e28 100644 (file)
@@ -190,7 +190,8 @@ static void caam_jr_dequeue(unsigned long devarg)
                BUG_ON(CIRC_CNT(head, tail + i, JOBR_DEPTH) <= 0);
 
                /* Unmap just-run descriptor so we can post-process */
-               dma_unmap_single(dev, jrp->outring[hw_idx].desc,
+               dma_unmap_single(dev,
+                                caam_dma_to_cpu(jrp->outring[hw_idx].desc),
                                 jrp->entinfo[sw_idx].desc_size,
                                 DMA_TO_DEVICE);
 
index 31b4407571460c6a8e7d1b4491a3209c2c4334fc..b5b4c12179dfd707fc920b157a119c3e01f2889a 100644 (file)
@@ -35,7 +35,7 @@
 #ifndef _SG_SW_QM2_H_
 #define _SG_SW_QM2_H_
 
-#include "../../../drivers/staging/fsl-mc/include/dpaa2-fd.h"
+#include <soc/fsl/dpaa2-fd.h>
 
 static inline void dma_to_qm_sg_one(struct dpaa2_sg_entry *qm_sg_ptr,
                                    dma_addr_t dma, u32 len, u16 offset)
index e586ffab83585a60e40c6b55206945abc5067ac4..dbfa9fce33e07d9df7de9e0cc62d853f5b0d094a 100644 (file)
@@ -12,7 +12,7 @@
 #include "ctrl.h"
 #include "regs.h"
 #include "sg_sw_qm2.h"
-#include "../../../drivers/staging/fsl-mc/include/dpaa2-fd.h"
+#include <soc/fsl/dpaa2-fd.h>
 
 struct sec4_sg_entry {
        u64 ptr;
index 9a476bb6d4c7eace932edb09b040098eccee7aa0..af596455b420f60d68096b8f2d4e9c71745785fc 100644 (file)
@@ -35,6 +35,7 @@ struct nitrox_cmdq {
        /* requests in backlog queues */
        atomic_t backlog_count;
 
+       int write_idx;
        /* command size 32B/64B */
        u8 instr_size;
        u8 qno;
@@ -87,7 +88,7 @@ struct nitrox_bh {
        struct bh_data *slc;
 };
 
-/* NITROX-5 driver state */
+/* NITROX-V driver state */
 #define NITROX_UCODE_LOADED    0
 #define NITROX_READY           1
 
index ebe267379ac95ede190832e8a9c0a1df174e6866..4d31df07777f63129715175f7aa4bc84b50fe49b 100644 (file)
@@ -36,6 +36,7 @@ static int cmdq_common_init(struct nitrox_cmdq *cmdq)
        cmdq->head = PTR_ALIGN(cmdq->head_unaligned, PKT_IN_ALIGN);
        cmdq->dma = PTR_ALIGN(cmdq->dma_unaligned, PKT_IN_ALIGN);
        cmdq->qsize = (qsize + PKT_IN_ALIGN);
+       cmdq->write_idx = 0;
 
        spin_lock_init(&cmdq->response_lock);
        spin_lock_init(&cmdq->cmdq_lock);
index deaefd532aaa155755faba33bba5fbee7b11430f..4a362fc22f6287638f749dfeacde20bc62517896 100644 (file)
  *   Invalid flag options in AES-CCM IV.
  */
 
+static inline int incr_index(int index, int count, int max)
+{
+       if ((index + count) >= max)
+               index = index + count - max;
+       else
+               index += count;
+
+       return index;
+}
+
 /**
  * dma_free_sglist - unmap and free the sg lists.
  * @ndev: N5 device
@@ -426,30 +436,29 @@ static void post_se_instr(struct nitrox_softreq *sr,
                          struct nitrox_cmdq *cmdq)
 {
        struct nitrox_device *ndev = sr->ndev;
-       union nps_pkt_in_instr_baoff_dbell pkt_in_baoff_dbell;
-       u64 offset;
+       int idx;
        u8 *ent;
 
        spin_lock_bh(&cmdq->cmdq_lock);
 
-       /* get the next write offset */
-       offset = NPS_PKT_IN_INSTR_BAOFF_DBELLX(cmdq->qno);
-       pkt_in_baoff_dbell.value = nitrox_read_csr(ndev, offset);
+       idx = cmdq->write_idx;
        /* copy the instruction */
-       ent = cmdq->head + pkt_in_baoff_dbell.s.aoff;
+       ent = cmdq->head + (idx * cmdq->instr_size);
        memcpy(ent, &sr->instr, cmdq->instr_size);
-       /* flush the command queue updates */
-       dma_wmb();
 
-       sr->tstamp = jiffies;
        atomic_set(&sr->status, REQ_POSTED);
        response_list_add(sr, cmdq);
+       sr->tstamp = jiffies;
+       /* flush the command queue updates */
+       dma_wmb();
 
        /* Ring doorbell with count 1 */
        writeq(1, cmdq->dbell_csr_addr);
        /* orders the doorbell rings */
        mmiowb();
 
+       cmdq->write_idx = incr_index(idx, 1, ndev->qlen);
+
        spin_unlock_bh(&cmdq->cmdq_lock);
 }
 
@@ -459,6 +468,9 @@ static int post_backlog_cmds(struct nitrox_cmdq *cmdq)
        struct nitrox_softreq *sr, *tmp;
        int ret = 0;
 
+       if (!atomic_read(&cmdq->backlog_count))
+               return 0;
+
        spin_lock_bh(&cmdq->backlog_lock);
 
        list_for_each_entry_safe(sr, tmp, &cmdq->backlog_head, backlog) {
@@ -466,7 +478,7 @@ static int post_backlog_cmds(struct nitrox_cmdq *cmdq)
 
                /* submit until space available */
                if (unlikely(cmdq_full(cmdq, ndev->qlen))) {
-                       ret = -EBUSY;
+                       ret = -ENOSPC;
                        break;
                }
                /* delete from backlog list */
@@ -491,23 +503,20 @@ static int nitrox_enqueue_request(struct nitrox_softreq *sr)
 {
        struct nitrox_cmdq *cmdq = sr->cmdq;
        struct nitrox_device *ndev = sr->ndev;
-       int ret = -EBUSY;
+
+       /* try to post backlog requests */
+       post_backlog_cmds(cmdq);
 
        if (unlikely(cmdq_full(cmdq, ndev->qlen))) {
                if (!(sr->flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
-                       return -EAGAIN;
-
+                       return -ENOSPC;
+               /* add to backlog list */
                backlog_list_add(sr, cmdq);
-       } else {
-               ret = post_backlog_cmds(cmdq);
-               if (ret) {
-                       backlog_list_add(sr, cmdq);
-                       return ret;
-               }
-               post_se_instr(sr, cmdq);
-               ret = -EINPROGRESS;
+               return -EBUSY;
        }
-       return ret;
+       post_se_instr(sr, cmdq);
+
+       return -EINPROGRESS;
 }
 
 /**
@@ -624,11 +633,9 @@ int nitrox_process_se_request(struct nitrox_device *ndev,
         */
        sr->instr.fdata[0] = *((u64 *)&req->gph);
        sr->instr.fdata[1] = 0;
-       /* flush the soft_req changes before posting the cmd */
-       wmb();
 
        ret = nitrox_enqueue_request(sr);
-       if (ret == -EAGAIN)
+       if (ret == -ENOSPC)
                goto send_fail;
 
        return ret;
index a53a0e6ba024e8175338859c634c81e94859cd13..7725b6ee14efb2ecc89d9c0822aa19903284d3f5 100644 (file)
@@ -96,6 +96,10 @@ enum csk_flags {
        CSK_CONN_INLINE,        /* Connection on HW */
 };
 
+enum chtls_cdev_state {
+       CHTLS_CDEV_STATE_UP = 1
+};
+
 struct listen_ctx {
        struct sock *lsk;
        struct chtls_dev *cdev;
@@ -146,6 +150,7 @@ struct chtls_dev {
        unsigned int send_page_order;
        int max_host_sndbuf;
        struct key_map kmap;
+       unsigned int cdev_state;
 };
 
 struct chtls_hws {
index 9b07f9165658beeb07a29edc4e00c3849176d2ec..f59b044ebd25528864d055c04b90f67b83248eac 100644 (file)
@@ -160,6 +160,7 @@ static void chtls_register_dev(struct chtls_dev *cdev)
        tlsdev->hash = chtls_create_hash;
        tlsdev->unhash = chtls_destroy_hash;
        tls_register_device(&cdev->tlsdev);
+       cdev->cdev_state = CHTLS_CDEV_STATE_UP;
 }
 
 static void chtls_unregister_dev(struct chtls_dev *cdev)
@@ -281,8 +282,10 @@ static void chtls_free_all_uld(void)
        struct chtls_dev *cdev, *tmp;
 
        mutex_lock(&cdev_mutex);
-       list_for_each_entry_safe(cdev, tmp, &cdev_list, list)
-               chtls_free_uld(cdev);
+       list_for_each_entry_safe(cdev, tmp, &cdev_list, list) {
+               if (cdev->cdev_state == CHTLS_CDEV_STATE_UP)
+                       chtls_free_uld(cdev);
+       }
        mutex_unlock(&cdev_mutex);
 }
 
index 5285ece4f33a36df39bfd18068dd14ce6a1213db..b71895871be3f1f2ec0b15d19d4087a16f40016f 100644 (file)
@@ -107,24 +107,23 @@ static int p8_aes_cbc_encrypt(struct blkcipher_desc *desc,
                ret = crypto_skcipher_encrypt(req);
                skcipher_request_zero(req);
        } else {
-               preempt_disable();
-               pagefault_disable();
-               enable_kernel_vsx();
-
                blkcipher_walk_init(&walk, dst, src, nbytes);
                ret = blkcipher_walk_virt(desc, &walk);
                while ((nbytes = walk.nbytes)) {
+                       preempt_disable();
+                       pagefault_disable();
+                       enable_kernel_vsx();
                        aes_p8_cbc_encrypt(walk.src.virt.addr,
                                           walk.dst.virt.addr,
                                           nbytes & AES_BLOCK_MASK,
                                           &ctx->enc_key, walk.iv, 1);
+                       disable_kernel_vsx();
+                       pagefault_enable();
+                       preempt_enable();
+
                        nbytes &= AES_BLOCK_SIZE - 1;
                        ret = blkcipher_walk_done(desc, &walk, nbytes);
                }
-
-               disable_kernel_vsx();
-               pagefault_enable();
-               preempt_enable();
        }
 
        return ret;
@@ -147,24 +146,23 @@ static int p8_aes_cbc_decrypt(struct blkcipher_desc *desc,
                ret = crypto_skcipher_decrypt(req);
                skcipher_request_zero(req);
        } else {
-               preempt_disable();
-               pagefault_disable();
-               enable_kernel_vsx();
-
                blkcipher_walk_init(&walk, dst, src, nbytes);
                ret = blkcipher_walk_virt(desc, &walk);
                while ((nbytes = walk.nbytes)) {
+                       preempt_disable();
+                       pagefault_disable();
+                       enable_kernel_vsx();
                        aes_p8_cbc_encrypt(walk.src.virt.addr,
                                           walk.dst.virt.addr,
                                           nbytes & AES_BLOCK_MASK,
                                           &ctx->dec_key, walk.iv, 0);
+                       disable_kernel_vsx();
+                       pagefault_enable();
+                       preempt_enable();
+
                        nbytes &= AES_BLOCK_SIZE - 1;
                        ret = blkcipher_walk_done(desc, &walk, nbytes);
                }
-
-               disable_kernel_vsx();
-               pagefault_enable();
-               preempt_enable();
        }
 
        return ret;
index 8bd9aff0f55fba6639b67147cf97c2fcfce12bfc..e9954a7d46944d36cd2aeffdfd8202b54c793d71 100644 (file)
@@ -116,32 +116,39 @@ static int p8_aes_xts_crypt(struct blkcipher_desc *desc,
                ret = enc? crypto_skcipher_encrypt(req) : crypto_skcipher_decrypt(req);
                skcipher_request_zero(req);
        } else {
+               blkcipher_walk_init(&walk, dst, src, nbytes);
+
+               ret = blkcipher_walk_virt(desc, &walk);
+
                preempt_disable();
                pagefault_disable();
                enable_kernel_vsx();
 
-               blkcipher_walk_init(&walk, dst, src, nbytes);
-
-               ret = blkcipher_walk_virt(desc, &walk);
                iv = walk.iv;
                memset(tweak, 0, AES_BLOCK_SIZE);
                aes_p8_encrypt(iv, tweak, &ctx->tweak_key);
 
+               disable_kernel_vsx();
+               pagefault_enable();
+               preempt_enable();
+
                while ((nbytes = walk.nbytes)) {
+                       preempt_disable();
+                       pagefault_disable();
+                       enable_kernel_vsx();
                        if (enc)
                                aes_p8_xts_encrypt(walk.src.virt.addr, walk.dst.virt.addr,
                                                nbytes & AES_BLOCK_MASK, &ctx->enc_key, NULL, tweak);
                        else
                                aes_p8_xts_decrypt(walk.src.virt.addr, walk.dst.virt.addr,
                                                nbytes & AES_BLOCK_MASK, &ctx->dec_key, NULL, tweak);
+                       disable_kernel_vsx();
+                       pagefault_enable();
+                       preempt_enable();
 
                        nbytes &= AES_BLOCK_SIZE - 1;
                        ret = blkcipher_walk_done(desc, &walk, nbytes);
                }
-
-               disable_kernel_vsx();
-               pagefault_enable();
-               preempt_enable();
        }
        return ret;
 }
index f746af271460071a2c40cd48b64eea03fe88a1e2..38b06503ede0c41699ef7ce0018ff1f4025e5de2 100644 (file)
@@ -129,9 +129,9 @@ $code=<<___;
         le?vperm       $IN,$IN,$IN,$lemask
        vxor            $zero,$zero,$zero
 
-       vpmsumd         $Xl,$IN,$Hl             # H.lo·Xi.lo
-       vpmsumd         $Xm,$IN,$H              # H.hi·Xi.lo+H.lo·Xi.hi
-       vpmsumd         $Xh,$IN,$Hh             # H.hi·Xi.hi
+       vpmsumd         $Xl,$IN,$Hl             # H.lo·Xi.lo
+       vpmsumd         $Xm,$IN,$H              # H.hi·Xi.lo+H.lo·Xi.hi
+       vpmsumd         $Xh,$IN,$Hh             # H.hi·Xi.hi
 
        vpmsumd         $t2,$Xl,$xC2            # 1st phase
 
@@ -187,11 +187,11 @@ $code=<<___;
 .align 5
 Loop:
         subic          $len,$len,16
-       vpmsumd         $Xl,$IN,$Hl             # H.lo·Xi.lo
+       vpmsumd         $Xl,$IN,$Hl             # H.lo·Xi.lo
         subfe.         r0,r0,r0                # borrow?-1:0
-       vpmsumd         $Xm,$IN,$H              # H.hi·Xi.lo+H.lo·Xi.hi
+       vpmsumd         $Xm,$IN,$H              # H.hi·Xi.lo+H.lo·Xi.hi
         and            r0,r0,$len
-       vpmsumd         $Xh,$IN,$Hh             # H.hi·Xi.hi
+       vpmsumd         $Xh,$IN,$Hh             # H.hi·Xi.hi
         add            $inp,$inp,r0
 
        vpmsumd         $t2,$Xl,$xC2            # 1st phase
index 0a2acd7993f0b3a561cf91beb0b4200838f601f4..bbe4d72ca105b001e36b1d09d382ee9e3a89ee7c 100644 (file)
@@ -248,13 +248,12 @@ __weak phys_addr_t dax_pgoff_to_phys(struct dev_dax *dev_dax, pgoff_t pgoff,
        return -1;
 }
 
-static int __dev_dax_pte_fault(struct dev_dax *dev_dax, struct vm_fault *vmf)
+static vm_fault_t __dev_dax_pte_fault(struct dev_dax *dev_dax,
+                               struct vm_fault *vmf, pfn_t *pfn)
 {
        struct device *dev = &dev_dax->dev;
        struct dax_region *dax_region;
-       int rc = VM_FAULT_SIGBUS;
        phys_addr_t phys;
-       pfn_t pfn;
        unsigned int fault_size = PAGE_SIZE;
 
        if (check_vma(dev_dax, vmf->vma, __func__))
@@ -276,26 +275,19 @@ static int __dev_dax_pte_fault(struct dev_dax *dev_dax, struct vm_fault *vmf)
                return VM_FAULT_SIGBUS;
        }
 
-       pfn = phys_to_pfn_t(phys, dax_region->pfn_flags);
-
-       rc = vm_insert_mixed(vmf->vma, vmf->address, pfn);
-
-       if (rc == -ENOMEM)
-               return VM_FAULT_OOM;
-       if (rc < 0 && rc != -EBUSY)
-               return VM_FAULT_SIGBUS;
+       *pfn = phys_to_pfn_t(phys, dax_region->pfn_flags);
 
-       return VM_FAULT_NOPAGE;
+       return vmf_insert_mixed(vmf->vma, vmf->address, *pfn);
 }
 
-static int __dev_dax_pmd_fault(struct dev_dax *dev_dax, struct vm_fault *vmf)
+static vm_fault_t __dev_dax_pmd_fault(struct dev_dax *dev_dax,
+                               struct vm_fault *vmf, pfn_t *pfn)
 {
        unsigned long pmd_addr = vmf->address & PMD_MASK;
        struct device *dev = &dev_dax->dev;
        struct dax_region *dax_region;
        phys_addr_t phys;
        pgoff_t pgoff;
-       pfn_t pfn;
        unsigned int fault_size = PMD_SIZE;
 
        if (check_vma(dev_dax, vmf->vma, __func__))
@@ -331,21 +323,21 @@ static int __dev_dax_pmd_fault(struct dev_dax *dev_dax, struct vm_fault *vmf)
                return VM_FAULT_SIGBUS;
        }
 
-       pfn = phys_to_pfn_t(phys, dax_region->pfn_flags);
+       *pfn = phys_to_pfn_t(phys, dax_region->pfn_flags);
 
-       return vmf_insert_pfn_pmd(vmf->vma, vmf->address, vmf->pmd, pfn,
+       return vmf_insert_pfn_pmd(vmf->vma, vmf->address, vmf->pmd, *pfn,
                        vmf->flags & FAULT_FLAG_WRITE);
 }
 
 #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
-static int __dev_dax_pud_fault(struct dev_dax *dev_dax, struct vm_fault *vmf)
+static vm_fault_t __dev_dax_pud_fault(struct dev_dax *dev_dax,
+                               struct vm_fault *vmf, pfn_t *pfn)
 {
        unsigned long pud_addr = vmf->address & PUD_MASK;
        struct device *dev = &dev_dax->dev;
        struct dax_region *dax_region;
        phys_addr_t phys;
        pgoff_t pgoff;
-       pfn_t pfn;
        unsigned int fault_size = PUD_SIZE;
 
 
@@ -382,23 +374,27 @@ static int __dev_dax_pud_fault(struct dev_dax *dev_dax, struct vm_fault *vmf)
                return VM_FAULT_SIGBUS;
        }
 
-       pfn = phys_to_pfn_t(phys, dax_region->pfn_flags);
+       *pfn = phys_to_pfn_t(phys, dax_region->pfn_flags);
 
-       return vmf_insert_pfn_pud(vmf->vma, vmf->address, vmf->pud, pfn,
+       return vmf_insert_pfn_pud(vmf->vma, vmf->address, vmf->pud, *pfn,
                        vmf->flags & FAULT_FLAG_WRITE);
 }
 #else
-static int __dev_dax_pud_fault(struct dev_dax *dev_dax, struct vm_fault *vmf)
+static vm_fault_t __dev_dax_pud_fault(struct dev_dax *dev_dax,
+                               struct vm_fault *vmf, pfn_t *pfn)
 {
        return VM_FAULT_FALLBACK;
 }
 #endif /* !CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD */
 
-static int dev_dax_huge_fault(struct vm_fault *vmf,
+static vm_fault_t dev_dax_huge_fault(struct vm_fault *vmf,
                enum page_entry_size pe_size)
 {
-       int rc, id;
        struct file *filp = vmf->vma->vm_file;
+       unsigned long fault_size;
+       vm_fault_t rc = VM_FAULT_SIGBUS;
+       int id;
+       pfn_t pfn;
        struct dev_dax *dev_dax = filp->private_data;
 
        dev_dbg(&dev_dax->dev, "%s: %s (%#lx - %#lx) size = %d\n", current->comm,
@@ -408,23 +404,49 @@ static int dev_dax_huge_fault(struct vm_fault *vmf,
        id = dax_read_lock();
        switch (pe_size) {
        case PE_SIZE_PTE:
-               rc = __dev_dax_pte_fault(dev_dax, vmf);
+               fault_size = PAGE_SIZE;
+               rc = __dev_dax_pte_fault(dev_dax, vmf, &pfn);
                break;
        case PE_SIZE_PMD:
-               rc = __dev_dax_pmd_fault(dev_dax, vmf);
+               fault_size = PMD_SIZE;
+               rc = __dev_dax_pmd_fault(dev_dax, vmf, &pfn);
                break;
        case PE_SIZE_PUD:
-               rc = __dev_dax_pud_fault(dev_dax, vmf);
+               fault_size = PUD_SIZE;
+               rc = __dev_dax_pud_fault(dev_dax, vmf, &pfn);
                break;
        default:
                rc = VM_FAULT_SIGBUS;
        }
+
+       if (rc == VM_FAULT_NOPAGE) {
+               unsigned long i;
+               pgoff_t pgoff;
+
+               /*
+                * In the device-dax case the only possibility for a
+                * VM_FAULT_NOPAGE result is when device-dax capacity is
+                * mapped. No need to consider the zero page, or racing
+                * conflicting mappings.
+                */
+               pgoff = linear_page_index(vmf->vma, vmf->address
+                               & ~(fault_size - 1));
+               for (i = 0; i < fault_size / PAGE_SIZE; i++) {
+                       struct page *page;
+
+                       page = pfn_to_page(pfn_t_to_pfn(pfn) + i);
+                       if (page->mapping)
+                               continue;
+                       page->mapping = filp->f_mapping;
+                       page->index = pgoff + i;
+               }
+       }
        dax_read_unlock(id);
 
        return rc;
 }
 
-static int dev_dax_fault(struct vm_fault *vmf)
+static vm_fault_t dev_dax_fault(struct vm_fault *vmf)
 {
        return dev_dax_huge_fault(vmf, PE_SIZE_PTE);
 }
index fd49b24fd6afd344335e38438fce9dd981d928c9..99e2aace8078c87fde81019ccd3380fcccc666ec 100644 (file)
@@ -105,15 +105,19 @@ static int dax_pmem_probe(struct device *dev)
        if (rc)
                return rc;
 
-       rc = devm_add_action_or_reset(dev, dax_pmem_percpu_exit,
-                                                       &dax_pmem->ref);
-       if (rc)
+       rc = devm_add_action(dev, dax_pmem_percpu_exit, &dax_pmem->ref);
+       if (rc) {
+               percpu_ref_exit(&dax_pmem->ref);
                return rc;
+       }
 
        dax_pmem->pgmap.ref = &dax_pmem->ref;
        addr = devm_memremap_pages(dev, &dax_pmem->pgmap);
-       if (IS_ERR(addr))
+       if (IS_ERR(addr)) {
+               devm_remove_action(dev, dax_pmem_percpu_exit, &dax_pmem->ref);
+               percpu_ref_exit(&dax_pmem->ref);
                return PTR_ERR(addr);
+       }
 
        rc = devm_add_action_or_reset(dev, dax_pmem_percpu_kill,
                                                        &dax_pmem->ref);
index 45276abf03aa2bd52aa9af56b8cbd45a4b1e5135..6e928f37d08429defdcecf71d1bf35c0ef5b613e 100644 (file)
@@ -89,7 +89,6 @@ bool __bdev_dax_supported(struct block_device *bdev, int blocksize)
        struct request_queue *q;
        pgoff_t pgoff;
        int err, id;
-       void *kaddr;
        pfn_t pfn;
        long len;
        char buf[BDEVNAME_SIZE];
@@ -122,7 +121,7 @@ bool __bdev_dax_supported(struct block_device *bdev, int blocksize)
        }
 
        id = dax_read_lock();
-       len = dax_direct_access(dax_dev, pgoff, 1, &kaddr, &pfn);
+       len = dax_direct_access(dax_dev, pgoff, 1, NULL, &pfn);
        dax_read_unlock(id);
 
        put_dax(dax_dev);
index 272bed6c8ba79d17cff68cf54d9b0aae20a28546..f1a441ab395d7529ebbc4f8d59e891e20c61419d 100644 (file)
@@ -161,9 +161,7 @@ static void chan_dev_release(struct device *dev)
 
        chan_dev = container_of(dev, typeof(*chan_dev), device);
        if (atomic_dec_and_test(chan_dev->idr_ref)) {
-               mutex_lock(&dma_list_mutex);
-               ida_remove(&dma_ida, chan_dev->dev_id);
-               mutex_unlock(&dma_list_mutex);
+               ida_free(&dma_ida, chan_dev->dev_id);
                kfree(chan_dev->idr_ref);
        }
        kfree(chan_dev);
@@ -898,17 +896,12 @@ static bool device_has_all_tx_types(struct dma_device *device)
 
 static int get_dma_id(struct dma_device *device)
 {
-       int rc;
-
-       do {
-               if (!ida_pre_get(&dma_ida, GFP_KERNEL))
-                       return -ENOMEM;
-               mutex_lock(&dma_list_mutex);
-               rc = ida_get_new(&dma_ida, &device->dev_id);
-               mutex_unlock(&dma_list_mutex);
-       } while (rc == -EAGAIN);
+       int rc = ida_alloc(&dma_ida, GFP_KERNEL);
 
-       return rc;
+       if (rc < 0)
+               return rc;
+       device->dev_id = rc;
+       return 0;
 }
 
 /**
@@ -1092,9 +1085,7 @@ int dma_async_device_register(struct dma_device *device)
 err_out:
        /* if we never registered a channel just release the idr */
        if (atomic_read(idr_ref) == 0) {
-               mutex_lock(&dma_list_mutex);
-               ida_remove(&dma_ida, device->dev_id);
-               mutex_unlock(&dma_list_mutex);
+               ida_free(&dma_ida, device->dev_id);
                kfree(idr_ref);
                return rc;
        }
index 2a219b1261b1c0f8b88612e7075d8b74a256a9e9..64342944d9175c54918100c36f0b43a20e6acae3 100644 (file)
@@ -166,7 +166,13 @@ scmi_perf_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
                                        le32_to_cpu(attr->sustained_freq_khz);
                dom_info->sustained_perf_level =
                                        le32_to_cpu(attr->sustained_perf_level);
-               dom_info->mult_factor = (dom_info->sustained_freq_khz * 1000) /
+               if (!dom_info->sustained_freq_khz ||
+                   !dom_info->sustained_perf_level)
+                       /* CPUFreq converts to kHz, hence default 1000 */
+                       dom_info->mult_factor = 1000;
+               else
+                       dom_info->mult_factor =
+                                       (dom_info->sustained_freq_khz * 1000) /
                                        dom_info->sustained_perf_level;
                memcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE);
        }
@@ -363,8 +369,6 @@ static int scmi_dvfs_device_opps_add(const struct scmi_handle *handle,
                return domain;
 
        dom = pi->dom_info + domain;
-       if (!dom)
-               return -EIO;
 
        for (opp = dom->opp, idx = 0; idx < dom->opp_count; idx++, opp++) {
                freq = opp->perf * dom->mult_factor;
@@ -394,9 +398,6 @@ static int scmi_dvfs_transition_latency_get(const struct scmi_handle *handle,
                return domain;
 
        dom = pi->dom_info + domain;
-       if (!dom)
-               return -EIO;
-
        /* uS to nS */
        return dom->opp[dom->opp_count - 1].trans_latency_us * 1000;
 }
index 50793fda78191da4d4889dcabf12744f71411254..b22ccfb0c991bde8c6d222d0a44ce527e304c7ae 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/efi-bgrt.h>
 
 struct acpi_table_bgrt bgrt_tab;
-size_t __initdata bgrt_image_size;
+size_t bgrt_image_size;
 
 struct bmp_header {
        u16 id;
index 88c322d7c71edf306591be82d717ac4426eb09e1..14c40a7750d1d4017edbc386d4e02df7949149fe 100644 (file)
@@ -24,6 +24,7 @@ KBUILD_CFLAGS                 := $(cflags-y) -DDISABLE_BRANCH_PROFILING \
                                   -D__NO_FORTIFY \
                                   $(call cc-option,-ffreestanding) \
                                   $(call cc-option,-fno-stack-protector) \
+                                  -D__DISABLE_EXPORTS
 
 GCOV_PROFILE                   := n
 KASAN_SANITIZE                 := n
index bb1c068bff19f3e9c24605257ea094221fc1ea75..3469436579622b957fcf805aff1edb0da41adc1c 100644 (file)
@@ -77,28 +77,6 @@ static int psci_ops_check(void)
        return 0;
 }
 
-static int find_cpu_groups(const struct cpumask *cpus,
-                          const struct cpumask **cpu_groups)
-{
-       unsigned int nb = 0;
-       cpumask_var_t tmp;
-
-       if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
-               return -ENOMEM;
-       cpumask_copy(tmp, cpus);
-
-       while (!cpumask_empty(tmp)) {
-               const struct cpumask *cpu_group =
-                       topology_core_cpumask(cpumask_any(tmp));
-
-               cpu_groups[nb++] = cpu_group;
-               cpumask_andnot(tmp, tmp, cpu_group);
-       }
-
-       free_cpumask_var(tmp);
-       return nb;
-}
-
 /*
  * offlined_cpus is a temporary array but passing it as an argument avoids
  * multiple allocations.
@@ -166,29 +144,66 @@ static unsigned int down_and_up_cpus(const struct cpumask *cpus,
        return err;
 }
 
+static void free_cpu_groups(int num, cpumask_var_t **pcpu_groups)
+{
+       int i;
+       cpumask_var_t *cpu_groups = *pcpu_groups;
+
+       for (i = 0; i < num; ++i)
+               free_cpumask_var(cpu_groups[i]);
+       kfree(cpu_groups);
+}
+
+static int alloc_init_cpu_groups(cpumask_var_t **pcpu_groups)
+{
+       int num_groups = 0;
+       cpumask_var_t tmp, *cpu_groups;
+
+       if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
+               return -ENOMEM;
+
+       cpu_groups = kcalloc(nb_available_cpus, sizeof(cpu_groups),
+                            GFP_KERNEL);
+       if (!cpu_groups)
+               return -ENOMEM;
+
+       cpumask_copy(tmp, cpu_online_mask);
+
+       while (!cpumask_empty(tmp)) {
+               const struct cpumask *cpu_group =
+                       topology_core_cpumask(cpumask_any(tmp));
+
+               if (!alloc_cpumask_var(&cpu_groups[num_groups], GFP_KERNEL)) {
+                       free_cpu_groups(num_groups, &cpu_groups);
+                       return -ENOMEM;
+               }
+               cpumask_copy(cpu_groups[num_groups++], cpu_group);
+               cpumask_andnot(tmp, tmp, cpu_group);
+       }
+
+       free_cpumask_var(tmp);
+       *pcpu_groups = cpu_groups;
+
+       return num_groups;
+}
+
 static int hotplug_tests(void)
 {
-       int err;
-       cpumask_var_t offlined_cpus;
-       int i, nb_cpu_group;
-       const struct cpumask **cpu_groups;
+       int i, nb_cpu_group, err = -ENOMEM;
+       cpumask_var_t offlined_cpus, *cpu_groups;
        char *page_buf;
 
-       err = -ENOMEM;
        if (!alloc_cpumask_var(&offlined_cpus, GFP_KERNEL))
                return err;
-       /* We may have up to nb_available_cpus cpu_groups. */
-       cpu_groups = kmalloc_array(nb_available_cpus, sizeof(*cpu_groups),
-                                  GFP_KERNEL);
-       if (!cpu_groups)
+
+       nb_cpu_group = alloc_init_cpu_groups(&cpu_groups);
+       if (nb_cpu_group < 0)
                goto out_free_cpus;
        page_buf = (char *)__get_free_page(GFP_KERNEL);
        if (!page_buf)
                goto out_free_cpu_groups;
 
        err = 0;
-       nb_cpu_group = find_cpu_groups(cpu_online_mask, cpu_groups);
-
        /*
         * Of course the last CPU cannot be powered down and cpu_down() should
         * refuse doing that.
@@ -212,7 +227,7 @@ static int hotplug_tests(void)
 
        free_page((unsigned long)page_buf);
 out_free_cpu_groups:
-       kfree(cpu_groups);
+       free_cpu_groups(nb_cpu_group, &cpu_groups);
 out_free_cpus:
        free_cpumask_var(offlined_cpus);
        return err;
index 6692888f04cfb8be4824f64efb3222f398937c3c..a200a217461191b796105682e599582bb736683e 100644 (file)
 #define MBOX_DATA28(msg)               ((msg) & ~0xf)
 #define MBOX_CHAN_PROPERTY             8
 
+#define MAX_RPI_FW_PROP_BUF_SIZE       32
+
+static struct platform_device *rpi_hwmon;
+
 struct rpi_firmware {
        struct mbox_client cl;
        struct mbox_chan *chan; /* The property channel. */
@@ -143,18 +147,22 @@ int rpi_firmware_property(struct rpi_firmware *fw,
        /* Single tags are very small (generally 8 bytes), so the
         * stack should be safe.
         */
-       u8 data[buf_size + sizeof(struct rpi_firmware_property_tag_header)];
+       u8 data[sizeof(struct rpi_firmware_property_tag_header) +
+               MAX_RPI_FW_PROP_BUF_SIZE];
        struct rpi_firmware_property_tag_header *header =
                (struct rpi_firmware_property_tag_header *)data;
        int ret;
 
+       if (WARN_ON(buf_size > sizeof(data) - sizeof(*header)))
+               return -EINVAL;
+
        header->tag = tag;
        header->buf_size = buf_size;
        header->req_resp_size = 0;
        memcpy(data + sizeof(struct rpi_firmware_property_tag_header),
               tag_data, buf_size);
 
-       ret = rpi_firmware_property_list(fw, &data, sizeof(data));
+       ret = rpi_firmware_property_list(fw, &data, buf_size + sizeof(*header));
        memcpy(tag_data,
               data + sizeof(struct rpi_firmware_property_tag_header),
               buf_size);
@@ -183,6 +191,20 @@ rpi_firmware_print_firmware_revision(struct rpi_firmware *fw)
        }
 }
 
+static void
+rpi_register_hwmon_driver(struct device *dev, struct rpi_firmware *fw)
+{
+       u32 packet;
+       int ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_THROTTLED,
+                                       &packet, sizeof(packet));
+
+       if (ret)
+               return;
+
+       rpi_hwmon = platform_device_register_data(dev, "raspberrypi-hwmon",
+                                                 -1, NULL, 0);
+}
+
 static int rpi_firmware_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -209,6 +231,7 @@ static int rpi_firmware_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, fw);
 
        rpi_firmware_print_firmware_revision(fw);
+       rpi_register_hwmon_driver(dev, fw);
 
        return 0;
 }
@@ -217,6 +240,8 @@ static int rpi_firmware_remove(struct platform_device *pdev)
 {
        struct rpi_firmware *fw = platform_get_drvdata(pdev);
 
+       platform_device_unregister(rpi_hwmon);
+       rpi_hwmon = NULL;
        mbox_free_channel(fw->chan);
 
        return 0;
index 3530ccd17e04487153cb5d1cff0b9796ca38673a..da9781a2ef4adf230fc6704945fc02ac2bca3823 100644 (file)
@@ -41,6 +41,8 @@ struct adp5588_gpio {
        uint8_t int_en[3];
        uint8_t irq_mask[3];
        uint8_t irq_stat[3];
+       uint8_t int_input_en[3];
+       uint8_t int_lvl_cached[3];
 };
 
 static int adp5588_gpio_read(struct i2c_client *client, u8 reg)
@@ -173,12 +175,28 @@ static void adp5588_irq_bus_sync_unlock(struct irq_data *d)
        struct adp5588_gpio *dev = irq_data_get_irq_chip_data(d);
        int i;
 
-       for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++)
+       for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) {
+               if (dev->int_input_en[i]) {
+                       mutex_lock(&dev->lock);
+                       dev->dir[i] &= ~dev->int_input_en[i];
+                       dev->int_input_en[i] = 0;
+                       adp5588_gpio_write(dev->client, GPIO_DIR1 + i,
+                                          dev->dir[i]);
+                       mutex_unlock(&dev->lock);
+               }
+
+               if (dev->int_lvl_cached[i] != dev->int_lvl[i]) {
+                       dev->int_lvl_cached[i] = dev->int_lvl[i];
+                       adp5588_gpio_write(dev->client, GPIO_INT_LVL1 + i,
+                                          dev->int_lvl[i]);
+               }
+
                if (dev->int_en[i] ^ dev->irq_mask[i]) {
                        dev->int_en[i] = dev->irq_mask[i];
                        adp5588_gpio_write(dev->client, GPIO_INT_EN1 + i,
                                           dev->int_en[i]);
                }
+       }
 
        mutex_unlock(&dev->irq_lock);
 }
@@ -221,9 +239,7 @@ static int adp5588_irq_set_type(struct irq_data *d, unsigned int type)
        else
                return -EINVAL;
 
-       adp5588_gpio_direction_input(&dev->gpio_chip, gpio);
-       adp5588_gpio_write(dev->client, GPIO_INT_LVL1 + bank,
-                          dev->int_lvl[bank]);
+       dev->int_input_en[bank] |= bit;
 
        return 0;
 }
index 28da700f5f5258f54117dee459904d2140d0d411..044888fd96a1f642617cba9a9dfc98655c5493aa 100644 (file)
@@ -728,6 +728,7 @@ static int dwapb_gpio_probe(struct platform_device *pdev)
 out_unregister:
        dwapb_gpio_unregister(gpio);
        dwapb_irq_teardown(gpio);
+       clk_disable_unprepare(gpio->clk);
 
        return err;
 }
index c48ed9d89ff5f7b74eb03fb7ee079fa2b18e0dcf..8b9d7e42c600b60d26bad7f26c32ed938be6e7a2 100644 (file)
@@ -25,7 +25,6 @@
 
 struct acpi_gpio_event {
        struct list_head node;
-       struct list_head initial_sync_list;
        acpi_handle handle;
        unsigned int pin;
        unsigned int irq;
@@ -49,10 +48,19 @@ struct acpi_gpio_chip {
        struct mutex conn_lock;
        struct gpio_chip *chip;
        struct list_head events;
+       struct list_head deferred_req_irqs_list_entry;
 };
 
-static LIST_HEAD(acpi_gpio_initial_sync_list);
-static DEFINE_MUTEX(acpi_gpio_initial_sync_list_lock);
+/*
+ * For gpiochips which call acpi_gpiochip_request_interrupts() before late_init
+ * (so builtin drivers) we register the ACPI GpioInt event handlers from a
+ * late_initcall_sync handler, so that other builtin drivers can register their
+ * OpRegions before the event handlers can run.  This list contains gpiochips
+ * for which the acpi_gpiochip_request_interrupts() has been deferred.
+ */
+static DEFINE_MUTEX(acpi_gpio_deferred_req_irqs_lock);
+static LIST_HEAD(acpi_gpio_deferred_req_irqs_list);
+static bool acpi_gpio_deferred_req_irqs_done;
 
 static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
 {
@@ -89,21 +97,6 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin)
        return gpiochip_get_desc(chip, pin);
 }
 
-static void acpi_gpio_add_to_initial_sync_list(struct acpi_gpio_event *event)
-{
-       mutex_lock(&acpi_gpio_initial_sync_list_lock);
-       list_add(&event->initial_sync_list, &acpi_gpio_initial_sync_list);
-       mutex_unlock(&acpi_gpio_initial_sync_list_lock);
-}
-
-static void acpi_gpio_del_from_initial_sync_list(struct acpi_gpio_event *event)
-{
-       mutex_lock(&acpi_gpio_initial_sync_list_lock);
-       if (!list_empty(&event->initial_sync_list))
-               list_del_init(&event->initial_sync_list);
-       mutex_unlock(&acpi_gpio_initial_sync_list_lock);
-}
-
 static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)
 {
        struct acpi_gpio_event *event = data;
@@ -186,7 +179,7 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
 
        gpiod_direction_input(desc);
 
-       value = gpiod_get_value(desc);
+       value = gpiod_get_value_cansleep(desc);
 
        ret = gpiochip_lock_as_irq(chip, pin);
        if (ret) {
@@ -229,7 +222,6 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
        event->irq = irq;
        event->pin = pin;
        event->desc = desc;
-       INIT_LIST_HEAD(&event->initial_sync_list);
 
        ret = request_threaded_irq(event->irq, NULL, handler, irqflags,
                                   "ACPI:Event", event);
@@ -251,10 +243,9 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
         * may refer to OperationRegions from other (builtin) drivers which
         * may be probed after us.
         */
-       if (handler == acpi_gpio_irq_handler &&
-           (((irqflags & IRQF_TRIGGER_RISING) && value == 1) ||
-            ((irqflags & IRQF_TRIGGER_FALLING) && value == 0)))
-               acpi_gpio_add_to_initial_sync_list(event);
+       if (((irqflags & IRQF_TRIGGER_RISING) && value == 1) ||
+           ((irqflags & IRQF_TRIGGER_FALLING) && value == 0))
+               handler(event->irq, event);
 
        return AE_OK;
 
@@ -283,6 +274,7 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
        struct acpi_gpio_chip *acpi_gpio;
        acpi_handle handle;
        acpi_status status;
+       bool defer;
 
        if (!chip->parent || !chip->to_irq)
                return;
@@ -295,6 +287,16 @@ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
        if (ACPI_FAILURE(status))
                return;
 
+       mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
+       defer = !acpi_gpio_deferred_req_irqs_done;
+       if (defer)
+               list_add(&acpi_gpio->deferred_req_irqs_list_entry,
+                        &acpi_gpio_deferred_req_irqs_list);
+       mutex_unlock(&acpi_gpio_deferred_req_irqs_lock);
+
+       if (defer)
+               return;
+
        acpi_walk_resources(handle, "_AEI",
                            acpi_gpiochip_request_interrupt, acpi_gpio);
 }
@@ -325,11 +327,14 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
        if (ACPI_FAILURE(status))
                return;
 
+       mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
+       if (!list_empty(&acpi_gpio->deferred_req_irqs_list_entry))
+               list_del_init(&acpi_gpio->deferred_req_irqs_list_entry);
+       mutex_unlock(&acpi_gpio_deferred_req_irqs_lock);
+
        list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) {
                struct gpio_desc *desc;
 
-               acpi_gpio_del_from_initial_sync_list(event);
-
                if (irqd_is_wakeup_set(irq_get_irq_data(event->irq)))
                        disable_irq_wake(event->irq);
 
@@ -1052,6 +1057,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip)
 
        acpi_gpio->chip = chip;
        INIT_LIST_HEAD(&acpi_gpio->events);
+       INIT_LIST_HEAD(&acpi_gpio->deferred_req_irqs_list_entry);
 
        status = acpi_attach_data(handle, acpi_gpio_chip_dh, acpi_gpio);
        if (ACPI_FAILURE(status)) {
@@ -1198,20 +1204,28 @@ bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id)
        return con_id == NULL;
 }
 
-/* Sync the initial state of handlers after all builtin drivers have probed */
-static int acpi_gpio_initial_sync(void)
+/* Run deferred acpi_gpiochip_request_interrupts() */
+static int acpi_gpio_handle_deferred_request_interrupts(void)
 {
-       struct acpi_gpio_event *event, *ep;
+       struct acpi_gpio_chip *acpi_gpio, *tmp;
+
+       mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
+       list_for_each_entry_safe(acpi_gpio, tmp,
+                                &acpi_gpio_deferred_req_irqs_list,
+                                deferred_req_irqs_list_entry) {
+               acpi_handle handle;
 
-       mutex_lock(&acpi_gpio_initial_sync_list_lock);
-       list_for_each_entry_safe(event, ep, &acpi_gpio_initial_sync_list,
-                                initial_sync_list) {
-               acpi_evaluate_object(event->handle, NULL, NULL, NULL);
-               list_del_init(&event->initial_sync_list);
+               handle = ACPI_HANDLE(acpi_gpio->chip->parent);
+               acpi_walk_resources(handle, "_AEI",
+                                   acpi_gpiochip_request_interrupt, acpi_gpio);
+
+               list_del_init(&acpi_gpio->deferred_req_irqs_list_entry);
        }
-       mutex_unlock(&acpi_gpio_initial_sync_list_lock);
+
+       acpi_gpio_deferred_req_irqs_done = true;
+       mutex_unlock(&acpi_gpio_deferred_req_irqs_lock);
 
        return 0;
 }
 /* We must use _sync so that this runs after the first deferred_probe run */
-late_initcall_sync(acpi_gpio_initial_sync);
+late_initcall_sync(acpi_gpio_handle_deferred_request_interrupts);
index a4f1157d6aa0893707d3880c9f0be4639c909b03..d4e7a09598faedbecb1ccdee24e6138b70e4e7d8 100644 (file)
@@ -31,6 +31,7 @@ static int of_gpiochip_match_node_and_xlate(struct gpio_chip *chip, void *data)
        struct of_phandle_args *gpiospec = data;
 
        return chip->gpiodev->dev.of_node == gpiospec->np &&
+                               chip->of_xlate &&
                                chip->of_xlate(chip, gpiospec, NULL) >= 0;
 }
 
index 8a707d8bbb1c3c57870aa3e38f5a85b708b6d18d..f92597c292fe5352e35bc6e6fa09865cff6ca292 100644 (file)
@@ -206,11 +206,9 @@ static int amdgpu_amdkfd_remove_eviction_fence(struct amdgpu_bo *bo,
                                        struct amdgpu_amdkfd_fence ***ef_list,
                                        unsigned int *ef_count)
 {
-       struct reservation_object_list *fobj;
-       struct reservation_object *resv;
-       unsigned int i = 0, j = 0, k = 0, shared_count;
-       unsigned int count = 0;
-       struct amdgpu_amdkfd_fence **fence_list;
+       struct reservation_object *resv = bo->tbo.resv;
+       struct reservation_object_list *old, *new;
+       unsigned int i, j, k;
 
        if (!ef && !ef_list)
                return -EINVAL;
@@ -220,76 +218,67 @@ static int amdgpu_amdkfd_remove_eviction_fence(struct amdgpu_bo *bo,
                *ef_count = 0;
        }
 
-       resv = bo->tbo.resv;
-       fobj = reservation_object_get_list(resv);
-
-       if (!fobj)
+       old = reservation_object_get_list(resv);
+       if (!old)
                return 0;
 
-       preempt_disable();
-       write_seqcount_begin(&resv->seq);
+       new = kmalloc(offsetof(typeof(*new), shared[old->shared_max]),
+                     GFP_KERNEL);
+       if (!new)
+               return -ENOMEM;
 
-       /* Go through all the shared fences in the resevation object. If
-        * ef is specified and it exists in the list, remove it and reduce the
-        * count. If ef is not specified, then get the count of eviction fences
-        * present.
+       /* Go through all the shared fences in the resevation object and sort
+        * the interesting ones to the end of the list.
         */
-       shared_count = fobj->shared_count;
-       for (i = 0; i < shared_count; ++i) {
+       for (i = 0, j = old->shared_count, k = 0; i < old->shared_count; ++i) {
                struct dma_fence *f;
 
-               f = rcu_dereference_protected(fobj->shared[i],
+               f = rcu_dereference_protected(old->shared[i],
                                              reservation_object_held(resv));
 
-               if (ef) {
-                       if (f->context == ef->base.context) {
-                               dma_fence_put(f);
-                               fobj->shared_count--;
-                       } else {
-                               RCU_INIT_POINTER(fobj->shared[j++], f);
-                       }
-               } else if (to_amdgpu_amdkfd_fence(f))
-                       count++;
+               if ((ef && f->context == ef->base.context) ||
+                   (!ef && to_amdgpu_amdkfd_fence(f)))
+                       RCU_INIT_POINTER(new->shared[--j], f);
+               else
+                       RCU_INIT_POINTER(new->shared[k++], f);
        }
-       write_seqcount_end(&resv->seq);
-       preempt_enable();
-
-       if (ef || !count)
-               return 0;
-
-       /* Alloc memory for count number of eviction fence pointers. Fill the
-        * ef_list array and ef_count
-        */
-       fence_list = kcalloc(count, sizeof(struct amdgpu_amdkfd_fence *),
-                            GFP_KERNEL);
-       if (!fence_list)
-               return -ENOMEM;
+       new->shared_max = old->shared_max;
+       new->shared_count = k;
 
-       preempt_disable();
-       write_seqcount_begin(&resv->seq);
+       if (!ef) {
+               unsigned int count = old->shared_count - j;
 
-       j = 0;
-       for (i = 0; i < shared_count; ++i) {
-               struct dma_fence *f;
-               struct amdgpu_amdkfd_fence *efence;
-
-               f = rcu_dereference_protected(fobj->shared[i],
-                       reservation_object_held(resv));
+               /* Alloc memory for count number of eviction fence pointers.
+                * Fill the ef_list array and ef_count
+                */
+               *ef_list = kcalloc(count, sizeof(**ef_list), GFP_KERNEL);
+               *ef_count = count;
 
-               efence = to_amdgpu_amdkfd_fence(f);
-               if (efence) {
-                       fence_list[k++] = efence;
-                       fobj->shared_count--;
-               } else {
-                       RCU_INIT_POINTER(fobj->shared[j++], f);
+               if (!*ef_list) {
+                       kfree(new);
+                       return -ENOMEM;
                }
        }
 
+       /* Install the new fence list, seqcount provides the barriers */
+       preempt_disable();
+       write_seqcount_begin(&resv->seq);
+       RCU_INIT_POINTER(resv->fence, new);
        write_seqcount_end(&resv->seq);
        preempt_enable();
 
-       *ef_list = fence_list;
-       *ef_count = k;
+       /* Drop the references to the removed fences or move them to ef_list */
+       for (i = j, k = 0; i < old->shared_count; ++i) {
+               struct dma_fence *f;
+
+               f = rcu_dereference_protected(new->shared[i],
+                                             reservation_object_held(resv));
+               if (!ef)
+                       (*ef_list)[k++] = to_amdgpu_amdkfd_fence(f);
+               else
+                       dma_fence_put(f);
+       }
+       kfree_rcu(old, rcu);
 
        return 0;
 }
index 502b94fb116a7070af89ce51da182c3a936e48a0..b6e9df11115d358734d686af7b26a9eec0a6de64 100644 (file)
@@ -1012,13 +1012,9 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
                if (r)
                        return r;
 
-               if (chunk_ib->flags & AMDGPU_IB_FLAG_PREAMBLE) {
-                       parser->job->preamble_status |= AMDGPU_PREAMBLE_IB_PRESENT;
-                       if (!parser->ctx->preamble_presented) {
-                               parser->job->preamble_status |= AMDGPU_PREAMBLE_IB_PRESENT_FIRST;
-                               parser->ctx->preamble_presented = true;
-                       }
-               }
+               if (chunk_ib->flags & AMDGPU_IB_FLAG_PREAMBLE)
+                       parser->job->preamble_status |=
+                               AMDGPU_PREAMBLE_IB_PRESENT;
 
                if (parser->ring && parser->ring != ring)
                        return -EINVAL;
@@ -1207,26 +1203,24 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
 
        int r;
 
+       job = p->job;
+       p->job = NULL;
+
+       r = drm_sched_job_init(&job->base, entity, p->filp);
+       if (r)
+               goto error_unlock;
+
+       /* No memory allocation is allowed while holding the mn lock */
        amdgpu_mn_lock(p->mn);
        amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
                struct amdgpu_bo *bo = e->robj;
 
                if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) {
-                       amdgpu_mn_unlock(p->mn);
-                       return -ERESTARTSYS;
+                       r = -ERESTARTSYS;
+                       goto error_abort;
                }
        }
 
-       job = p->job;
-       p->job = NULL;
-
-       r = drm_sched_job_init(&job->base, entity, p->filp);
-       if (r) {
-               amdgpu_job_free(job);
-               amdgpu_mn_unlock(p->mn);
-               return r;
-       }
-
        job->owner = p->filp;
        p->fence = dma_fence_get(&job->base.s_fence->finished);
 
@@ -1241,6 +1235,12 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
 
        amdgpu_cs_post_dependencies(p);
 
+       if ((job->preamble_status & AMDGPU_PREAMBLE_IB_PRESENT) &&
+           !p->ctx->preamble_presented) {
+               job->preamble_status |= AMDGPU_PREAMBLE_IB_PRESENT_FIRST;
+               p->ctx->preamble_presented = true;
+       }
+
        cs->out.handle = seq;
        job->uf_sequence = seq;
 
@@ -1258,6 +1258,15 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
        amdgpu_mn_unlock(p->mn);
 
        return 0;
+
+error_abort:
+       dma_fence_put(&job->base.s_fence->finished);
+       job->base.s_fence = NULL;
+
+error_unlock:
+       amdgpu_job_free(job);
+       amdgpu_mn_unlock(p->mn);
+       return r;
 }
 
 int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
index 1e66dfd0e39cf5ae923da0d5c646cae7efda5735..8ab5ccbc14ace34f6618452b01432bafd55cb5a3 100644 (file)
@@ -2274,7 +2274,7 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
        case CHIP_VEGA10:
        case CHIP_VEGA12:
        case CHIP_VEGA20:
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        case CHIP_RAVEN:
 #endif
                return amdgpu_dc != 0;
index 5518e623fed21046791c42e026383526f8cf8adb..51b5e977ca885ef1f7d7df49698f3c6843bab437 100644 (file)
@@ -164,8 +164,10 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
                return r;
        }
 
+       need_ctx_switch = ring->current_ctx != fence_ctx;
        if (ring->funcs->emit_pipeline_sync && job &&
            ((tmp = amdgpu_sync_get_fence(&job->sched_sync, NULL)) ||
+            (amdgpu_sriov_vf(adev) && need_ctx_switch) ||
             amdgpu_vm_need_pipeline_sync(ring, job))) {
                need_pipe_sync = true;
                dma_fence_put(tmp);
@@ -196,7 +198,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
        }
 
        skip_preamble = ring->current_ctx == fence_ctx;
-       need_ctx_switch = ring->current_ctx != fence_ctx;
        if (job && ring->funcs->emit_cntxcntl) {
                if (need_ctx_switch)
                        status |= AMDGPU_HAVE_CTX_SWITCH;
index a365ea2383d18c137df14d1fa116fad954d9ca45..e55508b394962d8d77e6fe285cee1a9544214714 100644 (file)
@@ -178,12 +178,18 @@ void amdgpu_mn_unlock(struct amdgpu_mn *mn)
  *
  * @amn: our notifier
  */
-static void amdgpu_mn_read_lock(struct amdgpu_mn *amn)
+static int amdgpu_mn_read_lock(struct amdgpu_mn *amn, bool blockable)
 {
-       mutex_lock(&amn->read_lock);
+       if (blockable)
+               mutex_lock(&amn->read_lock);
+       else if (!mutex_trylock(&amn->read_lock))
+               return -EAGAIN;
+
        if (atomic_inc_return(&amn->recursion) == 1)
                down_read_non_owner(&amn->lock);
        mutex_unlock(&amn->read_lock);
+
+       return 0;
 }
 
 /**
@@ -239,10 +245,11 @@ static void amdgpu_mn_invalidate_node(struct amdgpu_mn_node *node,
  * Block for operations on BOs to finish and mark pages as accessed and
  * potentially dirty.
  */
-static void amdgpu_mn_invalidate_range_start_gfx(struct mmu_notifier *mn,
+static int amdgpu_mn_invalidate_range_start_gfx(struct mmu_notifier *mn,
                                                 struct mm_struct *mm,
                                                 unsigned long start,
-                                                unsigned long end)
+                                                unsigned long end,
+                                                bool blockable)
 {
        struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn);
        struct interval_tree_node *it;
@@ -250,17 +257,28 @@ static void amdgpu_mn_invalidate_range_start_gfx(struct mmu_notifier *mn,
        /* notification is exclusive, but interval is inclusive */
        end -= 1;
 
-       amdgpu_mn_read_lock(amn);
+       /* TODO we should be able to split locking for interval tree and
+        * amdgpu_mn_invalidate_node
+        */
+       if (amdgpu_mn_read_lock(amn, blockable))
+               return -EAGAIN;
 
        it = interval_tree_iter_first(&amn->objects, start, end);
        while (it) {
                struct amdgpu_mn_node *node;
 
+               if (!blockable) {
+                       amdgpu_mn_read_unlock(amn);
+                       return -EAGAIN;
+               }
+
                node = container_of(it, struct amdgpu_mn_node, it);
                it = interval_tree_iter_next(it, start, end);
 
                amdgpu_mn_invalidate_node(node, start, end);
        }
+
+       return 0;
 }
 
 /**
@@ -275,10 +293,11 @@ static void amdgpu_mn_invalidate_range_start_gfx(struct mmu_notifier *mn,
  * necessitates evicting all user-mode queues of the process. The BOs
  * are restorted in amdgpu_mn_invalidate_range_end_hsa.
  */
-static void amdgpu_mn_invalidate_range_start_hsa(struct mmu_notifier *mn,
+static int amdgpu_mn_invalidate_range_start_hsa(struct mmu_notifier *mn,
                                                 struct mm_struct *mm,
                                                 unsigned long start,
-                                                unsigned long end)
+                                                unsigned long end,
+                                                bool blockable)
 {
        struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn);
        struct interval_tree_node *it;
@@ -286,13 +305,19 @@ static void amdgpu_mn_invalidate_range_start_hsa(struct mmu_notifier *mn,
        /* notification is exclusive, but interval is inclusive */
        end -= 1;
 
-       amdgpu_mn_read_lock(amn);
+       if (amdgpu_mn_read_lock(amn, blockable))
+               return -EAGAIN;
 
        it = interval_tree_iter_first(&amn->objects, start, end);
        while (it) {
                struct amdgpu_mn_node *node;
                struct amdgpu_bo *bo;
 
+               if (!blockable) {
+                       amdgpu_mn_read_unlock(amn);
+                       return -EAGAIN;
+               }
+
                node = container_of(it, struct amdgpu_mn_node, it);
                it = interval_tree_iter_next(it, start, end);
 
@@ -304,6 +329,8 @@ static void amdgpu_mn_invalidate_range_start_hsa(struct mmu_notifier *mn,
                                amdgpu_amdkfd_evict_userptr(mem, mm);
                }
        }
+
+       return 0;
 }
 
 /**
index 8f98629fbe5936858a3c77b3546fd106577f7254..7b4e657a95c700561298346654118a9915c8caec 100644 (file)
@@ -1932,14 +1932,6 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
                        amdgpu_fence_wait_empty(ring);
        }
 
-       mutex_lock(&adev->pm.mutex);
-       /* update battery/ac status */
-       if (power_supply_is_system_supplied() > 0)
-               adev->pm.ac_power = true;
-       else
-               adev->pm.ac_power = false;
-       mutex_unlock(&adev->pm.mutex);
-
        if (adev->powerplay.pp_funcs->dispatch_tasks) {
                if (!amdgpu_device_has_dc_support(adev)) {
                        mutex_lock(&adev->pm.mutex);
index 86a0715d9431ded69bac338a38143d82789ad949..1cafe8d83a4dbaa60915801a7849a81613ef69c0 100644 (file)
@@ -53,9 +53,8 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev,
                                                  int fd,
                                                  enum drm_sched_priority priority)
 {
-       struct file *filp = fcheck(fd);
+       struct file *filp = fget(fd);
        struct drm_file *file;
-       struct pid *pid;
        struct amdgpu_fpriv *fpriv;
        struct amdgpu_ctx *ctx;
        uint32_t id;
@@ -63,20 +62,12 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev,
        if (!filp)
                return -EINVAL;
 
-       pid = get_pid(((struct drm_file *)filp->private_data)->pid);
+       file = filp->private_data;
+       fpriv = file->driver_priv;
+       idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id)
+               amdgpu_ctx_priority_override(ctx, priority);
 
-       mutex_lock(&adev->ddev->filelist_mutex);
-       list_for_each_entry(file, &adev->ddev->filelist, lhead) {
-               if (file->pid != pid)
-                       continue;
-
-               fpriv = file->driver_priv;
-               idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id)
-                               amdgpu_ctx_priority_override(ctx, priority);
-       }
-       mutex_unlock(&adev->ddev->filelist_mutex);
-
-       put_pid(pid);
+       fput(filp);
 
        return 0;
 }
index ece0ac703e277282992422865f9945ce06ca5f0c..b17771dd5ce732620e8c058f788516b7ef9b6fee 100644 (file)
@@ -172,6 +172,7 @@ static void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base,
         * is validated on next vm use to avoid fault.
         * */
        list_move_tail(&base->vm_status, &vm->evicted);
+       base->moved = true;
 }
 
 /**
@@ -369,7 +370,6 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
        uint64_t addr;
        int r;
 
-       addr = amdgpu_bo_gpu_offset(bo);
        entries = amdgpu_bo_size(bo) / 8;
 
        if (pte_support_ats) {
@@ -401,6 +401,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev,
        if (r)
                goto error;
 
+       addr = amdgpu_bo_gpu_offset(bo);
        if (ats_entries) {
                uint64_t ats_value;
 
@@ -2483,28 +2484,52 @@ static uint32_t amdgpu_vm_get_block_size(uint64_t vm_size)
  * amdgpu_vm_adjust_size - adjust vm size, block size and fragment size
  *
  * @adev: amdgpu_device pointer
- * @vm_size: the default vm size if it's set auto
+ * @min_vm_size: the minimum vm size in GB if it's set auto
  * @fragment_size_default: Default PTE fragment size
  * @max_level: max VMPT level
  * @max_bits: max address space size in bits
  *
  */
-void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size,
+void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size,
                           uint32_t fragment_size_default, unsigned max_level,
                           unsigned max_bits)
 {
+       unsigned int max_size = 1 << (max_bits - 30);
+       unsigned int vm_size;
        uint64_t tmp;
 
        /* adjust vm size first */
        if (amdgpu_vm_size != -1) {
-               unsigned max_size = 1 << (max_bits - 30);
-
                vm_size = amdgpu_vm_size;
                if (vm_size > max_size) {
                        dev_warn(adev->dev, "VM size (%d) too large, max is %u GB\n",
                                 amdgpu_vm_size, max_size);
                        vm_size = max_size;
                }
+       } else {
+               struct sysinfo si;
+               unsigned int phys_ram_gb;
+
+               /* Optimal VM size depends on the amount of physical
+                * RAM available. Underlying requirements and
+                * assumptions:
+                *
+                *  - Need to map system memory and VRAM from all GPUs
+                *     - VRAM from other GPUs not known here
+                *     - Assume VRAM <= system memory
+                *  - On GFX8 and older, VM space can be segmented for
+                *    different MTYPEs
+                *  - Need to allow room for fragmentation, guard pages etc.
+                *
+                * This adds up to a rough guess of system memory x3.
+                * Round up to power of two to maximize the available
+                * VM size with the given page table size.
+                */
+               si_meminfo(&si);
+               phys_ram_gb = ((uint64_t)si.totalram * si.mem_unit +
+                              (1 << 30) - 1) >> 30;
+               vm_size = roundup_pow_of_two(
+                       min(max(phys_ram_gb * 3, min_vm_size), max_size));
        }
 
        adev->vm_manager.max_pfn = (uint64_t)vm_size << 18;
index 67a15d439ac006f97b48ffe7e74544d6688bf452..9fa9df0c5e7f9a19d1f9aed6e0430ea78aac8675 100644 (file)
@@ -321,7 +321,7 @@ struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm,
 void amdgpu_vm_bo_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket);
 void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
                      struct amdgpu_bo_va *bo_va);
-void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size,
+void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size,
                           uint32_t fragment_size_default, unsigned max_level,
                           unsigned max_bits);
 int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
index 5cd45210113f645062750e4ef54ffd4e7dc14da7..5a9534a82d40911cebb02462ba0cc5a995a5bfca 100644 (file)
@@ -5664,6 +5664,11 @@ static int gfx_v8_0_set_powergating_state(void *handle,
        if (amdgpu_sriov_vf(adev))
                return 0;
 
+       if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_SMG |
+                               AMD_PG_SUPPORT_RLC_SMU_HS |
+                               AMD_PG_SUPPORT_CP |
+                               AMD_PG_SUPPORT_GFX_DMG))
+               adev->gfx.rlc.funcs->enter_safe_mode(adev);
        switch (adev->asic_type) {
        case CHIP_CARRIZO:
        case CHIP_STONEY:
@@ -5713,7 +5718,11 @@ static int gfx_v8_0_set_powergating_state(void *handle,
        default:
                break;
        }
-
+       if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_SMG |
+                               AMD_PG_SUPPORT_RLC_SMU_HS |
+                               AMD_PG_SUPPORT_CP |
+                               AMD_PG_SUPPORT_GFX_DMG))
+               adev->gfx.rlc.funcs->exit_safe_mode(adev);
        return 0;
 }
 
index 75317f283c6967d2de4daaaf5dca4cfdaf9922b7..ad151fefa41f1ed1d6f19ae1783b13b1b76b4f2e 100644 (file)
@@ -632,12 +632,6 @@ static void gmc_v6_0_gart_disable(struct amdgpu_device *adev)
        amdgpu_gart_table_vram_unpin(adev);
 }
 
-static void gmc_v6_0_gart_fini(struct amdgpu_device *adev)
-{
-       amdgpu_gart_table_vram_free(adev);
-       amdgpu_gart_fini(adev);
-}
-
 static void gmc_v6_0_vm_decode_fault(struct amdgpu_device *adev,
                                     u32 status, u32 addr, u32 mc_client)
 {
@@ -935,8 +929,9 @@ static int gmc_v6_0_sw_fini(void *handle)
 
        amdgpu_gem_force_release(adev);
        amdgpu_vm_manager_fini(adev);
-       gmc_v6_0_gart_fini(adev);
+       amdgpu_gart_table_vram_free(adev);
        amdgpu_bo_fini(adev);
+       amdgpu_gart_fini(adev);
        release_firmware(adev->gmc.fw);
        adev->gmc.fw = NULL;
 
index 36dc367c4b45ea86a5a5b575ba357f9717ec92b0..f8d8a3a73e42b31397b97f743ab187da2732cd89 100644 (file)
@@ -746,19 +746,6 @@ static void gmc_v7_0_gart_disable(struct amdgpu_device *adev)
        amdgpu_gart_table_vram_unpin(adev);
 }
 
-/**
- * gmc_v7_0_gart_fini - vm fini callback
- *
- * @adev: amdgpu_device pointer
- *
- * Tears down the driver GART/VM setup (CIK).
- */
-static void gmc_v7_0_gart_fini(struct amdgpu_device *adev)
-{
-       amdgpu_gart_table_vram_free(adev);
-       amdgpu_gart_fini(adev);
-}
-
 /**
  * gmc_v7_0_vm_decode_fault - print human readable fault info
  *
@@ -1095,8 +1082,9 @@ static int gmc_v7_0_sw_fini(void *handle)
        amdgpu_gem_force_release(adev);
        amdgpu_vm_manager_fini(adev);
        kfree(adev->gmc.vm_fault_info);
-       gmc_v7_0_gart_fini(adev);
+       amdgpu_gart_table_vram_free(adev);
        amdgpu_bo_fini(adev);
+       amdgpu_gart_fini(adev);
        release_firmware(adev->gmc.fw);
        adev->gmc.fw = NULL;
 
index 70fc97b59b4f2dcf157b49885c8356fedfca05a3..9333109b210de810119f0d15d94ec5d125a84cf7 100644 (file)
@@ -968,19 +968,6 @@ static void gmc_v8_0_gart_disable(struct amdgpu_device *adev)
        amdgpu_gart_table_vram_unpin(adev);
 }
 
-/**
- * gmc_v8_0_gart_fini - vm fini callback
- *
- * @adev: amdgpu_device pointer
- *
- * Tears down the driver GART/VM setup (CIK).
- */
-static void gmc_v8_0_gart_fini(struct amdgpu_device *adev)
-{
-       amdgpu_gart_table_vram_free(adev);
-       amdgpu_gart_fini(adev);
-}
-
 /**
  * gmc_v8_0_vm_decode_fault - print human readable fault info
  *
@@ -1199,8 +1186,9 @@ static int gmc_v8_0_sw_fini(void *handle)
        amdgpu_gem_force_release(adev);
        amdgpu_vm_manager_fini(adev);
        kfree(adev->gmc.vm_fault_info);
-       gmc_v8_0_gart_fini(adev);
+       amdgpu_gart_table_vram_free(adev);
        amdgpu_bo_fini(adev);
+       amdgpu_gart_fini(adev);
        release_firmware(adev->gmc.fw);
        adev->gmc.fw = NULL;
 
index 399a5db27649728686868550502089391f3b0807..72f8018fa2a836572b9c898785bb99deecc1ca91 100644 (file)
@@ -942,26 +942,12 @@ static int gmc_v9_0_sw_init(void *handle)
        return 0;
 }
 
-/**
- * gmc_v9_0_gart_fini - vm fini callback
- *
- * @adev: amdgpu_device pointer
- *
- * Tears down the driver GART/VM setup (CIK).
- */
-static void gmc_v9_0_gart_fini(struct amdgpu_device *adev)
-{
-       amdgpu_gart_table_vram_free(adev);
-       amdgpu_gart_fini(adev);
-}
-
 static int gmc_v9_0_sw_fini(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
        amdgpu_gem_force_release(adev);
        amdgpu_vm_manager_fini(adev);
-       gmc_v9_0_gart_fini(adev);
 
        /*
        * TODO:
@@ -974,7 +960,9 @@ static int gmc_v9_0_sw_fini(void *handle)
        */
        amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, NULL);
 
+       amdgpu_gart_table_vram_free(adev);
        amdgpu_bo_fini(adev);
+       amdgpu_gart_fini(adev);
 
        return 0;
 }
index 3f57f6463dc880c797429d9f3080894b929e5eff..cb79a93c2eb73a5f23fb008cee50e80325ada627 100644 (file)
@@ -65,8 +65,6 @@ static int kv_set_thermal_temperature_range(struct amdgpu_device *adev,
                                            int min_temp, int max_temp);
 static int kv_init_fps_limits(struct amdgpu_device *adev);
 
-static void kv_dpm_powergate_uvd(void *handle, bool gate);
-static void kv_dpm_powergate_vce(struct amdgpu_device *adev, bool gate);
 static void kv_dpm_powergate_samu(struct amdgpu_device *adev, bool gate);
 static void kv_dpm_powergate_acp(struct amdgpu_device *adev, bool gate);
 
@@ -1354,8 +1352,6 @@ static int kv_dpm_enable(struct amdgpu_device *adev)
                return ret;
        }
 
-       kv_update_current_ps(adev, adev->pm.dpm.boot_ps);
-
        if (adev->irq.installed &&
            amdgpu_is_internal_thermal_sensor(adev->pm.int_thermal_type)) {
                ret = kv_set_thermal_temperature_range(adev, KV_TEMP_RANGE_MIN, KV_TEMP_RANGE_MAX);
@@ -1374,6 +1370,8 @@ static int kv_dpm_enable(struct amdgpu_device *adev)
 
 static void kv_dpm_disable(struct amdgpu_device *adev)
 {
+       struct kv_power_info *pi = kv_get_pi(adev);
+
        amdgpu_irq_put(adev, &adev->pm.dpm.thermal.irq,
                       AMDGPU_THERMAL_IRQ_LOW_TO_HIGH);
        amdgpu_irq_put(adev, &adev->pm.dpm.thermal.irq,
@@ -1387,8 +1385,10 @@ static void kv_dpm_disable(struct amdgpu_device *adev)
        /* powerup blocks */
        kv_dpm_powergate_acp(adev, false);
        kv_dpm_powergate_samu(adev, false);
-       kv_dpm_powergate_vce(adev, false);
-       kv_dpm_powergate_uvd(adev, false);
+       if (pi->caps_vce_pg) /* power on the VCE block */
+               amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerON);
+       if (pi->caps_uvd_pg) /* power on the UVD block */
+               amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_UVDPowerON);
 
        kv_enable_smc_cac(adev, false);
        kv_enable_didt(adev, false);
@@ -1551,7 +1551,6 @@ static int kv_update_vce_dpm(struct amdgpu_device *adev,
        int ret;
 
        if (amdgpu_new_state->evclk > 0 && amdgpu_current_state->evclk == 0) {
-               kv_dpm_powergate_vce(adev, false);
                if (pi->caps_stable_p_state)
                        pi->vce_boot_level = table->count - 1;
                else
@@ -1573,7 +1572,6 @@ static int kv_update_vce_dpm(struct amdgpu_device *adev,
                kv_enable_vce_dpm(adev, true);
        } else if (amdgpu_new_state->evclk == 0 && amdgpu_current_state->evclk > 0) {
                kv_enable_vce_dpm(adev, false);
-               kv_dpm_powergate_vce(adev, true);
        }
 
        return 0;
@@ -1702,24 +1700,32 @@ static void kv_dpm_powergate_uvd(void *handle, bool gate)
        }
 }
 
-static void kv_dpm_powergate_vce(struct amdgpu_device *adev, bool gate)
+static void kv_dpm_powergate_vce(void *handle, bool gate)
 {
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        struct kv_power_info *pi = kv_get_pi(adev);
-
-       if (pi->vce_power_gated == gate)
-               return;
+       int ret;
 
        pi->vce_power_gated = gate;
 
-       if (!pi->caps_vce_pg)
-               return;
-
-       if (gate)
-               amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerOFF);
-       else
-               amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerON);
+       if (gate) {
+               /* stop the VCE block */
+               ret = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
+                                                            AMD_PG_STATE_GATE);
+               kv_enable_vce_dpm(adev, false);
+               if (pi->caps_vce_pg) /* power off the VCE block */
+                       amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerOFF);
+       } else {
+               if (pi->caps_vce_pg) /* power on the VCE block */
+                       amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerON);
+               kv_enable_vce_dpm(adev, true);
+               /* re-init the VCE block */
+               ret = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
+                                                            AMD_PG_STATE_UNGATE);
+       }
 }
 
+
 static void kv_dpm_powergate_samu(struct amdgpu_device *adev, bool gate)
 {
        struct kv_power_info *pi = kv_get_pi(adev);
@@ -3061,7 +3067,7 @@ static int kv_dpm_hw_init(void *handle)
        else
                adev->pm.dpm_enabled = true;
        mutex_unlock(&adev->pm.mutex);
-
+       amdgpu_pm_compute_clocks(adev);
        return ret;
 }
 
@@ -3313,6 +3319,9 @@ static int kv_set_powergating_by_smu(void *handle,
        case AMD_IP_BLOCK_TYPE_UVD:
                kv_dpm_powergate_uvd(handle, gate);
                break;
+       case AMD_IP_BLOCK_TYPE_VCE:
+               kv_dpm_powergate_vce(handle, gate);
+               break;
        default:
                break;
        }
index db327b4125626d411e155de18bfeb28f4efb92b4..1de96995e6900c934c91cf610160768b6c08cd37 100644 (file)
@@ -6887,7 +6887,6 @@ static int si_dpm_enable(struct amdgpu_device *adev)
 
        si_enable_auto_throttle_source(adev, AMDGPU_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
        si_thermal_start_thermal_controller(adev);
-       ni_update_current_ps(adev, boot_ps);
 
        return 0;
 }
@@ -7763,7 +7762,7 @@ static int si_dpm_hw_init(void *handle)
        else
                adev->pm.dpm_enabled = true;
        mutex_unlock(&adev->pm.mutex);
-
+       amdgpu_pm_compute_clocks(adev);
        return ret;
 }
 
index 52778de93ab08e63710ad145d218ad8658efab9c..2d4473557b0d23210782ff72397b47bd7f9c94ef 100644 (file)
@@ -38,6 +38,7 @@ int vega20_reg_base_init(struct amdgpu_device *adev)
                adev->reg_offset[ATHUB_HWIP][i] = (uint32_t *)(&(ATHUB_BASE.instance[i]));
                adev->reg_offset[NBIO_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i]));
                adev->reg_offset[MP0_HWIP][i] = (uint32_t *)(&(MP0_BASE.instance[i]));
+               adev->reg_offset[MP1_HWIP][i] = (uint32_t *)(&(MP1_BASE.instance[i]));
                adev->reg_offset[UVD_HWIP][i] = (uint32_t *)(&(UVD_BASE.instance[i]));
                adev->reg_offset[VCE_HWIP][i] = (uint32_t *)(&(VCE_BASE.instance[i]));
                adev->reg_offset[DF_HWIP][i] = (uint32_t *)(&(DF_BASE.instance[i]));
@@ -46,6 +47,8 @@ int vega20_reg_base_init(struct amdgpu_device *adev)
                adev->reg_offset[SDMA0_HWIP][i] = (uint32_t *)(&(SDMA0_BASE.instance[i]));
                adev->reg_offset[SDMA1_HWIP][i] = (uint32_t *)(&(SDMA1_BASE.instance[i]));
                adev->reg_offset[SMUIO_HWIP][i] = (uint32_t *)(&(SMUIO_BASE.instance[i]));
+               adev->reg_offset[NBIF_HWIP][i] = (uint32_t *)(&(NBIO_BASE.instance[i]));
+               adev->reg_offset[THM_HWIP][i] = (uint32_t *)(&(THM_BASE.instance[i]));
        }
        return 0;
 }
index 42c8ad105b0503f1471f06215aa7e46b074aaa88..88b57a5e94892ddb4d41916aa9f38b08536090b5 100644 (file)
@@ -112,8 +112,8 @@ static u32 vi_smc_rreg(struct amdgpu_device *adev, u32 reg)
        u32 r;
 
        spin_lock_irqsave(&adev->smc_idx_lock, flags);
-       WREG32(mmSMC_IND_INDEX_11, (reg));
-       r = RREG32(mmSMC_IND_DATA_11);
+       WREG32_NO_KIQ(mmSMC_IND_INDEX_11, (reg));
+       r = RREG32_NO_KIQ(mmSMC_IND_DATA_11);
        spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
        return r;
 }
index 325083b0297e4a3d165a50410c3af180d987f7b2..ed654a76c76ab3bf074ec07c2a33aa2f2e3cca3d 100644 (file)
@@ -4,11 +4,17 @@ menu "Display Engine Configuration"
 config DRM_AMD_DC
        bool "AMD DC - Enable new display engine"
        default y
+       select DRM_AMD_DC_DCN1_0 if X86 && !(KCOV_INSTRUMENT_ALL && KCOV_ENABLE_COMPARISONS)
        help
          Choose this option if you want to use the new display engine
          support for AMDGPU. This adds required support for Vega and
          Raven ASICs.
 
+config DRM_AMD_DC_DCN1_0
+       def_bool n
+       help
+         RV family support for display engine
+
 config DEBUG_KERNEL_DC
        bool "Enable kgdb break in DC"
        depends on DRM_AMD_DC
index 34f34823bab5f68a25ddb91600413324c5dffc66..800f481a6995fce0129bb316e078d2dcd8ab9eeb 100644 (file)
@@ -58,9 +58,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_edid.h>
 
-#include "modules/inc/mod_freesync.h"
-
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 #include "ivsrcid/irqsrcs_dcn_1_0.h"
 
 #include "dcn/dcn_1_0_offset.h"
@@ -1192,7 +1190,7 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev)
        return 0;
 }
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 /* Register IRQ sources and initialize IRQ callbacks */
 static int dcn10_register_irq_handlers(struct amdgpu_device *adev)
 {
@@ -1532,7 +1530,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
                        goto fail;
                }
                break;
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        case CHIP_RAVEN:
                if (dcn10_register_irq_handlers(dm->adev)) {
                        DRM_ERROR("DM: Failed to initialize IRQ\n");
@@ -1716,7 +1714,7 @@ static int dm_early_init(void *handle)
                adev->mode_info.num_dig = 6;
                adev->mode_info.plane_type = dm_plane_type_default;
                break;
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        case CHIP_RAVEN:
                adev->mode_info.num_crtc = 4;
                adev->mode_info.num_hpd = 4;
index fbe878ae1e8c579cc6e2571e30e95400ba477cad..4ba0003a9d329545a59e1b8050bcecf922a5e55d 100644 (file)
@@ -480,12 +480,20 @@ void pp_rv_set_display_requirement(struct pp_smu *pp,
 {
        struct dc_context *ctx = pp->ctx;
        struct amdgpu_device *adev = ctx->driver_context;
+       void *pp_handle = adev->powerplay.pp_handle;
        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
+       struct pp_display_clock_request clock = {0};
 
-       if (!pp_funcs || !pp_funcs->display_configuration_changed)
+       if (!pp_funcs || !pp_funcs->display_clock_voltage_request)
                return;
 
-       amdgpu_dpm_display_configuration_changed(adev);
+       clock.clock_type = amd_pp_dcf_clock;
+       clock.clock_freq_in_khz = req->hard_min_dcefclk_khz;
+       pp_funcs->display_clock_voltage_request(pp_handle, &clock);
+
+       clock.clock_type = amd_pp_f_clock;
+       clock.clock_freq_in_khz = req->hard_min_fclk_khz;
+       pp_funcs->display_clock_voltage_request(pp_handle, &clock);
 }
 
 void pp_rv_set_wm_ranges(struct pp_smu *pp,
index 532a515fda9a11a0f03cb3c700152712ba4a7023..aed538a4d1bace016fb37526d099656227b81348 100644 (file)
@@ -25,7 +25,7 @@
 
 DC_LIBS = basics bios calcs dce gpio i2caux irq virtual
 
-ifdef CONFIG_X86
+ifdef CONFIG_DRM_AMD_DC_DCN1_0
 DC_LIBS += dcn10 dml
 endif
 
index 770ff89ba7e173c273006f122ba77622cde7559f..bbbcef566c551908d42c0c6fda57083c1bdd455e 100644 (file)
@@ -55,7 +55,7 @@ bool dal_bios_parser_init_cmd_tbl_helper2(
        case DCE_VERSION_11_22:
                *h = dal_cmd_tbl_helper_dce112_get_table2();
                return true;
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        case DCN_VERSION_1_0:
                *h = dal_cmd_tbl_helper_dce112_get_table2();
                return true;
index 416500e51b8dd2f20da95ec9b0a7730363d56f50..95f332ee3e7e6e3858294d485c03c23c1c25f613 100644 (file)
@@ -38,7 +38,7 @@ CFLAGS_dcn_calc_math.o := $(calcs_ccflags) -Wno-tautological-compare
 
 BW_CALCS = dce_calcs.o bw_fixed.o custom_float.o
 
-ifdef CONFIG_X86
+ifdef CONFIG_DRM_AMD_DC_DCN1_0
 BW_CALCS += dcn_calcs.o dcn_calc_math.o dcn_calc_auto.o
 endif
 
index 733ac224e7fdc6839438a1089ec93b5d1402dcaf..6ae050dc32209e0b3bbad59842bc2b0c01c7210c 100644 (file)
@@ -52,6 +52,8 @@
 #include "dm_helpers.h"
 #include "mem_input.h"
 #include "hubp.h"
+
+#include "dc_link_dp.h"
 #define DC_LOGGER \
        dc->ctx->logger
 
@@ -419,8 +421,17 @@ void dc_link_set_preferred_link_settings(struct dc *dc,
                                         struct dc_link_settings *link_setting,
                                         struct dc_link *link)
 {
-       link->preferred_link_setting = *link_setting;
-       dp_retrain_link_dp_test(link, link_setting, false);
+       struct dc_link_settings store_settings = *link_setting;
+       struct dc_stream_state *link_stream =
+               link->dc->current_state->res_ctx.pipe_ctx[0].stream;
+
+       link->preferred_link_setting = store_settings;
+       if (link_stream)
+               decide_link_settings(link_stream, &store_settings);
+
+       if ((store_settings.lane_count != LANE_COUNT_UNKNOWN) &&
+               (store_settings.link_rate != LINK_RATE_UNKNOWN))
+               dp_retrain_link_dp_test(link, &store_settings, false);
 }
 
 void dc_link_enable_hpd(const struct dc_link *link)
@@ -476,7 +487,7 @@ static void destruct(struct dc *dc)
        kfree(dc->bw_dceip);
        dc->bw_dceip = NULL;
 
-#ifdef CONFIG_X86
+#ifdef CONFIG_DRM_AMD_DC_DCN1_0
        kfree(dc->dcn_soc);
        dc->dcn_soc = NULL;
 
@@ -492,7 +503,7 @@ static bool construct(struct dc *dc,
        struct dc_context *dc_ctx;
        struct bw_calcs_dceip *dc_dceip;
        struct bw_calcs_vbios *dc_vbios;
-#ifdef CONFIG_X86
+#ifdef CONFIG_DRM_AMD_DC_DCN1_0
        struct dcn_soc_bounding_box *dcn_soc;
        struct dcn_ip_params *dcn_ip;
 #endif
@@ -514,7 +525,7 @@ static bool construct(struct dc *dc,
        }
 
        dc->bw_vbios = dc_vbios;
-#ifdef CONFIG_X86
+#ifdef CONFIG_DRM_AMD_DC_DCN1_0
        dcn_soc = kzalloc(sizeof(*dcn_soc), GFP_KERNEL);
        if (!dcn_soc) {
                dm_error("%s: failed to create dcn_soc\n", __func__);
index caece7c13bc642114d06779b12e613cdc1c6b8d7..e1ebdf7b5eaf3080882e5c3ea99de0278d9acdb0 100644 (file)
@@ -348,7 +348,7 @@ void context_clock_trace(
                struct dc *dc,
                struct dc_state *context)
 {
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        DC_LOGGER_INIT(dc->ctx->logger);
        CLOCK_TRACE("Current: dispclk_khz:%d  max_dppclk_khz:%d  dcfclk_khz:%d\n"
                        "dcfclk_deep_sleep_khz:%d  fclk_khz:%d  socclk_khz:%d\n",
index 326b3e99b7e4e63a8067207c368a546617050679..37eaf72ace549d6f132b9fc5933da434fc164396 100644 (file)
@@ -754,8 +754,12 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
                         * fail-safe mode
                         */
                        if (dc_is_hdmi_signal(link->connector_signal) ||
-                           dc_is_dvi_signal(link->connector_signal))
+                           dc_is_dvi_signal(link->connector_signal)) {
+                               if (prev_sink != NULL)
+                                       dc_sink_release(prev_sink);
+
                                return false;
+                       }
                default:
                        break;
                }
@@ -1039,9 +1043,6 @@ static bool construct(
 
        link->link_id = bios->funcs->get_connector_id(bios, init_params->connector_index);
 
-       if (dc_ctx->dc_bios->integrated_info)
-               link->dp_ss_off = !!dc_ctx->dc_bios->integrated_info->dp_ss_control;
-
        if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
                dm_error("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d! type %d expected %d\n",
                         __func__, init_params->connector_index,
@@ -1049,6 +1050,9 @@ static bool construct(
                goto create_fail;
        }
 
+       if (link->dc->res_pool->funcs->link_init)
+               link->dc->res_pool->funcs->link_init(link);
+
        hpd_gpio = get_hpd_gpio(link->ctx->dc_bios, link->link_id, link->ctx->gpio_service);
 
        if (hpd_gpio != NULL)
index 1644f2a946b09e79dfccf8306b887496e517df43..ea6beccfd89d3ac0e3aa2119e77f3f133195f89d 100644 (file)
@@ -41,7 +41,7 @@
 #include "dce100/dce100_resource.h"
 #include "dce110/dce110_resource.h"
 #include "dce112/dce112_resource.h"
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 #include "dcn10/dcn10_resource.h"
 #endif
 #include "dce120/dce120_resource.h"
@@ -85,7 +85,7 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id)
        case FAMILY_AI:
                dc_version = DCE_VERSION_12_0;
                break;
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        case FAMILY_RV:
                dc_version = DCN_VERSION_1_0;
                break;
@@ -136,7 +136,7 @@ struct resource_pool *dc_create_resource_pool(
                        num_virtual_links, dc);
                break;
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        case DCN_VERSION_1_0:
                res_pool = dcn10_create_resource_pool(
                                num_virtual_links, dc);
@@ -1251,7 +1251,7 @@ static struct pipe_ctx *acquire_free_pipe_for_stream(
 
 }
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 static int acquire_first_split_pipe(
                struct resource_context *res_ctx,
                const struct resource_pool *pool,
@@ -1322,7 +1322,7 @@ bool dc_add_plane_to_context(
 
        free_pipe = acquire_free_pipe_for_stream(context, pool, stream);
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        if (!free_pipe) {
                int pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream);
                if (pipe_idx >= 0)
@@ -1920,7 +1920,7 @@ enum dc_status resource_map_pool_resources(
        /* acquire new resources */
        pipe_idx = acquire_first_free_pipe(&context->res_ctx, pool, stream);
 
-#ifdef CONFIG_X86
+#ifdef CONFIG_DRM_AMD_DC_DCN1_0
        if (pipe_idx < 0)
                pipe_idx = acquire_first_split_pipe(&context->res_ctx, pool, stream);
 #endif
index e2f033d420a05bb755ece975e66311c942e7767c..6c9990bef267e1cd469de9ab10e60b603e809435 100644 (file)
@@ -294,7 +294,7 @@ struct dc {
        /* Inputs into BW and WM calculations. */
        struct bw_calcs_dceip *bw_dceip;
        struct bw_calcs_vbios *bw_vbios;
-#ifdef CONFIG_X86
+#ifdef CONFIG_DRM_AMD_DC_DCN1_0
        struct dcn_soc_bounding_box *dcn_soc;
        struct dcn_ip_params *dcn_ip;
        struct display_mode_lib dml;
index 439dcf3b596ccdec9447656796499b7848673848..ca137757a69e106e128b4d97c6c2dd99a940ae9a 100644 (file)
@@ -592,7 +592,7 @@ static uint32_t dce110_get_pix_clk_dividers(
        case DCE_VERSION_11_2:
        case DCE_VERSION_11_22:
        case DCE_VERSION_12_0:
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        case DCN_VERSION_1_0:
 #endif
 
@@ -909,7 +909,7 @@ static bool dce110_program_pix_clk(
        struct dce110_clk_src *clk_src = TO_DCE110_CLK_SRC(clock_source);
        struct bp_pixel_clock_parameters bp_pc_params = {0};
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        if (IS_FPGA_MAXIMUS_DC(clock_source->ctx->dce_environment)) {
                unsigned int inst = pix_clk_params->controller_id - CONTROLLER_ID_D0;
                unsigned dp_dto_ref_kHz = 700000;
@@ -982,7 +982,7 @@ static bool dce110_program_pix_clk(
        case DCE_VERSION_11_2:
        case DCE_VERSION_11_22:
        case DCE_VERSION_12_0:
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        case DCN_VERSION_1_0:
 #endif
 
index 801bb65707b3204ed1055d583926b055658a7179..c45e2f76189e7be44dc5178f3b1d25aec9c23f3a 100644 (file)
@@ -55,7 +55,7 @@
        CS_SF(PHYPLLA_PIXCLK_RESYNC_CNTL, PHYPLLA_DCCG_DEEP_COLOR_CNTL, mask_sh),\
        CS_SF(PHYPLLA_PIXCLK_RESYNC_CNTL, PHYPLLA_PIXCLK_DOUBLE_RATE_ENABLE, mask_sh)
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 
 #define CS_COMMON_REG_LIST_DCN1_0(index, pllid) \
                SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\
index 684da3db75686e7b3a2acb254f7adc6a43d3b3ea..fb1f373d08a12f082b3d312bd6abbdc2502f532d 100644 (file)
@@ -30,7 +30,7 @@
 #include "bios_parser_interface.h"
 #include "dc.h"
 #include "dmcu.h"
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 #include "dcn_calcs.h"
 #endif
 #include "core_types.h"
@@ -106,7 +106,8 @@ enum dentist_base_divider_id {
        DENTIST_BASE_DID_1 = 0x08,
        DENTIST_BASE_DID_2 = 0x40,
        DENTIST_BASE_DID_3 = 0x60,
-       DENTIST_MAX_DID    = 0x80
+       DENTIST_BASE_DID_4 = 0x7e,
+       DENTIST_MAX_DID = 0x7f
 };
 
 /* Starting point and step size for each divider range.*/
@@ -117,6 +118,8 @@ enum dentist_divider_range {
        DENTIST_DIVIDER_RANGE_2_STEP  = 2,   /* 0.50  */
        DENTIST_DIVIDER_RANGE_3_START = 128, /* 32.00 */
        DENTIST_DIVIDER_RANGE_3_STEP  = 4,   /* 1.00  */
+       DENTIST_DIVIDER_RANGE_4_START = 248, /* 62.00 */
+       DENTIST_DIVIDER_RANGE_4_STEP  = 264, /* 66.00 */
        DENTIST_DIVIDER_RANGE_SCALE_FACTOR = 4
 };
 
@@ -133,9 +136,12 @@ static int dentist_get_divider_from_did(int did)
        } else if (did < DENTIST_BASE_DID_3) {
                return DENTIST_DIVIDER_RANGE_2_START + DENTIST_DIVIDER_RANGE_2_STEP
                                                        * (did - DENTIST_BASE_DID_2);
-       } else {
+       } else if (did < DENTIST_BASE_DID_4) {
                return DENTIST_DIVIDER_RANGE_3_START + DENTIST_DIVIDER_RANGE_3_STEP
                                                        * (did - DENTIST_BASE_DID_3);
+       } else {
+               return DENTIST_DIVIDER_RANGE_4_START + DENTIST_DIVIDER_RANGE_4_STEP
+                                                       * (did - DENTIST_BASE_DID_4);
        }
 }
 
@@ -478,7 +484,7 @@ static void dce12_update_clocks(struct dccg *dccg,
        }
 }
 
-#ifdef CONFIG_X86
+#ifdef CONFIG_DRM_AMD_DC_DCN1_0
 static int dcn1_determine_dppclk_threshold(struct dccg *dccg, struct dc_clocks *new_clocks)
 {
        bool request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz;
@@ -668,7 +674,7 @@ static void dce_update_clocks(struct dccg *dccg,
        }
 }
 
-#ifdef CONFIG_X86
+#ifdef CONFIG_DRM_AMD_DC_DCN1_0
 static const struct display_clock_funcs dcn1_funcs = {
        .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
        .set_dispclk = dce112_set_clock,
@@ -823,7 +829,7 @@ struct dccg *dce120_dccg_create(struct dc_context *ctx)
        return &clk_dce->base;
 }
 
-#ifdef CONFIG_X86
+#ifdef CONFIG_DRM_AMD_DC_DCN1_0
 struct dccg *dcn1_dccg_create(struct dc_context *ctx)
 {
        struct dc_debug_options *debug = &ctx->dc->debug;
index e5e44adc6c27cda88930ab020c04ee6e0458e803..8a6b2d328467cd7ff011334beaeeda96e4ef0a3f 100644 (file)
@@ -111,7 +111,7 @@ struct dccg *dce112_dccg_create(
 
 struct dccg *dce120_dccg_create(struct dc_context *ctx);
 
-#ifdef CONFIG_X86
+#ifdef CONFIG_DRM_AMD_DC_DCN1_0
 struct dccg *dcn1_dccg_create(struct dc_context *ctx);
 #endif
 
index ca7989e4932bdd93a848ee46421986a094579228..dea40b3221918279795828d701aa336174dc9073 100644 (file)
@@ -316,7 +316,7 @@ static void dce_get_psr_wait_loop(
        return;
 }
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 static void dcn10_get_dmcu_state(struct dmcu *dmcu)
 {
        struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu);
@@ -743,7 +743,7 @@ static const struct dmcu_funcs dce_funcs = {
        .is_dmcu_initialized = dce_is_dmcu_initialized
 };
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 static const struct dmcu_funcs dcn10_funcs = {
        .dmcu_init = dcn10_dmcu_init,
        .load_iram = dcn10_dmcu_load_iram,
@@ -795,7 +795,7 @@ struct dmcu *dce_dmcu_create(
        return &dmcu_dce->base;
 }
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 struct dmcu *dcn10_dmcu_create(
        struct dc_context *ctx,
        const struct dce_dmcu_registers *regs,
index b139b40178200f41ce4c31e31beb899da0835df8..91642e6848587b54e2d6f7b33a9ea460c133926a 100644 (file)
@@ -135,7 +135,7 @@ static void dce110_update_generic_info_packet(
                        AFMT_GENERIC0_UPDATE, (packet_index == 0),
                        AFMT_GENERIC2_UPDATE, (packet_index == 2));
        }
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        if (REG(AFMT_VBI_PACKET_CONTROL1)) {
                switch (packet_index) {
                case 0:
@@ -229,7 +229,7 @@ static void dce110_update_hdmi_info_packet(
                                HDMI_GENERIC1_SEND, send,
                                HDMI_GENERIC1_LINE, line);
                break;
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        case 4:
                if (REG(HDMI_GENERIC_PACKET_CONTROL2))
                        REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL2,
@@ -274,7 +274,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute(
        struct dc_crtc_timing *crtc_timing,
        enum dc_color_space output_color_space)
 {
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        uint32_t h_active_start;
        uint32_t v_active_start;
        uint32_t misc0 = 0;
@@ -317,7 +317,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute(
                if (enc110->se_mask->DP_VID_M_DOUBLE_VALUE_EN)
                        REG_UPDATE(DP_VID_TIMING, DP_VID_M_DOUBLE_VALUE_EN, 1);
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
                if (enc110->se_mask->DP_VID_N_MUL)
                        REG_UPDATE(DP_VID_TIMING, DP_VID_N_MUL, 1);
 #endif
@@ -328,7 +328,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute(
                break;
        }
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        if (REG(DP_MSA_MISC))
                misc1 = REG_READ(DP_MSA_MISC);
 #endif
@@ -362,7 +362,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute(
        /* set dynamic range and YCbCr range */
 
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        switch (crtc_timing->display_color_depth) {
        case COLOR_DEPTH_666:
                colorimetry_bpc = 0;
@@ -441,7 +441,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute(
                                DP_DYN_RANGE, dynamic_range_rgb,
                                DP_YCBCR_RANGE, dynamic_range_ycbcr);
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
                if (REG(DP_MSA_COLORIMETRY))
                        REG_SET(DP_MSA_COLORIMETRY, 0, DP_MSA_MISC0, misc0);
 
@@ -476,7 +476,7 @@ static void dce110_stream_encoder_dp_set_stream_attribute(
                                crtc_timing->v_front_porch;
 
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
                /* start at begining of left border */
                if (REG(DP_MSA_TIMING_PARAM2))
                        REG_SET_2(DP_MSA_TIMING_PARAM2, 0,
@@ -751,7 +751,7 @@ static void dce110_stream_encoder_update_hdmi_info_packets(
                dce110_update_hdmi_info_packet(enc110, 3, &info_frame->hdrsmd);
        }
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        if (enc110->se_mask->HDMI_DB_DISABLE) {
                /* for bring up, disable dp double  TODO */
                if (REG(HDMI_DB_CONTROL))
@@ -789,7 +789,7 @@ static void dce110_stream_encoder_stop_hdmi_info_packets(
                HDMI_GENERIC1_LINE, 0,
                HDMI_GENERIC1_SEND, 0);
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        /* stop generic packets 2 & 3 on HDMI */
        if (REG(HDMI_GENERIC_PACKET_CONTROL2))
                REG_SET_6(HDMI_GENERIC_PACKET_CONTROL2, 0,
index 5450d4d38e8a49a3f59331eb0388b8d3fff54264..14384d9675a8c4cc23fc67162f9f3f9cd7a17a22 100644 (file)
@@ -1250,7 +1250,7 @@ static void program_scaler(const struct dc *dc,
 {
        struct tg_color color = {0};
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        /* TOFPGA */
        if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL)
                return;
@@ -1588,7 +1588,13 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
        bool can_eDP_fast_boot_optimize = false;
 
        if (edp_link) {
-               can_eDP_fast_boot_optimize =
+               /* this seems to cause blank screens on DCE8 */
+               if ((dc->ctx->dce_version == DCE_VERSION_8_0) ||
+                   (dc->ctx->dce_version == DCE_VERSION_8_1) ||
+                   (dc->ctx->dce_version == DCE_VERSION_8_3))
+                       can_eDP_fast_boot_optimize = false;
+               else
+                       can_eDP_fast_boot_optimize =
                                edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc);
        }
 
index b9d9930a49743cbae8d54c45d88326a7c3444be9..562ee189d780c4de20d150a16497c27ef44300a8 100644 (file)
@@ -61,7 +61,7 @@ AMD_DISPLAY_FILES += $(AMD_DAL_GPIO_DCE120)
 ###############################################################################
 # DCN 1x
 ###############################################################################
-ifdef CONFIG_X86
+ifdef CONFIG_DRM_AMD_DC_DCN1_0
 GPIO_DCN10 = hw_translate_dcn10.o hw_factory_dcn10.o
 
 AMD_DAL_GPIO_DCN10 = $(addprefix $(AMDDALPATH)/dc/gpio/dcn10/,$(GPIO_DCN10))
index 83df779984e5da9d32df682f5fea318426684d00..0caee3523017fe74e45a217e604cd57004a64486 100644 (file)
@@ -43,7 +43,7 @@
 #include "dce80/hw_factory_dce80.h"
 #include "dce110/hw_factory_dce110.h"
 #include "dce120/hw_factory_dce120.h"
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 #include "dcn10/hw_factory_dcn10.h"
 #endif
 
@@ -81,7 +81,7 @@ bool dal_hw_factory_init(
        case DCE_VERSION_12_0:
                dal_hw_factory_dce120_init(factory);
                return true;
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        case DCN_VERSION_1_0:
                dal_hw_factory_dcn10_init(factory);
                return true;
index e7541310480b1ce32f60fff366f56d99c0884b4b..55c7074885413e8ebba1ce2ccc886f6586850c87 100644 (file)
@@ -43,7 +43,7 @@
 #include "dce80/hw_translate_dce80.h"
 #include "dce110/hw_translate_dce110.h"
 #include "dce120/hw_translate_dce120.h"
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 #include "dcn10/hw_translate_dcn10.h"
 #endif
 
@@ -78,7 +78,7 @@ bool dal_hw_translate_init(
        case DCE_VERSION_12_0:
                dal_hw_translate_dce120_init(translate);
                return true;
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        case DCN_VERSION_1_0:
                dal_hw_translate_dcn10_init(translate);
                return true;
index a851d07f01901c1f4dad48090f26d3e0fd1c31c3..352885cb4d0763dd3bb4912e59722abd9ee4589c 100644 (file)
@@ -71,7 +71,7 @@ AMD_DISPLAY_FILES += $(AMD_DAL_I2CAUX_DCE112)
 ###############################################################################
 # DCN 1.0 family
 ###############################################################################
-ifdef CONFIG_X86
+ifdef CONFIG_DRM_AMD_DC_DCN1_0
 I2CAUX_DCN1 = i2caux_dcn10.o
 
 AMD_DAL_I2CAUX_DCN1 = $(addprefix $(AMDDALPATH)/dc/i2caux/dcn10/,$(I2CAUX_DCN1))
index f7ed355fc84f44441563a8aea903477cf89ed5d9..9b0bcc6b769b570c4a4ca4cf081072c2b260a4c4 100644 (file)
@@ -59,7 +59,7 @@
 
 #include "dce120/i2caux_dce120.h"
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 #include "dcn10/i2caux_dcn10.h"
 #endif
 
@@ -91,7 +91,7 @@ struct i2caux *dal_i2caux_create(
                return dal_i2caux_dce100_create(ctx);
        case DCE_VERSION_12_0:
                return dal_i2caux_dce120_create(ctx);
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
        case DCN_VERSION_1_0:
                return dal_i2caux_dcn10_create(ctx);
 #endif
index 9f33306f9014f08139ef908ea677b33b0db3f367..c0b9ca13393b61a502902b4950dc43e462b8c718 100644 (file)
@@ -33,7 +33,7 @@
 #include "dc_bios_types.h"
 #include "mem_input.h"
 #include "hubp.h"
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 #include "mpc.h"
 #endif
 
@@ -92,6 +92,7 @@ struct resource_context;
 
 struct resource_funcs {
        void (*destroy)(struct resource_pool **pool);
+       void (*link_init)(struct dc_link *link);
        struct link_encoder *(*link_enc_create)(
                        const struct encoder_init_data *init);
 
@@ -221,7 +222,7 @@ struct pipe_ctx {
        struct pipe_ctx *top_pipe;
        struct pipe_ctx *bottom_pipe;
 
-#ifdef CONFIG_X86
+#ifdef CONFIG_DRM_AMD_DC_DCN1_0
        struct _vcs_dpi_display_dlg_regs_st dlg_regs;
        struct _vcs_dpi_display_ttu_regs_st ttu_regs;
        struct _vcs_dpi_display_rq_regs_st rq_regs;
@@ -276,7 +277,7 @@ struct dc_state {
 
        /* Note: these are big structures, do *not* put on stack! */
        struct dm_pp_display_configuration pp_display_cfg;
-#ifdef CONFIG_X86
+#ifdef CONFIG_DRM_AMD_DC_DCN1_0
        struct dcn_bw_internal_vars dcn_bw_vars;
 #endif
 
index a76ee600eceeae72befe641578fd2c6032432647..498515aad4a50bf35133755d1bded3a387a0817e 100644 (file)
@@ -60,7 +60,7 @@ AMD_DISPLAY_FILES += $(AMD_DAL_IRQ_DCE12)
 ###############################################################################
 # DCN 1x
 ###############################################################################
-ifdef CONFIG_X86
+ifdef CONFIG_DRM_AMD_DC_DCN1_0
 IRQ_DCN1 = irq_service_dcn10.o
 
 AMD_DAL_IRQ_DCN1 = $(addprefix $(AMDDALPATH)/dc/irq/dcn10/,$(IRQ_DCN1))
index ae3fd0a235ba45ce900fe6b0aeba7354b7b847cf..604bea01fc13ee5eea9840d238d0fbcc98eec113 100644 (file)
@@ -36,7 +36,7 @@
 #include "dce120/irq_service_dce120.h"
 
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 #include "dcn10/irq_service_dcn10.h"
 #endif
 
index c9fce9066ad8b43b970c450c25690b3d5bb9096b..a407892905af29661a70ad75a6c76c5d502163c3 100644 (file)
@@ -48,7 +48,7 @@
 
 #define dm_error(fmt, ...) DRM_ERROR(fmt, ##__VA_ARGS__)
 
-#ifdef CONFIG_X86
+#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
 #include <asm/fpu/api.h>
 #endif
 
index 53207e76b0f348a9ba82cb7bc347e78a6c7daab3..6ef3c875fedd555edbd667267639a6ed4aeb4485 100644 (file)
@@ -75,10 +75,12 @@ int phm_set_power_state(struct pp_hwmgr *hwmgr,
 
 int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr)
 {
+       struct amdgpu_device *adev = NULL;
        int ret = -EINVAL;;
        PHM_FUNC_CHECK(hwmgr);
+       adev = hwmgr->adev;
 
-       if (smum_is_dpm_running(hwmgr)) {
+       if (smum_is_dpm_running(hwmgr) && !amdgpu_passthrough(adev)) {
                pr_info("dpm has been enabled\n");
                return 0;
        }
index 5dc742b27ca033652880ceaabc1257ae5b633328..3c9fc99648b7c912a4b9fa686798d8fe8d23b651 100644 (file)
@@ -116,6 +116,9 @@ static const struct edid_quirk {
        /* CPT panel of Asus UX303LA reports 8 bpc, but is a 6 bpc panel */
        { "CPT", 0x17df, EDID_QUIRK_FORCE_6BPC },
 
+       /* SDC panel of Lenovo B50-80 reports 8 bpc, but is a 6 bpc panel */
+       { "SDC", 0x3652, EDID_QUIRK_FORCE_6BPC },
+
        /* Belinea 10 15 55 */
        { "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
        { "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
index 2f00a37684a22b22042027adfbdf6358d55ff81f..adefae58b5fcd6e09d513aed236c12d220e406c5 100644 (file)
@@ -108,7 +108,7 @@ static int psbfb_pan(struct fb_var_screeninfo *var, struct fb_info *info)
         return 0;
 }
 
-static int psbfb_vm_fault(struct vm_fault *vmf)
+static vm_fault_t psbfb_vm_fault(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
        struct psb_framebuffer *psbfb = vma->vm_private_data;
@@ -118,7 +118,7 @@ static int psbfb_vm_fault(struct vm_fault *vmf)
        int page_num;
        int i;
        unsigned long address;
-       int ret;
+       vm_fault_t ret = VM_FAULT_SIGBUS;
        unsigned long pfn;
        unsigned long phys_addr = (unsigned long)dev_priv->stolen_base +
                                  gtt->offset;
@@ -131,18 +131,14 @@ static int psbfb_vm_fault(struct vm_fault *vmf)
        for (i = 0; i < page_num; i++) {
                pfn = (phys_addr >> PAGE_SHIFT);
 
-               ret = vm_insert_mixed(vma, address,
+               ret = vmf_insert_mixed(vma, address,
                                __pfn_to_pfn_t(pfn, PFN_DEV));
-               if (unlikely((ret == -EBUSY) || (ret != 0 && i > 0)))
+               if (unlikely(ret & VM_FAULT_ERROR))
                        break;
-               else if (unlikely(ret != 0)) {
-                       ret = (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS;
-                       return ret;
-               }
                address += PAGE_SIZE;
                phys_addr += PAGE_SIZE;
        }
-       return VM_FAULT_NOPAGE;
+       return ret;
 }
 
 static void psbfb_vm_open(struct vm_area_struct *vma)
index 913bf4c256faffa1fb3324df6b259f052004ba64..576f1b272f23854bf23277520052a03cb2562b9f 100644 (file)
@@ -134,12 +134,13 @@ int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
  *     vma->vm_private_data points to the GEM object that is backing this
  *     mapping.
  */
-int psb_gem_fault(struct vm_fault *vmf)
+vm_fault_t psb_gem_fault(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
        struct drm_gem_object *obj;
        struct gtt_range *r;
-       int ret;
+       int err;
+       vm_fault_t ret;
        unsigned long pfn;
        pgoff_t page_offset;
        struct drm_device *dev;
@@ -158,9 +159,10 @@ int psb_gem_fault(struct vm_fault *vmf)
        /* For now the mmap pins the object and it stays pinned. As things
           stand that will do us no harm */
        if (r->mmapping == 0) {
-               ret = psb_gtt_pin(r);
-               if (ret < 0) {
-                       dev_err(dev->dev, "gma500: pin failed: %d\n", ret);
+               err = psb_gtt_pin(r);
+               if (err < 0) {
+                       dev_err(dev->dev, "gma500: pin failed: %d\n", err);
+                       ret = vmf_error(err);
                        goto fail;
                }
                r->mmapping = 1;
@@ -175,18 +177,9 @@ int psb_gem_fault(struct vm_fault *vmf)
                pfn = (dev_priv->stolen_base + r->offset) >> PAGE_SHIFT;
        else
                pfn = page_to_pfn(r->pages[page_offset]);
-       ret = vm_insert_pfn(vma, vmf->address, pfn);
-
+       ret = vmf_insert_pfn(vma, vmf->address, pfn);
 fail:
        mutex_unlock(&dev_priv->mmap_mutex);
-       switch (ret) {
-       case 0:
-       case -ERESTARTSYS:
-       case -EINTR:
-               return VM_FAULT_NOPAGE;
-       case -ENOMEM:
-               return VM_FAULT_OOM;
-       default:
-               return VM_FAULT_SIGBUS;
-       }
+
+       return ret;
 }
index e8300f50902343957e2967a9cd581244a5bf01ad..93d2f4000d2f90beb943539dd0bdfc0f668c7707 100644 (file)
@@ -21,6 +21,7 @@
 #define _PSB_DRV_H_
 
 #include <linux/kref.h>
+#include <linux/mm_types.h>
 
 #include <drm/drmP.h>
 #include <drm/drm_global.h>
@@ -749,7 +750,7 @@ extern int psb_gem_get_aperture(struct drm_device *dev, void *data,
                        struct drm_file *file);
 extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
                        struct drm_mode_create_dumb *args);
-extern int psb_gem_fault(struct vm_fault *vmf);
+extern vm_fault_t psb_gem_fault(struct vm_fault *vmf);
 
 /* psb_device.c */
 extern const struct psb_ops psb_chip_ops;
index 6e3f56684f4ec03e7285b9e3715688ce31de311d..51ed99a37803310e2d9b7e84882ae7df97e3b59c 100644 (file)
@@ -170,20 +170,22 @@ static struct drm_i915_gem_object *vgpu_create_gem(struct drm_device *dev,
                unsigned int tiling_mode = 0;
                unsigned int stride = 0;
 
-               switch (info->drm_format_mod << 10) {
-               case PLANE_CTL_TILED_LINEAR:
+               switch (info->drm_format_mod) {
+               case DRM_FORMAT_MOD_LINEAR:
                        tiling_mode = I915_TILING_NONE;
                        break;
-               case PLANE_CTL_TILED_X:
+               case I915_FORMAT_MOD_X_TILED:
                        tiling_mode = I915_TILING_X;
                        stride = info->stride;
                        break;
-               case PLANE_CTL_TILED_Y:
+               case I915_FORMAT_MOD_Y_TILED:
+               case I915_FORMAT_MOD_Yf_TILED:
                        tiling_mode = I915_TILING_Y;
                        stride = info->stride;
                        break;
                default:
-                       gvt_dbg_core("not supported tiling mode\n");
+                       gvt_dbg_core("invalid drm_format_mod %llx for tiling\n",
+                                    info->drm_format_mod);
                }
                obj->tiling_and_stride = tiling_mode | stride;
        } else {
@@ -222,9 +224,26 @@ static int vgpu_get_plane_info(struct drm_device *dev,
                info->height = p.height;
                info->stride = p.stride;
                info->drm_format = p.drm_format;
-               info->drm_format_mod = p.tiled;
+
+               switch (p.tiled) {
+               case PLANE_CTL_TILED_LINEAR:
+                       info->drm_format_mod = DRM_FORMAT_MOD_LINEAR;
+                       break;
+               case PLANE_CTL_TILED_X:
+                       info->drm_format_mod = I915_FORMAT_MOD_X_TILED;
+                       break;
+               case PLANE_CTL_TILED_Y:
+                       info->drm_format_mod = I915_FORMAT_MOD_Y_TILED;
+                       break;
+               case PLANE_CTL_TILED_YF:
+                       info->drm_format_mod = I915_FORMAT_MOD_Yf_TILED;
+                       break;
+               default:
+                       gvt_vgpu_err("invalid tiling mode: %x\n", p.tiled);
+               }
+
                info->size = (((p.stride * p.height * p.bpp) / 8) +
-                               (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+                             (PAGE_SIZE - 1)) >> PAGE_SHIFT;
        } else if (plane_id == DRM_PLANE_TYPE_CURSOR) {
                ret = intel_vgpu_decode_cursor_plane(vgpu, &c);
                if (ret)
index face664be3e8e8bf673e589c7ff9b176f8102a76..481896fb712abf4c178b28af2f224a369d0aefd9 100644 (file)
@@ -220,8 +220,7 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
        if (IS_SKYLAKE(dev_priv)
                || IS_KABYLAKE(dev_priv)
                || IS_BROXTON(dev_priv)) {
-               plane->tiled = (val & PLANE_CTL_TILED_MASK) >>
-               _PLANE_CTL_TILED_SHIFT;
+               plane->tiled = val & PLANE_CTL_TILED_MASK;
                fmt = skl_format_to_drm(
                        val & PLANE_CTL_FORMAT_MASK,
                        val & PLANE_CTL_ORDER_RGBX,
@@ -260,7 +259,7 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
                return  -EINVAL;
        }
 
-       plane->stride = intel_vgpu_get_stride(vgpu, pipe, (plane->tiled << 10),
+       plane->stride = intel_vgpu_get_stride(vgpu, pipe, plane->tiled,
                (IS_SKYLAKE(dev_priv)
                || IS_KABYLAKE(dev_priv)
                || IS_BROXTON(dev_priv)) ?
index cb055f3c81a29c629f2dcc327ce0da9a1b827ee3..60c155085029cbb4742341a94d4d24a56da3d0c5 100644 (file)
@@ -101,7 +101,7 @@ struct intel_gvt;
 /* color space conversion and gamma correction are not included */
 struct intel_vgpu_primary_plane_format {
        u8      enabled;        /* plane is enabled */
-       u8      tiled;          /* X-tiled */
+       u32     tiled;          /* tiling mode: linear, X-tiled, Y tiled, etc */
        u8      bpp;            /* bits per pixel */
        u32     hw_format;      /* format field in the PRI_CTL register */
        u32     drm_format;     /* format in DRM definition */
index 7a58ca5551977a086ce8b25dbe18aa26497f45bc..72afa518edd91157f6a221f277536c0f96e30899 100644 (file)
@@ -1296,6 +1296,19 @@ static int power_well_ctl_mmio_write(struct intel_vgpu *vgpu,
        return 0;
 }
 
+static int gen9_dbuf_ctl_mmio_write(struct intel_vgpu *vgpu,
+               unsigned int offset, void *p_data, unsigned int bytes)
+{
+       write_vreg(vgpu, offset, p_data, bytes);
+
+       if (vgpu_vreg(vgpu, offset) & DBUF_POWER_REQUEST)
+               vgpu_vreg(vgpu, offset) |= DBUF_POWER_STATE;
+       else
+               vgpu_vreg(vgpu, offset) &= ~DBUF_POWER_STATE;
+
+       return 0;
+}
+
 static int fpga_dbg_mmio_write(struct intel_vgpu *vgpu,
        unsigned int offset, void *p_data, unsigned int bytes)
 {
@@ -1525,9 +1538,15 @@ static int bxt_phy_ctl_family_write(struct intel_vgpu *vgpu,
        u32 v = *(u32 *)p_data;
        u32 data = v & COMMON_RESET_DIS ? BXT_PHY_LANE_ENABLED : 0;
 
-       vgpu_vreg(vgpu, _BXT_PHY_CTL_DDI_A) = data;
-       vgpu_vreg(vgpu, _BXT_PHY_CTL_DDI_B) = data;
-       vgpu_vreg(vgpu, _BXT_PHY_CTL_DDI_C) = data;
+       switch (offset) {
+       case _PHY_CTL_FAMILY_EDP:
+               vgpu_vreg(vgpu, _BXT_PHY_CTL_DDI_A) = data;
+               break;
+       case _PHY_CTL_FAMILY_DDI:
+               vgpu_vreg(vgpu, _BXT_PHY_CTL_DDI_B) = data;
+               vgpu_vreg(vgpu, _BXT_PHY_CTL_DDI_C) = data;
+               break;
+       }
 
        vgpu_vreg(vgpu, offset) = v;
 
@@ -2812,6 +2831,8 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
        MMIO_DH(HSW_PWR_WELL_CTL_DRIVER(SKL_DISP_PW_MISC_IO), D_SKL_PLUS, NULL,
                skl_power_well_ctl_write);
 
+       MMIO_DH(DBUF_CTL, D_SKL_PLUS, NULL, gen9_dbuf_ctl_mmio_write);
+
        MMIO_D(_MMIO(0xa210), D_SKL_PLUS);
        MMIO_D(GEN9_MEDIA_PG_IDLE_HYSTERESIS, D_SKL_PLUS);
        MMIO_D(GEN9_RENDER_PG_IDLE_HYSTERESIS, D_SKL_PLUS);
@@ -2987,8 +3008,6 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
                NULL, gen9_trtte_write);
        MMIO_DH(_MMIO(0x4dfc), D_SKL_PLUS, NULL, gen9_trtt_chicken_write);
 
-       MMIO_D(_MMIO(0x45008), D_SKL_PLUS);
-
        MMIO_D(_MMIO(0x46430), D_SKL_PLUS);
 
        MMIO_D(_MMIO(0x46520), D_SKL_PLUS);
@@ -3025,7 +3044,9 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
        MMIO_D(_MMIO(0x44500), D_SKL_PLUS);
        MMIO_DFH(GEN9_CSFE_CHICKEN1_RCS, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
        MMIO_DFH(GEN8_HDC_CHICKEN1, D_SKL_PLUS, F_MODE_MASK | F_CMD_ACCESS,
-               NULL, NULL);
+                NULL, NULL);
+       MMIO_DFH(GEN9_WM_CHICKEN3, D_SKL_PLUS, F_MODE_MASK | F_CMD_ACCESS,
+                NULL, NULL);
 
        MMIO_D(_MMIO(0x4ab8), D_KBL);
        MMIO_D(_MMIO(0x2248), D_KBL | D_SKL);
index 42e1e6bdcc2cfe64a3446eea8019b9a912141ba0..e872f4847fbe0ce9a1e646bbea84eb0b6b2e1f29 100644 (file)
@@ -562,11 +562,9 @@ void intel_gvt_switch_mmio(struct intel_vgpu *pre,
         * performace for batch mmio read/write, so we need
         * handle forcewake mannually.
         */
-       intel_runtime_pm_get(dev_priv);
        intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
        switch_mmio(pre, next, ring_id);
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
-       intel_runtime_pm_put(dev_priv);
 }
 
 /**
index 09d7bb72b4ff30e45688add463c1fdaaa9a71ad1..c32e7d5e862914b787d7cf5cbf706cb5c4a41748 100644 (file)
@@ -47,11 +47,15 @@ static bool vgpu_has_pending_workload(struct intel_vgpu *vgpu)
        return false;
 }
 
+/* We give 2 seconds higher prio for vGPU during start */
+#define GVT_SCHED_VGPU_PRI_TIME  2
+
 struct vgpu_sched_data {
        struct list_head lru_list;
        struct intel_vgpu *vgpu;
        bool active;
-
+       bool pri_sched;
+       ktime_t pri_time;
        ktime_t sched_in_time;
        ktime_t sched_time;
        ktime_t left_ts;
@@ -183,6 +187,14 @@ static struct intel_vgpu *find_busy_vgpu(struct gvt_sched_data *sched_data)
                if (!vgpu_has_pending_workload(vgpu_data->vgpu))
                        continue;
 
+               if (vgpu_data->pri_sched) {
+                       if (ktime_before(ktime_get(), vgpu_data->pri_time)) {
+                               vgpu = vgpu_data->vgpu;
+                               break;
+                       } else
+                               vgpu_data->pri_sched = false;
+               }
+
                /* Return the vGPU only if it has time slice left */
                if (vgpu_data->left_ts > 0) {
                        vgpu = vgpu_data->vgpu;
@@ -202,6 +214,7 @@ static void tbs_sched_func(struct gvt_sched_data *sched_data)
        struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler;
        struct vgpu_sched_data *vgpu_data;
        struct intel_vgpu *vgpu = NULL;
+
        /* no active vgpu or has already had a target */
        if (list_empty(&sched_data->lru_runq_head) || scheduler->next_vgpu)
                goto out;
@@ -209,12 +222,13 @@ static void tbs_sched_func(struct gvt_sched_data *sched_data)
        vgpu = find_busy_vgpu(sched_data);
        if (vgpu) {
                scheduler->next_vgpu = vgpu;
-
-               /* Move the last used vGPU to the tail of lru_list */
                vgpu_data = vgpu->sched_data;
-               list_del_init(&vgpu_data->lru_list);
-               list_add_tail(&vgpu_data->lru_list,
-                               &sched_data->lru_runq_head);
+               if (!vgpu_data->pri_sched) {
+                       /* Move the last used vGPU to the tail of lru_list */
+                       list_del_init(&vgpu_data->lru_list);
+                       list_add_tail(&vgpu_data->lru_list,
+                                     &sched_data->lru_runq_head);
+               }
        } else {
                scheduler->next_vgpu = gvt->idle_vgpu;
        }
@@ -328,11 +342,17 @@ static void tbs_sched_start_schedule(struct intel_vgpu *vgpu)
 {
        struct gvt_sched_data *sched_data = vgpu->gvt->scheduler.sched_data;
        struct vgpu_sched_data *vgpu_data = vgpu->sched_data;
+       ktime_t now;
 
        if (!list_empty(&vgpu_data->lru_list))
                return;
 
-       list_add_tail(&vgpu_data->lru_list, &sched_data->lru_runq_head);
+       now = ktime_get();
+       vgpu_data->pri_time = ktime_add(now,
+                                       ktime_set(GVT_SCHED_VGPU_PRI_TIME, 0));
+       vgpu_data->pri_sched = true;
+
+       list_add(&vgpu_data->lru_list, &sched_data->lru_runq_head);
 
        if (!hrtimer_active(&sched_data->timer))
                hrtimer_start(&sched_data->timer, ktime_add_ns(ktime_get(),
@@ -426,6 +446,7 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu)
                &vgpu->gvt->scheduler;
        int ring_id;
        struct vgpu_sched_data *vgpu_data = vgpu->sched_data;
+       struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 
        if (!vgpu_data->active)
                return;
@@ -444,6 +465,7 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu)
                scheduler->current_vgpu = NULL;
        }
 
+       intel_runtime_pm_get(dev_priv);
        spin_lock_bh(&scheduler->mmio_context_lock);
        for (ring_id = 0; ring_id < I915_NUM_ENGINES; ring_id++) {
                if (scheduler->engine_owner[ring_id] == vgpu) {
@@ -452,5 +474,6 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu)
                }
        }
        spin_unlock_bh(&scheduler->mmio_context_lock);
+       intel_runtime_pm_put(dev_priv);
        mutex_unlock(&vgpu->gvt->sched_lock);
 }
index dcd6e230d16aa7905c1ae075fab469e333f7ef8b..2c9b284036d10217a013e146eba8704123006d65 100644 (file)
@@ -112,10 +112,11 @@ static void del_object(struct i915_mmu_object *mo)
        mo->attached = false;
 }
 
-static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
+static int i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
                                                       struct mm_struct *mm,
                                                       unsigned long start,
-                                                      unsigned long end)
+                                                      unsigned long end,
+                                                      bool blockable)
 {
        struct i915_mmu_notifier *mn =
                container_of(_mn, struct i915_mmu_notifier, mn);
@@ -124,7 +125,7 @@ static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
        LIST_HEAD(cancelled);
 
        if (RB_EMPTY_ROOT(&mn->objects.rb_root))
-               return;
+               return 0;
 
        /* interval ranges are inclusive, but invalidate range is exclusive */
        end--;
@@ -132,6 +133,10 @@ static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
        spin_lock(&mn->lock);
        it = interval_tree_iter_first(&mn->objects, start, end);
        while (it) {
+               if (!blockable) {
+                       spin_unlock(&mn->lock);
+                       return -EAGAIN;
+               }
                /* The mmu_object is released late when destroying the
                 * GEM object so it is entirely possible to gain a
                 * reference on an object in the process of being freed
@@ -154,6 +159,8 @@ static void i915_gem_userptr_mn_invalidate_range_start(struct mmu_notifier *_mn,
 
        if (!list_empty(&cancelled))
                flush_workqueue(mn->wq);
+
+       return 0;
 }
 
 static const struct mmu_notifier_ops i915_gem_userptr_notifier = {
index 08ec7446282e7f981f74272e8c29c755abad9e21..9e63cd47b60f30a5b0f7682d2c3038dd81e2b3ce 100644 (file)
@@ -10422,7 +10422,7 @@ enum skl_power_gate {
                                                           _ICL_DSC0_PICTURE_PARAMETER_SET_4_PB, \
                                                           _ICL_DSC0_PICTURE_PARAMETER_SET_4_PC)
 #define ICL_DSC1_PICTURE_PARAMETER_SET_4(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
-                                                          _ICL_DSC0_PICTURE_PARAMETER_SET_4_PB, \
+                                                          _ICL_DSC1_PICTURE_PARAMETER_SET_4_PB, \
                                                           _ICL_DSC1_PICTURE_PARAMETER_SET_4_PC)
 #define  DSC_INITIAL_DEC_DELAY(dec_delay)       ((dec_delay) << 16)
 #define  DSC_INITIAL_XMIT_DELAY(xmit_delay)     ((xmit_delay) << 0)
@@ -10437,7 +10437,7 @@ enum skl_power_gate {
                                                           _ICL_DSC0_PICTURE_PARAMETER_SET_5_PB, \
                                                           _ICL_DSC0_PICTURE_PARAMETER_SET_5_PC)
 #define ICL_DSC1_PICTURE_PARAMETER_SET_5(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
-                                                          _ICL_DSC1_PICTURE_PARAMETER_SET_5_PC, \
+                                                          _ICL_DSC1_PICTURE_PARAMETER_SET_5_PB, \
                                                           _ICL_DSC1_PICTURE_PARAMETER_SET_5_PC)
 #define  DSC_SCALE_DEC_INTINT(scale_dec)       ((scale_dec) << 16)
 #define  DSC_SCALE_INC_INT(scale_inc)          ((scale_inc) << 0)
index 00165ad55fb3dc9846447ac9a5d5cc0ca3a0e948..395dd251156833d46a48de3e49163c22a6627bc8 100644 (file)
@@ -43,7 +43,7 @@
 #define MISSING_CASE(x) WARN(1, "Missing case (%s == %ld)\n", \
                             __stringify(x), (long)(x))
 
-#if GCC_VERSION >= 70000
+#if defined(GCC_VERSION) && GCC_VERSION >= 70000
 #define add_overflows(A, B) \
        __builtin_add_overflow_p((A), (B), (typeof((A) + (B)))0)
 #else
index 11d834f942205f37c10c1a95a345b8908cb3411f..98358b4b36dea7e13177bdf38554ffaad4f994e9 100644 (file)
@@ -199,7 +199,6 @@ vma_create(struct drm_i915_gem_object *obj,
                vma->flags |= I915_VMA_GGTT;
                list_add(&vma->obj_link, &obj->vma_list);
        } else {
-               i915_ppgtt_get(i915_vm_to_ppgtt(vm));
                list_add_tail(&vma->obj_link, &obj->vma_list);
        }
 
@@ -807,9 +806,6 @@ static void __i915_vma_destroy(struct i915_vma *vma)
        if (vma->obj)
                rb_erase(&vma->obj_node, &vma->obj->vma_tree);
 
-       if (!i915_vma_is_ggtt(vma))
-               i915_ppgtt_put(i915_vm_to_ppgtt(vma->vm));
-
        rbtree_postorder_for_each_entry_safe(iter, n, &vma->active, node) {
                GEM_BUG_ON(i915_gem_active_isset(&iter->base));
                kfree(iter);
index b725835b47efc5116b53e3f27eeb6e0fcdbb65b4..769f3f5866611174cbabeca5e4d1fbb0711b9b86 100644 (file)
@@ -962,9 +962,6 @@ void i915_audio_component_init(struct drm_i915_private *dev_priv)
 {
        int ret;
 
-       if (INTEL_INFO(dev_priv)->num_pipes == 0)
-               return;
-
        ret = component_add(dev_priv->drm.dev, &i915_audio_component_bind_ops);
        if (ret < 0) {
                DRM_ERROR("failed to add audio component (%d)\n", ret);
index 8761513f3532c5c4bfb56151833ab6217a5ab99f..c9af34861d9e3a5bf3c090f4d5cf7afafed83dfa 100644 (file)
@@ -2708,7 +2708,8 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
        if (port != PORT_A || INTEL_GEN(dev_priv) >= 9)
                intel_dp_stop_link_train(intel_dp);
 
-       intel_ddi_enable_pipe_clock(crtc_state);
+       if (!is_mst)
+               intel_ddi_enable_pipe_clock(crtc_state);
 }
 
 static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
@@ -2810,14 +2811,14 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
        bool is_mst = intel_crtc_has_type(old_crtc_state,
                                          INTEL_OUTPUT_DP_MST);
 
-       intel_ddi_disable_pipe_clock(old_crtc_state);
-
-       /*
-        * Power down sink before disabling the port, otherwise we end
-        * up getting interrupts from the sink on detecting link loss.
-        */
-       if (!is_mst)
+       if (!is_mst) {
+               intel_ddi_disable_pipe_clock(old_crtc_state);
+               /*
+                * Power down sink before disabling the port, otherwise we end
+                * up getting interrupts from the sink on detecting link loss.
+                */
                intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+       }
 
        intel_disable_ddi_buf(encoder);
 
index ed3fa1c8a98342d549ec8bf5b027b3b783affa08..4a3c8ee9a9732cccc4e1ce1cc42197b0c662cc73 100644 (file)
@@ -2988,6 +2988,7 @@ static int skl_check_main_surface(const struct intel_crtc_state *crtc_state,
        int w = drm_rect_width(&plane_state->base.src) >> 16;
        int h = drm_rect_height(&plane_state->base.src) >> 16;
        int dst_x = plane_state->base.dst.x1;
+       int dst_w = drm_rect_width(&plane_state->base.dst);
        int pipe_src_w = crtc_state->pipe_src_w;
        int max_width = skl_max_plane_width(fb, 0, rotation);
        int max_height = 4096;
@@ -3009,10 +3010,10 @@ static int skl_check_main_surface(const struct intel_crtc_state *crtc_state,
         * screen may cause FIFO underflow and display corruption.
         */
        if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
-           (dst_x + w < 4 || dst_x > pipe_src_w - 4)) {
+           (dst_x + dst_w < 4 || dst_x > pipe_src_w - 4)) {
                DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
-                             dst_x + w < 4 ? "end" : "start",
-                             dst_x + w < 4 ? dst_x + w : dst_x,
+                             dst_x + dst_w < 4 ? "end" : "start",
+                             dst_x + dst_w < 4 ? dst_x + dst_w : dst_x,
                              4, pipe_src_w - 4);
                return -ERANGE;
        }
index cd0f649b57a5b75dff70265637a3a4b0ead4373b..1193202766a2cb86721cc8aa918c5f692c822c7e 100644 (file)
@@ -4160,18 +4160,6 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
        return !drm_dp_channel_eq_ok(link_status, intel_dp->lane_count);
 }
 
-/*
- * If display is now connected check links status,
- * there has been known issues of link loss triggering
- * long pulse.
- *
- * Some sinks (eg. ASUS PB287Q) seem to perform some
- * weird HPD ping pong during modesets. So we can apparently
- * end up with HPD going low during a modeset, and then
- * going back up soon after. And once that happens we must
- * retrain the link to get a picture. That's in case no
- * userspace component reacted to intermittent HPD dip.
- */
 int intel_dp_retrain_link(struct intel_encoder *encoder,
                          struct drm_modeset_acquire_ctx *ctx)
 {
@@ -4661,7 +4649,8 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
 }
 
 static int
-intel_dp_long_pulse(struct intel_connector *connector)
+intel_dp_long_pulse(struct intel_connector *connector,
+                   struct drm_modeset_acquire_ctx *ctx)
 {
        struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
        struct intel_dp *intel_dp = intel_attached_dp(&connector->base);
@@ -4720,6 +4709,22 @@ intel_dp_long_pulse(struct intel_connector *connector)
                 */
                status = connector_status_disconnected;
                goto out;
+       } else {
+               /*
+                * If display is now connected check links status,
+                * there has been known issues of link loss triggering
+                * long pulse.
+                *
+                * Some sinks (eg. ASUS PB287Q) seem to perform some
+                * weird HPD ping pong during modesets. So we can apparently
+                * end up with HPD going low during a modeset, and then
+                * going back up soon after. And once that happens we must
+                * retrain the link to get a picture. That's in case no
+                * userspace component reacted to intermittent HPD dip.
+                */
+               struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+
+               intel_dp_retrain_link(encoder, ctx);
        }
 
        /*
@@ -4781,7 +4786,7 @@ intel_dp_detect(struct drm_connector *connector,
                                return ret;
                }
 
-               status = intel_dp_long_pulse(intel_dp->attached_connector);
+               status = intel_dp_long_pulse(intel_dp->attached_connector, ctx);
        }
 
        intel_dp->detect_done = false;
index 7e3e01607643d3e6b4dfc6332284be001966e280..4ecd65375603391ee02f6a11831feecdae397b0b 100644 (file)
@@ -166,6 +166,8 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
        struct intel_connector *connector =
                to_intel_connector(old_conn_state->connector);
 
+       intel_ddi_disable_pipe_clock(old_crtc_state);
+
        /* this can fail */
        drm_dp_check_act_status(&intel_dp->mst_mgr);
        /* and this can also fail */
@@ -252,6 +254,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
        I915_WRITE(DP_TP_STATUS(port), temp);
 
        ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
+
+       intel_ddi_enable_pipe_clock(pipe_config);
 }
 
 static void intel_mst_enable_dp(struct intel_encoder *encoder,
index a9076402dcb0864ab6b7c6c4ea1d8346c95e949b..192972a7d287e9fd5ff9aeb599d6730007383500 100644 (file)
@@ -943,8 +943,12 @@ static int intel_hdmi_hdcp_write(struct intel_digital_port *intel_dig_port,
 
        ret = i2c_transfer(adapter, &msg, 1);
        if (ret == 1)
-               return 0;
-       return ret >= 0 ? -EIO : ret;
+               ret = 0;
+       else if (ret >= 0)
+               ret = -EIO;
+
+       kfree(write_buf);
+       return ret;
 }
 
 static
index 5dae16ccd9f1015fe80abc2c41d98937f3aaef89..3e085c5f2b81bfa87daf161bd96e3eb01da5d4ac 100644 (file)
@@ -74,7 +74,7 @@ static enum drm_lspcon_mode lspcon_wait_mode(struct intel_lspcon *lspcon,
        DRM_DEBUG_KMS("Waiting for LSPCON mode %s to settle\n",
                      lspcon_mode_name(mode));
 
-       wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode, 100);
+       wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode, 400);
        if (current_mode != mode)
                DRM_ERROR("LSPCON mode hasn't settled\n");
 
index 978782a776292e6d954755cc71786bd98b5d81ac..28d191192945b0690fd76eb9aa97a1bb3637215f 100644 (file)
@@ -132,6 +132,11 @@ static void mtk_ovl_config(struct mtk_ddp_comp *comp, unsigned int w,
        writel(0x0, comp->regs + DISP_REG_OVL_RST);
 }
 
+static unsigned int mtk_ovl_layer_nr(struct mtk_ddp_comp *comp)
+{
+       return 4;
+}
+
 static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx)
 {
        unsigned int reg;
@@ -157,6 +162,11 @@ static void mtk_ovl_layer_off(struct mtk_ddp_comp *comp, unsigned int idx)
 
 static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
 {
+       /* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX"
+        * is defined in mediatek HW data sheet.
+        * The alphabet order in XXX is no relation to data
+        * arrangement in memory.
+        */
        switch (fmt) {
        default:
        case DRM_FORMAT_RGB565:
@@ -221,6 +231,7 @@ static const struct mtk_ddp_comp_funcs mtk_disp_ovl_funcs = {
        .stop = mtk_ovl_stop,
        .enable_vblank = mtk_ovl_enable_vblank,
        .disable_vblank = mtk_ovl_disable_vblank,
+       .layer_nr = mtk_ovl_layer_nr,
        .layer_on = mtk_ovl_layer_on,
        .layer_off = mtk_ovl_layer_off,
        .layer_config = mtk_ovl_layer_config,
index 585943c81e1f8818de1a6bb481f6adb90c8ad308..b0a5cffe345ab77f90e443ca88bfac52d62804a4 100644 (file)
 #define RDMA_REG_UPDATE_INT                            BIT(0)
 #define DISP_REG_RDMA_GLOBAL_CON               0x0010
 #define RDMA_ENGINE_EN                                 BIT(0)
+#define RDMA_MODE_MEMORY                               BIT(1)
 #define DISP_REG_RDMA_SIZE_CON_0               0x0014
+#define RDMA_MATRIX_ENABLE                             BIT(17)
+#define RDMA_MATRIX_INT_MTX_SEL                                GENMASK(23, 20)
+#define RDMA_MATRIX_INT_MTX_BT601_to_RGB               (6 << 20)
 #define DISP_REG_RDMA_SIZE_CON_1               0x0018
 #define DISP_REG_RDMA_TARGET_LINE              0x001c
+#define DISP_RDMA_MEM_CON                      0x0024
+#define MEM_MODE_INPUT_FORMAT_RGB565                   (0x000 << 4)
+#define MEM_MODE_INPUT_FORMAT_RGB888                   (0x001 << 4)
+#define MEM_MODE_INPUT_FORMAT_RGBA8888                 (0x002 << 4)
+#define MEM_MODE_INPUT_FORMAT_ARGB8888                 (0x003 << 4)
+#define MEM_MODE_INPUT_FORMAT_UYVY                     (0x004 << 4)
+#define MEM_MODE_INPUT_FORMAT_YUYV                     (0x005 << 4)
+#define MEM_MODE_INPUT_SWAP                            BIT(8)
+#define DISP_RDMA_MEM_SRC_PITCH                        0x002c
+#define DISP_RDMA_MEM_GMC_SETTING_0            0x0030
 #define DISP_REG_RDMA_FIFO_CON                 0x0040
 #define RDMA_FIFO_UNDERFLOW_EN                         BIT(31)
 #define RDMA_FIFO_PSEUDO_SIZE(bytes)                   (((bytes) / 16) << 16)
 #define RDMA_OUTPUT_VALID_FIFO_THRESHOLD(bytes)                ((bytes) / 16)
 #define RDMA_FIFO_SIZE(rdma)                   ((rdma)->data->fifo_size)
+#define DISP_RDMA_MEM_START_ADDR               0x0f00
+
+#define RDMA_MEM_GMC                           0x40402020
 
 struct mtk_disp_rdma_data {
        unsigned int fifo_size;
@@ -138,12 +155,87 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,
        writel(reg, comp->regs + DISP_REG_RDMA_FIFO_CON);
 }
 
+static unsigned int rdma_fmt_convert(struct mtk_disp_rdma *rdma,
+                                    unsigned int fmt)
+{
+       /* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX"
+        * is defined in mediatek HW data sheet.
+        * The alphabet order in XXX is no relation to data
+        * arrangement in memory.
+        */
+       switch (fmt) {
+       default:
+       case DRM_FORMAT_RGB565:
+               return MEM_MODE_INPUT_FORMAT_RGB565;
+       case DRM_FORMAT_BGR565:
+               return MEM_MODE_INPUT_FORMAT_RGB565 | MEM_MODE_INPUT_SWAP;
+       case DRM_FORMAT_RGB888:
+               return MEM_MODE_INPUT_FORMAT_RGB888;
+       case DRM_FORMAT_BGR888:
+               return MEM_MODE_INPUT_FORMAT_RGB888 | MEM_MODE_INPUT_SWAP;
+       case DRM_FORMAT_RGBX8888:
+       case DRM_FORMAT_RGBA8888:
+               return MEM_MODE_INPUT_FORMAT_ARGB8888;
+       case DRM_FORMAT_BGRX8888:
+       case DRM_FORMAT_BGRA8888:
+               return MEM_MODE_INPUT_FORMAT_ARGB8888 | MEM_MODE_INPUT_SWAP;
+       case DRM_FORMAT_XRGB8888:
+       case DRM_FORMAT_ARGB8888:
+               return MEM_MODE_INPUT_FORMAT_RGBA8888;
+       case DRM_FORMAT_XBGR8888:
+       case DRM_FORMAT_ABGR8888:
+               return MEM_MODE_INPUT_FORMAT_RGBA8888 | MEM_MODE_INPUT_SWAP;
+       case DRM_FORMAT_UYVY:
+               return MEM_MODE_INPUT_FORMAT_UYVY;
+       case DRM_FORMAT_YUYV:
+               return MEM_MODE_INPUT_FORMAT_YUYV;
+       }
+}
+
+static unsigned int mtk_rdma_layer_nr(struct mtk_ddp_comp *comp)
+{
+       return 1;
+}
+
+static void mtk_rdma_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
+                                 struct mtk_plane_state *state)
+{
+       struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
+       struct mtk_plane_pending_state *pending = &state->pending;
+       unsigned int addr = pending->addr;
+       unsigned int pitch = pending->pitch & 0xffff;
+       unsigned int fmt = pending->format;
+       unsigned int con;
+
+       con = rdma_fmt_convert(rdma, fmt);
+       writel_relaxed(con, comp->regs + DISP_RDMA_MEM_CON);
+
+       if (fmt == DRM_FORMAT_UYVY || fmt == DRM_FORMAT_YUYV) {
+               rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0,
+                                RDMA_MATRIX_ENABLE, RDMA_MATRIX_ENABLE);
+               rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0,
+                                RDMA_MATRIX_INT_MTX_SEL,
+                                RDMA_MATRIX_INT_MTX_BT601_to_RGB);
+       } else {
+               rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0,
+                                RDMA_MATRIX_ENABLE, 0);
+       }
+
+       writel_relaxed(addr, comp->regs + DISP_RDMA_MEM_START_ADDR);
+       writel_relaxed(pitch, comp->regs + DISP_RDMA_MEM_SRC_PITCH);
+       writel(RDMA_MEM_GMC, comp->regs + DISP_RDMA_MEM_GMC_SETTING_0);
+       rdma_update_bits(comp, DISP_REG_RDMA_GLOBAL_CON,
+                        RDMA_MODE_MEMORY, RDMA_MODE_MEMORY);
+}
+
 static const struct mtk_ddp_comp_funcs mtk_disp_rdma_funcs = {
        .config = mtk_rdma_config,
        .start = mtk_rdma_start,
        .stop = mtk_rdma_stop,
        .enable_vblank = mtk_rdma_enable_vblank,
        .disable_vblank = mtk_rdma_disable_vblank,
+       .layer_nr = mtk_rdma_layer_nr,
+       .layer_config = mtk_rdma_layer_config,
 };
 
 static int mtk_disp_rdma_bind(struct device *dev, struct device *master,
index 2d6aa150a9ff08f0c0be658593abe1114d44a514..0b976dfd04df0b0c8b71bb0c6b2c471027a2e552 100644 (file)
@@ -45,7 +45,8 @@ struct mtk_drm_crtc {
        bool                            pending_needs_vblank;
        struct drm_pending_vblank_event *event;
 
-       struct drm_plane                planes[OVL_LAYER_NR];
+       struct drm_plane                *planes;
+       unsigned int                    layer_nr;
        bool                            pending_planes;
 
        void __iomem                    *config_regs;
@@ -171,9 +172,9 @@ static void mtk_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
 static int mtk_drm_crtc_enable_vblank(struct drm_crtc *crtc)
 {
        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
-       struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
+       struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 
-       mtk_ddp_comp_enable_vblank(ovl, &mtk_crtc->base);
+       mtk_ddp_comp_enable_vblank(comp, &mtk_crtc->base);
 
        return 0;
 }
@@ -181,9 +182,9 @@ static int mtk_drm_crtc_enable_vblank(struct drm_crtc *crtc)
 static void mtk_drm_crtc_disable_vblank(struct drm_crtc *crtc)
 {
        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
-       struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
+       struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 
-       mtk_ddp_comp_disable_vblank(ovl);
+       mtk_ddp_comp_disable_vblank(comp);
 }
 
 static int mtk_crtc_ddp_clk_enable(struct mtk_drm_crtc *mtk_crtc)
@@ -286,7 +287,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
        }
 
        /* Initially configure all planes */
-       for (i = 0; i < OVL_LAYER_NR; i++) {
+       for (i = 0; i < mtk_crtc->layer_nr; i++) {
                struct drm_plane *plane = &mtk_crtc->planes[i];
                struct mtk_plane_state *plane_state;
 
@@ -334,7 +335,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
 {
        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
        struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
-       struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
+       struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
        unsigned int i;
 
        /*
@@ -343,7 +344,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
         * queue update module registers on vblank.
         */
        if (state->pending_config) {
-               mtk_ddp_comp_config(ovl, state->pending_width,
+               mtk_ddp_comp_config(comp, state->pending_width,
                                    state->pending_height,
                                    state->pending_vrefresh, 0);
 
@@ -351,14 +352,14 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
        }
 
        if (mtk_crtc->pending_planes) {
-               for (i = 0; i < OVL_LAYER_NR; i++) {
+               for (i = 0; i < mtk_crtc->layer_nr; i++) {
                        struct drm_plane *plane = &mtk_crtc->planes[i];
                        struct mtk_plane_state *plane_state;
 
                        plane_state = to_mtk_plane_state(plane->state);
 
                        if (plane_state->pending.config) {
-                               mtk_ddp_comp_layer_config(ovl, i, plane_state);
+                               mtk_ddp_comp_layer_config(comp, i, plane_state);
                                plane_state->pending.config = false;
                        }
                }
@@ -370,12 +371,12 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
                                       struct drm_crtc_state *old_state)
 {
        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
-       struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
+       struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
        int ret;
 
        DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
 
-       ret = mtk_smi_larb_get(ovl->larb_dev);
+       ret = mtk_smi_larb_get(comp->larb_dev);
        if (ret) {
                DRM_ERROR("Failed to get larb: %d\n", ret);
                return;
@@ -383,7 +384,7 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
 
        ret = mtk_crtc_ddp_hw_init(mtk_crtc);
        if (ret) {
-               mtk_smi_larb_put(ovl->larb_dev);
+               mtk_smi_larb_put(comp->larb_dev);
                return;
        }
 
@@ -395,7 +396,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
                                        struct drm_crtc_state *old_state)
 {
        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
-       struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
+       struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
        int i;
 
        DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
@@ -403,7 +404,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
                return;
 
        /* Set all pending plane state to disabled */
-       for (i = 0; i < OVL_LAYER_NR; i++) {
+       for (i = 0; i < mtk_crtc->layer_nr; i++) {
                struct drm_plane *plane = &mtk_crtc->planes[i];
                struct mtk_plane_state *plane_state;
 
@@ -418,7 +419,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
 
        drm_crtc_vblank_off(crtc);
        mtk_crtc_ddp_hw_fini(mtk_crtc);
-       mtk_smi_larb_put(ovl->larb_dev);
+       mtk_smi_larb_put(comp->larb_dev);
 
        mtk_crtc->enabled = false;
 }
@@ -450,7 +451,7 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,
 
        if (mtk_crtc->event)
                mtk_crtc->pending_needs_vblank = true;
-       for (i = 0; i < OVL_LAYER_NR; i++) {
+       for (i = 0; i < mtk_crtc->layer_nr; i++) {
                struct drm_plane *plane = &mtk_crtc->planes[i];
                struct mtk_plane_state *plane_state;
 
@@ -516,7 +517,7 @@ err_cleanup_crtc:
        return ret;
 }
 
-void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl)
+void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *comp)
 {
        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
        struct mtk_drm_private *priv = crtc->dev->dev_private;
@@ -598,7 +599,12 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
                mtk_crtc->ddp_comp[i] = comp;
        }
 
-       for (zpos = 0; zpos < OVL_LAYER_NR; zpos++) {
+       mtk_crtc->layer_nr = mtk_ddp_comp_layer_nr(mtk_crtc->ddp_comp[0]);
+       mtk_crtc->planes = devm_kzalloc(dev, mtk_crtc->layer_nr *
+                                       sizeof(struct drm_plane),
+                                       GFP_KERNEL);
+
+       for (zpos = 0; zpos < mtk_crtc->layer_nr; zpos++) {
                type = (zpos == 0) ? DRM_PLANE_TYPE_PRIMARY :
                                (zpos == 1) ? DRM_PLANE_TYPE_CURSOR :
                                                DRM_PLANE_TYPE_OVERLAY;
@@ -609,7 +615,8 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
        }
 
        ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, &mtk_crtc->planes[0],
-                               &mtk_crtc->planes[1], pipe);
+                               mtk_crtc->layer_nr > 1 ? &mtk_crtc->planes[1] :
+                               NULL, pipe);
        if (ret < 0)
                goto unprepare;
        drm_mode_crtc_set_gamma_size(&mtk_crtc->base, MTK_LUT_SIZE);
index 9d9410c67ae9eb2026181b4a361e5c4e5707028d..091adb2087ebad132742195a4490e09efae4f427 100644 (file)
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_plane.h"
 
-#define OVL_LAYER_NR   4
 #define MTK_LUT_SIZE   512
 #define MTK_MAX_BPC    10
 #define MTK_MIN_BPC    3
 
 void mtk_drm_crtc_commit(struct drm_crtc *crtc);
-void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl);
+void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *comp);
 int mtk_drm_crtc_create(struct drm_device *drm_dev,
                        const enum mtk_ddp_comp_id *path,
                        unsigned int path_len);
index 87e4191c250ebea7f3f0acb3ca23d3fcb9a9639c..546b3e3b300ba8c6b8a4dc67bfe8c400d5b48de9 100644 (file)
 #define OVL1_MOUT_EN_COLOR1            0x1
 #define GAMMA_MOUT_EN_RDMA1            0x1
 #define RDMA0_SOUT_DPI0                        0x2
+#define RDMA0_SOUT_DPI1                        0x3
+#define RDMA0_SOUT_DSI1                        0x1
 #define RDMA0_SOUT_DSI2                        0x4
 #define RDMA0_SOUT_DSI3                        0x5
 #define RDMA1_SOUT_DPI0                        0x2
 #define DPI0_SEL_IN_RDMA2              0x3
 #define DPI1_SEL_IN_RDMA1              (0x1 << 8)
 #define DPI1_SEL_IN_RDMA2              (0x3 << 8)
+#define DSI0_SEL_IN_RDMA1              0x1
+#define DSI0_SEL_IN_RDMA2              0x4
 #define DSI1_SEL_IN_RDMA1              0x1
 #define DSI1_SEL_IN_RDMA2              0x4
 #define DSI2_SEL_IN_RDMA1              (0x1 << 16)
@@ -224,6 +228,12 @@ static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur,
        } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI0) {
                *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
                value = RDMA0_SOUT_DPI0;
+       } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI1) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
+               value = RDMA0_SOUT_DPI1;
+       } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI1) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
+               value = RDMA0_SOUT_DSI1;
        } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI2) {
                *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
                value = RDMA0_SOUT_DSI2;
@@ -282,6 +292,9 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur,
        } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) {
                *addr = DISP_REG_CONFIG_DPI_SEL_IN;
                value = DPI1_SEL_IN_RDMA1;
+       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI0) {
+               *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
+               value = DSI0_SEL_IN_RDMA1;
        } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) {
                *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
                value = DSI1_SEL_IN_RDMA1;
@@ -297,8 +310,11 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur,
        } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) {
                *addr = DISP_REG_CONFIG_DPI_SEL_IN;
                value = DPI1_SEL_IN_RDMA2;
-       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) {
+       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI0) {
                *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
+               value = DSI0_SEL_IN_RDMA2;
+       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) {
+               *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
                value = DSI1_SEL_IN_RDMA2;
        } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) {
                *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
index 7413ffeb3c9d8bee1ca6bb825eb7a54391c7d013..8399229e6ad2661b77a52a5d9f30eb7502ee2879 100644 (file)
@@ -78,6 +78,7 @@ struct mtk_ddp_comp_funcs {
        void (*stop)(struct mtk_ddp_comp *comp);
        void (*enable_vblank)(struct mtk_ddp_comp *comp, struct drm_crtc *crtc);
        void (*disable_vblank)(struct mtk_ddp_comp *comp);
+       unsigned int (*layer_nr)(struct mtk_ddp_comp *comp);
        void (*layer_on)(struct mtk_ddp_comp *comp, unsigned int idx);
        void (*layer_off)(struct mtk_ddp_comp *comp, unsigned int idx);
        void (*layer_config)(struct mtk_ddp_comp *comp, unsigned int idx,
@@ -128,6 +129,14 @@ static inline void mtk_ddp_comp_disable_vblank(struct mtk_ddp_comp *comp)
                comp->funcs->disable_vblank(comp);
 }
 
+static inline unsigned int mtk_ddp_comp_layer_nr(struct mtk_ddp_comp *comp)
+{
+       if (comp->funcs && comp->funcs->layer_nr)
+               return comp->funcs->layer_nr(comp);
+
+       return 0;
+}
+
 static inline void mtk_ddp_comp_layer_on(struct mtk_ddp_comp *comp,
                                         unsigned int idx)
 {
index 39721119713bc29d6cba63e2947d6be1ddc439cd..47ec604289b712148fdfa740a2d6c64ca4d0810f 100644 (file)
@@ -381,7 +381,7 @@ static int mtk_drm_bind(struct device *dev)
 err_deinit:
        mtk_drm_kms_deinit(drm);
 err_free:
-       drm_dev_unref(drm);
+       drm_dev_put(drm);
        return ret;
 }
 
@@ -390,7 +390,7 @@ static void mtk_drm_unbind(struct device *dev)
        struct mtk_drm_private *private = dev_get_drvdata(dev);
 
        drm_dev_unregister(private->drm);
-       drm_dev_unref(private->drm);
+       drm_dev_put(private->drm);
        private->drm = NULL;
 }
 
@@ -564,7 +564,7 @@ static int mtk_drm_remove(struct platform_device *pdev)
 
        drm_dev_unregister(drm);
        mtk_drm_kms_deinit(drm);
-       drm_dev_unref(drm);
+       drm_dev_put(drm);
 
        component_master_del(&pdev->dev, &mtk_drm_ops);
        pm_runtime_disable(&pdev->dev);
@@ -580,29 +580,24 @@ static int mtk_drm_sys_suspend(struct device *dev)
 {
        struct mtk_drm_private *private = dev_get_drvdata(dev);
        struct drm_device *drm = private->drm;
+       int ret;
 
-       drm_kms_helper_poll_disable(drm);
-
-       private->suspend_state = drm_atomic_helper_suspend(drm);
-       if (IS_ERR(private->suspend_state)) {
-               drm_kms_helper_poll_enable(drm);
-               return PTR_ERR(private->suspend_state);
-       }
-
+       ret = drm_mode_config_helper_suspend(drm);
        DRM_DEBUG_DRIVER("mtk_drm_sys_suspend\n");
-       return 0;
+
+       return ret;
 }
 
 static int mtk_drm_sys_resume(struct device *dev)
 {
        struct mtk_drm_private *private = dev_get_drvdata(dev);
        struct drm_device *drm = private->drm;
+       int ret;
 
-       drm_atomic_helper_resume(drm, private->suspend_state);
-       drm_kms_helper_poll_enable(drm);
-
+       ret = drm_mode_config_helper_resume(drm);
        DRM_DEBUG_DRIVER("mtk_drm_sys_resume\n");
-       return 0;
+
+       return ret;
 }
 #endif
 
index 5b5d0a24e713e25dc81ae32effcd57b2c4a8f6cf..97964f7f2acee08350101947a4ccd9a717f5f199 100644 (file)
@@ -1385,6 +1385,9 @@ static const struct panel_desc innolux_tv123wam = {
                .width = 259,
                .height = 173,
        },
+       .delay = {
+               .unprepare = 500,
+       },
 };
 
 static const struct drm_display_mode innolux_zj070na_01p_mode = {
index abd24975c9b1d946cec7c85ba7ebe3b820d1c8e4..f8b35df44c60eba57e7b2ec76c068190dd941c79 100644 (file)
@@ -118,19 +118,27 @@ static void radeon_mn_release(struct mmu_notifier *mn,
  * We block for all BOs between start and end to be idle and
  * unmap them by move them into system domain again.
  */
-static void radeon_mn_invalidate_range_start(struct mmu_notifier *mn,
+static int radeon_mn_invalidate_range_start(struct mmu_notifier *mn,
                                             struct mm_struct *mm,
                                             unsigned long start,
-                                            unsigned long end)
+                                            unsigned long end,
+                                            bool blockable)
 {
        struct radeon_mn *rmn = container_of(mn, struct radeon_mn, mn);
        struct ttm_operation_ctx ctx = { false, false };
        struct interval_tree_node *it;
+       int ret = 0;
 
        /* notification is exclusive, but interval is inclusive */
        end -= 1;
 
-       mutex_lock(&rmn->lock);
+       /* TODO we should be able to split locking for interval tree and
+        * the tear down.
+        */
+       if (blockable)
+               mutex_lock(&rmn->lock);
+       else if (!mutex_trylock(&rmn->lock))
+               return -EAGAIN;
 
        it = interval_tree_iter_first(&rmn->objects, start, end);
        while (it) {
@@ -138,6 +146,11 @@ static void radeon_mn_invalidate_range_start(struct mmu_notifier *mn,
                struct radeon_bo *bo;
                long r;
 
+               if (!blockable) {
+                       ret = -EAGAIN;
+                       goto out_unlock;
+               }
+
                node = container_of(it, struct radeon_mn_node, it);
                it = interval_tree_iter_next(it, start, end);
 
@@ -166,7 +179,10 @@ static void radeon_mn_invalidate_range_start(struct mmu_notifier *mn,
                }
        }
        
+out_unlock:
        mutex_unlock(&rmn->lock);
+
+       return ret;
 }
 
 static const struct mmu_notifier_ops radeon_mn_ops = {
index ddb1e9365a3e52ffc36465708ce676dff5158bec..b93c558dd86e0121741284becc87434a27b39d2a 100644 (file)
@@ -51,51 +51,34 @@ static int vmw_gmrid_man_get_node(struct ttm_mem_type_manager *man,
 {
        struct vmwgfx_gmrid_man *gman =
                (struct vmwgfx_gmrid_man *)man->priv;
-       int ret = 0;
        int id;
 
        mem->mm_node = NULL;
 
+       id = ida_alloc_max(&gman->gmr_ida, gman->max_gmr_ids - 1, GFP_KERNEL);
+       if (id < 0)
+               return id;
+
        spin_lock(&gman->lock);
 
        if (gman->max_gmr_pages > 0) {
                gman->used_gmr_pages += bo->num_pages;
                if (unlikely(gman->used_gmr_pages > gman->max_gmr_pages))
-                       goto out_err_locked;
+                       goto nospace;
        }
 
-       do {
-               spin_unlock(&gman->lock);
-               if (unlikely(ida_pre_get(&gman->gmr_ida, GFP_KERNEL) == 0)) {
-                       ret = -ENOMEM;
-                       goto out_err;
-               }
-               spin_lock(&gman->lock);
-
-               ret = ida_get_new(&gman->gmr_ida, &id);
-               if (unlikely(ret == 0 && id >= gman->max_gmr_ids)) {
-                       ida_remove(&gman->gmr_ida, id);
-                       ret = 0;
-                       goto out_err_locked;
-               }
-       } while (ret == -EAGAIN);
-
-       if (likely(ret == 0)) {
-               mem->mm_node = gman;
-               mem->start = id;
-               mem->num_pages = bo->num_pages;
-       } else
-               goto out_err_locked;
+       mem->mm_node = gman;
+       mem->start = id;
+       mem->num_pages = bo->num_pages;
 
        spin_unlock(&gman->lock);
        return 0;
 
-out_err:
-       spin_lock(&gman->lock);
-out_err_locked:
+nospace:
        gman->used_gmr_pages -= bo->num_pages;
        spin_unlock(&gman->lock);
-       return ret;
+       ida_free(&gman->gmr_ida, id);
+       return 0;
 }
 
 static void vmw_gmrid_man_put_node(struct ttm_mem_type_manager *man,
@@ -105,8 +88,8 @@ static void vmw_gmrid_man_put_node(struct ttm_mem_type_manager *man,
                (struct vmwgfx_gmrid_man *)man->priv;
 
        if (mem->mm_node) {
+               ida_free(&gman->gmr_ida, mem->start);
                spin_lock(&gman->lock);
-               ida_remove(&gman->gmr_ida, mem->start);
                gman->used_gmr_pages -= mem->num_pages;
                spin_unlock(&gman->lock);
                mem->mm_node = NULL;
index 0e0aa7f0e6fc056578cb50218a99f56702a63b01..80a9aea38fa34741d394abf481624b7625d82d60 100644 (file)
@@ -92,6 +92,7 @@
 #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE        0x0304
 #define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d
 #define USB_DEVICE_ID_APPLE_MAGICTRACKPAD      0x030e
+#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD2     0x0265
 #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI      0x020e
 #define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO       0x020f
 #define USB_DEVICE_ID_APPLE_GEYSER_ANSI        0x0214
index b454c43861578602e33d066a655eb5205e969533..1d5ea678d268768fe73f3bbf4fa6b589dbc6fcbe 100644 (file)
@@ -54,6 +54,8 @@ module_param(report_undeciphered, bool, 0644);
 MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event");
 
 #define TRACKPAD_REPORT_ID 0x28
+#define TRACKPAD2_USB_REPORT_ID 0x02
+#define TRACKPAD2_BT_REPORT_ID 0x31
 #define MOUSE_REPORT_ID    0x29
 #define DOUBLE_REPORT_ID   0xf7
 /* These definitions are not precise, but they're close enough.  (Bits
@@ -91,6 +93,17 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
 #define TRACKPAD_RES_Y \
        ((TRACKPAD_MAX_Y - TRACKPAD_MIN_Y) / (TRACKPAD_DIMENSION_Y / 100))
 
+#define TRACKPAD2_DIMENSION_X (float)16000
+#define TRACKPAD2_MIN_X -3678
+#define TRACKPAD2_MAX_X 3934
+#define TRACKPAD2_RES_X \
+       ((TRACKPAD2_MAX_X - TRACKPAD2_MIN_X) / (TRACKPAD2_DIMENSION_X / 100))
+#define TRACKPAD2_DIMENSION_Y (float)11490
+#define TRACKPAD2_MIN_Y -2478
+#define TRACKPAD2_MAX_Y 2587
+#define TRACKPAD2_RES_Y \
+       ((TRACKPAD2_MAX_Y - TRACKPAD2_MIN_Y) / (TRACKPAD2_DIMENSION_Y / 100))
+
 /**
  * struct magicmouse_sc - Tracks Magic Mouse-specific data.
  * @input: Input device through which we report events.
@@ -183,6 +196,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
 {
        struct input_dev *input = msc->input;
        int id, x, y, size, orientation, touch_major, touch_minor, state, down;
+       int pressure = 0;
 
        if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
                id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf;
@@ -194,6 +208,17 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
                touch_minor = tdata[4];
                state = tdata[7] & TOUCH_STATE_MASK;
                down = state != TOUCH_STATE_NONE;
+       } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
+               id = tdata[8] & 0xf;
+               x = (tdata[1] << 27 | tdata[0] << 19) >> 19;
+               y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19);
+               size = tdata[6];
+               orientation = (tdata[8] >> 5) - 4;
+               touch_major = tdata[4];
+               touch_minor = tdata[5];
+               pressure = tdata[7];
+               state = tdata[3] & 0xC0;
+               down = state == 0x80;
        } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
                id = (tdata[7] << 2 | tdata[6] >> 6) & 0xf;
                x = (tdata[1] << 27 | tdata[0] << 19) >> 19;
@@ -215,7 +240,8 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
        /* If requested, emulate a scroll wheel by detecting small
         * vertical touch motions.
         */
-       if (emulate_scroll_wheel) {
+       if (emulate_scroll_wheel && (input->id.product !=
+                       USB_DEVICE_ID_APPLE_MAGICTRACKPAD2)) {
                unsigned long now = jiffies;
                int step_x = msc->touches[id].scroll_x - x;
                int step_y = msc->touches[id].scroll_y - y;
@@ -269,10 +295,14 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
                input_report_abs(input, ABS_MT_POSITION_X, x);
                input_report_abs(input, ABS_MT_POSITION_Y, y);
 
+               if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2)
+                       input_report_abs(input, ABS_MT_PRESSURE, pressure);
+
                if (report_undeciphered) {
                        if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
                                input_event(input, EV_MSC, MSC_RAW, tdata[7]);
-                       else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
+                       else if (input->id.product !=
+                                       USB_DEVICE_ID_APPLE_MAGICTRACKPAD2)
                                input_event(input, EV_MSC, MSC_RAW, tdata[8]);
                }
        }
@@ -287,6 +317,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 
        switch (data[0]) {
        case TRACKPAD_REPORT_ID:
+       case TRACKPAD2_BT_REPORT_ID:
                /* Expect four bytes of prefix, and N*9 bytes of touch data. */
                if (size < 4 || ((size - 4) % 9) != 0)
                        return 0;
@@ -308,6 +339,22 @@ static int magicmouse_raw_event(struct hid_device *hdev,
                 * ts = data[1] >> 6 | data[2] << 2 | data[3] << 10;
                 */
                break;
+       case TRACKPAD2_USB_REPORT_ID:
+               /* Expect twelve bytes of prefix and N*9 bytes of touch data. */
+               if (size < 12 || ((size - 12) % 9) != 0)
+                       return 0;
+               npoints = (size - 12) / 9;
+               if (npoints > 15) {
+                       hid_warn(hdev, "invalid size value (%d) for TRACKPAD2_USB_REPORT_ID\n",
+                                       size);
+                       return 0;
+               }
+               msc->ntouches = 0;
+               for (ii = 0; ii < npoints; ii++)
+                       magicmouse_emit_touch(msc, ii, data + ii * 9 + 12);
+
+               clicks = data[1];
+               break;
        case MOUSE_REPORT_ID:
                /* Expect six bytes of prefix, and N*8 bytes of touch data. */
                if (size < 6 || ((size - 6) % 8) != 0)
@@ -352,6 +399,9 @@ static int magicmouse_raw_event(struct hid_device *hdev,
                magicmouse_emit_buttons(msc, clicks & 3);
                input_report_rel(input, REL_X, x);
                input_report_rel(input, REL_Y, y);
+       } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
+               input_mt_sync_frame(input);
+               input_report_key(input, BTN_MOUSE, clicks & 1);
        } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
                input_report_key(input, BTN_MOUSE, clicks & 1);
                input_mt_report_pointer_emulation(input, true);
@@ -364,6 +414,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev)
 {
        int error;
+       int mt_flags = 0;
 
        __set_bit(EV_KEY, input->evbit);
 
@@ -380,6 +431,22 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
                        __set_bit(REL_WHEEL, input->relbit);
                        __set_bit(REL_HWHEEL, input->relbit);
                }
+       } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
+               /* setting the device name to ensure the same driver settings
+                * get loaded, whether connected through bluetooth or USB
+                */
+               input->name = "Apple Inc. Magic Trackpad 2";
+
+               __clear_bit(EV_MSC, input->evbit);
+               __clear_bit(BTN_0, input->keybit);
+               __clear_bit(BTN_RIGHT, input->keybit);
+               __clear_bit(BTN_MIDDLE, input->keybit);
+               __set_bit(BTN_MOUSE, input->keybit);
+               __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
+               __set_bit(BTN_TOOL_FINGER, input->keybit);
+
+               mt_flags = INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED |
+                               INPUT_MT_TRACK;
        } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
                /* input->keybit is initialized with incorrect button info
                 * for Magic Trackpad. There really is only one physical
@@ -402,14 +469,13 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
 
        __set_bit(EV_ABS, input->evbit);
 
-       error = input_mt_init_slots(input, 16, 0);
+       error = input_mt_init_slots(input, 16, mt_flags);
        if (error)
                return error;
        input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2,
                             4, 0);
        input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255 << 2,
                             4, 0);
-       input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
 
        /* Note: Touch Y position from the device is inverted relative
         * to how pointer motion is reported (and relative to how USB
@@ -418,6 +484,7 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
         * inverse of the reported Y.
         */
        if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
+               input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
                input_set_abs_params(input, ABS_MT_POSITION_X,
                                     MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
                input_set_abs_params(input, ABS_MT_POSITION_Y,
@@ -427,7 +494,25 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
                                  MOUSE_RES_X);
                input_abs_set_res(input, ABS_MT_POSITION_Y,
                                  MOUSE_RES_Y);
+       } else if (input->id.product ==  USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
+               input_set_abs_params(input, ABS_MT_PRESSURE, 0, 253, 0, 0);
+               input_set_abs_params(input, ABS_PRESSURE, 0, 253, 0, 0);
+               input_set_abs_params(input, ABS_MT_ORIENTATION, -3, 4, 0, 0);
+               input_set_abs_params(input, ABS_X, TRACKPAD2_MIN_X,
+                                    TRACKPAD2_MAX_X, 0, 0);
+               input_set_abs_params(input, ABS_Y, TRACKPAD2_MIN_Y,
+                                    TRACKPAD2_MAX_Y, 0, 0);
+               input_set_abs_params(input, ABS_MT_POSITION_X,
+                                    TRACKPAD2_MIN_X, TRACKPAD2_MAX_X, 0, 0);
+               input_set_abs_params(input, ABS_MT_POSITION_Y,
+                                    TRACKPAD2_MIN_Y, TRACKPAD2_MAX_Y, 0, 0);
+
+               input_abs_set_res(input, ABS_X, TRACKPAD2_RES_X);
+               input_abs_set_res(input, ABS_Y, TRACKPAD2_RES_Y);
+               input_abs_set_res(input, ABS_MT_POSITION_X, TRACKPAD2_RES_X);
+               input_abs_set_res(input, ABS_MT_POSITION_Y, TRACKPAD2_RES_Y);
        } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
+               input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
                input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X,
                                     TRACKPAD_MAX_X, 4, 0);
                input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y,
@@ -447,7 +532,8 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
 
        input_set_events_per_packet(input, 60);
 
-       if (report_undeciphered) {
+       if (report_undeciphered &&
+           input->id.product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
                __set_bit(EV_MSC, input->evbit);
                __set_bit(MSC_RAW, input->mscbit);
        }
@@ -465,7 +551,8 @@ static int magicmouse_input_mapping(struct hid_device *hdev,
                msc->input = hi->input;
 
        /* Magic Trackpad does not give relative data after switching to MT */
-       if (hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD &&
+       if ((hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD ||
+            hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) &&
            field->flags & HID_MAIN_ITEM_RELATIVE)
                return -1;
 
@@ -494,11 +581,20 @@ static int magicmouse_input_configured(struct hid_device *hdev,
 static int magicmouse_probe(struct hid_device *hdev,
        const struct hid_device_id *id)
 {
-       const u8 feature[] = { 0xd7, 0x01 };
+       const u8 *feature;
+       const u8 feature_mt[] = { 0xD7, 0x01 };
+       const u8 feature_mt_trackpad2_usb[] = { 0x02, 0x01 };
+       const u8 feature_mt_trackpad2_bt[] = { 0xF1, 0x02, 0x01 };
        u8 *buf;
        struct magicmouse_sc *msc;
        struct hid_report *report;
        int ret;
+       int feature_size;
+
+       if (id->vendor == USB_VENDOR_ID_APPLE &&
+           id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
+           hdev->type != HID_TYPE_USBMOUSE)
+               return 0;
 
        msc = devm_kzalloc(&hdev->dev, sizeof(*msc), GFP_KERNEL);
        if (msc == NULL) {
@@ -532,7 +628,14 @@ static int magicmouse_probe(struct hid_device *hdev,
        if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
                report = hid_register_report(hdev, HID_INPUT_REPORT,
                        MOUSE_REPORT_ID, 0);
-       else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
+       else if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
+               if (id->vendor == BT_VENDOR_ID_APPLE)
+                       report = hid_register_report(hdev, HID_INPUT_REPORT,
+                               TRACKPAD2_BT_REPORT_ID, 0);
+               else /* USB_VENDOR_ID_APPLE */
+                       report = hid_register_report(hdev, HID_INPUT_REPORT,
+                               TRACKPAD2_USB_REPORT_ID, 0);
+       } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
                report = hid_register_report(hdev, HID_INPUT_REPORT,
                        TRACKPAD_REPORT_ID, 0);
                report = hid_register_report(hdev, HID_INPUT_REPORT,
@@ -546,7 +649,20 @@ static int magicmouse_probe(struct hid_device *hdev,
        }
        report->size = 6;
 
-       buf = kmemdup(feature, sizeof(feature), GFP_KERNEL);
+       if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
+               if (id->vendor == BT_VENDOR_ID_APPLE) {
+                       feature_size = sizeof(feature_mt_trackpad2_bt);
+                       feature = feature_mt_trackpad2_bt;
+               } else { /* USB_VENDOR_ID_APPLE */
+                       feature_size = sizeof(feature_mt_trackpad2_usb);
+                       feature = feature_mt_trackpad2_usb;
+               }
+       } else {
+               feature_size = sizeof(feature_mt);
+               feature = feature_mt;
+       }
+
+       buf = kmemdup(feature, feature_size, GFP_KERNEL);
        if (!buf) {
                ret = -ENOMEM;
                goto err_stop_hw;
@@ -560,10 +676,10 @@ static int magicmouse_probe(struct hid_device *hdev,
         * but there seems to be no other way of switching the mode.
         * Thus the super-ugly hacky success check below.
         */
-       ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(feature),
+       ret = hid_hw_raw_request(hdev, buf[0], buf, feature_size,
                                HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
        kfree(buf);
-       if (ret != -EIO && ret != sizeof(feature)) {
+       if (ret != -EIO && ret != feature_size) {
                hid_err(hdev, "unable to request touch data (%d)\n", ret);
                goto err_stop_hw;
        }
@@ -579,6 +695,10 @@ static const struct hid_device_id magic_mice[] = {
                USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
                USB_DEVICE_ID_APPLE_MAGICTRACKPAD), .driver_data = 0 },
+       { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE,
+               USB_DEVICE_ID_APPLE_MAGICTRACKPAD2), .driver_data = 0 },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
+               USB_DEVICE_ID_APPLE_MAGICTRACKPAD2), .driver_data = 0 },
        { }
 };
 MODULE_DEVICE_TABLE(hid, magic_mice);
index ccf42663a908a493aaddf669d43fa207d9ca0931..81da17a42dc92830bef2968a06d153a51c759f59 100644 (file)
@@ -1320,6 +1320,16 @@ config SENSORS_PWM_FAN
          This driver can also be built as a module.  If so, the module
          will be called pwm-fan.
 
+config SENSORS_RASPBERRYPI_HWMON
+       tristate "Raspberry Pi voltage monitor"
+       depends on RASPBERRYPI_FIRMWARE || (COMPILE_TEST && !RASPBERRYPI_FIRMWARE)
+       help
+         If you say yes here you get support for voltage sensor on the
+         Raspberry Pi.
+
+         This driver can also be built as a module. If so, the module
+         will be called raspberrypi-hwmon.
+
 config SENSORS_SHT15
        tristate "Sensiron humidity and temperature sensors. SHT15 and compat."
        depends on GPIOLIB || COMPILE_TEST
index 842c92f83ce62875e05b07e0bf7835fd3f3da6cd..93f7f41ea4ad514f88075ccd631358ae6b17ac93 100644 (file)
@@ -143,6 +143,7 @@ obj-$(CONFIG_SENSORS_PC87427)       += pc87427.o
 obj-$(CONFIG_SENSORS_PCF8591)  += pcf8591.o
 obj-$(CONFIG_SENSORS_POWR1220)  += powr1220.o
 obj-$(CONFIG_SENSORS_PWM_FAN)  += pwm-fan.o
+obj-$(CONFIG_SENSORS_RASPBERRYPI_HWMON)        += raspberrypi-hwmon.o
 obj-$(CONFIG_SENSORS_S3C)      += s3c-hwmon.o
 obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o
 obj-$(CONFIG_SENSORS_SCH5627)  += sch5627.o
index 90837f7c7d0f3203ee64de86dcccd8a1e7cc26ad..f4c7516eb9891fa923a2a736bfcc45ef9b84a6b9 100644 (file)
@@ -302,14 +302,18 @@ static inline u16 volt2reg(int channel, long volt, u8 bypass_attn)
        return clamp_val(reg, 0, 1023) & (0xff << 2);
 }
 
-static u16 adt7475_read_word(struct i2c_client *client, int reg)
+static int adt7475_read_word(struct i2c_client *client, int reg)
 {
-       u16 val;
+       int val1, val2;
 
-       val = i2c_smbus_read_byte_data(client, reg);
-       val |= (i2c_smbus_read_byte_data(client, reg + 1) << 8);
+       val1 = i2c_smbus_read_byte_data(client, reg);
+       if (val1 < 0)
+               return val1;
+       val2 = i2c_smbus_read_byte_data(client, reg + 1);
+       if (val2 < 0)
+               return val2;
 
-       return val;
+       return val1 | (val2 << 8);
 }
 
 static void adt7475_write_word(struct i2c_client *client, int reg, u16 val)
@@ -962,13 +966,14 @@ static ssize_t show_pwmfreq(struct device *dev, struct device_attribute *attr,
 {
        struct adt7475_data *data = adt7475_update_device(dev);
        struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-       int i = clamp_val(data->range[sattr->index] & 0xf, 0,
-                         ARRAY_SIZE(pwmfreq_table) - 1);
+       int idx;
 
        if (IS_ERR(data))
                return PTR_ERR(data);
+       idx = clamp_val(data->range[sattr->index] & 0xf, 0,
+                       ARRAY_SIZE(pwmfreq_table) - 1);
 
-       return sprintf(buf, "%d\n", pwmfreq_table[i]);
+       return sprintf(buf, "%d\n", pwmfreq_table[idx]);
 }
 
 static ssize_t set_pwmfreq(struct device *dev, struct device_attribute *attr,
@@ -1004,6 +1009,10 @@ static ssize_t pwm_use_point2_pwm_at_crit_show(struct device *dev,
                                        char *buf)
 {
        struct adt7475_data *data = adt7475_update_device(dev);
+
+       if (IS_ERR(data))
+               return PTR_ERR(data);
+
        return sprintf(buf, "%d\n", !!(data->config4 & CONFIG4_MAXDUTY));
 }
 
index e9e6aeabbf842ffd941e0476a185884adac85147..71d3445ba869c85654ae3dcaf3a5460e8fadb268 100644 (file)
@@ -17,7 +17,7 @@
  * Bi-directional Current/Power Monitor with I2C Interface
  * Datasheet: http://www.ti.com/product/ina230
  *
- * Copyright (C) 2012 Lothar Felten <l-felten@ti.com>
+ * Copyright (C) 2012 Lothar Felten <lothar.felten@gmail.com>
  * Thanks to Jan Volkering
  *
  * This program is free software; you can redistribute it and/or modify
@@ -329,6 +329,15 @@ static int ina2xx_set_shunt(struct ina2xx_data *data, long val)
        return 0;
 }
 
+static ssize_t ina2xx_show_shunt(struct device *dev,
+                             struct device_attribute *da,
+                             char *buf)
+{
+       struct ina2xx_data *data = dev_get_drvdata(dev);
+
+       return snprintf(buf, PAGE_SIZE, "%li\n", data->rshunt);
+}
+
 static ssize_t ina2xx_store_shunt(struct device *dev,
                                  struct device_attribute *da,
                                  const char *buf, size_t count)
@@ -403,7 +412,7 @@ static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina2xx_show_value, NULL,
 
 /* shunt resistance */
 static SENSOR_DEVICE_ATTR(shunt_resistor, S_IRUGO | S_IWUSR,
-                         ina2xx_show_value, ina2xx_store_shunt,
+                         ina2xx_show_shunt, ina2xx_store_shunt,
                          INA2XX_CALIBRATION);
 
 /* update interval (ina226 only) */
index c6bd61e4695abc01a7ed909f1d27f6944c45e246..944f5b63aecd706228ebcd3a128e3ec488bf63ba 100644 (file)
@@ -63,6 +63,7 @@
 #include <linux/bitops.h>
 #include <linux/dmi.h>
 #include <linux/io.h>
+#include <linux/nospec.h>
 #include "lm75.h"
 
 #define USE_ALTERNATE
@@ -2689,6 +2690,7 @@ store_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
                return err;
        if (val > NUM_TEMP)
                return -EINVAL;
+       val = array_index_nospec(val, NUM_TEMP + 1);
        if (val && (!(data->have_temp & BIT(val - 1)) ||
                    !data->temp_src[val - 1]))
                return -EINVAL;
diff --git a/drivers/hwmon/raspberrypi-hwmon.c b/drivers/hwmon/raspberrypi-hwmon.c
new file mode 100644 (file)
index 0000000..be5ba46
--- /dev/null
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Raspberry Pi voltage sensor driver
+ *
+ * Based on firmware/raspberrypi.c by Noralf Trønnes
+ *
+ * Copyright (C) 2018 Stefan Wahren <stefan.wahren@i2se.com>
+ */
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <soc/bcm2835/raspberrypi-firmware.h>
+
+#define UNDERVOLTAGE_STICKY_BIT        BIT(16)
+
+struct rpi_hwmon_data {
+       struct device *hwmon_dev;
+       struct rpi_firmware *fw;
+       u32 last_throttled;
+       struct delayed_work get_values_poll_work;
+};
+
+static void rpi_firmware_get_throttled(struct rpi_hwmon_data *data)
+{
+       u32 new_uv, old_uv, value;
+       int ret;
+
+       /* Request firmware to clear sticky bits */
+       value = 0xffff;
+
+       ret = rpi_firmware_property(data->fw, RPI_FIRMWARE_GET_THROTTLED,
+                                   &value, sizeof(value));
+       if (ret) {
+               dev_err_once(data->hwmon_dev, "Failed to get throttled (%d)\n",
+                            ret);
+               return;
+       }
+
+       new_uv = value & UNDERVOLTAGE_STICKY_BIT;
+       old_uv = data->last_throttled & UNDERVOLTAGE_STICKY_BIT;
+       data->last_throttled = value;
+
+       if (new_uv == old_uv)
+               return;
+
+       if (new_uv)
+               dev_crit(data->hwmon_dev, "Undervoltage detected!\n");
+       else
+               dev_info(data->hwmon_dev, "Voltage normalised\n");
+
+       sysfs_notify(&data->hwmon_dev->kobj, NULL, "in0_lcrit_alarm");
+}
+
+static void get_values_poll(struct work_struct *work)
+{
+       struct rpi_hwmon_data *data;
+
+       data = container_of(work, struct rpi_hwmon_data,
+                           get_values_poll_work.work);
+
+       rpi_firmware_get_throttled(data);
+
+       /*
+        * We can't run faster than the sticky shift (100ms) since we get
+        * flipping in the sticky bits that are cleared.
+        */
+       schedule_delayed_work(&data->get_values_poll_work, 2 * HZ);
+}
+
+static int rpi_read(struct device *dev, enum hwmon_sensor_types type,
+                   u32 attr, int channel, long *val)
+{
+       struct rpi_hwmon_data *data = dev_get_drvdata(dev);
+
+       *val = !!(data->last_throttled & UNDERVOLTAGE_STICKY_BIT);
+       return 0;
+}
+
+static umode_t rpi_is_visible(const void *_data, enum hwmon_sensor_types type,
+                             u32 attr, int channel)
+{
+       return 0444;
+}
+
+static const u32 rpi_in_config[] = {
+       HWMON_I_LCRIT_ALARM,
+       0
+};
+
+static const struct hwmon_channel_info rpi_in = {
+       .type = hwmon_in,
+       .config = rpi_in_config,
+};
+
+static const struct hwmon_channel_info *rpi_info[] = {
+       &rpi_in,
+       NULL
+};
+
+static const struct hwmon_ops rpi_hwmon_ops = {
+       .is_visible = rpi_is_visible,
+       .read = rpi_read,
+};
+
+static const struct hwmon_chip_info rpi_chip_info = {
+       .ops = &rpi_hwmon_ops,
+       .info = rpi_info,
+};
+
+static int rpi_hwmon_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct rpi_hwmon_data *data;
+       int ret;
+
+       data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       /* Parent driver assure that firmware is correct */
+       data->fw = dev_get_drvdata(dev->parent);
+
+       /* Init throttled */
+       ret = rpi_firmware_property(data->fw, RPI_FIRMWARE_GET_THROTTLED,
+                                   &data->last_throttled,
+                                   sizeof(data->last_throttled));
+
+       data->hwmon_dev = devm_hwmon_device_register_with_info(dev, "rpi_volt",
+                                                              data,
+                                                              &rpi_chip_info,
+                                                              NULL);
+
+       INIT_DELAYED_WORK(&data->get_values_poll_work, get_values_poll);
+       platform_set_drvdata(pdev, data);
+
+       if (!PTR_ERR_OR_ZERO(data->hwmon_dev))
+               schedule_delayed_work(&data->get_values_poll_work, 2 * HZ);
+
+       return PTR_ERR_OR_ZERO(data->hwmon_dev);
+}
+
+static int rpi_hwmon_remove(struct platform_device *pdev)
+{
+       struct rpi_hwmon_data *data = platform_get_drvdata(pdev);
+
+       cancel_delayed_work_sync(&data->get_values_poll_work);
+
+       return 0;
+}
+
+static struct platform_driver rpi_hwmon_driver = {
+       .probe = rpi_hwmon_probe,
+       .remove = rpi_hwmon_remove,
+       .driver = {
+               .name = "raspberrypi-hwmon",
+       },
+};
+module_platform_driver(rpi_hwmon_driver);
+
+MODULE_AUTHOR("Stefan Wahren <stefan.wahren@i2se.com>");
+MODULE_DESCRIPTION("Raspberry Pi voltage sensor driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:raspberrypi-hwmon");
index 634f58042c77f36b7e512a84510e2ac8947eab0e..d293e55553bd690ffc54f97a2b5e6b85916e2865 100644 (file)
@@ -1182,7 +1182,7 @@ static void msc_mmap_close(struct vm_area_struct *vma)
        mutex_unlock(&msc->buf_mutex);
 }
 
-static int msc_mmap_fault(struct vm_fault *vmf)
+static vm_fault_t msc_mmap_fault(struct vm_fault *vmf)
 {
        struct msc_iter *iter = vmf->vma->vm_file->private_data;
        struct msc *msc = iter->msc;
index 72c94c60fdd18b3dc6eb6c30b26c2b692003fa29..bed6ba63c98329cb73d6c7cbb45a72962245c793 100644 (file)
@@ -18,4 +18,3 @@ obj-$(CONFIG_I2C_STUB)                += i2c-stub.o
 obj-$(CONFIG_I2C_SLAVE_EEPROM) += i2c-slave-eeprom.o
 
 ccflags-$(CONFIG_I2C_DEBUG_CORE) := -DDEBUG
-CFLAGS_i2c-core-base.o := -Wno-deprecated-declarations
index 6ec65adaba49569ab7b9775f856859a0fcfbd967..c33dcfb87993b531d40c0f2cdb4954b08f47668a 100644 (file)
@@ -110,8 +110,8 @@ static int sclhi(struct i2c_algo_bit_data *adap)
        }
 #ifdef DEBUG
        if (jiffies != start && i2c_debug >= 3)
-               pr_debug("i2c-algo-bit: needed %ld jiffies for SCL to go "
-                        "high\n", jiffies - start);
+               pr_debug("i2c-algo-bit: needed %ld jiffies for SCL to go high\n",
+                        jiffies - start);
 #endif
 
 done:
@@ -171,8 +171,9 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c)
                setsda(adap, sb);
                udelay((adap->udelay + 1) / 2);
                if (sclhi(adap) < 0) { /* timed out */
-                       bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
-                               "timeout at bit #%d\n", (int)c, i);
+                       bit_dbg(1, &i2c_adap->dev,
+                               "i2c_outb: 0x%02x, timeout at bit #%d\n",
+                               (int)c, i);
                        return -ETIMEDOUT;
                }
                /* FIXME do arbitration here:
@@ -185,8 +186,8 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c)
        }
        sdahi(adap);
        if (sclhi(adap) < 0) { /* timeout */
-               bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
-                       "timeout at ack\n", (int)c);
+               bit_dbg(1, &i2c_adap->dev,
+                       "i2c_outb: 0x%02x, timeout at ack\n", (int)c);
                return -ETIMEDOUT;
        }
 
@@ -215,8 +216,9 @@ static int i2c_inb(struct i2c_adapter *i2c_adap)
        sdahi(adap);
        for (i = 0; i < 8; i++) {
                if (sclhi(adap) < 0) { /* timeout */
-                       bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit "
-                               "#%d\n", 7 - i);
+                       bit_dbg(1, &i2c_adap->dev,
+                               "i2c_inb: timeout at bit #%d\n",
+                               7 - i);
                        return -ETIMEDOUT;
                }
                indata *= 2;
@@ -265,8 +267,9 @@ static int test_bus(struct i2c_adapter *i2c_adap)
                goto bailout;
        }
        if (!scl) {
-               printk(KERN_WARNING "%s: SCL unexpected low "
-                      "while pulling SDA low!\n", name);
+               printk(KERN_WARNING
+                      "%s: SCL unexpected low while pulling SDA low!\n",
+                      name);
                goto bailout;
        }
 
@@ -278,8 +281,9 @@ static int test_bus(struct i2c_adapter *i2c_adap)
                goto bailout;
        }
        if (!scl) {
-               printk(KERN_WARNING "%s: SCL unexpected low "
-                      "while pulling SDA high!\n", name);
+               printk(KERN_WARNING
+                      "%s: SCL unexpected low while pulling SDA high!\n",
+                      name);
                goto bailout;
        }
 
@@ -291,8 +295,9 @@ static int test_bus(struct i2c_adapter *i2c_adap)
                goto bailout;
        }
        if (!sda) {
-               printk(KERN_WARNING "%s: SDA unexpected low "
-                      "while pulling SCL low!\n", name);
+               printk(KERN_WARNING
+                      "%s: SDA unexpected low while pulling SCL low!\n",
+                      name);
                goto bailout;
        }
 
@@ -304,8 +309,9 @@ static int test_bus(struct i2c_adapter *i2c_adap)
                goto bailout;
        }
        if (!sda) {
-               printk(KERN_WARNING "%s: SDA unexpected low "
-                      "while pulling SCL high!\n", name);
+               printk(KERN_WARNING
+                      "%s: SDA unexpected low while pulling SCL high!\n",
+                      name);
                goto bailout;
        }
 
@@ -352,8 +358,8 @@ static int try_address(struct i2c_adapter *i2c_adap,
                i2c_start(adap);
        }
        if (i && ret)
-               bit_dbg(1, &i2c_adap->dev, "Used %d tries to %s client at "
-                       "0x%02x: %s\n", i + 1,
+               bit_dbg(1, &i2c_adap->dev,
+                       "Used %d tries to %s client at 0x%02x: %s\n", i + 1,
                        addr & 1 ? "read from" : "write to", addr >> 1,
                        ret == 1 ? "success" : "failed, timeout?");
        return ret;
@@ -442,8 +448,9 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
                        if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) {
                                if (!(flags & I2C_M_NO_RD_ACK))
                                        acknak(i2c_adap, 0);
-                               dev_err(&i2c_adap->dev, "readbytes: invalid "
-                                       "block length (%d)\n", inval);
+                               dev_err(&i2c_adap->dev,
+                                       "readbytes: invalid block length (%d)\n",
+                                       inval);
                                return -EPROTO;
                        }
                        /* The original count value accounts for the extra
@@ -506,8 +513,8 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
                        return -ENXIO;
                }
                if (flags & I2C_M_RD) {
-                       bit_dbg(3, &i2c_adap->dev, "emitting repeated "
-                               "start condition\n");
+                       bit_dbg(3, &i2c_adap->dev,
+                               "emitting repeated start condition\n");
                        i2c_repstart(adap);
                        /* okay, now switch into reading mode */
                        addr |= 0x01;
@@ -564,8 +571,8 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
                        }
                        ret = bit_doAddress(i2c_adap, pmsg);
                        if ((ret != 0) && !nak_ok) {
-                               bit_dbg(1, &i2c_adap->dev, "NAK from "
-                                       "device addr 0x%02x msg #%d\n",
+                               bit_dbg(1, &i2c_adap->dev,
+                                       "NAK from device addr 0x%02x msg #%d\n",
                                        msgs[i].addr, i);
                                goto bailout;
                        }
index 4f8df2ec87b1b360d0bfefeb796c065edd348a61..451d4ae50e665bfcbcdabe7d7a0aceb8a0e1e29a 100644 (file)
@@ -116,24 +116,21 @@ config I2C_I801
            DH89xxCC (PCH)
            Panther Point (PCH)
            Lynx Point (PCH)
-           Lynx Point-LP (PCH)
            Avoton (SOC)
            Wellsburg (PCH)
            Coleto Creek (PCH)
            Wildcat Point (PCH)
-           Wildcat Point-LP (PCH)
            BayTrail (SOC)
            Braswell (SOC)
-           Sunrise Point-H (PCH)
-           Sunrise Point-LP (PCH)
-           Kaby Lake-H (PCH)
+           Sunrise Point (PCH)
+           Kaby Lake (PCH)
            DNV (SOC)
            Broxton (SOC)
            Lewisburg (PCH)
            Gemini Lake (SOC)
-           Cannon Lake-H (PCH)
-           Cannon Lake-LP (PCH)
+           Cannon Lake (PCH)
            Cedar Fork (PCH)
+           Ice Lake (PCH)
 
          This driver can also be built as a module.  If so, the module
          will be called i2c-i801.
@@ -762,6 +759,13 @@ config I2C_OMAP
          Like OMAP1510/1610/1710/5912 and OMAP242x.
          For details see http://www.ti.com/omap.
 
+config I2C_OWL
+       tristate "Actions Semiconductor Owl I2C Controller"
+       depends on ARCH_ACTIONS || COMPILE_TEST
+       help
+         Say Y here if you want to use the I2C bus controller on
+         the Actions Semiconductor Owl SoC's.
+
 config I2C_PASEMI
        tristate "PA Semi SMBus interface"
        depends on PPC_PASEMI && PCI
@@ -828,6 +832,19 @@ config I2C_PXA_SLAVE
          is necessary for systems where the PXA may be a target on the
          I2C bus.
 
+config I2C_QCOM_GENI
+       tristate "Qualcomm Technologies Inc.'s GENI based I2C controller"
+       depends on ARCH_QCOM || COMPILE_TEST
+       depends on QCOM_GENI_SE
+       help
+         This driver supports GENI serial engine based I2C controller in
+         master mode on the Qualcomm Technologies Inc.'s SoCs. If you say
+         yes to this option, support will be included for the built-in I2C
+         interface on the Qualcomm Technologies Inc.'s SoCs.
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-qcom-geni.
+
 config I2C_QUP
        tristate "Qualcomm QUP based I2C controller"
        depends on ARCH_QCOM
@@ -1330,4 +1347,15 @@ config I2C_ZX2967
          This driver can also be built as a module. If so, the module will be
          called i2c-zx2967.
 
+config I2C_FSI
+       tristate "FSI I2C driver"
+       depends on FSI
+       help
+         Driver for FSI bus attached I2C masters. These are I2C masters that
+         are connected to the system over an FSI bus, instead of the more
+         common PCI or MMIO interface.
+
+         This driver can also be built as a module. If so, the module will be
+         called as i2c-fsi.
+
 endmenu
index 5a869144a0c5cdc942584153c68570db3892c702..18b26af82b1c5425a9dcec9c61cca3cdff694d60 100644 (file)
@@ -76,6 +76,7 @@ obj-$(CONFIG_I2C_MXS)         += i2c-mxs.o
 obj-$(CONFIG_I2C_NOMADIK)      += i2c-nomadik.o
 obj-$(CONFIG_I2C_OCORES)       += i2c-ocores.o
 obj-$(CONFIG_I2C_OMAP)         += i2c-omap.o
+obj-$(CONFIG_I2C_OWL)          += i2c-owl.o
 obj-$(CONFIG_I2C_PASEMI)       += i2c-pasemi.o
 obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pca-platform.o
 obj-$(CONFIG_I2C_PMCMSP)       += i2c-pmcmsp.o
@@ -83,6 +84,7 @@ obj-$(CONFIG_I2C_PNX)         += i2c-pnx.o
 obj-$(CONFIG_I2C_PUV3)         += i2c-puv3.o
 obj-$(CONFIG_I2C_PXA)          += i2c-pxa.o
 obj-$(CONFIG_I2C_PXA_PCI)      += i2c-pxa-pci.o
+obj-$(CONFIG_I2C_QCOM_GENI)    += i2c-qcom-geni.o
 obj-$(CONFIG_I2C_QUP)          += i2c-qup.o
 obj-$(CONFIG_I2C_RIIC)         += i2c-riic.o
 obj-$(CONFIG_I2C_RK3X)         += i2c-rk3x.o
@@ -137,5 +139,6 @@ obj-$(CONFIG_I2C_PCA_ISA)   += i2c-pca-isa.o
 obj-$(CONFIG_I2C_SIBYTE)       += i2c-sibyte.o
 obj-$(CONFIG_I2C_XGENE_SLIMPRO) += i2c-xgene-slimpro.o
 obj-$(CONFIG_SCx200_ACB)       += scx200_acb.o
+obj-$(CONFIG_I2C_FSI)          += i2c-fsi.o
 
 ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG
index 95a80a8f81b55a2c56633a2980c821e5b0714875..134567f3019fb50ead037861a11eb3576b634891 100644 (file)
@@ -384,6 +384,7 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
                        if (status)
                                return status;
                        len = min_t(u8, len, I2C_SMBUS_BLOCK_MAX);
+                       /* fall through */
                case I2C_SMBUS_I2C_BLOCK_DATA:
                        for (i = 0; i < len; i++) {
                                status = amd_ec_read(smbus, AMD_SMB_DATA + i,
index 60e4d0e939a3814ffe142edba612817de7590c48..a4f956c6d567d4b380505b0da1eedba97b795360 100644 (file)
 #define ASPEED_I2CD_DEV_ADDR_MASK                      GENMASK(6, 0)
 
 enum aspeed_i2c_master_state {
+       ASPEED_I2C_MASTER_INACTIVE,
        ASPEED_I2C_MASTER_START,
        ASPEED_I2C_MASTER_TX_FIRST,
        ASPEED_I2C_MASTER_TX,
        ASPEED_I2C_MASTER_RX_FIRST,
        ASPEED_I2C_MASTER_RX,
        ASPEED_I2C_MASTER_STOP,
-       ASPEED_I2C_MASTER_INACTIVE,
 };
 
 enum aspeed_i2c_slave_state {
+       ASPEED_I2C_SLAVE_STOP,
        ASPEED_I2C_SLAVE_START,
        ASPEED_I2C_SLAVE_READ_REQUESTED,
        ASPEED_I2C_SLAVE_READ_PROCESSED,
        ASPEED_I2C_SLAVE_WRITE_REQUESTED,
        ASPEED_I2C_SLAVE_WRITE_RECEIVED,
-       ASPEED_I2C_SLAVE_STOP,
 };
 
 struct aspeed_i2c_bus {
@@ -234,7 +234,6 @@ static bool aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus)
        bool irq_handled = true;
        u8 value;
 
-       spin_lock(&bus->lock);
        if (!slave) {
                irq_handled = false;
                goto out;
@@ -325,7 +324,6 @@ static bool aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus)
        writel(status_ack, bus->base + ASPEED_I2C_INTR_STS_REG);
 
 out:
-       spin_unlock(&bus->lock);
        return irq_handled;
 }
 #endif /* CONFIG_I2C_SLAVE */
@@ -389,7 +387,6 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
        u8 recv_byte;
        int ret;
 
-       spin_lock(&bus->lock);
        irq_status = readl(bus->base + ASPEED_I2C_INTR_STS_REG);
        /* Ack all interrupt bits. */
        writel(irq_status, bus->base + ASPEED_I2C_INTR_STS_REG);
@@ -407,7 +404,7 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
         */
        ret = aspeed_i2c_is_irq_error(irq_status);
        if (ret < 0) {
-               dev_dbg(bus->dev, "received error interrupt: 0x%08x",
+               dev_dbg(bus->dev, "received error interrupt: 0x%08x\n",
                        irq_status);
                bus->cmd_err = ret;
                bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
@@ -416,7 +413,7 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
 
        /* We are in an invalid state; reset bus to a known state. */
        if (!bus->msgs) {
-               dev_err(bus->dev, "bus in unknown state");
+               dev_err(bus->dev, "bus in unknown state\n");
                bus->cmd_err = -EIO;
                if (bus->master_state != ASPEED_I2C_MASTER_STOP)
                        aspeed_i2c_do_stop(bus);
@@ -431,7 +428,7 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
         */
        if (bus->master_state == ASPEED_I2C_MASTER_START) {
                if (unlikely(!(irq_status & ASPEED_I2CD_INTR_TX_ACK))) {
-                       pr_devel("no slave present at %02x", msg->addr);
+                       pr_devel("no slave present at %02x\n", msg->addr);
                        status_ack |= ASPEED_I2CD_INTR_TX_NAK;
                        bus->cmd_err = -ENXIO;
                        aspeed_i2c_do_stop(bus);
@@ -451,11 +448,11 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
        switch (bus->master_state) {
        case ASPEED_I2C_MASTER_TX:
                if (unlikely(irq_status & ASPEED_I2CD_INTR_TX_NAK)) {
-                       dev_dbg(bus->dev, "slave NACKed TX");
+                       dev_dbg(bus->dev, "slave NACKed TX\n");
                        status_ack |= ASPEED_I2CD_INTR_TX_NAK;
                        goto error_and_stop;
                } else if (unlikely(!(irq_status & ASPEED_I2CD_INTR_TX_ACK))) {
-                       dev_err(bus->dev, "slave failed to ACK TX");
+                       dev_err(bus->dev, "slave failed to ACK TX\n");
                        goto error_and_stop;
                }
                status_ack |= ASPEED_I2CD_INTR_TX_ACK;
@@ -478,7 +475,7 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
                /* fallthrough intended */
        case ASPEED_I2C_MASTER_RX:
                if (unlikely(!(irq_status & ASPEED_I2CD_INTR_RX_DONE))) {
-                       dev_err(bus->dev, "master failed to RX");
+                       dev_err(bus->dev, "master failed to RX\n");
                        goto error_and_stop;
                }
                status_ack |= ASPEED_I2CD_INTR_RX_DONE;
@@ -509,7 +506,7 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
                goto out_no_complete;
        case ASPEED_I2C_MASTER_STOP:
                if (unlikely(!(irq_status & ASPEED_I2CD_INTR_NORMAL_STOP))) {
-                       dev_err(bus->dev, "master failed to STOP");
+                       dev_err(bus->dev, "master failed to STOP\n");
                        bus->cmd_err = -EIO;
                        /* Do not STOP as we have already tried. */
                } else {
@@ -520,7 +517,7 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
                goto out_complete;
        case ASPEED_I2C_MASTER_INACTIVE:
                dev_err(bus->dev,
-                       "master received interrupt 0x%08x, but is inactive",
+                       "master received interrupt 0x%08x, but is inactive\n",
                        irq_status);
                bus->cmd_err = -EIO;
                /* Do not STOP as we should be inactive. */
@@ -547,22 +544,29 @@ out_no_complete:
                dev_err(bus->dev,
                        "irq handled != irq. expected 0x%08x, but was 0x%08x\n",
                        irq_status, status_ack);
-       spin_unlock(&bus->lock);
        return !!irq_status;
 }
 
 static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
 {
        struct aspeed_i2c_bus *bus = dev_id;
+       bool ret;
+
+       spin_lock(&bus->lock);
 
 #if IS_ENABLED(CONFIG_I2C_SLAVE)
        if (aspeed_i2c_slave_irq(bus)) {
                dev_dbg(bus->dev, "irq handled by slave.\n");
-               return IRQ_HANDLED;
+               ret = true;
+               goto out;
        }
 #endif /* CONFIG_I2C_SLAVE */
 
-       return aspeed_i2c_master_irq(bus) ? IRQ_HANDLED : IRQ_NONE;
+       ret = aspeed_i2c_master_irq(bus);
+
+out:
+       spin_unlock(&bus->lock);
+       return ret ? IRQ_HANDLED : IRQ_NONE;
 }
 
 static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
@@ -851,7 +855,7 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev)
        bus->rst = devm_reset_control_get_shared(&pdev->dev, NULL);
        if (IS_ERR(bus->rst)) {
                dev_err(&pdev->dev,
-                       "missing or invalid reset controller device tree entry");
+                       "missing or invalid reset controller device tree entry\n");
                return PTR_ERR(bus->rst);
        }
        reset_control_deassert(bus->rst);
@@ -868,7 +872,7 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev)
        if (!match)
                bus->get_clk_reg_val = aspeed_i2c_24xx_get_clk_reg_val;
        else
-               bus->get_clk_reg_val = match->data;
+               bus->get_clk_reg_val = (u32 (*)(u32))match->data;
 
        /* Initialize the I2C adapter */
        spin_lock_init(&bus->lock);
index 78792b4d6437c7cca6d84fd4977773f0c65781e2..826d320499961691bacd3e33d04526125ae1a959 100644 (file)
@@ -689,9 +689,9 @@ static int brcmstb_i2c_suspend(struct device *dev)
 {
        struct brcmstb_i2c_dev *i2c_dev = dev_get_drvdata(dev);
 
-       i2c_lock_adapter(&i2c_dev->adapter);
+       i2c_lock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
        i2c_dev->is_suspended = true;
-       i2c_unlock_adapter(&i2c_dev->adapter);
+       i2c_unlock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
 
        return 0;
 }
@@ -700,10 +700,10 @@ static int brcmstb_i2c_resume(struct device *dev)
 {
        struct brcmstb_i2c_dev *i2c_dev = dev_get_drvdata(dev);
 
-       i2c_lock_adapter(&i2c_dev->adapter);
+       i2c_lock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
        brcmstb_i2c_set_bsc_reg_defaults(i2c_dev);
        i2c_dev->is_suspended = false;
-       i2c_unlock_adapter(&i2c_dev->adapter);
+       i2c_unlock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
 
        return 0;
 }
index 7379043711dfa89455abd65bce74ac08707073f9..11caafa0e050cd41e23885063b1ab12c16c5e8ee 100644 (file)
@@ -718,14 +718,14 @@ static int i2c_davinci_cpufreq_transition(struct notifier_block *nb,
 
        dev = container_of(nb, struct davinci_i2c_dev, freq_transition);
 
-       i2c_lock_adapter(&dev->adapter);
+       i2c_lock_bus(&dev->adapter, I2C_LOCK_ROOT_ADAPTER);
        if (val == CPUFREQ_PRECHANGE) {
                davinci_i2c_reset_ctrl(dev, 0);
        } else if (val == CPUFREQ_POSTCHANGE) {
                i2c_davinci_calc_clk_dividers(dev);
                davinci_i2c_reset_ctrl(dev, 1);
        }
-       i2c_unlock_adapter(&dev->adapter);
+       i2c_unlock_bus(&dev->adapter, I2C_LOCK_ROOT_ADAPTER);
 
        return 0;
 }
index dbda8c9c8a1ce07e0563182d3dbe01d6380b5ac6..a2a275cfc1f694896bf112b2862f1bd8f2530ece 100644 (file)
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Intel BayTrail PMIC I2C bus semaphore implementaion
  * Copyright (c) 2014, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
  */
 #include <linux/delay.h>
 #include <linux/device.h>
index 48914dfc8ce88ff54246a2f450ef2bc3ae9afe4d..69ec4a791f23e78e1462c002eaca62c9e400da5a 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Synopsys DesignWare I2C adapter driver.
  *
@@ -6,20 +7,6 @@
  * Copyright (C) 2006 Texas Instruments.
  * Copyright (C) 2007 MontaVista Software Inc.
  * Copyright (C) 2009 Provigent Ltd.
- *
- * ----------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * ----------------------------------------------------------------------------
- *
  */
 #include <linux/clk.h>
 #include <linux/delay.h>
@@ -31,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
+#include <linux/swab.h>
 
 #include "i2c-designware-core.h"
 
@@ -94,6 +82,40 @@ void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset)
        }
 }
 
+/**
+ * i2c_dw_set_reg_access() - Set register access flags
+ * @dev: device private data
+ *
+ * Autodetects needed register access mode and sets access flags accordingly.
+ * This must be called before doing any other register access.
+ */
+int i2c_dw_set_reg_access(struct dw_i2c_dev *dev)
+{
+       u32 reg;
+       int ret;
+
+       ret = i2c_dw_acquire_lock(dev);
+       if (ret)
+               return ret;
+
+       reg = dw_readl(dev, DW_IC_COMP_TYPE);
+       i2c_dw_release_lock(dev);
+
+       if (reg == swab32(DW_IC_COMP_TYPE_VALUE)) {
+               /* Configure register endianess access */
+               dev->flags |= ACCESS_SWAP;
+       } else if (reg == (DW_IC_COMP_TYPE_VALUE & 0x0000ffff)) {
+               /* Configure register access mode 16bit */
+               dev->flags |= ACCESS_16BIT;
+       } else if (reg != DW_IC_COMP_TYPE_VALUE) {
+               dev_err(dev->dev,
+                       "Unknown Synopsys component type: 0x%08x\n", reg);
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
 u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset)
 {
        /*
@@ -149,6 +171,47 @@ u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)
        return ((ic_clk * (tLOW + tf) + 500000) / 1000000) - 1 + offset;
 }
 
+int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev)
+{
+       u32 reg;
+       int ret;
+
+       ret = i2c_dw_acquire_lock(dev);
+       if (ret)
+               return ret;
+
+       /* Configure SDA Hold Time if required */
+       reg = dw_readl(dev, DW_IC_COMP_VERSION);
+       if (reg >= DW_IC_SDA_HOLD_MIN_VERS) {
+               if (!dev->sda_hold_time) {
+                       /* Keep previous hold time setting if no one set it */
+                       dev->sda_hold_time = dw_readl(dev, DW_IC_SDA_HOLD);
+               }
+
+               /*
+                * Workaround for avoiding TX arbitration lost in case I2C
+                * slave pulls SDA down "too quickly" after falling egde of
+                * SCL by enabling non-zero SDA RX hold. Specification says it
+                * extends incoming SDA low to high transition while SCL is
+                * high but it apprears to help also above issue.
+                */
+               if (!(dev->sda_hold_time & DW_IC_SDA_HOLD_RX_MASK))
+                       dev->sda_hold_time |= 1 << DW_IC_SDA_HOLD_RX_SHIFT;
+
+               dev_dbg(dev->dev, "SDA Hold Time TX:RX = %d:%d\n",
+                       dev->sda_hold_time & ~(u32)DW_IC_SDA_HOLD_RX_MASK,
+                       dev->sda_hold_time >> DW_IC_SDA_HOLD_RX_SHIFT);
+       } else if (dev->sda_hold_time) {
+               dev_warn(dev->dev,
+                       "Hardware too old to adjust SDA hold time.\n");
+               dev->sda_hold_time = 0;
+       }
+
+       i2c_dw_release_lock(dev);
+
+       return 0;
+}
+
 void __i2c_dw_disable(struct dw_i2c_dev *dev)
 {
        int timeout = 100;
index d690e648bc015efcd96d63b81c11969e9a6ceaae..e367b1af4ab2cdebb120fa72e3dbc1a9f7c94171 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
 /*
  * Synopsys DesignWare I2C adapter driver.
  *
@@ -6,20 +7,6 @@
  * Copyright (C) 2006 Texas Instruments.
  * Copyright (C) 2007 MontaVista Software Inc.
  * Copyright (C) 2009 Provigent Ltd.
- *
- * ----------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * ----------------------------------------------------------------------------
- *
  */
 
 #include <linux/i2c.h>
  * @tx_fifo_depth: depth of the hardware tx fifo
  * @rx_fifo_depth: depth of the hardware rx fifo
  * @rx_outstanding: current master-rx elements in tx fifo
- * @clk_freq: bus clock frequency
+ * @timings: bus clock frequency, SDA hold and other timings
+ * @sda_hold_time: SDA hold value
  * @ss_hcnt: standard speed HCNT value
  * @ss_lcnt: standard speed LCNT value
  * @fs_hcnt: fast speed HCNT value
@@ -264,10 +252,8 @@ struct dw_i2c_dev {
        unsigned int            tx_fifo_depth;
        unsigned int            rx_fifo_depth;
        int                     rx_outstanding;
-       u32                     clk_freq;
+       struct i2c_timings      timings;
        u32                     sda_hold_time;
-       u32                     sda_falling_time;
-       u32                     scl_falling_time;
        u16                     ss_hcnt;
        u16                     ss_lcnt;
        u16                     fs_hcnt;
@@ -295,8 +281,10 @@ struct dw_i2c_dev {
 
 u32 dw_readl(struct dw_i2c_dev *dev, int offset);
 void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset);
+int i2c_dw_set_reg_access(struct dw_i2c_dev *dev);
 u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset);
 u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset);
+int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev);
 unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev);
 int i2c_dw_prepare_clk(struct dw_i2c_dev *dev, bool prepare);
 int i2c_dw_acquire_lock(struct dw_i2c_dev *dev);
index 27436a937492d1afdefe77264bcd1afaf7d91856..94d94b4a9a0d989d932101422eb87feeb9cf7525 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Synopsys DesignWare I2C adapter driver (master only).
  *
@@ -6,20 +7,6 @@
  * Copyright (C) 2006 Texas Instruments.
  * Copyright (C) 2007 MontaVista Software Inc.
  * Copyright (C) 2009 Provigent Ltd.
- *
- * ----------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * ----------------------------------------------------------------------------
- *
  */
 #include <linux/delay.h>
 #include <linux/err.h>
@@ -45,90 +32,79 @@ static void i2c_dw_configure_fifo_master(struct dw_i2c_dev *dev)
        dw_writel(dev, dev->master_cfg, DW_IC_CON);
 }
 
-/**
- * i2c_dw_init() - Initialize the designware I2C master hardware
- * @dev: device private data
- *
- * This functions configures and enables the I2C master.
- * This function is called during I2C init function, and in case of timeout at
- * run time.
- */
-static int i2c_dw_init_master(struct dw_i2c_dev *dev)
+static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
 {
-       u32 hcnt, lcnt;
-       u32 reg, comp_param1;
+       u32 ic_clk = i2c_dw_clk_rate(dev);
+       const char *mode_str, *fp_str = "";
+       u32 comp_param1;
        u32 sda_falling_time, scl_falling_time;
+       struct i2c_timings *t = &dev->timings;
        int ret;
 
        ret = i2c_dw_acquire_lock(dev);
        if (ret)
                return ret;
-
-       reg = dw_readl(dev, DW_IC_COMP_TYPE);
-       if (reg == ___constant_swab32(DW_IC_COMP_TYPE_VALUE)) {
-               /* Configure register endianess access */
-               dev->flags |= ACCESS_SWAP;
-       } else if (reg == (DW_IC_COMP_TYPE_VALUE & 0x0000ffff)) {
-               /* Configure register access mode 16bit */
-               dev->flags |= ACCESS_16BIT;
-       } else if (reg != DW_IC_COMP_TYPE_VALUE) {
-               dev_err(dev->dev,
-                       "Unknown Synopsys component type: 0x%08x\n", reg);
-               i2c_dw_release_lock(dev);
-               return -ENODEV;
-       }
-
        comp_param1 = dw_readl(dev, DW_IC_COMP_PARAM_1);
+       i2c_dw_release_lock(dev);
 
-       /* Disable the adapter */
-       __i2c_dw_disable(dev);
-
-       /* Set standard and fast speed deviders for high/low periods */
-
-       sda_falling_time = dev->sda_falling_time ?: 300; /* ns */
-       scl_falling_time = dev->scl_falling_time ?: 300; /* ns */
+       /* Set standard and fast speed dividers for high/low periods */
+       sda_falling_time = t->sda_fall_ns ?: 300; /* ns */
+       scl_falling_time = t->scl_fall_ns ?: 300; /* ns */
 
-       /* Set SCL timing parameters for standard-mode */
-       if (dev->ss_hcnt && dev->ss_lcnt) {
-               hcnt = dev->ss_hcnt;
-               lcnt = dev->ss_lcnt;
-       } else {
-               hcnt = i2c_dw_scl_hcnt(i2c_dw_clk_rate(dev),
+       /* Calculate SCL timing parameters for standard mode if not set */
+       if (!dev->ss_hcnt || !dev->ss_lcnt) {
+               dev->ss_hcnt =
+                       i2c_dw_scl_hcnt(ic_clk,
                                        4000,   /* tHD;STA = tHIGH = 4.0 us */
                                        sda_falling_time,
                                        0,      /* 0: DW default, 1: Ideal */
                                        0);     /* No offset */
-               lcnt = i2c_dw_scl_lcnt(i2c_dw_clk_rate(dev),
+               dev->ss_lcnt =
+                       i2c_dw_scl_lcnt(ic_clk,
                                        4700,   /* tLOW = 4.7 us */
                                        scl_falling_time,
                                        0);     /* No offset */
        }
-       dw_writel(dev, hcnt, DW_IC_SS_SCL_HCNT);
-       dw_writel(dev, lcnt, DW_IC_SS_SCL_LCNT);
-       dev_dbg(dev->dev, "Standard-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
-
-       /* Set SCL timing parameters for fast-mode or fast-mode plus */
-       if ((dev->clk_freq == 1000000) && dev->fp_hcnt && dev->fp_lcnt) {
-               hcnt = dev->fp_hcnt;
-               lcnt = dev->fp_lcnt;
-       } else if (dev->fs_hcnt && dev->fs_lcnt) {
-               hcnt = dev->fs_hcnt;
-               lcnt = dev->fs_lcnt;
-       } else {
-               hcnt = i2c_dw_scl_hcnt(i2c_dw_clk_rate(dev),
+       dev_dbg(dev->dev, "Standard Mode HCNT:LCNT = %d:%d\n",
+               dev->ss_hcnt, dev->ss_lcnt);
+
+       /*
+        * Set SCL timing parameters for fast mode or fast mode plus. Only
+        * difference is the timing parameter values since the registers are
+        * the same.
+        */
+       if (t->bus_freq_hz == 1000000) {
+               /*
+                * Check are fast mode plus parameters available and use
+                * fast mode if not.
+                */
+               if (dev->fp_hcnt && dev->fp_lcnt) {
+                       dev->fs_hcnt = dev->fp_hcnt;
+                       dev->fs_lcnt = dev->fp_lcnt;
+                       fp_str = " Plus";
+               }
+       }
+       /*
+        * Calculate SCL timing parameters for fast mode if not set. They are
+        * needed also in high speed mode.
+        */
+       if (!dev->fs_hcnt || !dev->fs_lcnt) {
+               dev->fs_hcnt =
+                       i2c_dw_scl_hcnt(ic_clk,
                                        600,    /* tHD;STA = tHIGH = 0.6 us */
                                        sda_falling_time,
                                        0,      /* 0: DW default, 1: Ideal */
                                        0);     /* No offset */
-               lcnt = i2c_dw_scl_lcnt(i2c_dw_clk_rate(dev),
+               dev->fs_lcnt =
+                       i2c_dw_scl_lcnt(ic_clk,
                                        1300,   /* tLOW = 1.3 us */
                                        scl_falling_time,
                                        0);     /* No offset */
        }
-       dw_writel(dev, hcnt, DW_IC_FS_SCL_HCNT);
-       dw_writel(dev, lcnt, DW_IC_FS_SCL_LCNT);
-       dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
+       dev_dbg(dev->dev, "Fast Mode%s HCNT:LCNT = %d:%d\n",
+               fp_str, dev->fs_hcnt, dev->fs_lcnt);
 
+       /* Check is high speed possible and fall back to fast mode if not */
        if ((dev->master_cfg & DW_IC_CON_SPEED_MASK) ==
                DW_IC_CON_SPEED_HIGH) {
                if ((comp_param1 & DW_IC_COMP_PARAM_1_SPEED_MODE_MASK)
@@ -136,37 +112,70 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev)
                        dev_err(dev->dev, "High Speed not supported!\n");
                        dev->master_cfg &= ~DW_IC_CON_SPEED_MASK;
                        dev->master_cfg |= DW_IC_CON_SPEED_FAST;
+                       dev->hs_hcnt = 0;
+                       dev->hs_lcnt = 0;
                } else if (dev->hs_hcnt && dev->hs_lcnt) {
-                       hcnt = dev->hs_hcnt;
-                       lcnt = dev->hs_lcnt;
-                       dw_writel(dev, hcnt, DW_IC_HS_SCL_HCNT);
-                       dw_writel(dev, lcnt, DW_IC_HS_SCL_LCNT);
-                       dev_dbg(dev->dev, "HighSpeed-mode HCNT:LCNT = %d:%d\n",
-                               hcnt, lcnt);
+                       dev_dbg(dev->dev, "High Speed Mode HCNT:LCNT = %d:%d\n",
+                               dev->hs_hcnt, dev->hs_lcnt);
                }
        }
 
-       /* Configure SDA Hold Time if required */
-       reg = dw_readl(dev, DW_IC_COMP_VERSION);
-       if (reg >= DW_IC_SDA_HOLD_MIN_VERS) {
-               if (!dev->sda_hold_time) {
-                       /* Keep previous hold time setting if no one set it */
-                       dev->sda_hold_time = dw_readl(dev, DW_IC_SDA_HOLD);
-               }
-               /*
-                * Workaround for avoiding TX arbitration lost in case I2C
-                * slave pulls SDA down "too quickly" after falling egde of
-                * SCL by enabling non-zero SDA RX hold. Specification says it
-                * extends incoming SDA low to high transition while SCL is
-                * high but it apprears to help also above issue.
-                */
-               if (!(dev->sda_hold_time & DW_IC_SDA_HOLD_RX_MASK))
-                       dev->sda_hold_time |= 1 << DW_IC_SDA_HOLD_RX_SHIFT;
-               dw_writel(dev, dev->sda_hold_time, DW_IC_SDA_HOLD);
-       } else if (dev->sda_hold_time) {
-               dev_warn(dev->dev,
-                       "Hardware too old to adjust SDA hold time.\n");
+       ret = i2c_dw_set_sda_hold(dev);
+       if (ret)
+               goto out;
+
+       switch (dev->master_cfg & DW_IC_CON_SPEED_MASK) {
+       case DW_IC_CON_SPEED_STD:
+               mode_str = "Standard Mode";
+               break;
+       case DW_IC_CON_SPEED_HIGH:
+               mode_str = "High Speed Mode";
+               break;
+       default:
+               mode_str = "Fast Mode";
        }
+       dev_dbg(dev->dev, "Bus speed: %s%s\n", mode_str, fp_str);
+
+out:
+       return ret;
+}
+
+/**
+ * i2c_dw_init() - Initialize the designware I2C master hardware
+ * @dev: device private data
+ *
+ * This functions configures and enables the I2C master.
+ * This function is called during I2C init function, and in case of timeout at
+ * run time.
+ */
+static int i2c_dw_init_master(struct dw_i2c_dev *dev)
+{
+       int ret;
+
+       ret = i2c_dw_acquire_lock(dev);
+       if (ret)
+               return ret;
+
+       /* Disable the adapter */
+       __i2c_dw_disable(dev);
+
+       /* Write standard speed timing parameters */
+       dw_writel(dev, dev->ss_hcnt, DW_IC_SS_SCL_HCNT);
+       dw_writel(dev, dev->ss_lcnt, DW_IC_SS_SCL_LCNT);
+
+       /* Write fast mode/fast mode plus timing parameters */
+       dw_writel(dev, dev->fs_hcnt, DW_IC_FS_SCL_HCNT);
+       dw_writel(dev, dev->fs_lcnt, DW_IC_FS_SCL_LCNT);
+
+       /* Write high speed timing parameters if supported */
+       if (dev->hs_hcnt && dev->hs_lcnt) {
+               dw_writel(dev, dev->hs_hcnt, DW_IC_HS_SCL_HCNT);
+               dw_writel(dev, dev->hs_lcnt, DW_IC_HS_SCL_LCNT);
+       }
+
+       /* Write SDA hold time if supported */
+       if (dev->sda_hold_time)
+               dw_writel(dev, dev->sda_hold_time, DW_IC_SDA_HOLD);
 
        i2c_dw_configure_fifo_master(dev);
        i2c_dw_release_lock(dev);
@@ -253,13 +262,6 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
                        break;
                }
 
-               if (msgs[dev->msg_write_idx].len == 0) {
-                       dev_err(dev->dev,
-                               "%s: invalid message length\n", __func__);
-                       dev->msg_err = -EINVAL;
-                       break;
-               }
-
                if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) {
                        /* new i2c_msg */
                        buf = msgs[dev->msg_write_idx].buf;
@@ -502,6 +504,10 @@ static const struct i2c_algorithm i2c_dw_algo = {
        .functionality = i2c_dw_func,
 };
 
+static const struct i2c_adapter_quirks i2c_dw_quirks = {
+       .flags = I2C_AQ_NO_ZERO_LEN,
+};
+
 static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev)
 {
        u32 stat;
@@ -681,6 +687,14 @@ int i2c_dw_probe(struct dw_i2c_dev *dev)
        dev->disable = i2c_dw_disable;
        dev->disable_int = i2c_dw_disable_int;
 
+       ret = i2c_dw_set_reg_access(dev);
+       if (ret)
+               return ret;
+
+       ret = i2c_dw_set_timings_master(dev);
+       if (ret)
+               return ret;
+
        ret = dev->init(dev);
        if (ret)
                return ret;
@@ -689,11 +703,11 @@ int i2c_dw_probe(struct dw_i2c_dev *dev)
                 "Synopsys DesignWare I2C adapter");
        adap->retries = 3;
        adap->algo = &i2c_dw_algo;
+       adap->quirks = &i2c_dw_quirks;
        adap->dev.parent = dev->dev;
        i2c_set_adapdata(adap, dev);
 
        if (dev->pm_disabled) {
-               dev_pm_syscore_device(dev->dev, true);
                irq_flags = IRQF_NO_SUSPEND;
        } else {
                irq_flags = IRQF_SHARED | IRQF_COND_SUSPEND;
index 86e1bd0b82e91ac6a17d081e3dd626aa252a8652..d50f804872149864ae75c73f00c88138daa45ede 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Synopsys DesignWare I2C adapter driver (master only).
  *
@@ -7,22 +8,7 @@
  * Copyright (C) 2007 MontaVista Software Inc.
  * Copyright (C) 2009 Provigent Ltd.
  * Copyright (C) 2011, 2015, 2016 Intel Corporation.
- *
- * ----------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * ----------------------------------------------------------------------------
- *
  */
-
 #include <linux/acpi.h>
 #include <linux/delay.h>
 #include <linux/err.h>
@@ -105,6 +91,7 @@ static int mfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
        case 0x0817:
                c->bus_cfg &= ~DW_IC_CON_SPEED_MASK;
                c->bus_cfg |= DW_IC_CON_SPEED_STD;
+               /* fall through */
        case 0x0818:
        case 0x0819:
                c->bus_num = pdev->device - 0x817 + 3;
index 5660daf6c92ef541b6755e73361cc32826ac04ff..b5750fd851251e74b0558576774da4a82d81c757 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Synopsys DesignWare I2C adapter driver.
  *
@@ -6,20 +7,6 @@
  * Copyright (C) 2006 Texas Instruments.
  * Copyright (C) 2007 MontaVista Software Inc.
  * Copyright (C) 2009 Provigent Ltd.
- *
- * ----------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * ----------------------------------------------------------------------------
- *
  */
 #include <linux/acpi.h>
 #include <linux/clk-provider.h>
@@ -96,6 +83,7 @@ static void dw_i2c_acpi_params(struct platform_device *pdev, char method[],
 static int dw_i2c_acpi_configure(struct platform_device *pdev)
 {
        struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
+       struct i2c_timings *t = &dev->timings;
        u32 ss_ht = 0, fp_ht = 0, hs_ht = 0, fs_ht = 0;
        acpi_handle handle = ACPI_HANDLE(&pdev->dev);
        const struct acpi_device_id *id;
@@ -115,7 +103,7 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
        dw_i2c_acpi_params(pdev, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt, &hs_ht);
        dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, &fs_ht);
 
-       switch (dev->clk_freq) {
+       switch (t->bus_freq_hz) {
        case 100000:
                dev->sda_hold_time = ss_ht;
                break;
@@ -175,6 +163,8 @@ static inline int dw_i2c_acpi_configure(struct platform_device *pdev)
 
 static void i2c_dw_configure_master(struct dw_i2c_dev *dev)
 {
+       struct i2c_timings *t = &dev->timings;
+
        dev->functionality = I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY;
 
        dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
@@ -182,7 +172,7 @@ static void i2c_dw_configure_master(struct dw_i2c_dev *dev)
 
        dev->mode = DW_IC_MASTER;
 
-       switch (dev->clk_freq) {
+       switch (t->bus_freq_hz) {
        case 100000:
                dev->master_cfg |= DW_IC_CON_SPEED_STD;
                break;
@@ -240,7 +230,8 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
        struct dw_i2c_platform_data *pdata = dev_get_platdata(&pdev->dev);
        struct i2c_adapter *adap;
        struct dw_i2c_dev *dev;
-       u32 acpi_speed, ht = 0;
+       struct i2c_timings *t;
+       u32 acpi_speed;
        struct resource *mem;
        int i, irq, ret;
        static const int supported_speeds[] = {
@@ -272,18 +263,11 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
                reset_control_deassert(dev->rst);
        }
 
-       if (pdata) {
-               dev->clk_freq = pdata->i2c_scl_freq;
-       } else {
-               device_property_read_u32(&pdev->dev, "i2c-sda-hold-time-ns",
-                                        &ht);
-               device_property_read_u32(&pdev->dev, "i2c-sda-falling-time-ns",
-                                        &dev->sda_falling_time);
-               device_property_read_u32(&pdev->dev, "i2c-scl-falling-time-ns",
-                                        &dev->scl_falling_time);
-               device_property_read_u32(&pdev->dev, "clock-frequency",
-                                        &dev->clk_freq);
-       }
+       t = &dev->timings;
+       if (pdata)
+               t->bus_freq_hz = pdata->i2c_scl_freq;
+       else
+               i2c_parse_fw_timings(&pdev->dev, t, false);
 
        acpi_speed = i2c_acpi_find_bus_speed(&pdev->dev);
        /*
@@ -300,12 +284,12 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
         * Find bus speed from the "clock-frequency" device property, ACPI
         * or by using fast mode if neither is set.
         */
-       if (acpi_speed && dev->clk_freq)
-               dev->clk_freq = min(dev->clk_freq, acpi_speed);
-       else if (acpi_speed || dev->clk_freq)
-               dev->clk_freq = max(dev->clk_freq, acpi_speed);
+       if (acpi_speed && t->bus_freq_hz)
+               t->bus_freq_hz = min(t->bus_freq_hz, acpi_speed);
+       else if (acpi_speed || t->bus_freq_hz)
+               t->bus_freq_hz = max(t->bus_freq_hz, acpi_speed);
        else
-               dev->clk_freq = 400000;
+               t->bus_freq_hz = 400000;
 
        if (has_acpi_companion(&pdev->dev))
                dw_i2c_acpi_configure(pdev);
@@ -314,11 +298,11 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
         * Only standard mode at 100kHz, fast mode at 400kHz,
         * fast mode plus at 1MHz and high speed mode at 3.4MHz are supported.
         */
-       if (dev->clk_freq != 100000 && dev->clk_freq != 400000
-           && dev->clk_freq != 1000000 && dev->clk_freq != 3400000) {
+       if (t->bus_freq_hz != 100000 && t->bus_freq_hz != 400000 &&
+           t->bus_freq_hz != 1000000 && t->bus_freq_hz != 3400000) {
                dev_err(&pdev->dev,
                        "%d Hz is unsupported, only 100kHz, 400kHz, 1MHz and 3.4MHz are supported\n",
-                       dev->clk_freq);
+                       t->bus_freq_hz);
                ret = -EINVAL;
                goto exit_reset;
        }
@@ -334,12 +318,14 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
 
        dev->clk = devm_clk_get(&pdev->dev, NULL);
        if (!i2c_dw_prepare_clk(dev, true)) {
+               u64 clk_khz;
+
                dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
+               clk_khz = dev->get_clk_rate_khz(dev);
 
-               if (!dev->sda_hold_time && ht)
-                       dev->sda_hold_time = div_u64(
-                               (u64)dev->get_clk_rate_khz(dev) * ht + 500000,
-                               1000000);
+               if (!dev->sda_hold_time && t->sda_hold_ns)
+                       dev->sda_hold_time =
+                               div_u64(clk_khz * t->sda_hold_ns + 500000, 1000000);
        }
 
        dw_i2c_set_fifo_size(dev, pdev->id);
@@ -448,6 +434,9 @@ static int dw_i2c_plat_suspend(struct device *dev)
 {
        struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
 
+       if (i_dev->pm_disabled)
+               return 0;
+
        i_dev->disable(i_dev);
        i2c_dw_prepare_clk(i_dev, false);
 
@@ -458,7 +447,9 @@ static int dw_i2c_plat_resume(struct device *dev)
 {
        struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
 
-       i2c_dw_prepare_clk(i_dev, true);
+       if (!i_dev->pm_disabled)
+               i2c_dw_prepare_clk(i_dev, true);
+
        i_dev->init(i_dev);
 
        return 0;
index 8ce2cd36847717f72a6e2057d8a23922591b7050..e7f9305b2dd9f661c8863839dee346aa49438c4e 100644 (file)
@@ -1,23 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Synopsys DesignWare I2C adapter driver (slave only).
  *
  * Based on the Synopsys DesignWare I2C adapter driver (master).
  *
  * Copyright (C) 2016 Synopsys Inc.
- *
- * ----------------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * ----------------------------------------------------------------------------
- *
  */
 #include <linux/delay.h>
 #include <linux/err.h>
@@ -51,53 +38,18 @@ static void i2c_dw_configure_fifo_slave(struct dw_i2c_dev *dev)
  */
 static int i2c_dw_init_slave(struct dw_i2c_dev *dev)
 {
-       u32 reg, comp_param1;
        int ret;
 
        ret = i2c_dw_acquire_lock(dev);
        if (ret)
                return ret;
 
-       reg = dw_readl(dev, DW_IC_COMP_TYPE);
-       if (reg == ___constant_swab32(DW_IC_COMP_TYPE_VALUE)) {
-               /* Configure register endianness access. */
-               dev->flags |= ACCESS_SWAP;
-       } else if (reg == (DW_IC_COMP_TYPE_VALUE & 0x0000ffff)) {
-               /* Configure register access mode 16bit. */
-               dev->flags |= ACCESS_16BIT;
-       } else if (reg != DW_IC_COMP_TYPE_VALUE) {
-               dev_err(dev->dev,
-                       "Unknown Synopsys component type: 0x%08x\n", reg);
-               i2c_dw_release_lock(dev);
-               return -ENODEV;
-       }
-
-       comp_param1 = dw_readl(dev, DW_IC_COMP_PARAM_1);
-
        /* Disable the adapter. */
        __i2c_dw_disable(dev);
 
-       /* Configure SDA Hold Time if required. */
-       reg = dw_readl(dev, DW_IC_COMP_VERSION);
-       if (reg >= DW_IC_SDA_HOLD_MIN_VERS) {
-               if (!dev->sda_hold_time) {
-                       /* Keep previous hold time setting if no one set it. */
-                       dev->sda_hold_time = dw_readl(dev, DW_IC_SDA_HOLD);
-               }
-               /*
-                * Workaround for avoiding TX arbitration lost in case I2C
-                * slave pulls SDA down "too quickly" after falling egde of
-                * SCL by enabling non-zero SDA RX hold. Specification says it
-                * extends incoming SDA low to high transition while SCL is
-                * high but it apprears to help also above issue.
-                */
-               if (!(dev->sda_hold_time & DW_IC_SDA_HOLD_RX_MASK))
-                       dev->sda_hold_time |= 1 << DW_IC_SDA_HOLD_RX_SHIFT;
+       /* Write SDA hold time if supported */
+       if (dev->sda_hold_time)
                dw_writel(dev, dev->sda_hold_time, DW_IC_SDA_HOLD);
-       } else {
-               dev_warn(dev->dev,
-                        "Hardware too old to adjust SDA hold time.\n");
-       }
 
        i2c_dw_configure_fifo_slave(dev);
        i2c_dw_release_lock(dev);
@@ -299,6 +251,14 @@ int i2c_dw_probe_slave(struct dw_i2c_dev *dev)
        dev->disable = i2c_dw_disable;
        dev->disable_int = i2c_dw_disable_int;
 
+       ret = i2c_dw_set_reg_access(dev);
+       if (ret)
+               return ret;
+
+       ret = i2c_dw_set_sda_hold(dev);
+       if (ret)
+               return ret;
+
        ret = dev->init(dev);
        if (ret)
                return ret;
index ba9b6ea48a31362951bdc5a50b53fc2b222bf1d7..35b302d983e0d93d74b255d57f113226f9c799f9 100644 (file)
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * I2C driver for the Renesas EMEV2 SoC
  *
  * Copyright (C) 2015 Wolfram Sang <wsa@sang-engineering.com>
  * Copyright 2013 Codethink Ltd.
  * Copyright 2010-2015 Renesas Electronics Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
  */
 
 #include <linux/clk.h>
index de82ad8ff5347cdb7a8ddfc6005619633164ef40..c1ce2299a76e3f67910d9a98071779dacab2ace7 100644 (file)
 
 #define EXYNOS5_I2C_TIMEOUT (msecs_to_jiffies(100))
 
-#define HSI2C_EXYNOS7  BIT(0)
+enum i2c_type_exynos {
+       I2C_TYPE_EXYNOS5,
+       I2C_TYPE_EXYNOS7,
+};
 
 struct exynos5_i2c {
        struct i2c_adapter      adap;
@@ -212,27 +215,30 @@ struct exynos5_i2c {
 /**
  * struct exynos_hsi2c_variant - platform specific HSI2C driver data
  * @fifo_depth: the fifo depth supported by the HSI2C module
+ * @hw: the hardware variant of Exynos I2C controller
  *
  * Specifies platform specific configuration of HSI2C module.
  * Note: A structure for driver specific platform data is used for future
  * expansion of its usage.
  */
 struct exynos_hsi2c_variant {
-       unsigned int    fifo_depth;
-       unsigned int    hw;
+       unsigned int            fifo_depth;
+       enum i2c_type_exynos    hw;
 };
 
 static const struct exynos_hsi2c_variant exynos5250_hsi2c_data = {
        .fifo_depth     = 64,
+       .hw             = I2C_TYPE_EXYNOS5,
 };
 
 static const struct exynos_hsi2c_variant exynos5260_hsi2c_data = {
        .fifo_depth     = 16,
+       .hw             = I2C_TYPE_EXYNOS5,
 };
 
 static const struct exynos_hsi2c_variant exynos7_hsi2c_data = {
        .fifo_depth     = 16,
-       .hw             = HSI2C_EXYNOS7,
+       .hw             = I2C_TYPE_EXYNOS7,
 };
 
 static const struct of_device_id exynos5_i2c_match[] = {
@@ -300,7 +306,7 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, bool hs_timings)
         */
        t_ftl_cycle = (readl(i2c->regs + HSI2C_CONF) >> 16) & 0x7;
        temp = clkin / op_clk - 8 - t_ftl_cycle;
-       if (i2c->variant->hw != HSI2C_EXYNOS7)
+       if (i2c->variant->hw != I2C_TYPE_EXYNOS7)
                temp -= t_ftl_cycle;
        div = temp / 512;
        clk_cycle = temp / (div + 1) - 2;
@@ -424,7 +430,7 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)
        writel(int_status, i2c->regs + HSI2C_INT_STATUS);
 
        /* handle interrupt related to the transfer status */
-       if (i2c->variant->hw == HSI2C_EXYNOS7) {
+       if (i2c->variant->hw == I2C_TYPE_EXYNOS7) {
                if (int_status & HSI2C_INT_TRANS_DONE) {
                        i2c->trans_done = 1;
                        i2c->state = 0;
@@ -571,7 +577,7 @@ static void exynos5_i2c_bus_check(struct exynos5_i2c *i2c)
 {
        unsigned long timeout;
 
-       if (i2c->variant->hw != HSI2C_EXYNOS7)
+       if (i2c->variant->hw != I2C_TYPE_EXYNOS7)
                return;
 
        /*
@@ -612,7 +618,7 @@ static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop)
        unsigned long flags;
        unsigned short trig_lvl;
 
-       if (i2c->variant->hw == HSI2C_EXYNOS7)
+       if (i2c->variant->hw == I2C_TYPE_EXYNOS7)
                int_en |= HSI2C_INT_I2C_TRANS;
        else
                int_en |= HSI2C_INT_I2C;
diff --git a/drivers/i2c/busses/i2c-fsi.c b/drivers/i2c/busses/i2c-fsi.c
new file mode 100644 (file)
index 0000000..1e2be22
--- /dev/null
@@ -0,0 +1,752 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * FSI-attached I2C master algorithm
+ *
+ * Copyright 2018 IBM 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; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/fsi.h>
+#include <linux/i2c.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#define FSI_ENGID_I2C          0x7
+
+#define I2C_DEFAULT_CLK_DIV    6
+
+/* i2c registers */
+#define I2C_FSI_FIFO           0x00
+#define I2C_FSI_CMD            0x04
+#define I2C_FSI_MODE           0x08
+#define I2C_FSI_WATER_MARK     0x0C
+#define I2C_FSI_INT_MASK       0x10
+#define I2C_FSI_INT_COND       0x14
+#define I2C_FSI_OR_INT_MASK    0x14
+#define I2C_FSI_INTS           0x18
+#define I2C_FSI_AND_INT_MASK   0x18
+#define I2C_FSI_STAT           0x1C
+#define I2C_FSI_RESET_I2C      0x1C
+#define I2C_FSI_ESTAT          0x20
+#define I2C_FSI_RESET_ERR      0x20
+#define I2C_FSI_RESID_LEN      0x24
+#define I2C_FSI_SET_SCL                0x24
+#define I2C_FSI_PORT_BUSY      0x28
+#define I2C_FSI_RESET_SCL      0x2C
+#define I2C_FSI_SET_SDA                0x30
+#define I2C_FSI_RESET_SDA      0x34
+
+/* cmd register */
+#define I2C_CMD_WITH_START     BIT(31)
+#define I2C_CMD_WITH_ADDR      BIT(30)
+#define I2C_CMD_RD_CONT                BIT(29)
+#define I2C_CMD_WITH_STOP      BIT(28)
+#define I2C_CMD_FORCELAUNCH    BIT(27)
+#define I2C_CMD_ADDR           GENMASK(23, 17)
+#define I2C_CMD_READ           BIT(16)
+#define I2C_CMD_LEN            GENMASK(15, 0)
+
+/* mode register */
+#define I2C_MODE_CLKDIV                GENMASK(31, 16)
+#define I2C_MODE_PORT          GENMASK(15, 10)
+#define I2C_MODE_ENHANCED      BIT(3)
+#define I2C_MODE_DIAG          BIT(2)
+#define I2C_MODE_PACE_ALLOW    BIT(1)
+#define I2C_MODE_WRAP          BIT(0)
+
+/* watermark register */
+#define I2C_WATERMARK_HI       GENMASK(15, 12)
+#define I2C_WATERMARK_LO       GENMASK(7, 4)
+
+#define I2C_FIFO_HI_LVL                4
+#define I2C_FIFO_LO_LVL                4
+
+/* interrupt register */
+#define I2C_INT_INV_CMD                BIT(15)
+#define I2C_INT_PARITY         BIT(14)
+#define I2C_INT_BE_OVERRUN     BIT(13)
+#define I2C_INT_BE_ACCESS      BIT(12)
+#define I2C_INT_LOST_ARB       BIT(11)
+#define I2C_INT_NACK           BIT(10)
+#define I2C_INT_DAT_REQ                BIT(9)
+#define I2C_INT_CMD_COMP       BIT(8)
+#define I2C_INT_STOP_ERR       BIT(7)
+#define I2C_INT_BUSY           BIT(6)
+#define I2C_INT_IDLE           BIT(5)
+
+/* status register */
+#define I2C_STAT_INV_CMD       BIT(31)
+#define I2C_STAT_PARITY                BIT(30)
+#define I2C_STAT_BE_OVERRUN    BIT(29)
+#define I2C_STAT_BE_ACCESS     BIT(28)
+#define I2C_STAT_LOST_ARB      BIT(27)
+#define I2C_STAT_NACK          BIT(26)
+#define I2C_STAT_DAT_REQ       BIT(25)
+#define I2C_STAT_CMD_COMP      BIT(24)
+#define I2C_STAT_STOP_ERR      BIT(23)
+#define I2C_STAT_MAX_PORT      GENMASK(19, 16)
+#define I2C_STAT_ANY_INT       BIT(15)
+#define I2C_STAT_SCL_IN                BIT(11)
+#define I2C_STAT_SDA_IN                BIT(10)
+#define I2C_STAT_PORT_BUSY     BIT(9)
+#define I2C_STAT_SELF_BUSY     BIT(8)
+#define I2C_STAT_FIFO_COUNT    GENMASK(7, 0)
+
+#define I2C_STAT_ERR           (I2C_STAT_INV_CMD |                     \
+                                I2C_STAT_PARITY |                      \
+                                I2C_STAT_BE_OVERRUN |                  \
+                                I2C_STAT_BE_ACCESS |                   \
+                                I2C_STAT_LOST_ARB |                    \
+                                I2C_STAT_NACK |                        \
+                                I2C_STAT_STOP_ERR)
+#define I2C_STAT_ANY_RESP      (I2C_STAT_ERR |                         \
+                                I2C_STAT_DAT_REQ |                     \
+                                I2C_STAT_CMD_COMP)
+
+/* extended status register */
+#define I2C_ESTAT_FIFO_SZ      GENMASK(31, 24)
+#define I2C_ESTAT_SCL_IN_SY    BIT(15)
+#define I2C_ESTAT_SDA_IN_SY    BIT(14)
+#define I2C_ESTAT_S_SCL                BIT(13)
+#define I2C_ESTAT_S_SDA                BIT(12)
+#define I2C_ESTAT_M_SCL                BIT(11)
+#define I2C_ESTAT_M_SDA                BIT(10)
+#define I2C_ESTAT_HI_WATER     BIT(9)
+#define I2C_ESTAT_LO_WATER     BIT(8)
+#define I2C_ESTAT_PORT_BUSY    BIT(7)
+#define I2C_ESTAT_SELF_BUSY    BIT(6)
+#define I2C_ESTAT_VERSION      GENMASK(4, 0)
+
+/* port busy register */
+#define I2C_PORT_BUSY_RESET    BIT(31)
+
+/* wait for command complete or data request */
+#define I2C_CMD_SLEEP_MAX_US   500
+#define I2C_CMD_SLEEP_MIN_US   50
+
+/* wait after reset; choose time from legacy driver */
+#define I2C_RESET_SLEEP_MAX_US 2000
+#define I2C_RESET_SLEEP_MIN_US 1000
+
+/* choose timeout length from legacy driver; it's well tested */
+#define I2C_ABORT_TIMEOUT      msecs_to_jiffies(100)
+
+struct fsi_i2c_master {
+       struct fsi_device       *fsi;
+       u8                      fifo_size;
+       struct list_head        ports;
+       struct mutex            lock;
+};
+
+struct fsi_i2c_port {
+       struct list_head        list;
+       struct i2c_adapter      adapter;
+       struct fsi_i2c_master   *master;
+       u16                     port;
+       u16                     xfrd;
+};
+
+static int fsi_i2c_read_reg(struct fsi_device *fsi, unsigned int reg,
+                           u32 *data)
+{
+       int rc;
+       __be32 data_be;
+
+       rc = fsi_device_read(fsi, reg, &data_be, sizeof(data_be));
+       if (rc)
+               return rc;
+
+       *data = be32_to_cpu(data_be);
+
+       return 0;
+}
+
+static int fsi_i2c_write_reg(struct fsi_device *fsi, unsigned int reg,
+                            u32 *data)
+{
+       __be32 data_be = cpu_to_be32p(data);
+
+       return fsi_device_write(fsi, reg, &data_be, sizeof(data_be));
+}
+
+static int fsi_i2c_dev_init(struct fsi_i2c_master *i2c)
+{
+       int rc;
+       u32 mode = I2C_MODE_ENHANCED, extended_status, watermark;
+       u32 interrupt = 0;
+
+       /* since we use polling, disable interrupts */
+       rc = fsi_i2c_write_reg(i2c->fsi, I2C_FSI_INT_MASK, &interrupt);
+       if (rc)
+               return rc;
+
+       mode |= FIELD_PREP(I2C_MODE_CLKDIV, I2C_DEFAULT_CLK_DIV);
+       rc = fsi_i2c_write_reg(i2c->fsi, I2C_FSI_MODE, &mode);
+       if (rc)
+               return rc;
+
+       rc = fsi_i2c_read_reg(i2c->fsi, I2C_FSI_ESTAT, &extended_status);
+       if (rc)
+               return rc;
+
+       i2c->fifo_size = FIELD_GET(I2C_ESTAT_FIFO_SZ, extended_status);
+       watermark = FIELD_PREP(I2C_WATERMARK_HI,
+                              i2c->fifo_size - I2C_FIFO_HI_LVL);
+       watermark |= FIELD_PREP(I2C_WATERMARK_LO, I2C_FIFO_LO_LVL);
+
+       return fsi_i2c_write_reg(i2c->fsi, I2C_FSI_WATER_MARK, &watermark);
+}
+
+static int fsi_i2c_set_port(struct fsi_i2c_port *port)
+{
+       int rc;
+       struct fsi_device *fsi = port->master->fsi;
+       u32 mode, dummy = 0;
+
+       rc = fsi_i2c_read_reg(fsi, I2C_FSI_MODE, &mode);
+       if (rc)
+               return rc;
+
+       if (FIELD_GET(I2C_MODE_PORT, mode) == port->port)
+               return 0;
+
+       mode = (mode & ~I2C_MODE_PORT) | FIELD_PREP(I2C_MODE_PORT, port->port);
+       rc = fsi_i2c_write_reg(fsi, I2C_FSI_MODE, &mode);
+       if (rc)
+               return rc;
+
+       /* reset engine when port is changed */
+       return fsi_i2c_write_reg(fsi, I2C_FSI_RESET_ERR, &dummy);
+}
+
+static int fsi_i2c_start(struct fsi_i2c_port *port, struct i2c_msg *msg,
+                        bool stop)
+{
+       struct fsi_i2c_master *i2c = port->master;
+       u32 cmd = I2C_CMD_WITH_START | I2C_CMD_WITH_ADDR;
+
+       port->xfrd = 0;
+
+       if (msg->flags & I2C_M_RD)
+               cmd |= I2C_CMD_READ;
+
+       if (stop || msg->flags & I2C_M_STOP)
+               cmd |= I2C_CMD_WITH_STOP;
+
+       cmd |= FIELD_PREP(I2C_CMD_ADDR, msg->addr);
+       cmd |= FIELD_PREP(I2C_CMD_LEN, msg->len);
+
+       return fsi_i2c_write_reg(i2c->fsi, I2C_FSI_CMD, &cmd);
+}
+
+static int fsi_i2c_get_op_bytes(int op_bytes)
+{
+       /* fsi is limited to max 4 byte aligned ops */
+       if (op_bytes > 4)
+               return 4;
+       else if (op_bytes == 3)
+               return 2;
+       return op_bytes;
+}
+
+static int fsi_i2c_write_fifo(struct fsi_i2c_port *port, struct i2c_msg *msg,
+                             u8 fifo_count)
+{
+       int write;
+       int rc;
+       struct fsi_i2c_master *i2c = port->master;
+       int bytes_to_write = i2c->fifo_size - fifo_count;
+       int bytes_remaining = msg->len - port->xfrd;
+
+       bytes_to_write = min(bytes_to_write, bytes_remaining);
+
+       while (bytes_to_write) {
+               write = fsi_i2c_get_op_bytes(bytes_to_write);
+
+               rc = fsi_device_write(i2c->fsi, I2C_FSI_FIFO,
+                                     &msg->buf[port->xfrd], write);
+               if (rc)
+                       return rc;
+
+               port->xfrd += write;
+               bytes_to_write -= write;
+       }
+
+       return 0;
+}
+
+static int fsi_i2c_read_fifo(struct fsi_i2c_port *port, struct i2c_msg *msg,
+                            u8 fifo_count)
+{
+       int read;
+       int rc;
+       struct fsi_i2c_master *i2c = port->master;
+       int bytes_to_read;
+       int xfr_remaining = msg->len - port->xfrd;
+       u32 dummy;
+
+       bytes_to_read = min_t(int, fifo_count, xfr_remaining);
+
+       while (bytes_to_read) {
+               read = fsi_i2c_get_op_bytes(bytes_to_read);
+
+               if (xfr_remaining) {
+                       rc = fsi_device_read(i2c->fsi, I2C_FSI_FIFO,
+                                            &msg->buf[port->xfrd], read);
+                       if (rc)
+                               return rc;
+
+                       port->xfrd += read;
+                       xfr_remaining -= read;
+               } else {
+                       /* no more buffer but data in fifo, need to clear it */
+                       rc = fsi_device_read(i2c->fsi, I2C_FSI_FIFO, &dummy,
+                                            read);
+                       if (rc)
+                               return rc;
+               }
+
+               bytes_to_read -= read;
+       }
+
+       return 0;
+}
+
+static int fsi_i2c_get_scl(struct i2c_adapter *adap)
+{
+       u32 stat = 0;
+       struct fsi_i2c_port *port = adap->algo_data;
+       struct fsi_i2c_master *i2c = port->master;
+
+       fsi_i2c_read_reg(i2c->fsi, I2C_FSI_STAT, &stat);
+
+       return !!(stat & I2C_STAT_SCL_IN);
+}
+
+static void fsi_i2c_set_scl(struct i2c_adapter *adap, int val)
+{
+       u32 dummy = 0;
+       struct fsi_i2c_port *port = adap->algo_data;
+       struct fsi_i2c_master *i2c = port->master;
+
+       if (val)
+               fsi_i2c_write_reg(i2c->fsi, I2C_FSI_SET_SCL, &dummy);
+       else
+               fsi_i2c_write_reg(i2c->fsi, I2C_FSI_RESET_SCL, &dummy);
+}
+
+static int fsi_i2c_get_sda(struct i2c_adapter *adap)
+{
+       u32 stat = 0;
+       struct fsi_i2c_port *port = adap->algo_data;
+       struct fsi_i2c_master *i2c = port->master;
+
+       fsi_i2c_read_reg(i2c->fsi, I2C_FSI_STAT, &stat);
+
+       return !!(stat & I2C_STAT_SDA_IN);
+}
+
+static void fsi_i2c_set_sda(struct i2c_adapter *adap, int val)
+{
+       u32 dummy = 0;
+       struct fsi_i2c_port *port = adap->algo_data;
+       struct fsi_i2c_master *i2c = port->master;
+
+       if (val)
+               fsi_i2c_write_reg(i2c->fsi, I2C_FSI_SET_SDA, &dummy);
+       else
+               fsi_i2c_write_reg(i2c->fsi, I2C_FSI_RESET_SDA, &dummy);
+}
+
+static void fsi_i2c_prepare_recovery(struct i2c_adapter *adap)
+{
+       int rc;
+       u32 mode;
+       struct fsi_i2c_port *port = adap->algo_data;
+       struct fsi_i2c_master *i2c = port->master;
+
+       rc = fsi_i2c_read_reg(i2c->fsi, I2C_FSI_MODE, &mode);
+       if (rc)
+               return;
+
+       mode |= I2C_MODE_DIAG;
+       fsi_i2c_write_reg(i2c->fsi, I2C_FSI_MODE, &mode);
+}
+
+static void fsi_i2c_unprepare_recovery(struct i2c_adapter *adap)
+{
+       int rc;
+       u32 mode;
+       struct fsi_i2c_port *port = adap->algo_data;
+       struct fsi_i2c_master *i2c = port->master;
+
+       rc = fsi_i2c_read_reg(i2c->fsi, I2C_FSI_MODE, &mode);
+       if (rc)
+               return;
+
+       mode &= ~I2C_MODE_DIAG;
+       fsi_i2c_write_reg(i2c->fsi, I2C_FSI_MODE, &mode);
+}
+
+static int fsi_i2c_reset_bus(struct fsi_i2c_master *i2c,
+                            struct fsi_i2c_port *port)
+{
+       int rc;
+       u32 stat, dummy = 0;
+
+       /* force bus reset, ignore errors */
+       i2c_recover_bus(&port->adapter);
+
+       /* reset errors */
+       rc = fsi_i2c_write_reg(i2c->fsi, I2C_FSI_RESET_ERR, &dummy);
+       if (rc)
+               return rc;
+
+       /* wait for command complete */
+       usleep_range(I2C_RESET_SLEEP_MIN_US, I2C_RESET_SLEEP_MAX_US);
+
+       rc = fsi_i2c_read_reg(i2c->fsi, I2C_FSI_STAT, &stat);
+       if (rc)
+               return rc;
+
+       if (stat & I2C_STAT_CMD_COMP)
+               return 0;
+
+       /* failed to get command complete; reset engine again */
+       rc = fsi_i2c_write_reg(i2c->fsi, I2C_FSI_RESET_I2C, &dummy);
+       if (rc)
+               return rc;
+
+       /* re-init engine again */
+       return fsi_i2c_dev_init(i2c);
+}
+
+static int fsi_i2c_reset_engine(struct fsi_i2c_master *i2c, u16 port)
+{
+       int rc;
+       u32 mode, dummy = 0;
+
+       /* reset engine */
+       rc = fsi_i2c_write_reg(i2c->fsi, I2C_FSI_RESET_I2C, &dummy);
+       if (rc)
+               return rc;
+
+       /* re-init engine */
+       rc = fsi_i2c_dev_init(i2c);
+       if (rc)
+               return rc;
+
+       rc = fsi_i2c_read_reg(i2c->fsi, I2C_FSI_MODE, &mode);
+       if (rc)
+               return rc;
+
+       /* set port; default after reset is 0 */
+       if (port) {
+               mode &= ~I2C_MODE_PORT;
+               mode |= FIELD_PREP(I2C_MODE_PORT, port);
+               rc = fsi_i2c_write_reg(i2c->fsi, I2C_FSI_MODE, &mode);
+               if (rc)
+                       return rc;
+       }
+
+       /* reset busy register; hw workaround */
+       dummy = I2C_PORT_BUSY_RESET;
+       rc = fsi_i2c_write_reg(i2c->fsi, I2C_FSI_PORT_BUSY, &dummy);
+       if (rc)
+               return rc;
+
+       return 0;
+}
+
+static int fsi_i2c_abort(struct fsi_i2c_port *port, u32 status)
+{
+       int rc;
+       unsigned long start;
+       u32 cmd = I2C_CMD_WITH_STOP;
+       u32 stat;
+       struct fsi_i2c_master *i2c = port->master;
+       struct fsi_device *fsi = i2c->fsi;
+
+       rc = fsi_i2c_reset_engine(i2c, port->port);
+       if (rc)
+               return rc;
+
+       rc = fsi_i2c_read_reg(fsi, I2C_FSI_STAT, &stat);
+       if (rc)
+               return rc;
+
+       /* if sda is low, peform full bus reset */
+       if (!(stat & I2C_STAT_SDA_IN)) {
+               rc = fsi_i2c_reset_bus(i2c, port);
+               if (rc)
+                       return rc;
+       }
+
+       /* skip final stop command for these errors */
+       if (status & (I2C_STAT_PARITY | I2C_STAT_LOST_ARB | I2C_STAT_STOP_ERR))
+               return 0;
+
+       /* write stop command */
+       rc = fsi_i2c_write_reg(fsi, I2C_FSI_CMD, &cmd);
+       if (rc)
+               return rc;
+
+       /* wait until we see command complete in the master */
+       start = jiffies;
+
+       do {
+               rc = fsi_i2c_read_reg(fsi, I2C_FSI_STAT, &status);
+               if (rc)
+                       return rc;
+
+               if (status & I2C_STAT_CMD_COMP)
+                       return 0;
+
+               usleep_range(I2C_CMD_SLEEP_MIN_US, I2C_CMD_SLEEP_MAX_US);
+       } while (time_after(start + I2C_ABORT_TIMEOUT, jiffies));
+
+       return -ETIMEDOUT;
+}
+
+static int fsi_i2c_handle_status(struct fsi_i2c_port *port,
+                                struct i2c_msg *msg, u32 status)
+{
+       int rc;
+       u8 fifo_count;
+
+       if (status & I2C_STAT_ERR) {
+               rc = fsi_i2c_abort(port, status);
+               if (rc)
+                       return rc;
+
+               if (status & I2C_STAT_INV_CMD)
+                       return -EINVAL;
+
+               if (status & (I2C_STAT_PARITY | I2C_STAT_BE_OVERRUN |
+                   I2C_STAT_BE_ACCESS))
+                       return -EPROTO;
+
+               if (status & I2C_STAT_NACK)
+                       return -ENXIO;
+
+               if (status & I2C_STAT_LOST_ARB)
+                       return -EAGAIN;
+
+               if (status & I2C_STAT_STOP_ERR)
+                       return -EBADMSG;
+
+               return -EIO;
+       }
+
+       if (status & I2C_STAT_DAT_REQ) {
+               fifo_count = FIELD_GET(I2C_STAT_FIFO_COUNT, status);
+
+               if (msg->flags & I2C_M_RD)
+                       return fsi_i2c_read_fifo(port, msg, fifo_count);
+
+               return fsi_i2c_write_fifo(port, msg, fifo_count);
+       }
+
+       if (status & I2C_STAT_CMD_COMP) {
+               if (port->xfrd < msg->len)
+                       return -ENODATA;
+
+               return msg->len;
+       }
+
+       return 0;
+}
+
+static int fsi_i2c_wait(struct fsi_i2c_port *port, struct i2c_msg *msg,
+                       unsigned long timeout)
+{
+       u32 status = 0;
+       int rc;
+       unsigned long start = jiffies;
+
+       do {
+               rc = fsi_i2c_read_reg(port->master->fsi, I2C_FSI_STAT,
+                                     &status);
+               if (rc)
+                       return rc;
+
+               if (status & I2C_STAT_ANY_RESP) {
+                       rc = fsi_i2c_handle_status(port, msg, status);
+                       if (rc < 0)
+                               return rc;
+
+                       /* cmd complete and all data xfrd */
+                       if (rc == msg->len)
+                               return 0;
+
+                       /* need to xfr more data, but maybe don't need wait */
+                       continue;
+               }
+
+               usleep_range(I2C_CMD_SLEEP_MIN_US, I2C_CMD_SLEEP_MAX_US);
+       } while (time_after(start + timeout, jiffies));
+
+       return -ETIMEDOUT;
+}
+
+static int fsi_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+                       int num)
+{
+       int i, rc;
+       unsigned long start_time;
+       struct fsi_i2c_port *port = adap->algo_data;
+       struct fsi_i2c_master *master = port->master;
+       struct i2c_msg *msg;
+
+       mutex_lock(&master->lock);
+
+       rc = fsi_i2c_set_port(port);
+       if (rc)
+               goto unlock;
+
+       for (i = 0; i < num; i++) {
+               msg = msgs + i;
+               start_time = jiffies;
+
+               rc = fsi_i2c_start(port, msg, i == num - 1);
+               if (rc)
+                       goto unlock;
+
+               rc = fsi_i2c_wait(port, msg,
+                                 adap->timeout - (jiffies - start_time));
+               if (rc)
+                       goto unlock;
+       }
+
+unlock:
+       mutex_unlock(&master->lock);
+       return rc ? : num;
+}
+
+static u32 fsi_i2c_functionality(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_I2C | I2C_FUNC_PROTOCOL_MANGLING |
+               I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_BLOCK_DATA;
+}
+
+static struct i2c_bus_recovery_info fsi_i2c_bus_recovery_info = {
+       .recover_bus = i2c_generic_scl_recovery,
+       .get_scl = fsi_i2c_get_scl,
+       .set_scl = fsi_i2c_set_scl,
+       .get_sda = fsi_i2c_get_sda,
+       .set_sda = fsi_i2c_set_sda,
+       .prepare_recovery = fsi_i2c_prepare_recovery,
+       .unprepare_recovery = fsi_i2c_unprepare_recovery,
+};
+
+static const struct i2c_algorithm fsi_i2c_algorithm = {
+       .master_xfer = fsi_i2c_xfer,
+       .functionality = fsi_i2c_functionality,
+};
+
+static int fsi_i2c_probe(struct device *dev)
+{
+       struct fsi_i2c_master *i2c;
+       struct fsi_i2c_port *port;
+       struct device_node *np;
+       int rc;
+       u32 port_no;
+
+       i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
+       if (!i2c)
+               return -ENOMEM;
+
+       mutex_init(&i2c->lock);
+       i2c->fsi = to_fsi_dev(dev);
+       INIT_LIST_HEAD(&i2c->ports);
+
+       rc = fsi_i2c_dev_init(i2c);
+       if (rc)
+               return rc;
+
+       /* Add adapter for each i2c port of the master. */
+       for_each_available_child_of_node(dev->of_node, np) {
+               rc = of_property_read_u32(np, "reg", &port_no);
+               if (rc || port_no > USHRT_MAX)
+                       continue;
+
+               port = kzalloc(sizeof(*port), GFP_KERNEL);
+               if (!port)
+                       break;
+
+               port->master = i2c;
+               port->port = port_no;
+
+               port->adapter.owner = THIS_MODULE;
+               port->adapter.dev.of_node = np;
+               port->adapter.dev.parent = dev;
+               port->adapter.algo = &fsi_i2c_algorithm;
+               port->adapter.bus_recovery_info = &fsi_i2c_bus_recovery_info;
+               port->adapter.algo_data = port;
+
+               snprintf(port->adapter.name, sizeof(port->adapter.name),
+                        "i2c_bus-%u", port_no);
+
+               rc = i2c_add_adapter(&port->adapter);
+               if (rc < 0) {
+                       dev_err(dev, "Failed to register adapter: %d\n", rc);
+                       kfree(port);
+                       continue;
+               }
+
+               list_add(&port->list, &i2c->ports);
+       }
+
+       dev_set_drvdata(dev, i2c);
+
+       return 0;
+}
+
+static int fsi_i2c_remove(struct device *dev)
+{
+       struct fsi_i2c_master *i2c = dev_get_drvdata(dev);
+       struct fsi_i2c_port *port, *tmp;
+
+       list_for_each_entry_safe(port, tmp, &i2c->ports, list) {
+               list_del(&port->list);
+               i2c_del_adapter(&port->adapter);
+               kfree(port);
+       }
+
+       return 0;
+}
+
+static const struct fsi_device_id fsi_i2c_ids[] = {
+       { FSI_ENGID_I2C, FSI_VERSION_ANY },
+       { }
+};
+
+static struct fsi_driver fsi_i2c_driver = {
+       .id_table = fsi_i2c_ids,
+       .drv = {
+               .name = "i2c-fsi",
+               .bus = &fsi_bus_type,
+               .probe = fsi_i2c_probe,
+               .remove = fsi_i2c_remove,
+       },
+};
+
+module_fsi_driver(fsi_i2c_driver);
+
+MODULE_AUTHOR("Eddie James <eajames@us.ibm.com>");
+MODULE_DESCRIPTION("FSI attached I2C master");
+MODULE_LICENSE("GPL");
index 66f85bbf35917161cc36e4ffb308d78b8401c0cb..c008d209f0b83c7623c724b865be3f4c9d264583 100644 (file)
@@ -78,49 +78,43 @@ static struct dentry *i2c_gpio_debug_dir;
 #define getscl(bd)     ((bd)->getscl((bd)->data))
 
 #define WIRE_ATTRIBUTE(wire) \
-static int fops_##wire##_get(void *data, u64 *val)     \
-{                                                      \
-       struct i2c_gpio_private_data *priv = data;      \
-                                                       \
-       i2c_lock_adapter(&priv->adap);                  \
-       *val = get##wire(&priv->bit_data);              \
-       i2c_unlock_adapter(&priv->adap);                \
-       return 0;                                       \
-}                                                      \
-static int fops_##wire##_set(void *data, u64 val)      \
-{                                                      \
-       struct i2c_gpio_private_data *priv = data;      \
-                                                       \
-       i2c_lock_adapter(&priv->adap);                  \
-       set##wire(&priv->bit_data, val);                \
-       i2c_unlock_adapter(&priv->adap);                \
-       return 0;                                       \
-}                                                      \
+static int fops_##wire##_get(void *data, u64 *val)             \
+{                                                              \
+       struct i2c_gpio_private_data *priv = data;              \
+                                                               \
+       i2c_lock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER);       \
+       *val = get##wire(&priv->bit_data);                      \
+       i2c_unlock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER);     \
+       return 0;                                               \
+}                                                              \
+static int fops_##wire##_set(void *data, u64 val)              \
+{                                                              \
+       struct i2c_gpio_private_data *priv = data;              \
+                                                               \
+       i2c_lock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER);       \
+       set##wire(&priv->bit_data, val);                        \
+       i2c_unlock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER);     \
+       return 0;                                               \
+}                                                              \
 DEFINE_DEBUGFS_ATTRIBUTE(fops_##wire, fops_##wire##_get, fops_##wire##_set, "%llu\n")
 
 WIRE_ATTRIBUTE(scl);
 WIRE_ATTRIBUTE(sda);
 
-static int fops_incomplete_transfer_set(void *data, u64 addr)
+static void i2c_gpio_incomplete_transfer(struct i2c_gpio_private_data *priv,
+                                       u32 pattern, u8 pattern_size)
 {
-       struct i2c_gpio_private_data *priv = data;
        struct i2c_algo_bit_data *bit_data = &priv->bit_data;
-       int i, pattern;
+       int i;
 
-       if (addr > 0x7f)
-               return -EINVAL;
-
-       /* ADDR (7 bit) + RD (1 bit) + SDA hi (1 bit) */
-       pattern = (addr << 2) | 3;
-
-       i2c_lock_adapter(&priv->adap);
+       i2c_lock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER);
 
        /* START condition */
        setsda(bit_data, 0);
        udelay(bit_data->udelay);
 
-       /* Send ADDR+RD, request ACK, don't send STOP */
-       for (i = 8; i >= 0; i--) {
+       /* Send pattern, request ACK, don't send STOP */
+       for (i = pattern_size - 1; i >= 0; i--) {
                setscl(bit_data, 0);
                udelay(bit_data->udelay / 2);
                setsda(bit_data, (pattern >> i) & 1);
@@ -129,11 +123,44 @@ static int fops_incomplete_transfer_set(void *data, u64 addr)
                udelay(bit_data->udelay);
        }
 
-       i2c_unlock_adapter(&priv->adap);
+       i2c_unlock_bus(&priv->adap, I2C_LOCK_ROOT_ADAPTER);
+}
+
+static int fops_incomplete_addr_phase_set(void *data, u64 addr)
+{
+       struct i2c_gpio_private_data *priv = data;
+       u32 pattern;
+
+       if (addr > 0x7f)
+               return -EINVAL;
+
+       /* ADDR (7 bit) + RD (1 bit) + Client ACK, keep SDA hi (1 bit) */
+       pattern = (addr << 2) | 3;
+
+       i2c_gpio_incomplete_transfer(priv, pattern, 9);
+
+       return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(fops_incomplete_addr_phase, NULL, fops_incomplete_addr_phase_set, "%llu\n");
+
+static int fops_incomplete_write_byte_set(void *data, u64 addr)
+{
+       struct i2c_gpio_private_data *priv = data;
+       u32 pattern;
+
+       if (addr > 0x7f)
+               return -EINVAL;
+
+       /* ADDR (7 bit) + WR (1 bit) + Client ACK (1 bit) */
+       pattern = (addr << 2) | 1;
+       /* 0x00 (8 bit) + Client ACK, keep SDA hi (1 bit) */
+       pattern = (pattern << 9) | 1;
+
+       i2c_gpio_incomplete_transfer(priv, pattern, 18);
 
        return 0;
 }
-DEFINE_DEBUGFS_ATTRIBUTE(fops_incomplete_transfer, NULL, fops_incomplete_transfer_set, "%llu\n");
+DEFINE_DEBUGFS_ATTRIBUTE(fops_incomplete_write_byte, NULL, fops_incomplete_write_byte_set, "%llu\n");
 
 static void i2c_gpio_fault_injector_init(struct platform_device *pdev)
 {
@@ -156,8 +183,10 @@ static void i2c_gpio_fault_injector_init(struct platform_device *pdev)
 
        debugfs_create_file_unsafe("scl", 0600, priv->debug_dir, priv, &fops_scl);
        debugfs_create_file_unsafe("sda", 0600, priv->debug_dir, priv, &fops_sda);
-       debugfs_create_file_unsafe("incomplete_transfer", 0200, priv->debug_dir,
-                                  priv, &fops_incomplete_transfer);
+       debugfs_create_file_unsafe("incomplete_address_phase", 0200, priv->debug_dir,
+                                  priv, &fops_incomplete_addr_phase);
+       debugfs_create_file_unsafe("incomplete_write_byte", 0200, priv->debug_dir,
+                                  priv, &fops_incomplete_write_byte);
 }
 
 static void i2c_gpio_fault_injector_exit(struct platform_device *pdev)
index 56dc69e7349fcb553835b8258741351fcdcff51e..ff340d7ae2e52c1442e25bceaadffa8d67dcee33 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas Solutions Highlander FPGA I2C/SMBus support.
  *
@@ -6,10 +7,6 @@
  * Copyright (C) 2008  Paul Mundt
  * Copyright (C) 2008  Renesas Solutions Corp.
  * Copyright (C) 2008  Atom Create Engineering Co., Ltd.
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License version 2. See the file "COPYING" in the main directory
- * of this archive for more details.
  */
 #include <linux/module.h>
 #include <linux/interrupt.h>
index aa726607645ee6c5cb2565d645a45da71982c306..c91e145ef5a56dbb1a512c23611f06ad7d22aa05 100644 (file)
@@ -70,6 +70,7 @@
  * Cannon Lake-H (PCH)         0xa323  32      hard    yes     yes     yes
  * Cannon Lake-LP (PCH)                0x9da3  32      hard    yes     yes     yes
  * Cedar Fork (PCH)            0x18df  32      hard    yes     yes     yes
+ * Ice Lake-LP (PCH)           0x34a3  32      hard    yes     yes     yes
  *
  * Features supported by this driver:
  * Software PEC                                no
 
 #define SBREG_BAR              0x10
 #define SBREG_SMBCTRL          0xc6000c
+#define SBREG_SMBCTRL_DNV      0xcf000c
 
 /* Host status bits for SMBPCISTS */
 #define SMBPCISTS_INTS         BIT(3)
 #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS             0x2330
 #define PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS          0x23b0
 #define PCI_DEVICE_ID_INTEL_GEMINILAKE_SMBUS           0x31d4
+#define PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS           0x34a3
 #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS                0x3b30
 #define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS              0x5ad4
 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS            0x8c22
@@ -1034,6 +1037,7 @@ static const struct pci_device_id i801_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS) },
        { 0, }
 };
 
@@ -1396,7 +1400,11 @@ static void i801_add_tco(struct i801_priv *priv)
        spin_unlock(&p2sb_spinlock);
 
        res = &tco_res[ICH_RES_MEM_OFF];
-       res->start = (resource_size_t)base64_addr + SBREG_SMBCTRL;
+       if (pci_dev->device == PCI_DEVICE_ID_INTEL_DNV_SMBUS)
+               res->start = (resource_size_t)base64_addr + SBREG_SMBCTRL_DNV;
+       else
+               res->start = (resource_size_t)base64_addr + SBREG_SMBCTRL;
+
        res->end = res->start + 3;
        res->flags = IORESOURCE_MEM;
 
@@ -1412,6 +1420,13 @@ static void i801_add_tco(struct i801_priv *priv)
 }
 
 #ifdef CONFIG_ACPI
+static bool i801_acpi_is_smbus_ioport(const struct i801_priv *priv,
+                                     acpi_physical_address address)
+{
+       return address >= priv->smba &&
+              address <= pci_resource_end(priv->pci_dev, SMBBAR);
+}
+
 static acpi_status
 i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
                     u64 *value, void *handler_context, void *region_context)
@@ -1427,7 +1442,7 @@ i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
         */
        mutex_lock(&priv->acpi_lock);
 
-       if (!priv->acpi_reserved) {
+       if (!priv->acpi_reserved && i801_acpi_is_smbus_ioport(priv, address)) {
                priv->acpi_reserved = true;
 
                dev_warn(&pdev->dev, "BIOS is accessing SMBus registers\n");
@@ -1518,6 +1533,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
        case PCI_DEVICE_ID_INTEL_CDF_SMBUS:
        case PCI_DEVICE_ID_INTEL_DNV_SMBUS:
        case PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS:
+       case PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS:
                priv->features |= FEATURE_I2C_BLOCK_READ;
                priv->features |= FEATURE_IRQ;
                priv->features |= FEATURE_SMBUS_PEC;
index 6d975f5221ca0e37410c9d2e770f7d78bfe270b2..06c4c767af322aa2704d5ae51a59e5c103579fc5 100644 (file)
@@ -538,7 +538,6 @@ static const struct i2c_algorithm lpi2c_imx_algo = {
 
 static const struct of_device_id lpi2c_imx_of_match[] = {
        { .compatible = "fsl,imx7ulp-lpi2c" },
-       { .compatible = "fsl,imx8dv-lpi2c" },
        { },
 };
 MODULE_DEVICE_TABLE(of, lpi2c_imx_of_match);
index 498c5e89164988beb8d82e5f4bc53aac82b137ac..c406700789e1f9c5a3af5c3fa62f045180702bb1 100644 (file)
@@ -421,10 +421,14 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
                        return -EAGAIN;
                }
 
-               if (for_busy && (temp & I2SR_IBB))
+               if (for_busy && (temp & I2SR_IBB)) {
+                       i2c_imx->stopped = 0;
                        break;
-               if (!for_busy && !(temp & I2SR_IBB))
+               }
+               if (!for_busy && !(temp & I2SR_IBB)) {
+                       i2c_imx->stopped = 1;
                        break;
+               }
                if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
                        dev_dbg(&i2c_imx->adapter.dev,
                                "<%s> I2C bus is busy\n", __func__);
@@ -538,7 +542,6 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
        result = i2c_imx_bus_busy(i2c_imx, 1);
        if (result)
                return result;
-       i2c_imx->stopped = 0;
 
        temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK;
        temp &= ~I2CR_DMAEN;
@@ -567,10 +570,8 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
                udelay(i2c_imx->disable_delay);
        }
 
-       if (!i2c_imx->stopped) {
+       if (!i2c_imx->stopped)
                i2c_imx_bus_busy(i2c_imx, 0);
-               i2c_imx->stopped = 1;
-       }
 
        /* Disable I2C controller */
        temp = i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN,
@@ -668,9 +669,6 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx,
        struct imx_i2c_dma *dma = i2c_imx->dma;
        struct device *dev = &i2c_imx->adapter.dev;
 
-       temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
-       temp |= I2CR_DMAEN;
-       imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
 
        dma->chan_using = dma->chan_rx;
        dma->dma_transfer_dir = DMA_DEV_TO_MEM;
@@ -727,7 +725,6 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx,
                temp &= ~(I2CR_MSTA | I2CR_MTX);
                imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
                i2c_imx_bus_busy(i2c_imx, 0);
-               i2c_imx->stopped = 1;
        } else {
                /*
                 * For i2c master receiver repeat restart operation like:
@@ -783,6 +780,7 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo
        int i, result;
        unsigned int temp;
        int block_data = msgs->flags & I2C_M_RECV_LEN;
+       int use_dma = i2c_imx->dma && msgs->len >= DMA_THRESHOLD && !block_data;
 
        dev_dbg(&i2c_imx->adapter.dev,
                "<%s> write slave address: addr=0x%x\n",
@@ -809,12 +807,14 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo
         */
        if ((msgs->len - 1) || block_data)
                temp &= ~I2CR_TXAK;
+       if (use_dma)
+               temp |= I2CR_DMAEN;
        imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
        imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR); /* dummy read */
 
        dev_dbg(&i2c_imx->adapter.dev, "<%s> read data\n", __func__);
 
-       if (i2c_imx->dma && msgs->len >= DMA_THRESHOLD && !block_data)
+       if (use_dma)
                return i2c_imx_dma_read(i2c_imx, msgs, is_lastmsg);
 
        /* read data */
@@ -850,7 +850,6 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo
                                temp &= ~(I2CR_MSTA | I2CR_MTX);
                                imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
                                i2c_imx_bus_busy(i2c_imx, 0);
-                               i2c_imx->stopped = 1;
                        } else {
                                /*
                                 * For i2c master receiver repeat restart operation like:
index 642c58946d8d261a48cd146ffe7bff65a90ef660..7d79317a1046de323ddebdb0644baebee160e251 100644 (file)
@@ -567,9 +567,6 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
        dev_dbg(i2c->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n",
                msg->addr, msg->len, msg->flags, stop);
 
-       if (msg->len == 0)
-               return -EINVAL;
-
        /*
         * The MX28 I2C IP block can only do PIO READ for transfer of to up
         * 4 bytes of length. The write transfer is not limited as it can use
@@ -683,6 +680,10 @@ static const struct i2c_algorithm mxs_i2c_algo = {
        .functionality = mxs_i2c_func,
 };
 
+static const struct i2c_adapter_quirks mxs_i2c_quirks = {
+       .flags = I2C_AQ_NO_ZERO_LEN,
+};
+
 static void mxs_i2c_derive_timing(struct mxs_i2c_dev *i2c, uint32_t speed)
 {
        /* The I2C block clock runs at 24MHz */
@@ -854,6 +855,7 @@ static int mxs_i2c_probe(struct platform_device *pdev)
        strlcpy(adap->name, "MXS I2C adapter", sizeof(adap->name));
        adap->owner = THIS_MODULE;
        adap->algo = &mxs_i2c_algo;
+       adap->quirks = &mxs_i2c_quirks;
        adap->dev.parent = dev;
        adap->nr = pdev->id;
        adap->dev.of_node = pdev->dev.of_node;
index 88444ef74943dcd64b7bdddff9c47a93e6a4093f..87f9caacba85672736325cc253cacc5b447f8c55 100644 (file)
@@ -2,7 +2,7 @@
  * i2c-ocores.c: I2C bus driver for OpenCores I2C controller
  * (https://opencores.org/project/i2c/overview)
  *
- * Peter Korsgaard <jacmet@sunsite.dk>
+ * Peter Korsgaard <peter@korsgaard.com>
  *
  * Support for the GRLIB port of the controller by
  * Andreas Larsson <andreas@gaisler.com>
@@ -576,7 +576,7 @@ static struct platform_driver ocores_i2c_driver = {
 
 module_platform_driver(ocores_i2c_driver);
 
-MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
+MODULE_AUTHOR("Peter Korsgaard <peter@korsgaard.com>");
 MODULE_DESCRIPTION("OpenCores I2C bus driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:ocores-i2c");
diff --git a/drivers/i2c/busses/i2c-owl.c b/drivers/i2c/busses/i2c-owl.c
new file mode 100644 (file)
index 0000000..96b4572
--- /dev/null
@@ -0,0 +1,495 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Actions Semiconductor Owl SoC's I2C driver
+ *
+ * Copyright (c) 2014 Actions Semi Inc.
+ * Author: David Liu <liuwei@actions-semi.com>
+ *
+ * Copyright (c) 2018 Linaro Ltd.
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+
+/* I2C registers */
+#define OWL_I2C_REG_CTL                0x0000
+#define OWL_I2C_REG_CLKDIV     0x0004
+#define OWL_I2C_REG_STAT       0x0008
+#define OWL_I2C_REG_ADDR       0x000C
+#define OWL_I2C_REG_TXDAT      0x0010
+#define OWL_I2C_REG_RXDAT      0x0014
+#define OWL_I2C_REG_CMD                0x0018
+#define OWL_I2C_REG_FIFOCTL    0x001C
+#define OWL_I2C_REG_FIFOSTAT   0x0020
+#define OWL_I2C_REG_DATCNT     0x0024
+#define OWL_I2C_REG_RCNT       0x0028
+
+/* I2Cx_CTL Bit Mask */
+#define OWL_I2C_CTL_RB         BIT(1)
+#define OWL_I2C_CTL_GBCC(x)    (((x) & 0x3) << 2)
+#define        OWL_I2C_CTL_GBCC_NONE   OWL_I2C_CTL_GBCC(0)
+#define        OWL_I2C_CTL_GBCC_START  OWL_I2C_CTL_GBCC(1)
+#define        OWL_I2C_CTL_GBCC_STOP   OWL_I2C_CTL_GBCC(2)
+#define        OWL_I2C_CTL_GBCC_RSTART OWL_I2C_CTL_GBCC(3)
+#define OWL_I2C_CTL_IRQE       BIT(5)
+#define OWL_I2C_CTL_EN         BIT(7)
+#define OWL_I2C_CTL_AE         BIT(8)
+#define OWL_I2C_CTL_SHSM       BIT(10)
+
+#define OWL_I2C_DIV_FACTOR(x)  ((x) & 0xff)
+
+/* I2Cx_STAT Bit Mask */
+#define OWL_I2C_STAT_RACK      BIT(0)
+#define OWL_I2C_STAT_BEB       BIT(1)
+#define OWL_I2C_STAT_IRQP      BIT(2)
+#define OWL_I2C_STAT_LAB       BIT(3)
+#define OWL_I2C_STAT_STPD      BIT(4)
+#define OWL_I2C_STAT_STAD      BIT(5)
+#define OWL_I2C_STAT_BBB       BIT(6)
+#define OWL_I2C_STAT_TCB       BIT(7)
+#define OWL_I2C_STAT_LBST      BIT(8)
+#define OWL_I2C_STAT_SAMB      BIT(9)
+#define OWL_I2C_STAT_SRGC      BIT(10)
+
+/* I2Cx_CMD Bit Mask */
+#define OWL_I2C_CMD_SBE                BIT(0)
+#define OWL_I2C_CMD_RBE                BIT(4)
+#define OWL_I2C_CMD_DE         BIT(8)
+#define OWL_I2C_CMD_NS         BIT(9)
+#define OWL_I2C_CMD_SE         BIT(10)
+#define OWL_I2C_CMD_MSS                BIT(11)
+#define OWL_I2C_CMD_WRS                BIT(12)
+#define OWL_I2C_CMD_SECL       BIT(15)
+
+#define OWL_I2C_CMD_AS(x)      (((x) & 0x7) << 1)
+#define OWL_I2C_CMD_SAS(x)     (((x) & 0x7) << 5)
+
+/* I2Cx_FIFOCTL Bit Mask */
+#define OWL_I2C_FIFOCTL_NIB    BIT(0)
+#define OWL_I2C_FIFOCTL_RFR    BIT(1)
+#define OWL_I2C_FIFOCTL_TFR    BIT(2)
+
+/* I2Cc_FIFOSTAT Bit Mask */
+#define OWL_I2C_FIFOSTAT_RNB   BIT(1)
+#define OWL_I2C_FIFOSTAT_RFE   BIT(2)
+#define OWL_I2C_FIFOSTAT_TFF   BIT(5)
+#define OWL_I2C_FIFOSTAT_TFD   GENMASK(23, 16)
+#define OWL_I2C_FIFOSTAT_RFD   GENMASK(15, 8)
+
+/* I2C bus timeout */
+#define OWL_I2C_TIMEOUT                msecs_to_jiffies(4 * 1000)
+
+#define OWL_I2C_MAX_RETRIES    50
+
+#define OWL_I2C_DEF_SPEED_HZ   100000
+#define OWL_I2C_MAX_SPEED_HZ   400000
+
+struct owl_i2c_dev {
+       struct i2c_adapter      adap;
+       struct i2c_msg          *msg;
+       struct completion       msg_complete;
+       struct clk              *clk;
+       spinlock_t              lock;
+       void __iomem            *base;
+       unsigned long           clk_rate;
+       u32                     bus_freq;
+       u32                     msg_ptr;
+       int                     err;
+};
+
+static void owl_i2c_update_reg(void __iomem *reg, unsigned int val, bool state)
+{
+       unsigned int regval;
+
+       regval = readl(reg);
+
+       if (state)
+               regval |= val;
+       else
+               regval &= ~val;
+
+       writel(regval, reg);
+}
+
+static void owl_i2c_reset(struct owl_i2c_dev *i2c_dev)
+{
+       owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_CTL,
+                          OWL_I2C_CTL_EN, false);
+       mdelay(1);
+       owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_CTL,
+                          OWL_I2C_CTL_EN, true);
+
+       /* Clear status registers */
+       writel(0, i2c_dev->base + OWL_I2C_REG_STAT);
+}
+
+static int owl_i2c_reset_fifo(struct owl_i2c_dev *i2c_dev)
+{
+       unsigned int val, timeout = 0;
+
+       /* Reset FIFO */
+       owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_FIFOCTL,
+                          OWL_I2C_FIFOCTL_RFR | OWL_I2C_FIFOCTL_TFR,
+                          true);
+
+       /* Wait 50ms for FIFO reset complete */
+       do {
+               val = readl(i2c_dev->base + OWL_I2C_REG_FIFOCTL);
+               if (!(val & (OWL_I2C_FIFOCTL_RFR | OWL_I2C_FIFOCTL_TFR)))
+                       break;
+               usleep_range(500, 1000);
+       } while (timeout++ < OWL_I2C_MAX_RETRIES);
+
+       if (timeout > OWL_I2C_MAX_RETRIES) {
+               dev_err(&i2c_dev->adap.dev, "FIFO reset timeout\n");
+               return -ETIMEDOUT;
+       }
+
+       return 0;
+}
+
+static void owl_i2c_set_freq(struct owl_i2c_dev *i2c_dev)
+{
+       unsigned int val;
+
+       val = DIV_ROUND_UP(i2c_dev->clk_rate, i2c_dev->bus_freq * 16);
+
+       /* Set clock divider factor */
+       writel(OWL_I2C_DIV_FACTOR(val), i2c_dev->base + OWL_I2C_REG_CLKDIV);
+}
+
+static irqreturn_t owl_i2c_interrupt(int irq, void *_dev)
+{
+       struct owl_i2c_dev *i2c_dev = _dev;
+       struct i2c_msg *msg = i2c_dev->msg;
+       unsigned long flags;
+       unsigned int stat, fifostat;
+
+       spin_lock_irqsave(&i2c_dev->lock, flags);
+
+       i2c_dev->err = 0;
+
+       /* Handle NACK from slave */
+       fifostat = readl(i2c_dev->base + OWL_I2C_REG_FIFOSTAT);
+       if (fifostat & OWL_I2C_FIFOSTAT_RNB) {
+               i2c_dev->err = -ENXIO;
+               goto stop;
+       }
+
+       /* Handle bus error */
+       stat = readl(i2c_dev->base + OWL_I2C_REG_STAT);
+       if (stat & OWL_I2C_STAT_BEB) {
+               i2c_dev->err = -EIO;
+               goto stop;
+       }
+
+       /* Handle FIFO read */
+       if (msg->flags & I2C_M_RD) {
+               while ((readl(i2c_dev->base + OWL_I2C_REG_FIFOSTAT) &
+                       OWL_I2C_FIFOSTAT_RFE) && i2c_dev->msg_ptr < msg->len) {
+                       msg->buf[i2c_dev->msg_ptr++] = readl(i2c_dev->base +
+                                                            OWL_I2C_REG_RXDAT);
+               }
+       } else {
+               /* Handle the remaining bytes which were not sent */
+               while (!(readl(i2c_dev->base + OWL_I2C_REG_FIFOSTAT) &
+                        OWL_I2C_FIFOSTAT_TFF) && i2c_dev->msg_ptr < msg->len) {
+                       writel(msg->buf[i2c_dev->msg_ptr++],
+                              i2c_dev->base + OWL_I2C_REG_TXDAT);
+               }
+       }
+
+stop:
+       /* Clear pending interrupts */
+       owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_STAT,
+                          OWL_I2C_STAT_IRQP, true);
+
+       complete_all(&i2c_dev->msg_complete);
+       spin_unlock_irqrestore(&i2c_dev->lock, flags);
+
+       return IRQ_HANDLED;
+}
+
+static u32 owl_i2c_func(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static int owl_i2c_check_bus_busy(struct i2c_adapter *adap)
+{
+       struct owl_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
+       unsigned long timeout;
+
+       /* Check for Bus busy */
+       timeout = jiffies + OWL_I2C_TIMEOUT;
+       while (readl(i2c_dev->base + OWL_I2C_REG_STAT) & OWL_I2C_STAT_BBB) {
+               if (time_after(jiffies, timeout)) {
+                       dev_err(&adap->dev, "Bus busy timeout\n");
+                       return -ETIMEDOUT;
+               }
+       }
+
+       return 0;
+}
+
+static int owl_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+                              int num)
+{
+       struct owl_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
+       struct i2c_msg *msg;
+       unsigned long time_left, flags;
+       unsigned int i2c_cmd, val;
+       unsigned int addr;
+       int ret, idx;
+
+       spin_lock_irqsave(&i2c_dev->lock, flags);
+
+       /* Reset I2C controller */
+       owl_i2c_reset(i2c_dev);
+
+       /* Set bus frequency */
+       owl_i2c_set_freq(i2c_dev);
+
+       /*
+        * Spinlock should be released before calling reset FIFO and
+        * bus busy check since those functions may sleep
+        */
+       spin_unlock_irqrestore(&i2c_dev->lock, flags);
+
+       /* Reset FIFO */
+       ret = owl_i2c_reset_fifo(i2c_dev);
+       if (ret)
+               goto unlocked_err_exit;
+
+       /* Check for bus busy */
+       ret = owl_i2c_check_bus_busy(adap);
+       if (ret)
+               goto unlocked_err_exit;
+
+       spin_lock_irqsave(&i2c_dev->lock, flags);
+
+       /* Check for Arbitration lost */
+       val = readl(i2c_dev->base + OWL_I2C_REG_STAT);
+       if (val & OWL_I2C_STAT_LAB) {
+               val &= ~OWL_I2C_STAT_LAB;
+               writel(val, i2c_dev->base + OWL_I2C_REG_STAT);
+               ret = -EAGAIN;
+               goto err_exit;
+       }
+
+       reinit_completion(&i2c_dev->msg_complete);
+
+       /* Enable I2C controller interrupt */
+       owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_CTL,
+                          OWL_I2C_CTL_IRQE, true);
+
+       /*
+        * Select: FIFO enable, Master mode, Stop enable, Data count enable,
+        * Send start bit
+        */
+       i2c_cmd = OWL_I2C_CMD_SECL | OWL_I2C_CMD_MSS | OWL_I2C_CMD_SE |
+                 OWL_I2C_CMD_NS | OWL_I2C_CMD_DE | OWL_I2C_CMD_SBE;
+
+       /* Handle repeated start condition */
+       if (num > 1) {
+               /* Set internal address length and enable repeated start */
+               i2c_cmd |= OWL_I2C_CMD_AS(msgs[0].len + 1) |
+                          OWL_I2C_CMD_SAS(1) | OWL_I2C_CMD_RBE;
+
+               /* Write slave address */
+               addr = i2c_8bit_addr_from_msg(&msgs[0]);
+               writel(addr, i2c_dev->base + OWL_I2C_REG_TXDAT);
+
+               /* Write internal register address */
+               for (idx = 0; idx < msgs[0].len; idx++)
+                       writel(msgs[0].buf[idx],
+                              i2c_dev->base + OWL_I2C_REG_TXDAT);
+
+               msg = &msgs[1];
+       } else {
+               /* Set address length */
+               i2c_cmd |= OWL_I2C_CMD_AS(1);
+               msg = &msgs[0];
+       }
+
+       i2c_dev->msg = msg;
+       i2c_dev->msg_ptr = 0;
+
+       /* Set data count for the message */
+       writel(msg->len, i2c_dev->base + OWL_I2C_REG_DATCNT);
+
+       addr = i2c_8bit_addr_from_msg(msg);
+       writel(addr, i2c_dev->base + OWL_I2C_REG_TXDAT);
+
+       if (!(msg->flags & I2C_M_RD)) {
+               /* Write data to FIFO */
+               for (idx = 0; idx < msg->len; idx++) {
+                       /* Check for FIFO full */
+                       if (readl(i2c_dev->base + OWL_I2C_REG_FIFOSTAT) &
+                           OWL_I2C_FIFOSTAT_TFF)
+                               break;
+
+                       writel(msg->buf[idx],
+                              i2c_dev->base + OWL_I2C_REG_TXDAT);
+               }
+
+               i2c_dev->msg_ptr = idx;
+       }
+
+       /* Ignore the NACK if needed */
+       if (msg->flags & I2C_M_IGNORE_NAK)
+               owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_FIFOCTL,
+                                  OWL_I2C_FIFOCTL_NIB, true);
+       else
+               owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_FIFOCTL,
+                                  OWL_I2C_FIFOCTL_NIB, false);
+
+       /* Start the transfer */
+       writel(i2c_cmd, i2c_dev->base + OWL_I2C_REG_CMD);
+
+       spin_unlock_irqrestore(&i2c_dev->lock, flags);
+
+       time_left = wait_for_completion_timeout(&i2c_dev->msg_complete,
+                                               adap->timeout);
+
+       spin_lock_irqsave(&i2c_dev->lock, flags);
+       if (time_left == 0) {
+               dev_err(&adap->dev, "Transaction timed out\n");
+               /* Send stop condition and release the bus */
+               owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_CTL,
+                                  OWL_I2C_CTL_GBCC_STOP | OWL_I2C_CTL_RB,
+                                  true);
+               ret = -ETIMEDOUT;
+               goto err_exit;
+       }
+
+       ret = i2c_dev->err < 0 ? i2c_dev->err : num;
+
+err_exit:
+       spin_unlock_irqrestore(&i2c_dev->lock, flags);
+
+unlocked_err_exit:
+       /* Disable I2C controller */
+       owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_CTL,
+                          OWL_I2C_CTL_EN, false);
+
+       return ret;
+}
+
+static const struct i2c_algorithm owl_i2c_algorithm = {
+       .master_xfer    = owl_i2c_master_xfer,
+       .functionality  = owl_i2c_func,
+};
+
+static const struct i2c_adapter_quirks owl_i2c_quirks = {
+       .flags          = I2C_AQ_COMB | I2C_AQ_COMB_WRITE_FIRST,
+       .max_read_len   = 240,
+       .max_write_len  = 240,
+       .max_comb_1st_msg_len = 6,
+       .max_comb_2nd_msg_len = 240,
+};
+
+static int owl_i2c_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct owl_i2c_dev *i2c_dev;
+       struct resource *res;
+       int ret, irq;
+
+       i2c_dev = devm_kzalloc(dev, sizeof(*i2c_dev), GFP_KERNEL);
+       if (!i2c_dev)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       i2c_dev->base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(i2c_dev->base))
+               return PTR_ERR(i2c_dev->base);
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(dev, "failed to get IRQ number\n");
+               return irq;
+       }
+
+       if (of_property_read_u32(dev->of_node, "clock-frequency",
+                                &i2c_dev->bus_freq))
+               i2c_dev->bus_freq = OWL_I2C_DEF_SPEED_HZ;
+
+       /* We support only frequencies of 100k and 400k for now */
+       if (i2c_dev->bus_freq != OWL_I2C_DEF_SPEED_HZ &&
+           i2c_dev->bus_freq != OWL_I2C_MAX_SPEED_HZ) {
+               dev_err(dev, "invalid clock-frequency %d\n", i2c_dev->bus_freq);
+               return -EINVAL;
+       }
+
+       i2c_dev->clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(i2c_dev->clk)) {
+               dev_err(dev, "failed to get clock\n");
+               return PTR_ERR(i2c_dev->clk);
+       }
+
+       ret = clk_prepare_enable(i2c_dev->clk);
+       if (ret)
+               return ret;
+
+       i2c_dev->clk_rate = clk_get_rate(i2c_dev->clk);
+       if (!i2c_dev->clk_rate) {
+               dev_err(dev, "input clock rate should not be zero\n");
+               ret = -EINVAL;
+               goto disable_clk;
+       }
+
+       init_completion(&i2c_dev->msg_complete);
+       spin_lock_init(&i2c_dev->lock);
+       i2c_dev->adap.owner = THIS_MODULE;
+       i2c_dev->adap.algo = &owl_i2c_algorithm;
+       i2c_dev->adap.timeout = OWL_I2C_TIMEOUT;
+       i2c_dev->adap.quirks = &owl_i2c_quirks;
+       i2c_dev->adap.dev.parent = dev;
+       i2c_dev->adap.dev.of_node = dev->of_node;
+       snprintf(i2c_dev->adap.name, sizeof(i2c_dev->adap.name),
+                "%s", "OWL I2C adapter");
+       i2c_set_adapdata(&i2c_dev->adap, i2c_dev);
+
+       platform_set_drvdata(pdev, i2c_dev);
+
+       ret = devm_request_irq(dev, irq, owl_i2c_interrupt, 0, pdev->name,
+                              i2c_dev);
+       if (ret) {
+               dev_err(dev, "failed to request irq %d\n", irq);
+               goto disable_clk;
+       }
+
+       return i2c_add_adapter(&i2c_dev->adap);
+
+disable_clk:
+       clk_disable_unprepare(i2c_dev->clk);
+
+       return ret;
+}
+
+static const struct of_device_id owl_i2c_of_match[] = {
+       { .compatible = "actions,s900-i2c" },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, owl_i2c_of_match);
+
+static struct platform_driver owl_i2c_driver = {
+       .probe          = owl_i2c_probe,
+       .driver         = {
+               .name   = "owl-i2c",
+               .of_match_table = of_match_ptr(owl_i2c_of_match),
+       },
+};
+module_platform_driver(owl_i2c_driver);
+
+MODULE_AUTHOR("David Liu <liuwei@actions-semi.com>");
+MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
+MODULE_DESCRIPTION("Actions Semiconductor Owl SoC's I2C driver");
+MODULE_LICENSE("GPL");
index 55fd5c6f3cca1523715f6f80f5fc061b79304728..50803e5d995b3a241a7dcbb35065d9c2e6ebe9ec 100644 (file)
@@ -365,7 +365,6 @@ static int pasemi_smb_probe(struct pci_dev *dev,
        smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
        smbus->adapter.algo = &smbus_algorithm;
        smbus->adapter.algo_data = smbus;
-       smbus->adapter.nr = PCI_FUNC(dev->devfn);
 
        /* set up the sysfs linkage to our parent device */
        smbus->adapter.dev.parent = &dev->dev;
@@ -373,7 +372,7 @@ static int pasemi_smb_probe(struct pci_dev *dev,
        reg_write(smbus, REG_CTL, (CTL_MTR | CTL_MRR |
                  (CLK_100K_DIV & CTL_CLK_M)));
 
-       error = i2c_add_numbered_adapter(&smbus->adapter);
+       error = i2c_add_adapter(&smbus->adapter);
        if (error)
                goto out_release_region;
 
index dae8ac618a5221fdd886afab417f88945af7f143..0829cb696d9d4a276bbb80038fe0c9186b8b2579 100644 (file)
@@ -444,16 +444,6 @@ static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd(
 {
        enum pmcmsptwi_xfer_result retval;
 
-       if ((cmd->type == MSP_TWI_CMD_WRITE && cmd->write_len == 0) ||
-           (cmd->type == MSP_TWI_CMD_READ && cmd->read_len == 0) ||
-           (cmd->type == MSP_TWI_CMD_WRITE_READ &&
-           (cmd->read_len == 0 || cmd->write_len == 0))) {
-               dev_err(&pmcmsptwi_adapter.dev,
-                       "%s: Cannot transfer less than 1 byte\n",
-                       __func__);
-               return -EINVAL;
-       }
-
        mutex_lock(&data->lock);
        dev_dbg(&pmcmsptwi_adapter.dev,
                "Setting address to 0x%04x\n", cmd->addr);
@@ -532,11 +522,6 @@ static int pmcmsptwi_master_xfer(struct i2c_adapter *adap,
                cmd.write_data = msg->buf;
        }
 
-       if (msg->len == 0) {
-               dev_err(&adap->dev, "Zero-byte messages unsupported\n");
-               return -EINVAL;
-       }
-
        cmd.addr = msg->addr;
 
        if (msg->flags & I2C_M_TEN) {
@@ -578,7 +563,7 @@ static u32 pmcmsptwi_i2c_func(struct i2c_adapter *adapter)
 }
 
 static const struct i2c_adapter_quirks pmcmsptwi_i2c_quirks = {
-       .flags = I2C_AQ_COMB_WRITE_THEN_READ,
+       .flags = I2C_AQ_COMB_WRITE_THEN_READ | I2C_AQ_NO_ZERO_LEN,
        .max_write_len = MSP_MAX_BYTES_PER_RW,
        .max_read_len = MSP_MAX_BYTES_PER_RW,
        .max_comb_1st_msg_len = MSP_MAX_BYTES_PER_RW,
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
new file mode 100644 (file)
index 0000000..36732eb
--- /dev/null
@@ -0,0 +1,673 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/qcom-geni-se.h>
+#include <linux/spinlock.h>
+
+#define SE_I2C_TX_TRANS_LEN            0x26c
+#define SE_I2C_RX_TRANS_LEN            0x270
+#define SE_I2C_SCL_COUNTERS            0x278
+
+#define SE_I2C_ERR  (M_CMD_OVERRUN_EN | M_ILLEGAL_CMD_EN | M_CMD_FAILURE_EN |\
+                       M_GP_IRQ_1_EN | M_GP_IRQ_3_EN | M_GP_IRQ_4_EN)
+#define SE_I2C_ABORT           BIT(1)
+
+/* M_CMD OP codes for I2C */
+#define I2C_WRITE              0x1
+#define I2C_READ               0x2
+#define I2C_WRITE_READ         0x3
+#define I2C_ADDR_ONLY          0x4
+#define I2C_BUS_CLEAR          0x6
+#define I2C_STOP_ON_BUS                0x7
+/* M_CMD params for I2C */
+#define PRE_CMD_DELAY          BIT(0)
+#define TIMESTAMP_BEFORE       BIT(1)
+#define STOP_STRETCH           BIT(2)
+#define TIMESTAMP_AFTER                BIT(3)
+#define POST_COMMAND_DELAY     BIT(4)
+#define IGNORE_ADD_NACK                BIT(6)
+#define READ_FINISHED_WITH_ACK BIT(7)
+#define BYPASS_ADDR_PHASE      BIT(8)
+#define SLV_ADDR_MSK           GENMASK(15, 9)
+#define SLV_ADDR_SHFT          9
+/* I2C SCL COUNTER fields */
+#define HIGH_COUNTER_MSK       GENMASK(29, 20)
+#define HIGH_COUNTER_SHFT      20
+#define LOW_COUNTER_MSK                GENMASK(19, 10)
+#define LOW_COUNTER_SHFT       10
+#define CYCLE_COUNTER_MSK      GENMASK(9, 0)
+
+enum geni_i2c_err_code {
+       GP_IRQ0,
+       NACK,
+       GP_IRQ2,
+       BUS_PROTO,
+       ARB_LOST,
+       GP_IRQ5,
+       GENI_OVERRUN,
+       GENI_ILLEGAL_CMD,
+       GENI_ABORT_DONE,
+       GENI_TIMEOUT,
+};
+
+#define DM_I2C_CB_ERR          ((BIT(NACK) | BIT(BUS_PROTO) | BIT(ARB_LOST)) \
+                                                                       << 5)
+
+#define I2C_AUTO_SUSPEND_DELAY 250
+#define KHZ(freq)              (1000 * freq)
+#define PACKING_BYTES_PW       4
+
+#define ABORT_TIMEOUT          HZ
+#define XFER_TIMEOUT           HZ
+#define RST_TIMEOUT            HZ
+
+struct geni_i2c_dev {
+       struct geni_se se;
+       u32 tx_wm;
+       int irq;
+       int err;
+       struct i2c_adapter adap;
+       struct completion done;
+       struct i2c_msg *cur;
+       int cur_wr;
+       int cur_rd;
+       spinlock_t lock;
+       u32 clk_freq_out;
+       const struct geni_i2c_clk_fld *clk_fld;
+       int suspended;
+};
+
+struct geni_i2c_err_log {
+       int err;
+       const char *msg;
+};
+
+static const struct geni_i2c_err_log gi2c_log[] = {
+       [GP_IRQ0] = {-EIO, "Unknown I2C err GP_IRQ0"},
+       [NACK] = {-ENXIO, "NACK: slv unresponsive, check its power/reset-ln"},
+       [GP_IRQ2] = {-EIO, "Unknown I2C err GP IRQ2"},
+       [BUS_PROTO] = {-EPROTO, "Bus proto err, noisy/unepxected start/stop"},
+       [ARB_LOST] = {-EAGAIN, "Bus arbitration lost, clock line undriveable"},
+       [GP_IRQ5] = {-EIO, "Unknown I2C err GP IRQ5"},
+       [GENI_OVERRUN] = {-EIO, "Cmd overrun, check GENI cmd-state machine"},
+       [GENI_ILLEGAL_CMD] = {-EIO, "Illegal cmd, check GENI cmd-state machine"},
+       [GENI_ABORT_DONE] = {-ETIMEDOUT, "Abort after timeout successful"},
+       [GENI_TIMEOUT] = {-ETIMEDOUT, "I2C TXN timed out"},
+};
+
+struct geni_i2c_clk_fld {
+       u32     clk_freq_out;
+       u8      clk_div;
+       u8      t_high_cnt;
+       u8      t_low_cnt;
+       u8      t_cycle_cnt;
+};
+
+/*
+ * Hardware uses the underlying formula to calculate time periods of
+ * SCL clock cycle. Firmware uses some additional cycles excluded from the
+ * below formula and it is confirmed that the time periods are within
+ * specification limits.
+ *
+ * time of high period of SCL: t_high = (t_high_cnt * clk_div) / source_clock
+ * time of low period of SCL: t_low = (t_low_cnt * clk_div) / source_clock
+ * time of full period of SCL: t_cycle = (t_cycle_cnt * clk_div) / source_clock
+ * clk_freq_out = t / t_cycle
+ * source_clock = 19.2 MHz
+ */
+static const struct geni_i2c_clk_fld geni_i2c_clk_map[] = {
+       {KHZ(100), 7, 10, 11, 26},
+       {KHZ(400), 2,  5, 12, 24},
+       {KHZ(1000), 1, 3,  9, 18},
+};
+
+static int geni_i2c_clk_map_idx(struct geni_i2c_dev *gi2c)
+{
+       int i;
+       const struct geni_i2c_clk_fld *itr = geni_i2c_clk_map;
+
+       for (i = 0; i < ARRAY_SIZE(geni_i2c_clk_map); i++, itr++) {
+               if (itr->clk_freq_out == gi2c->clk_freq_out) {
+                       gi2c->clk_fld = itr;
+                       return 0;
+               }
+       }
+       return -EINVAL;
+}
+
+static void qcom_geni_i2c_conf(struct geni_i2c_dev *gi2c)
+{
+       const struct geni_i2c_clk_fld *itr = gi2c->clk_fld;
+       u32 val;
+
+       writel_relaxed(0, gi2c->se.base + SE_GENI_CLK_SEL);
+
+       val = (itr->clk_div << CLK_DIV_SHFT) | SER_CLK_EN;
+       writel_relaxed(val, gi2c->se.base + GENI_SER_M_CLK_CFG);
+
+       val = itr->t_high_cnt << HIGH_COUNTER_SHFT;
+       val |= itr->t_low_cnt << LOW_COUNTER_SHFT;
+       val |= itr->t_cycle_cnt;
+       writel_relaxed(val, gi2c->se.base + SE_I2C_SCL_COUNTERS);
+}
+
+static void geni_i2c_err_misc(struct geni_i2c_dev *gi2c)
+{
+       u32 m_cmd = readl_relaxed(gi2c->se.base + SE_GENI_M_CMD0);
+       u32 m_stat = readl_relaxed(gi2c->se.base + SE_GENI_M_IRQ_STATUS);
+       u32 geni_s = readl_relaxed(gi2c->se.base + SE_GENI_STATUS);
+       u32 geni_ios = readl_relaxed(gi2c->se.base + SE_GENI_IOS);
+       u32 dma = readl_relaxed(gi2c->se.base + SE_GENI_DMA_MODE_EN);
+       u32 rx_st, tx_st;
+
+       if (dma) {
+               rx_st = readl_relaxed(gi2c->se.base + SE_DMA_RX_IRQ_STAT);
+               tx_st = readl_relaxed(gi2c->se.base + SE_DMA_TX_IRQ_STAT);
+       } else {
+               rx_st = readl_relaxed(gi2c->se.base + SE_GENI_RX_FIFO_STATUS);
+               tx_st = readl_relaxed(gi2c->se.base + SE_GENI_TX_FIFO_STATUS);
+       }
+       dev_dbg(gi2c->se.dev, "DMA:%d tx_stat:0x%x, rx_stat:0x%x, irq-stat:0x%x\n",
+               dma, tx_st, rx_st, m_stat);
+       dev_dbg(gi2c->se.dev, "m_cmd:0x%x, geni_status:0x%x, geni_ios:0x%x\n",
+               m_cmd, geni_s, geni_ios);
+}
+
+static void geni_i2c_err(struct geni_i2c_dev *gi2c, int err)
+{
+       if (!gi2c->err)
+               gi2c->err = gi2c_log[err].err;
+       if (gi2c->cur)
+               dev_dbg(gi2c->se.dev, "len:%d, slv-addr:0x%x, RD/WR:%d\n",
+                       gi2c->cur->len, gi2c->cur->addr, gi2c->cur->flags);
+
+       if (err != NACK && err != GENI_ABORT_DONE) {
+               dev_err(gi2c->se.dev, "%s\n", gi2c_log[err].msg);
+               geni_i2c_err_misc(gi2c);
+       }
+}
+
+static irqreturn_t geni_i2c_irq(int irq, void *dev)
+{
+       struct geni_i2c_dev *gi2c = dev;
+       int j;
+       u32 m_stat;
+       u32 rx_st;
+       u32 dm_tx_st;
+       u32 dm_rx_st;
+       u32 dma;
+       struct i2c_msg *cur;
+       unsigned long flags;
+
+       spin_lock_irqsave(&gi2c->lock, flags);
+       m_stat = readl_relaxed(gi2c->se.base + SE_GENI_M_IRQ_STATUS);
+       rx_st = readl_relaxed(gi2c->se.base + SE_GENI_RX_FIFO_STATUS);
+       dm_tx_st = readl_relaxed(gi2c->se.base + SE_DMA_TX_IRQ_STAT);
+       dm_rx_st = readl_relaxed(gi2c->se.base + SE_DMA_RX_IRQ_STAT);
+       dma = readl_relaxed(gi2c->se.base + SE_GENI_DMA_MODE_EN);
+       cur = gi2c->cur;
+
+       if (!cur ||
+           m_stat & (M_CMD_FAILURE_EN | M_CMD_ABORT_EN) ||
+           dm_rx_st & (DM_I2C_CB_ERR)) {
+               if (m_stat & M_GP_IRQ_1_EN)
+                       geni_i2c_err(gi2c, NACK);
+               if (m_stat & M_GP_IRQ_3_EN)
+                       geni_i2c_err(gi2c, BUS_PROTO);
+               if (m_stat & M_GP_IRQ_4_EN)
+                       geni_i2c_err(gi2c, ARB_LOST);
+               if (m_stat & M_CMD_OVERRUN_EN)
+                       geni_i2c_err(gi2c, GENI_OVERRUN);
+               if (m_stat & M_ILLEGAL_CMD_EN)
+                       geni_i2c_err(gi2c, GENI_ILLEGAL_CMD);
+               if (m_stat & M_CMD_ABORT_EN)
+                       geni_i2c_err(gi2c, GENI_ABORT_DONE);
+               if (m_stat & M_GP_IRQ_0_EN)
+                       geni_i2c_err(gi2c, GP_IRQ0);
+
+               /* Disable the TX Watermark interrupt to stop TX */
+               if (!dma)
+                       writel_relaxed(0, gi2c->se.base +
+                                          SE_GENI_TX_WATERMARK_REG);
+               goto irqret;
+       }
+
+       if (dma) {
+               dev_dbg(gi2c->se.dev, "i2c dma tx:0x%x, dma rx:0x%x\n",
+                       dm_tx_st, dm_rx_st);
+               goto irqret;
+       }
+
+       if (cur->flags & I2C_M_RD &&
+           m_stat & (M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN)) {
+               u32 rxcnt = rx_st & RX_FIFO_WC_MSK;
+
+               for (j = 0; j < rxcnt; j++) {
+                       u32 val;
+                       int p = 0;
+
+                       val = readl_relaxed(gi2c->se.base + SE_GENI_RX_FIFOn);
+                       while (gi2c->cur_rd < cur->len && p < sizeof(val)) {
+                               cur->buf[gi2c->cur_rd++] = val & 0xff;
+                               val >>= 8;
+                               p++;
+                       }
+                       if (gi2c->cur_rd == cur->len)
+                               break;
+               }
+       } else if (!(cur->flags & I2C_M_RD) &&
+                  m_stat & M_TX_FIFO_WATERMARK_EN) {
+               for (j = 0; j < gi2c->tx_wm; j++) {
+                       u32 temp;
+                       u32 val = 0;
+                       int p = 0;
+
+                       while (gi2c->cur_wr < cur->len && p < sizeof(val)) {
+                               temp = cur->buf[gi2c->cur_wr++];
+                               val |= temp << (p * 8);
+                               p++;
+                       }
+                       writel_relaxed(val, gi2c->se.base + SE_GENI_TX_FIFOn);
+                       /* TX Complete, Disable the TX Watermark interrupt */
+                       if (gi2c->cur_wr == cur->len) {
+                               writel_relaxed(0, gi2c->se.base +
+                                               SE_GENI_TX_WATERMARK_REG);
+                               break;
+                       }
+               }
+       }
+irqret:
+       if (m_stat)
+               writel_relaxed(m_stat, gi2c->se.base + SE_GENI_M_IRQ_CLEAR);
+
+       if (dma) {
+               if (dm_tx_st)
+                       writel_relaxed(dm_tx_st, gi2c->se.base +
+                                               SE_DMA_TX_IRQ_CLR);
+               if (dm_rx_st)
+                       writel_relaxed(dm_rx_st, gi2c->se.base +
+                                               SE_DMA_RX_IRQ_CLR);
+       }
+       /* if this is err with done-bit not set, handle that through timeout. */
+       if (m_stat & M_CMD_DONE_EN || m_stat & M_CMD_ABORT_EN)
+               complete(&gi2c->done);
+       else if (dm_tx_st & TX_DMA_DONE || dm_tx_st & TX_RESET_DONE)
+               complete(&gi2c->done);
+       else if (dm_rx_st & RX_DMA_DONE || dm_rx_st & RX_RESET_DONE)
+               complete(&gi2c->done);
+
+       spin_unlock_irqrestore(&gi2c->lock, flags);
+       return IRQ_HANDLED;
+}
+
+static void geni_i2c_abort_xfer(struct geni_i2c_dev *gi2c)
+{
+       u32 val;
+       unsigned long time_left = ABORT_TIMEOUT;
+       unsigned long flags;
+
+       spin_lock_irqsave(&gi2c->lock, flags);
+       geni_i2c_err(gi2c, GENI_TIMEOUT);
+       gi2c->cur = NULL;
+       geni_se_abort_m_cmd(&gi2c->se);
+       spin_unlock_irqrestore(&gi2c->lock, flags);
+       do {
+               time_left = wait_for_completion_timeout(&gi2c->done, time_left);
+               val = readl_relaxed(gi2c->se.base + SE_GENI_M_IRQ_STATUS);
+       } while (!(val & M_CMD_ABORT_EN) && time_left);
+
+       if (!(val & M_CMD_ABORT_EN))
+               dev_err(gi2c->se.dev, "Timeout abort_m_cmd\n");
+}
+
+static void geni_i2c_rx_fsm_rst(struct geni_i2c_dev *gi2c)
+{
+       u32 val;
+       unsigned long time_left = RST_TIMEOUT;
+
+       writel_relaxed(1, gi2c->se.base + SE_DMA_RX_FSM_RST);
+       do {
+               time_left = wait_for_completion_timeout(&gi2c->done, time_left);
+               val = readl_relaxed(gi2c->se.base + SE_DMA_RX_IRQ_STAT);
+       } while (!(val & RX_RESET_DONE) && time_left);
+
+       if (!(val & RX_RESET_DONE))
+               dev_err(gi2c->se.dev, "Timeout resetting RX_FSM\n");
+}
+
+static void geni_i2c_tx_fsm_rst(struct geni_i2c_dev *gi2c)
+{
+       u32 val;
+       unsigned long time_left = RST_TIMEOUT;
+
+       writel_relaxed(1, gi2c->se.base + SE_DMA_TX_FSM_RST);
+       do {
+               time_left = wait_for_completion_timeout(&gi2c->done, time_left);
+               val = readl_relaxed(gi2c->se.base + SE_DMA_TX_IRQ_STAT);
+       } while (!(val & TX_RESET_DONE) && time_left);
+
+       if (!(val & TX_RESET_DONE))
+               dev_err(gi2c->se.dev, "Timeout resetting TX_FSM\n");
+}
+
+static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
+                               u32 m_param)
+{
+       dma_addr_t rx_dma;
+       enum geni_se_xfer_mode mode;
+       unsigned long time_left = XFER_TIMEOUT;
+
+       gi2c->cur = msg;
+       mode = msg->len > 32 ? GENI_SE_DMA : GENI_SE_FIFO;
+       geni_se_select_mode(&gi2c->se, mode);
+       writel_relaxed(msg->len, gi2c->se.base + SE_I2C_RX_TRANS_LEN);
+       geni_se_setup_m_cmd(&gi2c->se, I2C_READ, m_param);
+       if (mode == GENI_SE_DMA) {
+               int ret;
+
+               ret = geni_se_rx_dma_prep(&gi2c->se, msg->buf, msg->len,
+                                                               &rx_dma);
+               if (ret) {
+                       mode = GENI_SE_FIFO;
+                       geni_se_select_mode(&gi2c->se, mode);
+               }
+       }
+
+       time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
+       if (!time_left)
+               geni_i2c_abort_xfer(gi2c);
+
+       gi2c->cur_rd = 0;
+       if (mode == GENI_SE_DMA) {
+               if (gi2c->err)
+                       geni_i2c_rx_fsm_rst(gi2c);
+               geni_se_rx_dma_unprep(&gi2c->se, rx_dma, msg->len);
+       }
+       return gi2c->err;
+}
+
+static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
+                               u32 m_param)
+{
+       dma_addr_t tx_dma;
+       enum geni_se_xfer_mode mode;
+       unsigned long time_left;
+
+       gi2c->cur = msg;
+       mode = msg->len > 32 ? GENI_SE_DMA : GENI_SE_FIFO;
+       geni_se_select_mode(&gi2c->se, mode);
+       writel_relaxed(msg->len, gi2c->se.base + SE_I2C_TX_TRANS_LEN);
+       geni_se_setup_m_cmd(&gi2c->se, I2C_WRITE, m_param);
+       if (mode == GENI_SE_DMA) {
+               int ret;
+
+               ret = geni_se_tx_dma_prep(&gi2c->se, msg->buf, msg->len,
+                                                               &tx_dma);
+               if (ret) {
+                       mode = GENI_SE_FIFO;
+                       geni_se_select_mode(&gi2c->se, mode);
+               }
+       }
+
+       if (mode == GENI_SE_FIFO) /* Get FIFO IRQ */
+               writel_relaxed(1, gi2c->se.base + SE_GENI_TX_WATERMARK_REG);
+
+       time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
+       if (!time_left)
+               geni_i2c_abort_xfer(gi2c);
+
+       gi2c->cur_wr = 0;
+       if (mode == GENI_SE_DMA) {
+               if (gi2c->err)
+                       geni_i2c_tx_fsm_rst(gi2c);
+               geni_se_tx_dma_unprep(&gi2c->se, tx_dma, msg->len);
+       }
+       return gi2c->err;
+}
+
+static int geni_i2c_xfer(struct i2c_adapter *adap,
+                        struct i2c_msg msgs[],
+                        int num)
+{
+       struct geni_i2c_dev *gi2c = i2c_get_adapdata(adap);
+       int i, ret;
+
+       gi2c->err = 0;
+       reinit_completion(&gi2c->done);
+       ret = pm_runtime_get_sync(gi2c->se.dev);
+       if (ret < 0) {
+               dev_err(gi2c->se.dev, "error turning SE resources:%d\n", ret);
+               pm_runtime_put_noidle(gi2c->se.dev);
+               /* Set device in suspended since resume failed */
+               pm_runtime_set_suspended(gi2c->se.dev);
+               return ret;
+       }
+
+       qcom_geni_i2c_conf(gi2c);
+       for (i = 0; i < num; i++) {
+               u32 m_param = i < (num - 1) ? STOP_STRETCH : 0;
+
+               m_param |= ((msgs[i].addr << SLV_ADDR_SHFT) & SLV_ADDR_MSK);
+
+               if (msgs[i].flags & I2C_M_RD)
+                       ret = geni_i2c_rx_one_msg(gi2c, &msgs[i], m_param);
+               else
+                       ret = geni_i2c_tx_one_msg(gi2c, &msgs[i], m_param);
+
+               if (ret)
+                       break;
+       }
+       if (ret == 0)
+               ret = num;
+
+       pm_runtime_mark_last_busy(gi2c->se.dev);
+       pm_runtime_put_autosuspend(gi2c->se.dev);
+       gi2c->cur = NULL;
+       gi2c->err = 0;
+       return ret;
+}
+
+static u32 geni_i2c_func(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
+}
+
+static const struct i2c_algorithm geni_i2c_algo = {
+       .master_xfer    = geni_i2c_xfer,
+       .functionality  = geni_i2c_func,
+};
+
+static int geni_i2c_probe(struct platform_device *pdev)
+{
+       struct geni_i2c_dev *gi2c;
+       struct resource *res;
+       u32 proto, tx_depth;
+       int ret;
+
+       gi2c = devm_kzalloc(&pdev->dev, sizeof(*gi2c), GFP_KERNEL);
+       if (!gi2c)
+               return -ENOMEM;
+
+       gi2c->se.dev = &pdev->dev;
+       gi2c->se.wrapper = dev_get_drvdata(pdev->dev.parent);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       gi2c->se.base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(gi2c->se.base))
+               return PTR_ERR(gi2c->se.base);
+
+       gi2c->se.clk = devm_clk_get(&pdev->dev, "se");
+       if (IS_ERR(gi2c->se.clk)) {
+               ret = PTR_ERR(gi2c->se.clk);
+               dev_err(&pdev->dev, "Err getting SE Core clk %d\n", ret);
+               return ret;
+       }
+
+       ret = device_property_read_u32(&pdev->dev, "clock-frequency",
+                                                       &gi2c->clk_freq_out);
+       if (ret) {
+               dev_info(&pdev->dev,
+                       "Bus frequency not specified, default to 100kHz.\n");
+               gi2c->clk_freq_out = KHZ(100);
+       }
+
+       gi2c->irq = platform_get_irq(pdev, 0);
+       if (gi2c->irq < 0) {
+               dev_err(&pdev->dev, "IRQ error for i2c-geni\n");
+               return gi2c->irq;
+       }
+
+       ret = geni_i2c_clk_map_idx(gi2c);
+       if (ret) {
+               dev_err(&pdev->dev, "Invalid clk frequency %d Hz: %d\n",
+                       gi2c->clk_freq_out, ret);
+               return ret;
+       }
+
+       gi2c->adap.algo = &geni_i2c_algo;
+       init_completion(&gi2c->done);
+       spin_lock_init(&gi2c->lock);
+       platform_set_drvdata(pdev, gi2c);
+       ret = devm_request_irq(&pdev->dev, gi2c->irq, geni_i2c_irq,
+                              IRQF_TRIGGER_HIGH, "i2c_geni", gi2c);
+       if (ret) {
+               dev_err(&pdev->dev, "Request_irq failed:%d: err:%d\n",
+                       gi2c->irq, ret);
+               return ret;
+       }
+       /* Disable the interrupt so that the system can enter low-power mode */
+       disable_irq(gi2c->irq);
+       i2c_set_adapdata(&gi2c->adap, gi2c);
+       gi2c->adap.dev.parent = &pdev->dev;
+       gi2c->adap.dev.of_node = pdev->dev.of_node;
+       strlcpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name));
+
+       ret = geni_se_resources_on(&gi2c->se);
+       if (ret) {
+               dev_err(&pdev->dev, "Error turning on resources %d\n", ret);
+               return ret;
+       }
+       proto = geni_se_read_proto(&gi2c->se);
+       tx_depth = geni_se_get_tx_fifo_depth(&gi2c->se);
+       if (proto != GENI_SE_I2C) {
+               dev_err(&pdev->dev, "Invalid proto %d\n", proto);
+               geni_se_resources_off(&gi2c->se);
+               return -ENXIO;
+       }
+       gi2c->tx_wm = tx_depth - 1;
+       geni_se_init(&gi2c->se, gi2c->tx_wm, tx_depth);
+       geni_se_config_packing(&gi2c->se, BITS_PER_BYTE, PACKING_BYTES_PW,
+                                                       true, true, true);
+       ret = geni_se_resources_off(&gi2c->se);
+       if (ret) {
+               dev_err(&pdev->dev, "Error turning off resources %d\n", ret);
+               return ret;
+       }
+
+       dev_dbg(&pdev->dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth);
+
+       ret = i2c_add_adapter(&gi2c->adap);
+       if (ret) {
+               dev_err(&pdev->dev, "Error adding i2c adapter %d\n", ret);
+               return ret;
+       }
+
+       gi2c->suspended = 1;
+       pm_runtime_set_suspended(gi2c->se.dev);
+       pm_runtime_set_autosuspend_delay(gi2c->se.dev, I2C_AUTO_SUSPEND_DELAY);
+       pm_runtime_use_autosuspend(gi2c->se.dev);
+       pm_runtime_enable(gi2c->se.dev);
+
+       return 0;
+}
+
+static int geni_i2c_remove(struct platform_device *pdev)
+{
+       struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev);
+
+       pm_runtime_disable(gi2c->se.dev);
+       i2c_del_adapter(&gi2c->adap);
+       return 0;
+}
+
+static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev)
+{
+       int ret;
+       struct geni_i2c_dev *gi2c = dev_get_drvdata(dev);
+
+       disable_irq(gi2c->irq);
+       ret = geni_se_resources_off(&gi2c->se);
+       if (ret) {
+               enable_irq(gi2c->irq);
+               return ret;
+
+       } else {
+               gi2c->suspended = 1;
+       }
+
+       return 0;
+}
+
+static int __maybe_unused geni_i2c_runtime_resume(struct device *dev)
+{
+       int ret;
+       struct geni_i2c_dev *gi2c = dev_get_drvdata(dev);
+
+       ret = geni_se_resources_on(&gi2c->se);
+       if (ret)
+               return ret;
+
+       enable_irq(gi2c->irq);
+       gi2c->suspended = 0;
+       return 0;
+}
+
+static int __maybe_unused geni_i2c_suspend_noirq(struct device *dev)
+{
+       struct geni_i2c_dev *gi2c = dev_get_drvdata(dev);
+
+       if (!gi2c->suspended) {
+               geni_i2c_runtime_suspend(dev);
+               pm_runtime_disable(dev);
+               pm_runtime_set_suspended(dev);
+               pm_runtime_enable(dev);
+       }
+       return 0;
+}
+
+static const struct dev_pm_ops geni_i2c_pm_ops = {
+       SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(geni_i2c_suspend_noirq, NULL)
+       SET_RUNTIME_PM_OPS(geni_i2c_runtime_suspend, geni_i2c_runtime_resume,
+                                                                       NULL)
+};
+
+static const struct of_device_id geni_i2c_dt_match[] = {
+       { .compatible = "qcom,geni-i2c" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, geni_i2c_dt_match);
+
+static struct platform_driver geni_i2c_driver = {
+       .probe  = geni_i2c_probe,
+       .remove = geni_i2c_remove,
+       .driver = {
+               .name = "geni_i2c",
+               .pm = &geni_i2c_pm_ops,
+               .of_match_table = geni_i2c_dt_match,
+       },
+};
+
+module_platform_driver(geni_i2c_driver);
+
+MODULE_DESCRIPTION("I2C Controller Driver for GENI based QUP cores");
+MODULE_LICENSE("GPL v2");
index 3c1c817f6968e43fdafd73ff6f53d381c2528b96..52cf42b32f0a27ffc6a35810a823ea739f587987 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Driver for the Renesas R-Car I2C unit
  *
@@ -9,16 +10,8 @@
  *
  * This file is based on the drivers/i2c/busses/i2c-sh7760.c
  * (c) 2005-2008 MSC Vertriebsges.m.b.H, Manuel Lauss <mlau@msc-ge.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
+#include <linux/bitops.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/dmaengine.h>
 #define ID_ARBLOST     (1 << 3)
 #define ID_NACK                (1 << 4)
 /* persistent flags */
-#define ID_P_NO_RXDMA  (1 << 30) /* HW forbids RXDMA sometimes */
-#define ID_P_PM_BLOCKED        (1 << 31)
-#define ID_P_MASK      (ID_P_PM_BLOCKED | ID_P_NO_RXDMA)
+#define ID_P_REP_AFTER_RD      BIT(29)
+#define ID_P_NO_RXDMA          BIT(30) /* HW forbids RXDMA sometimes */
+#define ID_P_PM_BLOCKED                BIT(31)
+#define ID_P_MASK              GENMASK(31, 29)
 
 enum rcar_i2c_type {
        I2C_RCAR_GEN1,
@@ -183,8 +177,6 @@ static void rcar_i2c_set_scl(struct i2c_adapter *adap, int val)
        rcar_i2c_write(priv, ICMCR, priv->recovery_icmcr);
 };
 
-/* No get_sda, because the HW only reports its bus free logic, not SDA itself */
-
 static void rcar_i2c_set_sda(struct i2c_adapter *adap, int val)
 {
        struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
@@ -197,10 +189,19 @@ static void rcar_i2c_set_sda(struct i2c_adapter *adap, int val)
        rcar_i2c_write(priv, ICMCR, priv->recovery_icmcr);
 };
 
+static int rcar_i2c_get_bus_free(struct i2c_adapter *adap)
+{
+       struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
+
+       return !(rcar_i2c_read(priv, ICMCR) & FSDA);
+
+};
+
 static struct i2c_bus_recovery_info rcar_i2c_bri = {
        .get_scl = rcar_i2c_get_scl,
        .set_scl = rcar_i2c_set_scl,
        .set_sda = rcar_i2c_set_sda,
+       .get_bus_free = rcar_i2c_get_bus_free,
        .recover_bus = i2c_generic_scl_recovery,
 };
 static void rcar_i2c_init(struct rcar_i2c_priv *priv)
@@ -215,7 +216,7 @@ static void rcar_i2c_init(struct rcar_i2c_priv *priv)
 
 static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv)
 {
-       int i, ret;
+       int i;
 
        for (i = 0; i < LOOP_TIMEOUT; i++) {
                /* make sure that bus is not busy */
@@ -226,13 +227,7 @@ static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv)
 
        /* Waiting did not help, try to recover */
        priv->recovery_icmcr = MDBS | OBPC | FSDA | FSCL;
-       ret = i2c_recover_bus(&priv->adap);
-
-       /* No failure when recovering, so check bus busy bit again */
-       if (ret == 0)
-               ret = (rcar_i2c_read(priv, ICMCR) & FSDA) ? -EBUSY : 0;
-
-       return ret;
+       return i2c_recover_bus(&priv->adap);
 }
 
 static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, struct i2c_timings *t)
@@ -343,7 +338,10 @@ static void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv)
                rcar_i2c_write(priv, ICMSR, 0);
                rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
        } else {
-               rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
+               if (priv->flags & ID_P_REP_AFTER_RD)
+                       priv->flags &= ~ID_P_REP_AFTER_RD;
+               else
+                       rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
                rcar_i2c_write(priv, ICMSR, 0);
        }
        rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND);
@@ -548,15 +546,15 @@ static void rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)
                priv->pos++;
        }
 
-       /*
-        * If next received data is the _LAST_, go to STOP phase. Might be
-        * overwritten by REP START when setting up a new msg. Not elegant
-        * but the only stable sequence for REP START I have found so far.
-        * If you want to change this code, make sure sending one transfer with
-        * four messages (WR-RD-WR-RD) works!
-        */
-       if (priv->pos + 1 >= msg->len)
-               rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
+       /* If next received data is the _LAST_, go to new phase. */
+       if (priv->pos + 1 == msg->len) {
+               if (priv->flags & ID_LAST_MSG) {
+                       rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
+               } else {
+                       rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
+                       priv->flags |= ID_P_REP_AFTER_RD;
+               }
+       }
 
        if (priv->pos == msg->len && !(priv->flags & ID_LAST_MSG))
                rcar_i2c_next_msg(priv);
@@ -624,9 +622,11 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
        struct rcar_i2c_priv *priv = ptr;
        u32 msr, val;
 
-       /* Clear START or STOP as soon as we can */
-       val = rcar_i2c_read(priv, ICMCR);
-       rcar_i2c_write(priv, ICMCR, val & RCAR_BUS_MASK_DATA);
+       /* Clear START or STOP immediately, except for REPSTART after read */
+       if (likely(!(priv->flags & ID_P_REP_AFTER_RD))) {
+               val = rcar_i2c_read(priv, ICMCR);
+               rcar_i2c_write(priv, ICMCR, val & RCAR_BUS_MASK_DATA);
+       }
 
        msr = rcar_i2c_read(priv, ICMSR);
 
@@ -795,14 +795,8 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
        if (ret < 0)
                goto out;
 
-       for (i = 0; i < num; i++) {
-               /* This HW can't send STOP after address phase */
-               if (msgs[i].len == 0) {
-                       ret = -EOPNOTSUPP;
-                       goto out;
-               }
+       for (i = 0; i < num; i++)
                rcar_i2c_request_dma(priv, msgs + i);
-       }
 
        /* init first message */
        priv->msg = msgs;
@@ -889,6 +883,10 @@ static const struct i2c_algorithm rcar_i2c_algo = {
        .unreg_slave    = rcar_unreg_slave,
 };
 
+static const struct i2c_adapter_quirks rcar_i2c_quirks = {
+       .flags = I2C_AQ_NO_ZERO_LEN,
+};
+
 static const struct of_device_id rcar_i2c_dt_ids[] = {
        { .compatible = "renesas,i2c-r8a7778", .data = (void *)I2C_RCAR_GEN1 },
        { .compatible = "renesas,i2c-r8a7779", .data = (void *)I2C_RCAR_GEN1 },
@@ -942,6 +940,7 @@ static int rcar_i2c_probe(struct platform_device *pdev)
        adap->dev.parent = dev;
        adap->dev.of_node = dev->of_node;
        adap->bus_recovery_info = &rcar_i2c_bri;
+       adap->quirks = &rcar_i2c_quirks;
        i2c_set_adapdata(adap, priv);
        strlcpy(adap->name, pdev->name, sizeof(adap->name));
 
index 5f1fca7880b1b28d0c2387b9f7dc414527c23e81..b75ff144b5704293e0946c4919e747d91ede0b85 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Renesas RIIC driver
  *
  * Copyright (C) 2013 Wolfram Sang <wsa@sang-engineering.com>
  * Copyright (C) 2013 Renesas Solutions Corp.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
  */
 
 /*
index 9fe2b6951895b6b27984eedeb82c8ec6c34604e7..2f2e28d60ef5246dcc870b5cf92b48d649350833 100644 (file)
@@ -919,9 +919,9 @@ static int s3c24xx_i2c_cpufreq_transition(struct notifier_block *nb,
 
        if ((val == CPUFREQ_POSTCHANGE && delta_f < 0) ||
            (val == CPUFREQ_PRECHANGE && delta_f > 0)) {
-               i2c_lock_adapter(&i2c->adap);
+               i2c_lock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER);
                ret = s3c24xx_i2c_clockrate(i2c, &got);
-               i2c_unlock_adapter(&i2c->adap);
+               i2c_unlock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER);
 
                if (ret < 0)
                        dev_err(i2c->dev, "cannot find frequency (%d)\n", ret);
index 5fda4188a9e51d6aa33613e0247e462913f7b2c4..818cab14e87c5ea47e5c6daaa7b76c818465df52 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * SuperH Mobile I2C Controller
  *
@@ -7,15 +8,6 @@
  *
  * Portions of the code based on out-of-tree driver i2c-sh7343.c
  * Copyright (c) 2006 Carlos Munoz <carlos@kenati.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
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/clk.h>
@@ -515,8 +507,6 @@ static void sh_mobile_i2c_dma_callback(void *data)
        pd->pos = pd->msg->len;
        pd->stop_after_dma = true;
 
-       i2c_release_dma_safe_msg_buf(pd->msg, pd->dma_buf);
-
        iic_set_clr(pd, ICIC, 0, ICIC_TDMAE | ICIC_RDMAE);
 }
 
@@ -610,14 +600,9 @@ static void sh_mobile_i2c_xfer_dma(struct sh_mobile_i2c_data *pd)
        dma_async_issue_pending(chan);
 }
 
-static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg,
-                   bool do_init)
+static void start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg,
+                    bool do_init)
 {
-       if (usr_msg->len == 0 && (usr_msg->flags & I2C_M_RD)) {
-               dev_err(pd->dev, "Unsupported zero length i2c read\n");
-               return -EOPNOTSUPP;
-       }
-
        if (do_init) {
                /* Initialize channel registers */
                iic_wr(pd, ICCR, ICCR_SCP);
@@ -640,7 +625,6 @@ static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg,
 
        /* Enable all interrupts to begin with */
        iic_wr(pd, ICIC, ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
-       return 0;
 }
 
 static int poll_dte(struct sh_mobile_i2c_data *pd)
@@ -711,9 +695,7 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
                pd->send_stop = i == num - 1 || msg->flags & I2C_M_STOP;
                pd->stop_after_dma = false;
 
-               err = start_ch(pd, msg, do_start);
-               if (err)
-                       break;
+               start_ch(pd, msg, do_start);
 
                if (do_start)
                        i2c_op(pd, OP_START, 0);
@@ -722,6 +704,10 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
                timeout = wait_event_timeout(pd->wait,
                                       pd->sr & (ICSR_TACK | SW_DONE),
                                       adapter->timeout);
+
+               /* 'stop_after_dma' tells if DMA transfer was complete */
+               i2c_put_dma_safe_msg_buf(pd->dma_buf, pd->msg, pd->stop_after_dma);
+
                if (!timeout) {
                        dev_err(pd->dev, "Transfer request timed out\n");
                        if (pd->dma_direction != DMA_NONE)
@@ -758,6 +744,10 @@ static const struct i2c_algorithm sh_mobile_i2c_algorithm = {
        .master_xfer    = sh_mobile_i2c_xfer,
 };
 
+static const struct i2c_adapter_quirks sh_mobile_i2c_quirks = {
+       .flags = I2C_AQ_NO_ZERO_LEN_READ,
+};
+
 /*
  * r8a7740 chip has lasting errata on I2C I/O pad reset.
  * this is work-around for it.
@@ -925,6 +915,7 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
 
        adap->owner = THIS_MODULE;
        adap->algo = &sh_mobile_i2c_algorithm;
+       adap->quirks = &sh_mobile_i2c_quirks;
        adap->dev.parent = &dev->dev;
        adap->retries = 5;
        adap->nr = dev->id;
index 4053259bccb8d704d9d386287086841690174844..a94e724f51dcf5787b808881486acb1e44b689b9 100644 (file)
@@ -590,9 +590,9 @@ static int __maybe_unused sprd_i2c_suspend_noirq(struct device *pdev)
 {
        struct sprd_i2c *i2c_dev = dev_get_drvdata(pdev);
 
-       i2c_lock_adapter(&i2c_dev->adap);
+       i2c_lock_bus(&i2c_dev->adap, I2C_LOCK_ROOT_ADAPTER);
        i2c_dev->is_suspended = true;
-       i2c_unlock_adapter(&i2c_dev->adap);
+       i2c_unlock_bus(&i2c_dev->adap, I2C_LOCK_ROOT_ADAPTER);
 
        return pm_runtime_force_suspend(pdev);
 }
@@ -601,9 +601,9 @@ static int __maybe_unused sprd_i2c_resume_noirq(struct device *pdev)
 {
        struct sprd_i2c *i2c_dev = dev_get_drvdata(pdev);
 
-       i2c_lock_adapter(&i2c_dev->adap);
+       i2c_lock_bus(&i2c_dev->adap, I2C_LOCK_ROOT_ADAPTER);
        i2c_dev->is_suspended = false;
-       i2c_unlock_adapter(&i2c_dev->adap);
+       i2c_unlock_bus(&i2c_dev->adap, I2C_LOCK_ROOT_ADAPTER);
 
        return pm_runtime_force_resume(pdev);
 }
index fce52bdab2b715a7123e34b153e2206662c67bf9..5503fa171df0dbd3ef73d0e63852d8931f4d47a3 100644 (file)
@@ -673,12 +673,6 @@ static int stu300_xfer_msg(struct i2c_adapter *adap,
                        msg->addr, msg->len, msg->flags, stop);
        }
 
-       /* Zero-length messages are not supported by this hardware */
-       if (msg->len == 0) {
-               ret = -EINVAL;
-               goto exit_disable;
-       }
-
        /*
         * For some reason, sending the address sometimes fails when running
         * on  the 13 MHz clock. No interrupt arrives. This is a work around,
@@ -863,6 +857,10 @@ static const struct i2c_algorithm stu300_algo = {
        .functionality  = stu300_func,
 };
 
+static const struct i2c_adapter_quirks stu300_quirks = {
+       .flags = I2C_AQ_NO_ZERO_LEN,
+};
+
 static int stu300_probe(struct platform_device *pdev)
 {
        struct stu300_dev *dev;
@@ -920,6 +918,8 @@ static int stu300_probe(struct platform_device *pdev)
        adap->algo = &stu300_algo;
        adap->dev.parent = &pdev->dev;
        adap->dev.of_node = pdev->dev.of_node;
+       adap->quirks = &stu300_quirks;
+
        i2c_set_adapdata(adap, dev);
 
        /* i2c device drivers may be active on return from add_adapter() */
index 797def5319f1325adacf1974c0b44cdb3a7ca4a6..60c8561fbe65e62d3bec217d8eb7157cd377609e 100644 (file)
 
 #define I2C_CONFIG_LOAD_TIMEOUT                        1000000
 
+#define I2C_MST_FIFO_CONTROL                   0x0b4
+#define I2C_MST_FIFO_CONTROL_RX_FLUSH          BIT(0)
+#define I2C_MST_FIFO_CONTROL_TX_FLUSH          BIT(1)
+#define I2C_MST_FIFO_CONTROL_RX_TRIG(x)                (((x) - 1) <<  4)
+#define I2C_MST_FIFO_CONTROL_TX_TRIG(x)                (((x) - 1) << 16)
+
+#define I2C_MST_FIFO_STATUS                    0x0b8
+#define I2C_MST_FIFO_STATUS_RX_MASK            0xff
+#define I2C_MST_FIFO_STATUS_RX_SHIFT           0
+#define I2C_MST_FIFO_STATUS_TX_MASK            0xff0000
+#define I2C_MST_FIFO_STATUS_TX_SHIFT           16
+
 /*
  * msg_end_type: The bus control which need to be send at end of transfer.
  * @MSG_END_STOP: Send stop pulse at end of transfer.
@@ -154,6 +166,7 @@ struct tegra_i2c_hw_feature {
        u16 clk_divisor_fast_plus_mode;
        bool has_multi_master_mode;
        bool has_slcg_override_reg;
+       bool has_mst_fifo;
 };
 
 /**
@@ -266,13 +279,24 @@ static void tegra_i2c_unmask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask)
 static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
 {
        unsigned long timeout = jiffies + HZ;
-       u32 val = i2c_readl(i2c_dev, I2C_FIFO_CONTROL);
+       unsigned int offset;
+       u32 mask, val;
+
+       if (i2c_dev->hw->has_mst_fifo) {
+               mask = I2C_MST_FIFO_CONTROL_TX_FLUSH |
+                      I2C_MST_FIFO_CONTROL_RX_FLUSH;
+               offset = I2C_MST_FIFO_CONTROL;
+       } else {
+               mask = I2C_FIFO_CONTROL_TX_FLUSH |
+                      I2C_FIFO_CONTROL_RX_FLUSH;
+               offset = I2C_FIFO_CONTROL;
+       }
 
-       val |= I2C_FIFO_CONTROL_TX_FLUSH | I2C_FIFO_CONTROL_RX_FLUSH;
-       i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL);
+       val = i2c_readl(i2c_dev, offset);
+       val |= mask;
+       i2c_writel(i2c_dev, val, offset);
 
-       while (i2c_readl(i2c_dev, I2C_FIFO_CONTROL) &
-               (I2C_FIFO_CONTROL_TX_FLUSH | I2C_FIFO_CONTROL_RX_FLUSH)) {
+       while (i2c_readl(i2c_dev, offset) & mask) {
                if (time_after(jiffies, timeout)) {
                        dev_warn(i2c_dev->dev, "timeout waiting for fifo flush\n");
                        return -ETIMEDOUT;
@@ -290,9 +314,15 @@ static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
        size_t buf_remaining = i2c_dev->msg_buf_remaining;
        int words_to_transfer;
 
-       val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);
-       rx_fifo_avail = (val & I2C_FIFO_STATUS_RX_MASK) >>
-               I2C_FIFO_STATUS_RX_SHIFT;
+       if (i2c_dev->hw->has_mst_fifo) {
+               val = i2c_readl(i2c_dev, I2C_MST_FIFO_STATUS);
+               rx_fifo_avail = (val & I2C_MST_FIFO_STATUS_RX_MASK) >>
+                       I2C_MST_FIFO_STATUS_RX_SHIFT;
+       } else {
+               val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);
+               rx_fifo_avail = (val & I2C_FIFO_STATUS_RX_MASK) >>
+                       I2C_FIFO_STATUS_RX_SHIFT;
+       }
 
        /* Rounds down to not include partial word at the end of buf */
        words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;
@@ -321,6 +351,7 @@ static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
        BUG_ON(rx_fifo_avail > 0 && buf_remaining > 0);
        i2c_dev->msg_buf_remaining = buf_remaining;
        i2c_dev->msg_buf = buf;
+
        return 0;
 }
 
@@ -332,9 +363,15 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
        size_t buf_remaining = i2c_dev->msg_buf_remaining;
        int words_to_transfer;
 
-       val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);
-       tx_fifo_avail = (val & I2C_FIFO_STATUS_TX_MASK) >>
-               I2C_FIFO_STATUS_TX_SHIFT;
+       if (i2c_dev->hw->has_mst_fifo) {
+               val = i2c_readl(i2c_dev, I2C_MST_FIFO_STATUS);
+               tx_fifo_avail = (val & I2C_MST_FIFO_STATUS_TX_MASK) >>
+                       I2C_MST_FIFO_STATUS_TX_SHIFT;
+       } else {
+               val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);
+               tx_fifo_avail = (val & I2C_FIFO_STATUS_TX_MASK) >>
+                       I2C_FIFO_STATUS_TX_SHIFT;
+       }
 
        /* Rounds down to not include partial word at the end of buf */
        words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;
@@ -516,9 +553,15 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
                i2c_writel(i2c_dev, 0x00, I2C_SL_ADDR2);
        }
 
-       val = 7 << I2C_FIFO_CONTROL_TX_TRIG_SHIFT |
-               0 << I2C_FIFO_CONTROL_RX_TRIG_SHIFT;
-       i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL);
+       if (i2c_dev->hw->has_mst_fifo) {
+               val = I2C_MST_FIFO_CONTROL_TX_TRIG(8) |
+                     I2C_MST_FIFO_CONTROL_RX_TRIG(1);
+               i2c_writel(i2c_dev, val, I2C_MST_FIFO_CONTROL);
+       } else {
+               val = 7 << I2C_FIFO_CONTROL_TX_TRIG_SHIFT |
+                       0 << I2C_FIFO_CONTROL_RX_TRIG_SHIFT;
+               i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL);
+       }
 
        err = tegra_i2c_flush_fifos(i2c_dev);
        if (err)
@@ -802,6 +845,7 @@ static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
        .has_config_load_reg = false,
        .has_multi_master_mode = false,
        .has_slcg_override_reg = false,
+       .has_mst_fifo = false,
 };
 
 static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
@@ -814,6 +858,7 @@ static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
        .has_config_load_reg = false,
        .has_multi_master_mode = false,
        .has_slcg_override_reg = false,
+       .has_mst_fifo = false,
 };
 
 static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
@@ -826,6 +871,7 @@ static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
        .has_config_load_reg = false,
        .has_multi_master_mode = false,
        .has_slcg_override_reg = false,
+       .has_mst_fifo = false,
 };
 
 static const struct tegra_i2c_hw_feature tegra124_i2c_hw = {
@@ -838,6 +884,7 @@ static const struct tegra_i2c_hw_feature tegra124_i2c_hw = {
        .has_config_load_reg = true,
        .has_multi_master_mode = false,
        .has_slcg_override_reg = true,
+       .has_mst_fifo = false,
 };
 
 static const struct tegra_i2c_hw_feature tegra210_i2c_hw = {
@@ -850,10 +897,25 @@ static const struct tegra_i2c_hw_feature tegra210_i2c_hw = {
        .has_config_load_reg = true,
        .has_multi_master_mode = true,
        .has_slcg_override_reg = true,
+       .has_mst_fifo = false,
+};
+
+static const struct tegra_i2c_hw_feature tegra194_i2c_hw = {
+       .has_continue_xfer_support = true,
+       .has_per_pkt_xfer_complete_irq = true,
+       .has_single_clk_source = true,
+       .clk_divisor_hs_mode = 1,
+       .clk_divisor_std_fast_mode = 0x19,
+       .clk_divisor_fast_plus_mode = 0x10,
+       .has_config_load_reg = true,
+       .has_multi_master_mode = true,
+       .has_slcg_override_reg = true,
+       .has_mst_fifo = true,
 };
 
 /* Match table for of_platform binding */
 static const struct of_device_id tegra_i2c_of_match[] = {
+       { .compatible = "nvidia,tegra194-i2c", .data = &tegra194_i2c_hw, },
        { .compatible = "nvidia,tegra210-i2c", .data = &tegra210_i2c_hw, },
        { .compatible = "nvidia,tegra124-i2c", .data = &tegra124_i2c_hw, },
        { .compatible = "nvidia,tegra114-i2c", .data = &tegra114_i2c_hw, },
index 9918bdd816196281ae6c64d364d34ecaf89a65ef..a403e8579b652b6e2486f746b91b9357c3ab7381 100644 (file)
@@ -401,11 +401,8 @@ static int uniphier_fi2c_master_xfer(struct i2c_adapter *adap,
                return ret;
 
        for (msg = msgs; msg < emsg; msg++) {
-               /* If next message is read, skip the stop condition */
-               bool stop = !(msg + 1 < emsg && msg[1].flags & I2C_M_RD);
-               /* but, force it if I2C_M_STOP is set */
-               if (msg->flags & I2C_M_STOP)
-                       stop = true;
+               /* Emit STOP if it is the last message or I2C_M_STOP is set. */
+               bool stop = (msg + 1 == emsg) || (msg->flags & I2C_M_STOP);
 
                ret = uniphier_fi2c_master_xfer_one(adap, msg, stop);
                if (ret)
index bb181b0882919acef145d27ec236b705b8f2e7f0..454f914ae66dbd49931575122bb7c7dea662b11b 100644 (file)
@@ -248,11 +248,8 @@ static int uniphier_i2c_master_xfer(struct i2c_adapter *adap,
                return ret;
 
        for (msg = msgs; msg < emsg; msg++) {
-               /* If next message is read, skip the stop condition */
-               bool stop = !(msg + 1 < emsg && msg[1].flags & I2C_M_RD);
-               /* but, force it if I2C_M_STOP is set */
-               if (msg->flags & I2C_M_STOP)
-                       stop = true;
+               /* Emit STOP if it is the last message or I2C_M_STOP is set. */
+               bool stop = (msg + 1 == emsg) || (msg->flags & I2C_M_STOP);
 
                ret = uniphier_i2c_master_xfer_one(adap, msg, stop);
                if (ret)
index 9a71e50d21f1fbae53ebdb2b1831e7f6067a67b9..0c51c0ffdda9d99d03f28c5503ef1cffaa5316c2 100644 (file)
@@ -532,6 +532,7 @@ static void xiic_start_recv(struct xiic_i2c *i2c)
 {
        u8 rx_watermark;
        struct i2c_msg *msg = i2c->rx_msg = i2c->tx_msg;
+       unsigned long flags;
 
        /* Clear and enable Rx full interrupt. */
        xiic_irq_clr_en(i2c, XIIC_INTR_RX_FULL_MASK | XIIC_INTR_TX_ERROR_MASK);
@@ -547,6 +548,7 @@ static void xiic_start_recv(struct xiic_i2c *i2c)
                rx_watermark = IIC_RX_FIFO_DEPTH;
        xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, rx_watermark - 1);
 
+       local_irq_save(flags);
        if (!(msg->flags & I2C_M_NOSTART))
                /* write the address */
                xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET,
@@ -556,6 +558,8 @@ static void xiic_start_recv(struct xiic_i2c *i2c)
 
        xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET,
                msg->len | ((i2c->nmsgs == 1) ? XIIC_TX_DYN_STOP_MASK : 0));
+       local_irq_restore(flags);
+
        if (i2c->nmsgs == 1)
                /* very last, enable bus not busy as well */
                xiic_irq_clr_en(i2c, XIIC_INTR_BNB_MASK);
index 484bfa15d58ee445aee64097c36f7f271463f0c8..34cd4b3085402a4d2cdfdc7e2a5fa8a1e847763b 100644 (file)
@@ -173,9 +173,6 @@ static int xlr_i2c_tx(struct xlr_i2c_private *priv,  u16 len,
        u8 offset;
        u32 xfer;
 
-       if (!len)
-               return -EOPNOTSUPP;
-
        offset = buf[0];
        xlr_i2c_wreg(priv->iobase, XLR_I2C_ADDR, offset);
        xlr_i2c_wreg(priv->iobase, XLR_I2C_DEVADDR, addr);
@@ -241,9 +238,6 @@ static int xlr_i2c_rx(struct xlr_i2c_private *priv, u16 len, u8 *buf, u16 addr)
        unsigned long timeout, stoptime, checktime;
        int nbytes, timedout;
 
-       if (!len)
-               return -EOPNOTSUPP;
-
        xlr_i2c_wreg(priv->iobase, XLR_I2C_CFG,
                        XLR_I2C_CFG_NOADDR | priv->cfg->cfg_extra);
        xlr_i2c_wreg(priv->iobase, XLR_I2C_BYTECNT, len - 1);
@@ -340,6 +334,10 @@ static const struct i2c_algorithm xlr_i2c_algo = {
        .functionality  = xlr_func,
 };
 
+static const struct i2c_adapter_quirks xlr_i2c_quirks = {
+       .flags = I2C_AQ_NO_ZERO_LEN,
+};
+
 static const struct xlr_i2c_config xlr_i2c_config_default = {
        .status_busy    = XLR_I2C_BUS_BUSY,
        .cfg_extra      = 0,
@@ -427,6 +425,7 @@ static int xlr_i2c_probe(struct platform_device *pdev)
        priv->adap.owner        = THIS_MODULE;
        priv->adap.algo_data    = priv;
        priv->adap.algo         = &xlr_i2c_algo;
+       priv->adap.quirks       = &xlr_i2c_quirks;
        priv->adap.nr           = pdev->id;
        priv->adap.class        = I2C_CLASS_HWMON;
        snprintf(priv->adap.name, sizeof(priv->adap.name), "xlr-i2c");
index 7c3b4740b94b644509ae3658fa2eda4885086bba..32affd3fa8bd1ffe462c5f66abd6b9e40ba6a36f 100644 (file)
@@ -453,8 +453,12 @@ static int acpi_gsb_i2c_read_bytes(struct i2c_client *client,
                else
                        dev_err(&client->adapter->dev, "i2c read %d bytes from client@%#x starting at reg %#x failed, error: %d\n",
                                data_len, client->addr, cmd, ret);
-       } else {
+       /* 2 transfers must have completed successfully */
+       } else if (ret == 2) {
                memcpy(data, buffer, data_len);
+               ret = 0;
+       } else {
+               ret = -EIO;
        }
 
        kfree(buffer);
@@ -482,11 +486,16 @@ static int acpi_gsb_i2c_write_bytes(struct i2c_client *client,
        msgs[0].buf = buffer;
 
        ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
-       if (ret < 0)
-               dev_err(&client->adapter->dev, "i2c write failed\n");
 
        kfree(buffer);
-       return ret;
+
+       if (ret < 0) {
+               dev_err(&client->adapter->dev, "i2c write failed: %d\n", ret);
+               return ret;
+       }
+
+       /* 1 transfer must have completed successfully */
+       return (ret == 1) ? 0 : -EIO;
 }
 
 static acpi_status
@@ -590,8 +599,6 @@ i2c_acpi_space_handler(u32 function, acpi_physical_address command,
                if (action == ACPI_READ) {
                        status = acpi_gsb_i2c_read_bytes(client, command,
                                        gsb->data, info->access_length);
-                       if (status > 0)
-                               status = 0;
                } else {
                        status = acpi_gsb_i2c_write_bytes(client, command,
                                        gsb->data, info->access_length);
index 15c95aaa484cfdd845111e27a69944939edeafe1..9ee9a15e71347629d024709a17b9a6bb04fca8aa 100644 (file)
@@ -62,7 +62,7 @@
 
 /*
  * core_lock protects i2c_adapter_idr, and guarantees that device detection,
- * deletion of detected devices, and attach_adapter calls are serialized
+ * deletion of detected devices are serialized
  */
 static DEFINE_MUTEX(core_lock);
 static DEFINE_IDR(i2c_adapter_idr);
@@ -158,6 +158,22 @@ static void set_sda_gpio_value(struct i2c_adapter *adap, int val)
        gpiod_set_value_cansleep(adap->bus_recovery_info->sda_gpiod, val);
 }
 
+static int i2c_generic_bus_free(struct i2c_adapter *adap)
+{
+       struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
+       int ret = -EOPNOTSUPP;
+
+       if (bri->get_bus_free)
+               ret = bri->get_bus_free(adap);
+       else if (bri->get_sda)
+               ret = bri->get_sda(adap);
+
+       if (ret < 0)
+               return ret;
+
+       return ret ? 0 : -EBUSY;
+}
+
 /*
  * We are generating clock pulses. ndelay() determines durating of clk pulses.
  * We will generate clock with rate 100 KHz and so duration of both clock levels
@@ -169,21 +185,28 @@ static void set_sda_gpio_value(struct i2c_adapter *adap, int val)
 int i2c_generic_scl_recovery(struct i2c_adapter *adap)
 {
        struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
-       int i = 0, val = 1, ret = 0;
+       int i = 0, scl = 1, ret;
 
        if (bri->prepare_recovery)
                bri->prepare_recovery(adap);
 
-       bri->set_scl(adap, val);
+       /*
+        * If we can set SDA, we will always create a STOP to ensure additional
+        * pulses will do no harm. This is achieved by letting SDA follow SCL
+        * half a cycle later. Check the 'incomplete_write_byte' fault injector
+        * for details.
+        */
+       bri->set_scl(adap, scl);
+       ndelay(RECOVERY_NDELAY / 2);
        if (bri->set_sda)
-               bri->set_sda(adap, 1);
-       ndelay(RECOVERY_NDELAY);
+               bri->set_sda(adap, scl);
+       ndelay(RECOVERY_NDELAY / 2);
 
        /*
         * By this time SCL is high, as we need to give 9 falling-rising edges
         */
        while (i++ < RECOVERY_CLK_CNT * 2) {
-               if (val) {
+               if (scl) {
                        /* SCL shouldn't be low here */
                        if (!bri->get_scl(adap)) {
                                dev_err(&adap->dev,
@@ -191,41 +214,27 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap)
                                ret = -EBUSY;
                                break;
                        }
-                       /* Break if SDA is high */
-                       if (bri->get_sda && bri->get_sda(adap))
-                               break;
                }
 
-               val = !val;
-               bri->set_scl(adap, val);
-
-               /*
-                * If we can set SDA, we will always create STOP here to ensure
-                * the additional pulses will do no harm. This is achieved by
-                * letting SDA follow SCL half a cycle later.
-                */
+               scl = !scl;
+               bri->set_scl(adap, scl);
+               /* Creating STOP again, see above */
                ndelay(RECOVERY_NDELAY / 2);
                if (bri->set_sda)
-                       bri->set_sda(adap, val);
+                       bri->set_sda(adap, scl);
                ndelay(RECOVERY_NDELAY / 2);
-       }
-
-       /* check if recovery actually succeeded */
-       if (bri->get_sda && !bri->get_sda(adap))
-               ret = -EBUSY;
 
-       /* If all went well, send STOP for a sane bus state. */
-       if (ret == 0 && bri->set_sda) {
-               bri->set_scl(adap, 0);
-               ndelay(RECOVERY_NDELAY / 2);
-               bri->set_sda(adap, 0);
-               ndelay(RECOVERY_NDELAY / 2);
-               bri->set_scl(adap, 1);
-               ndelay(RECOVERY_NDELAY / 2);
-               bri->set_sda(adap, 1);
-               ndelay(RECOVERY_NDELAY / 2);
+               if (scl) {
+                       ret = i2c_generic_bus_free(adap);
+                       if (ret == 0)
+                               break;
+               }
        }
 
+       /* If we can't check bus status, assume recovery worked */
+       if (ret == -EOPNOTSUPP)
+               ret = 0;
+
        if (bri->unprepare_recovery)
                bri->unprepare_recovery(adap);
 
@@ -274,6 +283,10 @@ static void i2c_init_recovery(struct i2c_adapter *adap)
                        err_str = "no {get|set}_scl() found";
                        goto err;
                }
+               if (!bri->set_sda && !bri->get_sda) {
+                       err_str = "either get_sda() or set_sda() needed";
+                       goto err;
+               }
        }
 
        return;
@@ -1111,15 +1124,6 @@ static int i2c_do_add_adapter(struct i2c_driver *driver,
        /* Detect supported devices on that bus, and instantiate them */
        i2c_detect(adap, driver);
 
-       /* Let legacy drivers scan this bus for matching devices */
-       if (driver->attach_adapter) {
-               dev_warn(&adap->dev, "%s: attach_adapter method is deprecated\n",
-                        driver->driver.name);
-               dev_warn(&adap->dev,
-                        "Please use another way to instantiate your i2c_client\n");
-               /* We ignore the return code; if it fails, too bad */
-               driver->attach_adapter(adap);
-       }
        return 0;
 }
 
@@ -1563,6 +1567,8 @@ void i2c_parse_fw_timings(struct device *dev, struct i2c_timings *t, bool use_de
        ret = device_property_read_u32(dev, "i2c-sda-falling-time-ns", &t->sda_fall_ns);
        if (ret && use_defaults)
                t->sda_fall_ns = t->scl_fall_ns;
+
+       device_property_read_u32(dev, "i2c-sda-hold-time-ns", &t->sda_hold_ns);
 }
 EXPORT_SYMBOL_GPL(i2c_parse_fw_timings);
 
@@ -1826,9 +1832,15 @@ static int i2c_check_for_quirks(struct i2c_adapter *adap, struct i2c_msg *msgs,
                if (msgs[i].flags & I2C_M_RD) {
                        if (do_len_check && i2c_quirk_exceeded(len, q->max_read_len))
                                return i2c_quirk_error(adap, &msgs[i], "msg too long");
+
+                       if (q->flags & I2C_AQ_NO_ZERO_LEN_READ && len == 0)
+                               return i2c_quirk_error(adap, &msgs[i], "no zero length");
                } else {
                        if (do_len_check && i2c_quirk_exceeded(len, q->max_write_len))
                                return i2c_quirk_error(adap, &msgs[i], "msg too long");
+
+                       if (q->flags & I2C_AQ_NO_ZERO_LEN_WRITE && len == 0)
+                               return i2c_quirk_error(adap, &msgs[i], "no zero length");
                }
        }
 
@@ -2281,21 +2293,22 @@ u8 *i2c_get_dma_safe_msg_buf(struct i2c_msg *msg, unsigned int threshold)
 EXPORT_SYMBOL_GPL(i2c_get_dma_safe_msg_buf);
 
 /**
- * i2c_release_dma_safe_msg_buf - release DMA safe buffer and sync with i2c_msg
- * @msg: the message to be synced with
+ * i2c_put_dma_safe_msg_buf - release DMA safe buffer and sync with i2c_msg
  * @buf: the buffer obtained from i2c_get_dma_safe_msg_buf(). May be NULL.
+ * @msg: the message which the buffer corresponds to
+ * @xferred: bool saying if the message was transferred
  */
-void i2c_release_dma_safe_msg_buf(struct i2c_msg *msg, u8 *buf)
+void i2c_put_dma_safe_msg_buf(u8 *buf, struct i2c_msg *msg, bool xferred)
 {
        if (!buf || buf == msg->buf)
                return;
 
-       if (msg->flags & I2C_M_RD)
+       if (xferred && msg->flags & I2C_M_RD)
                memcpy(msg->buf, buf, msg->len);
 
        kfree(buf);
 }
-EXPORT_SYMBOL_GPL(i2c_release_dma_safe_msg_buf);
+EXPORT_SYMBOL_GPL(i2c_put_dma_safe_msg_buf);
 
 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
 MODULE_DESCRIPTION("I2C-Bus main module");
index 4a78c65e997133f512dd2722cb49fa1e8b7ca5cb..47a9f70a24a972810b431a997eba934d5a6b520f 100644 (file)
@@ -47,9 +47,9 @@ int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb)
 
        client->slave_cb = slave_cb;
 
-       i2c_lock_adapter(client->adapter);
+       i2c_lock_bus(client->adapter, I2C_LOCK_ROOT_ADAPTER);
        ret = client->adapter->algo->reg_slave(client);
-       i2c_unlock_adapter(client->adapter);
+       i2c_unlock_bus(client->adapter, I2C_LOCK_ROOT_ADAPTER);
 
        if (ret) {
                client->slave_cb = NULL;
@@ -69,9 +69,9 @@ int i2c_slave_unregister(struct i2c_client *client)
                return -EOPNOTSUPP;
        }
 
-       i2c_lock_adapter(client->adapter);
+       i2c_lock_bus(client->adapter, I2C_LOCK_ROOT_ADAPTER);
        ret = client->adapter->algo->unreg_slave(client);
-       i2c_unlock_adapter(client->adapter);
+       i2c_unlock_bus(client->adapter, I2C_LOCK_ROOT_ADAPTER);
 
        if (ret == 0)
                client->slave_cb = NULL;
index 29646aa6132e997a46f73cad48d195eb58a7b9e4..f330690b41253ff75e352b321575cc008fcf0353 100644 (file)
@@ -87,8 +87,8 @@ static int __i2c_mux_smbus_xfer(struct i2c_adapter *adap,
 
        ret = muxc->select(muxc, priv->chan_id);
        if (ret >= 0)
-               ret = parent->algo->smbus_xfer(parent, addr, flags,
-                                       read_write, command, size, data);
+               ret = __i2c_smbus_xfer(parent, addr, flags,
+                                      read_write, command, size, data);
        if (muxc->deselect)
                muxc->deselect(muxc, priv->chan_id);
 
index 12ad8d65faf64283e5c08031d35caa99238a7f89..f2bf3e57ed67b15d0897ade8c250b92ddace812b 100644 (file)
@@ -94,31 +94,11 @@ static int mlxcpld_mux_reg_write(struct i2c_adapter *adap,
                                 struct i2c_client *client, u8 val)
 {
        struct mlxcpld_mux_plat_data *pdata = dev_get_platdata(&client->dev);
-       int ret = -ENODEV;
-
-       if (adap->algo->master_xfer) {
-               struct i2c_msg msg;
-               u8 msgbuf[] = {pdata->sel_reg_addr, val};
-
-               msg.addr = client->addr;
-               msg.flags = 0;
-               msg.len = 2;
-               msg.buf = msgbuf;
-               ret = __i2c_transfer(adap, &msg, 1);
-
-               if (ret >= 0 && ret != 1)
-                       ret = -EREMOTEIO;
-       } else if (adap->algo->smbus_xfer) {
-               union i2c_smbus_data data;
-
-               data.byte = val;
-               ret = adap->algo->smbus_xfer(adap, client->addr,
-                                            client->flags, I2C_SMBUS_WRITE,
-                                            pdata->sel_reg_addr,
-                                            I2C_SMBUS_BYTE_DATA, &data);
-       }
+       union i2c_smbus_data data = { .byte = val };
 
-       return ret;
+       return __i2c_smbus_xfer(adap, client->addr, client->flags,
+                               I2C_SMBUS_WRITE, pdata->sel_reg_addr,
+                               I2C_SMBUS_BYTE_DATA, &data);
 }
 
 static int mlxcpld_mux_select_chan(struct i2c_mux_core *muxc, u32 chan)
index 6a39adaf433f4ab4979ebd1e7b875cbbf0bbb846..9e75d6b9140b53a929accf512200d942796ff55a 100644 (file)
@@ -99,31 +99,11 @@ MODULE_DEVICE_TABLE(of, pca9541_of_match);
 static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val)
 {
        struct i2c_adapter *adap = client->adapter;
-       int ret;
-
-       if (adap->algo->master_xfer) {
-               struct i2c_msg msg;
-               char buf[2];
-
-               msg.addr = client->addr;
-               msg.flags = 0;
-               msg.len = 2;
-               buf[0] = command;
-               buf[1] = val;
-               msg.buf = buf;
-               ret = __i2c_transfer(adap, &msg, 1);
-       } else {
-               union i2c_smbus_data data;
-
-               data.byte = val;
-               ret = adap->algo->smbus_xfer(adap, client->addr,
-                                            client->flags,
-                                            I2C_SMBUS_WRITE,
-                                            command,
-                                            I2C_SMBUS_BYTE_DATA, &data);
-       }
+       union i2c_smbus_data data = { .byte = val };
 
-       return ret;
+       return __i2c_smbus_xfer(adap, client->addr, client->flags,
+                               I2C_SMBUS_WRITE, command,
+                               I2C_SMBUS_BYTE_DATA, &data);
 }
 
 /*
@@ -133,41 +113,14 @@ static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val)
 static int pca9541_reg_read(struct i2c_client *client, u8 command)
 {
        struct i2c_adapter *adap = client->adapter;
+       union i2c_smbus_data data;
        int ret;
-       u8 val;
-
-       if (adap->algo->master_xfer) {
-               struct i2c_msg msg[2] = {
-                       {
-                               .addr = client->addr,
-                               .flags = 0,
-                               .len = 1,
-                               .buf = &command
-                       },
-                       {
-                               .addr = client->addr,
-                               .flags = I2C_M_RD,
-                               .len = 1,
-                               .buf = &val
-                       }
-               };
-               ret = __i2c_transfer(adap, msg, 2);
-               if (ret == 2)
-                       ret = val;
-               else if (ret >= 0)
-                       ret = -EIO;
-       } else {
-               union i2c_smbus_data data;
-
-               ret = adap->algo->smbus_xfer(adap, client->addr,
-                                            client->flags,
-                                            I2C_SMBUS_READ,
-                                            command,
-                                            I2C_SMBUS_BYTE_DATA, &data);
-               if (!ret)
-                       ret = data.byte;
-       }
-       return ret;
+
+       ret = __i2c_smbus_xfer(adap, client->addr, client->flags,
+                              I2C_SMBUS_READ, command,
+                              I2C_SMBUS_BYTE_DATA, &data);
+
+       return ret ?: data.byte;
 }
 
 /*
@@ -345,11 +298,11 @@ static int pca9541_probe(struct i2c_client *client,
 
        /*
         * I2C accesses are unprotected here.
-        * We have to lock the adapter before releasing the bus.
+        * We have to lock the I2C segment before releasing the bus.
         */
-       i2c_lock_adapter(adap);
+       i2c_lock_bus(adap, I2C_LOCK_SEGMENT);
        pca9541_release_bus(client);
-       i2c_unlock_adapter(adap);
+       i2c_unlock_bus(adap, I2C_LOCK_SEGMENT);
 
        /* Create mux adapter */
 
index fbc748027087dbfd9783a459ccc74a7834d1a480..24bd9275fde5fc8775407c56b80825aa1d4c1aaf 100644 (file)
@@ -220,30 +220,11 @@ MODULE_DEVICE_TABLE(of, pca954x_of_match);
 static int pca954x_reg_write(struct i2c_adapter *adap,
                             struct i2c_client *client, u8 val)
 {
-       int ret = -ENODEV;
-
-       if (adap->algo->master_xfer) {
-               struct i2c_msg msg;
-               char buf[1];
-
-               msg.addr = client->addr;
-               msg.flags = 0;
-               msg.len = 1;
-               buf[0] = val;
-               msg.buf = buf;
-               ret = __i2c_transfer(adap, &msg, 1);
-
-               if (ret >= 0 && ret != 1)
-                       ret = -EREMOTEIO;
-       } else {
-               union i2c_smbus_data data;
-               ret = adap->algo->smbus_xfer(adap, client->addr,
-                                            client->flags,
-                                            I2C_SMBUS_WRITE,
-                                            val, I2C_SMBUS_BYTE, &data);
-       }
+       union i2c_smbus_data dummy;
 
-       return ret;
+       return __i2c_smbus_xfer(adap, client->addr, client->flags,
+                               I2C_SMBUS_WRITE, val,
+                               I2C_SMBUS_BYTE, &dummy);
 }
 
 static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan)
@@ -368,7 +349,8 @@ static int pca954x_probe(struct i2c_client *client,
 {
        struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
        struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
-       struct device_node *of_node = client->dev.of_node;
+       struct device *dev = &client->dev;
+       struct device_node *np = dev->of_node;
        bool idle_disconnect_dt;
        struct gpio_desc *gpio;
        int num, force, class;
@@ -379,8 +361,7 @@ static int pca954x_probe(struct i2c_client *client,
        if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
                return -ENODEV;
 
-       muxc = i2c_mux_alloc(adap, &client->dev,
-                            PCA954X_MAX_NCHANS, sizeof(*data), 0,
+       muxc = i2c_mux_alloc(adap, dev, PCA954X_MAX_NCHANS, sizeof(*data), 0,
                             pca954x_select_chan, pca954x_deselect_mux);
        if (!muxc)
                return -ENOMEM;
@@ -390,7 +371,7 @@ static int pca954x_probe(struct i2c_client *client,
        data->client = client;
 
        /* Reset the mux if a reset GPIO is specified. */
-       gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH);
+       gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
        if (IS_ERR(gpio))
                return PTR_ERR(gpio);
        if (gpio) {
@@ -400,7 +381,7 @@ static int pca954x_probe(struct i2c_client *client,
                udelay(1);
        }
 
-       data->chip = of_device_get_match_data(&client->dev);
+       data->chip = of_device_get_match_data(dev);
        if (!data->chip)
                data->chip = &chips[id->driver_data];
 
@@ -414,8 +395,7 @@ static int pca954x_probe(struct i2c_client *client,
                if (!ret &&
                    (id.manufacturer_id != data->chip->id.manufacturer_id ||
                     id.part_id != data->chip->id.part_id)) {
-                       dev_warn(&client->dev,
-                                "unexpected device id %03x-%03x-%x\n",
+                       dev_warn(dev, "unexpected device id %03x-%03x-%x\n",
                                 id.manufacturer_id, id.part_id,
                                 id.die_revision);
                        return -ENODEV;
@@ -427,14 +407,14 @@ static int pca954x_probe(struct i2c_client *client,
         * initializes the mux to disconnected state.
         */
        if (i2c_smbus_write_byte(client, 0) < 0) {
-               dev_warn(&client->dev, "probe failed\n");
+               dev_warn(dev, "probe failed\n");
                return -ENODEV;
        }
 
        data->last_chan = 0;               /* force the first selection */
 
-       idle_disconnect_dt = of_node &&
-               of_property_read_bool(of_node, "i2c-mux-idle-disconnect");
+       idle_disconnect_dt = np &&
+               of_property_read_bool(np, "i2c-mux-idle-disconnect");
 
        ret = pca954x_irq_setup(muxc);
        if (ret)
@@ -465,7 +445,7 @@ static int pca954x_probe(struct i2c_client *client,
        }
 
        if (data->irq) {
-               ret = devm_request_threaded_irq(&client->dev, data->client->irq,
+               ret = devm_request_threaded_irq(dev, data->client->irq,
                                                NULL, pca954x_irq_handler,
                                                IRQF_ONESHOT | IRQF_SHARED,
                                                "pca954x", data);
@@ -473,8 +453,7 @@ static int pca954x_probe(struct i2c_client *client,
                        goto fail_cleanup;
        }
 
-       dev_info(&client->dev,
-                "registered %d multiplexed busses for I2C %s %s\n",
+       dev_info(dev, "registered %d multiplexed busses for I2C %s %s\n",
                 num, data->chip->muxtype == pca954x_ismux
                                ? "mux" : "switch", client->name);
 
index e52c58c29d9a71fc43818bdef99de45c194e8764..4d565b0c5a6e6a9cf7a280e7b3ccf28f7bd542a3 100644 (file)
@@ -574,13 +574,14 @@ static u8 hpt3xx_udma_filter(ide_drive_t *drive)
                if (!HPT370_ALLOW_ATA100_5 ||
                    check_in_drive_list(drive, bad_ata100_5))
                        return ATA_UDMA4;
+               /* else: fall through */
        case HPT372 :
        case HPT372A:
        case HPT372N:
        case HPT374 :
                if (ata_id_is_sata(drive->id))
                        mask &= ~0x0e;
-               /* Fall thru */
+               /* fall through */
        default:
                return mask;
        }
@@ -600,7 +601,7 @@ static u8 hpt3xx_mdma_filter(ide_drive_t *drive)
        case HPT374 :
                if (ata_id_is_sata(drive->id))
                        return 0x00;
-               /* Fall thru */
+               /* else: fall through */
        default:
                return 0x07;
        }
index 5bd2aafc375346fdae583545b7779d6a8bbe5923..a8df300f949c2859b9c708d5848795e5cd6d3415 100644 (file)
@@ -427,6 +427,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
                                 * (maintains previous driver behaviour)
                                 */
                                break;
+                       /* else: fall through */
                case CAPACITY_CURRENT:
                        /* Normal Zip/LS-120 disks */
                        if (memcmp(cap_desc, &floppy->cap_desc, 8))
index a444bad7a2aa50fdd9d8248ace46c64935b84015..0d93e0cfbeaf91ad0592589dcdf2141abdbc951e 100644 (file)
@@ -460,7 +460,6 @@ void do_ide_request(struct request_queue *q)
        struct ide_host *host = hwif->host;
        struct request  *rq = NULL;
        ide_startstop_t startstop;
-       unsigned long queue_run_ms = 3; /* old plug delay */
 
        spin_unlock_irq(q->queue_lock);
 
@@ -480,9 +479,6 @@ repeat:
                prev_port = hwif->host->cur_port;
                if (drive->dev_flags & IDE_DFLAG_SLEEPING &&
                    time_after(drive->sleep, jiffies)) {
-                       unsigned long left = jiffies - drive->sleep;
-
-                       queue_run_ms = jiffies_to_msecs(left + 1);
                        ide_unlock_port(hwif);
                        goto plug_device;
                }
index 416a2f3530711aa556acec93eba46df0ead97a2b..3b75a7b7a28408a84545d610c5bbdaafd223b59d 100644 (file)
@@ -142,6 +142,7 @@ static void ide_classify_atapi_dev(ide_drive_t *drive)
                }
                /* Early cdrom models used zero */
                type = ide_cdrom;
+               /* fall through */
        case ide_cdrom:
                drive->dev_flags |= IDE_DFLAG_REMOVABLE;
 #ifdef CONFIG_PPC
index aee7b46d2330c8e7fa670545d8815ae484ac53f9..34c1165226a4c050fd33444136875801a8be0b86 100644 (file)
@@ -1746,7 +1746,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
 {
        unsigned long t;
        int speed;
-       int buffer_size;
        u16 *ctl = (u16 *)&tape->caps[12];
 
        ide_debug_log(IDE_DBG_FUNC, "minor: %d", minor);
@@ -1781,7 +1780,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
                *ctl /= 2;
                tape->buffer_size = *ctl * tape->blk_size;
        }
-       buffer_size = tape->buffer_size;
 
        /* select the "best" DSC read/write polling freq */
        speed = max(*(u16 *)&tape->caps[14], *(u16 *)&tape->caps[8]);
index 89b29028d315b17b6602c5cb8ad9b1a6731c76dc..c21d5c50ae3a1678f19c89a3496cc223dcfc7cc2 100644 (file)
@@ -128,7 +128,7 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
                        return pre_task_out_intr(drive, cmd);
                }
                handler = task_pio_intr;
-               /* fall-through */
+               /* fall through */
        case ATA_PROT_NODATA:
                if (handler == NULL)
                        handler = task_no_data_intr;
@@ -140,6 +140,7 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
                hwif->expiry = dma_ops->dma_timer_expiry;
                ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD);
                dma_ops->dma_start(drive);
+               /* fall through */
        default:
                return ide_started;
        }
index c3062b53056f2b70e63230e53a4c6465e8349af2..024bc7ba49ee5e8198b49a2f510ff05d0be70840 100644 (file)
@@ -494,6 +494,7 @@ static int init_chipset_sis5513(struct pci_dev *dev)
                pci_read_config_byte(dev, 0x09, &reg);
                if ((reg & 0x0f) != 0x00)
                        pci_write_config_byte(dev, 0x09, reg&0xf0);
+               /* fall through */
        case ATA_16:
                /* force per drive recovery and active timings
                   needed on ATA_33 and below chips */
index 28e9b7656b204cd390e53d2ad9f23144a28804d2..15d498fc475873ccf17b741e9171d5335df80b9d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * LTC2632 Digital to analog convertors spi driver
  *
- * Copyright 2017 Maxime Roussin-Bélanger
+ * Copyright 2017 Maxime Roussin-Bélanger
  * expanded by Silvan Murer <silvan.murer@gmail.com>
  *
  * Licensed under the GPL-2.
index d619e8634a00fb93bd526bc3527d8f516d07a8a2..13a4cec64ea88d69f63e01ea817cdaf990ebe267 100644 (file)
@@ -433,11 +433,11 @@ static int mlx90614_wakeup(struct mlx90614_data *data)
 
        dev_dbg(&data->client->dev, "Requesting wake-up");
 
-       i2c_lock_adapter(data->client->adapter);
+       i2c_lock_bus(data->client->adapter, I2C_LOCK_ROOT_ADAPTER);
        gpiod_direction_output(data->wakeup_gpio, 0);
        msleep(MLX90614_TIMING_WAKEUP);
        gpiod_direction_input(data->wakeup_gpio);
-       i2c_unlock_adapter(data->client->adapter);
+       i2c_unlock_bus(data->client->adapter, I2C_LOCK_ROOT_ADAPTER);
 
        data->ready_timestamp = jiffies +
                        msecs_to_jiffies(MLX90614_TIMING_STARTUP);
index d160d2d1f3a3fbe1b18ddf5a8d26ec7d74e8df2f..abb6660c099c9f44767c1f2aad27730658fba28d 100644 (file)
@@ -36,7 +36,7 @@ config INFINIBAND_USER_ACCESS
          rdma-core <https://github.com/linux-rdma/rdma-core>.
 
 config INFINIBAND_USER_ACCESS_UCM
-       bool "Userspace CM (UCM, DEPRECATED)"
+       tristate "Userspace CM (UCM, DEPRECATED)"
        depends on BROKEN || COMPILE_TEST
        depends on INFINIBAND_USER_ACCESS
        help
index f72677291b692511ce7abcf1e9e8da9bf8f06326..a36c94930c31de8a03652cbf07844c10bcc09877 100644 (file)
@@ -724,6 +724,7 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv)
        dgid = (union ib_gid *) &addr->sib_addr;
        pkey = ntohs(addr->sib_pkey);
 
+       mutex_lock(&lock);
        list_for_each_entry(cur_dev, &dev_list, list) {
                for (p = 1; p <= cur_dev->device->phys_port_cnt; ++p) {
                        if (!rdma_cap_af_ib(cur_dev->device, p))
@@ -750,18 +751,19 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv)
                                        cma_dev = cur_dev;
                                        sgid = gid;
                                        id_priv->id.port_num = p;
+                                       goto found;
                                }
                        }
                }
        }
-
-       if (!cma_dev)
-               return -ENODEV;
+       mutex_unlock(&lock);
+       return -ENODEV;
 
 found:
        cma_attach_to_dev(id_priv, cma_dev);
-       addr = (struct sockaddr_ib *) cma_src_addr(id_priv);
-       memcpy(&addr->sib_addr, &sgid, sizeof sgid);
+       mutex_unlock(&lock);
+       addr = (struct sockaddr_ib *)cma_src_addr(id_priv);
+       memcpy(&addr->sib_addr, &sgid, sizeof(sgid));
        cma_translate_ib(addr, &id_priv->id.route.addr.dev_addr);
        return 0;
 }
index 6eb64c6f08028b6c4a92407435bb2339128fe48b..c4118bcd5103565e3b20b6a970e67322061d195f 100644 (file)
@@ -882,6 +882,8 @@ static int __uverbs_cleanup_ufile(struct ib_uverbs_file *ufile,
                WARN_ON(uverbs_try_lock_object(obj, UVERBS_LOOKUP_WRITE));
                if (!uverbs_destroy_uobject(obj, reason))
                        ret = 0;
+               else
+                       atomic_set(&obj->usecnt, 0);
        }
        return ret;
 }
index ec8fb289621fb7590dd3e3f4000967fa2b6c9aae..5f437d1570fb02d516b1ee60f0a4cee42053da50 100644 (file)
@@ -124,6 +124,8 @@ static DEFINE_MUTEX(mut);
 static DEFINE_IDR(ctx_idr);
 static DEFINE_IDR(multicast_idr);
 
+static const struct file_operations ucma_fops;
+
 static inline struct ucma_context *_ucma_find_context(int id,
                                                      struct ucma_file *file)
 {
@@ -1581,6 +1583,10 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
        f = fdget(cmd.fd);
        if (!f.file)
                return -ENOENT;
+       if (f.file->f_op != &ucma_fops) {
+               ret = -EINVAL;
+               goto file_put;
+       }
 
        /* Validate current fd and prevent destruction of id. */
        ctx = ucma_get_ctx(f.file->private_data, cmd.id);
index 182436b92ba93a95ca6e119108c30d50706b7212..6ec748eccff7e87d7691b92a6d50534d89d4625e 100644 (file)
@@ -186,6 +186,7 @@ static void ib_umem_notifier_release(struct mmu_notifier *mn,
        rbt_ib_umem_for_each_in_range(&context->umem_tree, 0,
                                      ULLONG_MAX,
                                      ib_umem_notifier_release_trampoline,
+                                     true,
                                      NULL);
        up_read(&context->umem_rwsem);
 }
@@ -207,22 +208,31 @@ static int invalidate_range_start_trampoline(struct ib_umem *item, u64 start,
        return 0;
 }
 
-static void ib_umem_notifier_invalidate_range_start(struct mmu_notifier *mn,
+static int ib_umem_notifier_invalidate_range_start(struct mmu_notifier *mn,
                                                    struct mm_struct *mm,
                                                    unsigned long start,
-                                                   unsigned long end)
+                                                   unsigned long end,
+                                                   bool blockable)
 {
        struct ib_ucontext *context = container_of(mn, struct ib_ucontext, mn);
+       int ret;
 
        if (!context->invalidate_range)
-               return;
+               return 0;
+
+       if (blockable)
+               down_read(&context->umem_rwsem);
+       else if (!down_read_trylock(&context->umem_rwsem))
+               return -EAGAIN;
 
        ib_ucontext_notifier_start_account(context);
-       down_read(&context->umem_rwsem);
-       rbt_ib_umem_for_each_in_range(&context->umem_tree, start,
+       ret = rbt_ib_umem_for_each_in_range(&context->umem_tree, start,
                                      end,
-                                     invalidate_range_start_trampoline, NULL);
+                                     invalidate_range_start_trampoline,
+                                     blockable, NULL);
        up_read(&context->umem_rwsem);
+
+       return ret;
 }
 
 static int invalidate_range_end_trampoline(struct ib_umem *item, u64 start,
@@ -242,10 +252,15 @@ static void ib_umem_notifier_invalidate_range_end(struct mmu_notifier *mn,
        if (!context->invalidate_range)
                return;
 
+       /*
+        * TODO: we currently bail out if there is any sleepable work to be done
+        * in ib_umem_notifier_invalidate_range_start so we shouldn't really block
+        * here. But this is ugly and fragile.
+        */
        down_read(&context->umem_rwsem);
        rbt_ib_umem_for_each_in_range(&context->umem_tree, start,
                                      end,
-                                     invalidate_range_end_trampoline, NULL);
+                                     invalidate_range_end_trampoline, true, NULL);
        up_read(&context->umem_rwsem);
        ib_ucontext_notifier_end_account(context);
 }
@@ -798,6 +813,7 @@ EXPORT_SYMBOL(ib_umem_odp_unmap_dma_pages);
 int rbt_ib_umem_for_each_in_range(struct rb_root_cached *root,
                                  u64 start, u64 last,
                                  umem_call_back cb,
+                                 bool blockable,
                                  void *cookie)
 {
        int ret_val = 0;
@@ -809,6 +825,9 @@ int rbt_ib_umem_for_each_in_range(struct rb_root_cached *root,
 
        for (node = rbt_ib_umem_iter_first(root, start, last - 1);
                        node; node = next) {
+               /* TODO move the blockable decision up to the callback */
+               if (!blockable)
+                       return -EAGAIN;
                next = rbt_ib_umem_iter_next(node, start, last - 1);
                umem = container_of(node, struct ib_umem_odp, interval_tree);
                ret_val = cb(umem->umem, start, last, cookie) || ret_val;
index 823beca448e10937d290b9ebaf0bf3aed444f05b..6d974e2363df249c4291a3331d9d16f0a14232a6 100644 (file)
@@ -1050,7 +1050,7 @@ static void ib_uverbs_add_one(struct ib_device *device)
        uverbs_dev->num_comp_vectors = device->num_comp_vectors;
 
        if (ib_uverbs_create_uapi(device, uverbs_dev))
-               goto err;
+               goto err_uapi;
 
        cdev_init(&uverbs_dev->cdev, NULL);
        uverbs_dev->cdev.owner = THIS_MODULE;
@@ -1077,11 +1077,10 @@ static void ib_uverbs_add_one(struct ib_device *device)
 
 err_class:
        device_destroy(uverbs_class, uverbs_dev->cdev.dev);
-
 err_cdev:
        cdev_del(&uverbs_dev->cdev);
+err_uapi:
        clear_bit(devnum, dev_map);
-
 err:
        if (atomic_dec_and_test(&uverbs_dev->refcount))
                ib_uverbs_comp_dev(uverbs_dev);
index bbfb86eb2d24204565c78187faa6eb23984f24bf..bc2b9e03843903750aba02c0994430cd024cf4e3 100644 (file)
@@ -833,6 +833,8 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp)
                                "Failed to destroy Shadow QP");
                        return rc;
                }
+               bnxt_qplib_free_qp_res(&rdev->qplib_res,
+                                      &rdev->qp1_sqp->qplib_qp);
                mutex_lock(&rdev->qp_lock);
                list_del(&rdev->qp1_sqp->list);
                atomic_dec(&rdev->qp_count);
index e426b990c1dd5bf3fa08966f41ccd08e3f3c4e44..6ad0d46ab879a6a1bf6d231e22b6e766b796efd2 100644 (file)
@@ -196,7 +196,7 @@ static int bnxt_qplib_alloc_qp_hdr_buf(struct bnxt_qplib_res *res,
                                       struct bnxt_qplib_qp *qp)
 {
        struct bnxt_qplib_q *rq = &qp->rq;
-       struct bnxt_qplib_q *sq = &qp->rq;
+       struct bnxt_qplib_q *sq = &qp->sq;
        int rc = 0;
 
        if (qp->sq_hdr_buf_size && sq->hwq.max_elements) {
index b3203afa3b1de705c74da5aaec9ca55a3172b0d2..347fe18b1a41c0990c753aa29f2efaaea0cd119b 100644 (file)
@@ -1685,6 +1685,12 @@ static void flush_qp(struct c4iw_qp *qhp)
        schp = to_c4iw_cq(qhp->ibqp.send_cq);
 
        if (qhp->ibqp.uobject) {
+
+               /* for user qps, qhp->wq.flushed is protected by qhp->mutex */
+               if (qhp->wq.flushed)
+                       return;
+
+               qhp->wq.flushed = 1;
                t4_set_wq_in_error(&qhp->wq, 0);
                t4_set_cq_in_error(&rchp->cq);
                spin_lock_irqsave(&rchp->comp_handler_lock, flag);
index fbe7198a715a1278f0b2c7068d8a740177f50253..bedd5fba33b080a075405c9a01fa8006f5b0a3f2 100644 (file)
@@ -198,7 +198,7 @@ int node_affinity_init(void)
                while ((dev = pci_get_device(ids->vendor, ids->device, dev))) {
                        node = pcibus_to_node(dev->bus);
                        if (node < 0)
-                               node = numa_node_id();
+                               goto out;
 
                        hfi1_per_node_cntr[node]++;
                }
@@ -206,6 +206,18 @@ int node_affinity_init(void)
        }
 
        return 0;
+
+out:
+       /*
+        * Invalid PCI NUMA node information found, note it, and populate
+        * our database 1:1.
+        */
+       pr_err("HFI: Invalid PCI NUMA node. Performance may be affected\n");
+       pr_err("HFI: System BIOS may need to be upgraded\n");
+       for (node = 0; node < node_affinity.num_possible_nodes; node++)
+               hfi1_per_node_cntr[node] = 1;
+
+       return 0;
 }
 
 static void node_affinity_destroy(struct hfi1_affinity_node *entry)
@@ -622,8 +634,14 @@ int hfi1_dev_affinity_init(struct hfi1_devdata *dd)
        int curr_cpu, possible, i, ret;
        bool new_entry = false;
 
-       if (node < 0)
-               node = numa_node_id();
+       /*
+        * If the BIOS does not have the NUMA node information set, select
+        * NUMA 0 so we get consistent performance.
+        */
+       if (node < 0) {
+               dd_dev_err(dd, "Invalid PCI NUMA node. Performance may be affected\n");
+               node = 0;
+       }
        dd->node = node;
 
        local_mask = cpumask_of_node(dd->node);
index 70aceefe14d5fa306a3ce78408b9866518030104..e1c7996c018efe688dbe081cc0928f05c5f0bbdd 100644 (file)
@@ -67,9 +67,9 @@ struct mmu_rb_handler {
 
 static unsigned long mmu_node_start(struct mmu_rb_node *);
 static unsigned long mmu_node_last(struct mmu_rb_node *);
-static void mmu_notifier_range_start(struct mmu_notifier *,
+static int mmu_notifier_range_start(struct mmu_notifier *,
                                     struct mm_struct *,
-                                    unsigned long, unsigned long);
+                                    unsigned long, unsigned long, bool);
 static struct mmu_rb_node *__mmu_rb_search(struct mmu_rb_handler *,
                                           unsigned long, unsigned long);
 static void do_remove(struct mmu_rb_handler *handler,
@@ -284,10 +284,11 @@ void hfi1_mmu_rb_remove(struct mmu_rb_handler *handler,
        handler->ops->remove(handler->ops_arg, node);
 }
 
-static void mmu_notifier_range_start(struct mmu_notifier *mn,
+static int mmu_notifier_range_start(struct mmu_notifier *mn,
                                     struct mm_struct *mm,
                                     unsigned long start,
-                                    unsigned long end)
+                                    unsigned long end,
+                                    bool blockable)
 {
        struct mmu_rb_handler *handler =
                container_of(mn, struct mmu_rb_handler, mn);
@@ -313,6 +314,8 @@ static void mmu_notifier_range_start(struct mmu_notifier *mn,
 
        if (added)
                queue_work(handler->wq, &handler->del_work);
+
+       return 0;
 }
 
 /*
index ca0f1ee26091b38200b2447ccfe92324a3c0bd32..0bbeaaae47e07d2e99529925bb6236ab98be377b 100644 (file)
@@ -517,9 +517,11 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
        props->page_size_cap       = dev->dev->caps.page_size_cap;
        props->max_qp              = dev->dev->quotas.qp;
        props->max_qp_wr           = dev->dev->caps.max_wqes - MLX4_IB_SQ_MAX_SPARE;
-       props->max_send_sge        = dev->dev->caps.max_sq_sg;
-       props->max_recv_sge        = dev->dev->caps.max_rq_sg;
-       props->max_sge_rd          = MLX4_MAX_SGE_RD;
+       props->max_send_sge =
+               min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg);
+       props->max_recv_sge =
+               min(dev->dev->caps.max_sq_sg, dev->dev->caps.max_rq_sg);
+       props->max_sge_rd = MLX4_MAX_SGE_RD;
        props->max_cq              = dev->dev->quotas.cq;
        props->max_cqe             = dev->dev->caps.max_cqes;
        props->max_mr              = dev->dev->quotas.mpt;
index f1a87a690a4cd0555a1bb0ccbd585bb114a498b9..d216e0d2921dafc28b59e9a56dfbd82c660cc0d8 100644 (file)
@@ -488,7 +488,7 @@ void mlx5_ib_free_implicit_mr(struct mlx5_ib_mr *imr)
 
        down_read(&ctx->umem_rwsem);
        rbt_ib_umem_for_each_in_range(&ctx->umem_tree, 0, ULLONG_MAX,
-                                     mr_leaf_free, imr);
+                                     mr_leaf_free, true, imr);
        up_read(&ctx->umem_rwsem);
 
        wait_event(imr->q_leaf_free, !atomic_read(&imr->num_leaf_free));
index ea01b8dd2be606206193408ca7bf9c42e4ea4e39..3d5424f335cb06e1dcaad16a4f4c3c7910d3295e 100644 (file)
@@ -1027,12 +1027,14 @@ static int ipoib_cm_rep_handler(struct ib_cm_id *cm_id,
 
        skb_queue_head_init(&skqueue);
 
+       netif_tx_lock_bh(p->dev);
        spin_lock_irq(&priv->lock);
        set_bit(IPOIB_FLAG_OPER_UP, &p->flags);
        if (p->neigh)
                while ((skb = __skb_dequeue(&p->neigh->queue)))
                        __skb_queue_tail(&skqueue, skb);
        spin_unlock_irq(&priv->lock);
+       netif_tx_unlock_bh(p->dev);
 
        while ((skb = __skb_dequeue(&skqueue))) {
                skb->dev = p->dev;
index 3df501c3421b6755981b58f38439f71bfa157070..f8663d7891f270bb4e3b00b20e6eaf64c312cd5a 100644 (file)
  * However, when used with the E3 mailboard that producecs non-standard
  * scancodes, a custom key table must be prepared and loaded from userspace.
  */
-#include <linux/gpio.h>
 #include <linux/irq.h>
+#include <linux/platform_data/ams-delta-fiq.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
 #include <linux/serio.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 
-#include <asm/mach-types.h>
-#include <mach/board-ams-delta.h>
-
-#include <mach/ams-delta-fiq.h>
+#define DRIVER_NAME    "ams-delta-serio"
 
 MODULE_AUTHOR("Matt Callow");
 MODULE_DESCRIPTION("AMS Delta (E3) keyboard port driver");
 MODULE_LICENSE("GPL");
 
-static struct serio *ams_delta_serio;
+struct ams_delta_serio {
+       struct serio *serio;
+       struct regulator *vcc;
+       unsigned int *fiq_buffer;
+};
 
-static int check_data(int data)
+static int check_data(struct serio *serio, int data)
 {
        int i, parity = 0;
 
        /* check valid stop bit */
        if (!(data & 0x400)) {
-               dev_warn(&ams_delta_serio->dev,
-                               "invalid stop bit, data=0x%X\n",
-                               data);
+               dev_warn(&serio->dev, "invalid stop bit, data=0x%X\n", data);
                return SERIO_FRAME;
        }
        /* calculate the parity */
@@ -55,9 +56,9 @@ static int check_data(int data)
        }
        /* it should be odd */
        if (!(parity & 0x01)) {
-               dev_warn(&ams_delta_serio->dev,
-                               "parity check failed, data=0x%X parity=0x%X\n",
-                               data, parity);
+               dev_warn(&serio->dev,
+                        "parity check failed, data=0x%X parity=0x%X\n", data,
+                        parity);
                return SERIO_PARITY;
        }
        return 0;
@@ -65,127 +66,130 @@ static int check_data(int data)
 
 static irqreturn_t ams_delta_serio_interrupt(int irq, void *dev_id)
 {
-       int *circ_buff = &fiq_buffer[FIQ_CIRC_BUFF];
+       struct ams_delta_serio *priv = dev_id;
+       int *circ_buff = &priv->fiq_buffer[FIQ_CIRC_BUFF];
        int data, dfl;
        u8 scancode;
 
-       fiq_buffer[FIQ_IRQ_PEND] = 0;
+       priv->fiq_buffer[FIQ_IRQ_PEND] = 0;
 
        /*
         * Read data from the circular buffer, check it
         * and then pass it on the serio
         */
-       while (fiq_buffer[FIQ_KEYS_CNT] > 0) {
+       while (priv->fiq_buffer[FIQ_KEYS_CNT] > 0) {
 
-               data = circ_buff[fiq_buffer[FIQ_HEAD_OFFSET]++];
-               fiq_buffer[FIQ_KEYS_CNT]--;
-               if (fiq_buffer[FIQ_HEAD_OFFSET] == fiq_buffer[FIQ_BUF_LEN])
-                       fiq_buffer[FIQ_HEAD_OFFSET] = 0;
+               data = circ_buff[priv->fiq_buffer[FIQ_HEAD_OFFSET]++];
+               priv->fiq_buffer[FIQ_KEYS_CNT]--;
+               if (priv->fiq_buffer[FIQ_HEAD_OFFSET] ==
+                   priv->fiq_buffer[FIQ_BUF_LEN])
+                       priv->fiq_buffer[FIQ_HEAD_OFFSET] = 0;
 
-               dfl = check_data(data);
+               dfl = check_data(priv->serio, data);
                scancode = (u8) (data >> 1) & 0xFF;
-               serio_interrupt(ams_delta_serio, scancode, dfl);
+               serio_interrupt(priv->serio, scancode, dfl);
        }
        return IRQ_HANDLED;
 }
 
 static int ams_delta_serio_open(struct serio *serio)
 {
-       /* enable keyboard */
-       gpio_set_value(AMS_DELTA_GPIO_PIN_KEYBRD_PWR, 1);
+       struct ams_delta_serio *priv = serio->port_data;
 
-       return 0;
+       /* enable keyboard */
+       return regulator_enable(priv->vcc);
 }
 
 static void ams_delta_serio_close(struct serio *serio)
 {
+       struct ams_delta_serio *priv = serio->port_data;
+
        /* disable keyboard */
-       gpio_set_value(AMS_DELTA_GPIO_PIN_KEYBRD_PWR, 0);
+       regulator_disable(priv->vcc);
 }
 
-static const struct gpio ams_delta_gpios[] __initconst_or_module = {
-       {
-               .gpio   = AMS_DELTA_GPIO_PIN_KEYBRD_DATA,
-               .flags  = GPIOF_DIR_IN,
-               .label  = "serio-data",
-       },
-       {
-               .gpio   = AMS_DELTA_GPIO_PIN_KEYBRD_CLK,
-               .flags  = GPIOF_DIR_IN,
-               .label  = "serio-clock",
-       },
-       {
-               .gpio   = AMS_DELTA_GPIO_PIN_KEYBRD_PWR,
-               .flags  = GPIOF_OUT_INIT_LOW,
-               .label  = "serio-power",
-       },
-       {
-               .gpio   = AMS_DELTA_GPIO_PIN_KEYBRD_DATAOUT,
-               .flags  = GPIOF_OUT_INIT_LOW,
-               .label  = "serio-dataout",
-       },
-};
-
-static int __init ams_delta_serio_init(void)
+static int ams_delta_serio_init(struct platform_device *pdev)
 {
-       int err;
-
-       if (!machine_is_ams_delta())
-               return -ENODEV;
+       struct ams_delta_serio *priv;
+       struct serio *serio;
+       int irq, err;
 
-       ams_delta_serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
-       if (!ams_delta_serio)
+       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
                return -ENOMEM;
 
-       ams_delta_serio->id.type = SERIO_8042;
-       ams_delta_serio->open = ams_delta_serio_open;
-       ams_delta_serio->close = ams_delta_serio_close;
-       strlcpy(ams_delta_serio->name, "AMS DELTA keyboard adapter",
-                       sizeof(ams_delta_serio->name));
-       strlcpy(ams_delta_serio->phys, "GPIO/serio0",
-                       sizeof(ams_delta_serio->phys));
-
-       err = gpio_request_array(ams_delta_gpios,
-                               ARRAY_SIZE(ams_delta_gpios));
-       if (err) {
-               pr_err("ams_delta_serio: Couldn't request gpio pins\n");
-               goto serio;
+       priv->fiq_buffer = pdev->dev.platform_data;
+       if (!priv->fiq_buffer)
+               return -EINVAL;
+
+       priv->vcc = devm_regulator_get(&pdev->dev, "vcc");
+       if (IS_ERR(priv->vcc)) {
+               err = PTR_ERR(priv->vcc);
+               dev_err(&pdev->dev, "regulator request failed (%d)\n", err);
+               /*
+                * When running on a non-dt platform and requested regulator
+                * is not available, devm_regulator_get() never returns
+                * -EPROBE_DEFER as it is not able to justify if the regulator
+                * may still appear later.  On the other hand, the board can
+                * still set full constriants flag at late_initcall in order
+                * to instruct devm_regulator_get() to returnn a dummy one
+                * if sufficient.  Hence, if we get -ENODEV here, let's convert
+                * it to -EPROBE_DEFER and wait for the board to decide or
+                * let Deferred Probe infrastructure handle this error.
+                */
+               if (err == -ENODEV)
+                       err = -EPROBE_DEFER;
+               return err;
        }
 
-       err = request_irq(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK),
-                       ams_delta_serio_interrupt, IRQ_TYPE_EDGE_RISING,
-                       "ams-delta-serio", 0);
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0)
+               return -ENXIO;
+
+       err = devm_request_irq(&pdev->dev, irq, ams_delta_serio_interrupt,
+                              IRQ_TYPE_EDGE_RISING, DRIVER_NAME, priv);
        if (err < 0) {
-               pr_err("ams_delta_serio: couldn't request gpio interrupt %d\n",
-                               gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK));
-               goto gpio;
+               dev_err(&pdev->dev, "IRQ request failed (%d)\n", err);
+               return err;
        }
-       /*
-        * Since GPIO register handling for keyboard clock pin is performed
-        * at FIQ level, switch back from edge to simple interrupt handler
-        * to avoid bad interaction.
-        */
-       irq_set_handler(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK),
-                       handle_simple_irq);
 
-       serio_register_port(ams_delta_serio);
-       dev_info(&ams_delta_serio->dev, "%s\n", ams_delta_serio->name);
+       serio = kzalloc(sizeof(*serio), GFP_KERNEL);
+       if (!serio)
+               return -ENOMEM;
+
+       priv->serio = serio;
+
+       serio->id.type = SERIO_8042;
+       serio->open = ams_delta_serio_open;
+       serio->close = ams_delta_serio_close;
+       strlcpy(serio->name, "AMS DELTA keyboard adapter", sizeof(serio->name));
+       strlcpy(serio->phys, dev_name(&pdev->dev), sizeof(serio->phys));
+       serio->dev.parent = &pdev->dev;
+       serio->port_data = priv;
+
+       serio_register_port(serio);
+
+       platform_set_drvdata(pdev, priv);
+
+       dev_info(&serio->dev, "%s\n", serio->name);
 
        return 0;
-gpio:
-       gpio_free_array(ams_delta_gpios,
-                       ARRAY_SIZE(ams_delta_gpios));
-serio:
-       kfree(ams_delta_serio);
-       return err;
 }
-module_init(ams_delta_serio_init);
 
-static void __exit ams_delta_serio_exit(void)
+static int ams_delta_serio_exit(struct platform_device *pdev)
 {
-       serio_unregister_port(ams_delta_serio);
-       free_irq(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), 0);
-       gpio_free_array(ams_delta_gpios,
-                       ARRAY_SIZE(ams_delta_gpios));
+       struct ams_delta_serio *priv = platform_get_drvdata(pdev);
+
+       serio_unregister_port(priv->serio);
+
+       return 0;
 }
-module_exit(ams_delta_serio_exit);
+
+static struct platform_driver ams_delta_serio_driver = {
+       .probe  = ams_delta_serio_init,
+       .remove = ams_delta_serio_exit,
+       .driver = {
+               .name   = DRIVER_NAME
+       },
+};
+module_platform_driver(ams_delta_serio_driver);
index bda0500c9b5779ba250b7260b0d368f4462334aa..714affdd742fdaa446344fceb57ffaa80cdac492 100644 (file)
@@ -304,7 +304,7 @@ static int rohm_i2c_burst_read(struct i2c_client *client, u8 start, void *buf,
        msg[1].len = len;
        msg[1].buf = buf;
 
-       i2c_lock_adapter(adap);
+       i2c_lock_bus(adap, I2C_LOCK_SEGMENT);
 
        for (i = 0; i < 2; i++) {
                if (__i2c_transfer(adap, &msg[i], 1) < 0) {
@@ -313,7 +313,7 @@ static int rohm_i2c_burst_read(struct i2c_client *client, u8 start, void *buf,
                }
        }
 
-       i2c_unlock_adapter(adap);
+       i2c_unlock_bus(adap, I2C_LOCK_SEGMENT);
 
        return ret;
 }
index 689ffe5383706dd062cd9ce7aac9bc631c7656ba..c60395b7470f640cc229c53bbd825235d61194c1 100644 (file)
@@ -60,6 +60,27 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
 
 endmenu
 
+config IOMMU_DEBUGFS
+       bool "Export IOMMU internals in DebugFS"
+       depends on DEBUG_FS
+       help
+         Allows exposure of IOMMU device internals. This option enables
+         the use of debugfs by IOMMU drivers as required. Devices can,
+         at initialization time, cause the IOMMU code to create a top-level
+         debug/iommu directory, and then populate a subdirectory with
+         entries as required.
+
+config IOMMU_DEFAULT_PASSTHROUGH
+       bool "IOMMU passthrough by default"
+       depends on IOMMU_API
+        help
+         Enable passthrough by default, removing the need to pass in
+         iommu.passthrough=on or iommu=pt through command line. If this
+         is enabled, you can still disable with iommu.passthrough=off
+         or iommu=nopt depending on the architecture.
+
+         If unsure, say N here.
+
 config IOMMU_IOVA
        tristate
 
@@ -135,6 +156,18 @@ config AMD_IOMMU_V2
          hardware. Select this option if you want to use devices that support
          the PCI PRI and PASID interface.
 
+config AMD_IOMMU_DEBUGFS
+       bool "Enable AMD IOMMU internals in DebugFS"
+       depends on AMD_IOMMU && IOMMU_DEBUGFS
+       ---help---
+         !!!WARNING!!!  !!!WARNING!!!  !!!WARNING!!!  !!!WARNING!!!
+
+         DO NOT ENABLE THIS OPTION UNLESS YOU REALLY, -REALLY- KNOW WHAT YOU ARE DOING!!!
+         Exposes AMD IOMMU device internals in DebugFS.
+
+         This option is -NOT- intended for production environments, and should
+         not generally be enabled.
+
 # Intel IOMMU support
 config DMAR_TABLE
        bool
@@ -284,8 +317,8 @@ config IPMMU_VMSA
        select IOMMU_IO_PGTABLE_LPAE
        select ARM_DMA_USE_IOMMU
        help
-         Support for the Renesas VMSA-compatible IPMMU Renesas found in the
-         R-Mobile APE6 and R-Car H2/M2 SoCs.
+         Support for the Renesas VMSA-compatible IPMMU found in the R-Mobile
+         APE6, R-Car Gen2, and R-Car Gen3 SoCs.
 
          If unsure, say N.
 
index 1fb695854809b0ff261dec43f51d72f90ff7e178..ab5eba6edf82b308f81a7c5acf9f992e8e0e2dde 100644 (file)
@@ -2,6 +2,7 @@
 obj-$(CONFIG_IOMMU_API) += iommu.o
 obj-$(CONFIG_IOMMU_API) += iommu-traces.o
 obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o
 obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
@@ -10,11 +11,12 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU) += of_iommu.o
 obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
+obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd_iommu_debugfs.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
 obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
 obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
 obj-$(CONFIG_DMAR_TABLE) += dmar.o
-obj-$(CONFIG_INTEL_IOMMU) += intel-iommu.o
+obj-$(CONFIG_INTEL_IOMMU) += intel-iommu.o intel-pasid.o
 obj-$(CONFIG_INTEL_IOMMU_SVM) += intel-svm.o
 obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o
 obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
index 60b2eab29cd8fb1c80985085eee96f99ccb960e3..4e04fff23977348877cce7a00d4ae394fadf91ef 100644 (file)
@@ -1404,6 +1404,8 @@ static u64 *fetch_pte(struct protection_domain *domain,
        int level;
        u64 *pte;
 
+       *page_size = 0;
+
        if (address > PM_LEVEL_SIZE(domain->mode))
                return NULL;
 
@@ -1944,12 +1946,6 @@ static int __attach_device(struct iommu_dev_data *dev_data,
 {
        int ret;
 
-       /*
-        * Must be called with IRQs disabled. Warn here to detect early
-        * when its not.
-        */
-       WARN_ON(!irqs_disabled());
-
        /* lock domain */
        spin_lock(&domain->lock);
 
@@ -2115,12 +2111,6 @@ static void __detach_device(struct iommu_dev_data *dev_data)
 {
        struct protection_domain *domain;
 
-       /*
-        * Must be called with IRQs disabled. Warn here to detect early
-        * when its not.
-        */
-       WARN_ON(!irqs_disabled());
-
        domain = dev_data->domain;
 
        spin_lock(&domain->lock);
@@ -2405,9 +2395,9 @@ static void __unmap_single(struct dma_ops_domain *dma_dom,
        }
 
        if (amd_iommu_unmap_flush) {
-               dma_ops_free_iova(dma_dom, dma_addr, pages);
                domain_flush_tlb(&dma_dom->domain);
                domain_flush_complete(&dma_dom->domain);
+               dma_ops_free_iova(dma_dom, dma_addr, pages);
        } else {
                pages = __roundup_pow_of_two(pages);
                queue_iova(&dma_dom->iovad, dma_addr >> PAGE_SHIFT, pages, 0);
@@ -3192,7 +3182,6 @@ const struct iommu_ops amd_iommu_ops = {
        .detach_dev = amd_iommu_detach_device,
        .map = amd_iommu_map,
        .unmap = amd_iommu_unmap,
-       .map_sg = default_iommu_map_sg,
        .iova_to_phys = amd_iommu_iova_to_phys,
        .add_device = amd_iommu_add_device,
        .remove_device = amd_iommu_remove_device,
@@ -3874,7 +3863,8 @@ static void irte_ga_prepare(void *entry,
        irte->lo.fields_remap.int_type    = delivery_mode;
        irte->lo.fields_remap.dm          = dest_mode;
        irte->hi.fields.vector            = vector;
-       irte->lo.fields_remap.destination = dest_apicid;
+       irte->lo.fields_remap.destination = APICID_TO_IRTE_DEST_LO(dest_apicid);
+       irte->hi.fields.destination       = APICID_TO_IRTE_DEST_HI(dest_apicid);
        irte->lo.fields_remap.valid       = 1;
 }
 
@@ -3927,7 +3917,10 @@ static void irte_ga_set_affinity(void *entry, u16 devid, u16 index,
 
        if (!irte->lo.fields_remap.guest_mode) {
                irte->hi.fields.vector = vector;
-               irte->lo.fields_remap.destination = dest_apicid;
+               irte->lo.fields_remap.destination =
+                                       APICID_TO_IRTE_DEST_LO(dest_apicid);
+               irte->hi.fields.destination =
+                                       APICID_TO_IRTE_DEST_HI(dest_apicid);
                modify_irte_ga(devid, index, irte, NULL);
        }
 }
@@ -4344,7 +4337,10 @@ static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info)
                irte->lo.val = 0;
                irte->hi.fields.vector = cfg->vector;
                irte->lo.fields_remap.guest_mode = 0;
-               irte->lo.fields_remap.destination = cfg->dest_apicid;
+               irte->lo.fields_remap.destination =
+                               APICID_TO_IRTE_DEST_LO(cfg->dest_apicid);
+               irte->hi.fields.destination =
+                               APICID_TO_IRTE_DEST_HI(cfg->dest_apicid);
                irte->lo.fields_remap.int_type = apic->irq_delivery_mode;
                irte->lo.fields_remap.dm = apic->irq_dest_mode;
 
@@ -4461,8 +4457,12 @@ int amd_iommu_update_ga(int cpu, bool is_run, void *data)
        raw_spin_lock_irqsave(&table->lock, flags);
 
        if (ref->lo.fields_vapic.guest_mode) {
-               if (cpu >= 0)
-                       ref->lo.fields_vapic.destination = cpu;
+               if (cpu >= 0) {
+                       ref->lo.fields_vapic.destination =
+                                               APICID_TO_IRTE_DEST_LO(cpu);
+                       ref->hi.fields.destination =
+                                               APICID_TO_IRTE_DEST_HI(cpu);
+               }
                ref->lo.fields_vapic.is_run = is_run;
                barrier();
        }
diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c
new file mode 100644 (file)
index 0000000..c6a5c73
--- /dev/null
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.hook@amd.com>
+ */
+
+#include <linux/debugfs.h>
+#include <linux/iommu.h>
+#include <linux/pci.h>
+#include "amd_iommu_proto.h"
+#include "amd_iommu_types.h"
+
+static struct dentry *amd_iommu_debugfs;
+static DEFINE_MUTEX(amd_iommu_debugfs_lock);
+
+#define        MAX_NAME_LEN    20
+
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
+{
+       char name[MAX_NAME_LEN + 1];
+
+       mutex_lock(&amd_iommu_debugfs_lock);
+       if (!amd_iommu_debugfs)
+               amd_iommu_debugfs = debugfs_create_dir("amd",
+                                                      iommu_debugfs_dir);
+       mutex_unlock(&amd_iommu_debugfs_lock);
+
+       snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index);
+       iommu->debugfs = debugfs_create_dir(name, amd_iommu_debugfs);
+}
index 904c575d1677ffadfe35c0087edf55849da3f7d2..84b3e4445d46d0a6064437dc57f1ff0ecbdd9f36 100644 (file)
@@ -153,6 +153,7 @@ bool amd_iommu_dump;
 bool amd_iommu_irq_remap __read_mostly;
 
 int amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_VAPIC;
+static int amd_iommu_xt_mode = IRQ_REMAP_X2APIC_MODE;
 
 static bool amd_iommu_detected;
 static bool __initdata amd_iommu_disabled;
@@ -280,9 +281,9 @@ static void clear_translation_pre_enabled(struct amd_iommu *iommu)
 
 static void init_translation_status(struct amd_iommu *iommu)
 {
-       u32 ctrl;
+       u64 ctrl;
 
-       ctrl = readl(iommu->mmio_base + MMIO_CONTROL_OFFSET);
+       ctrl = readq(iommu->mmio_base + MMIO_CONTROL_OFFSET);
        if (ctrl & (1<<CONTROL_IOMMU_EN))
                iommu->flags |= AMD_IOMMU_FLAG_TRANS_PRE_ENABLED;
 }
@@ -386,30 +387,30 @@ static void iommu_set_device_table(struct amd_iommu *iommu)
 /* Generic functions to enable/disable certain features of the IOMMU. */
 static void iommu_feature_enable(struct amd_iommu *iommu, u8 bit)
 {
-       u32 ctrl;
+       u64 ctrl;
 
-       ctrl = readl(iommu->mmio_base + MMIO_CONTROL_OFFSET);
-       ctrl |= (1 << bit);
-       writel(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
+       ctrl = readq(iommu->mmio_base +  MMIO_CONTROL_OFFSET);
+       ctrl |= (1ULL << bit);
+       writeq(ctrl, iommu->mmio_base +  MMIO_CONTROL_OFFSET);
 }
 
 static void iommu_feature_disable(struct amd_iommu *iommu, u8 bit)
 {
-       u32 ctrl;
+       u64 ctrl;
 
-       ctrl = readl(iommu->mmio_base + MMIO_CONTROL_OFFSET);
-       ctrl &= ~(1 << bit);
-       writel(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
+       ctrl = readq(iommu->mmio_base + MMIO_CONTROL_OFFSET);
+       ctrl &= ~(1ULL << bit);
+       writeq(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
 }
 
 static void iommu_set_inv_tlb_timeout(struct amd_iommu *iommu, int timeout)
 {
-       u32 ctrl;
+       u64 ctrl;
 
-       ctrl = readl(iommu->mmio_base + MMIO_CONTROL_OFFSET);
+       ctrl = readq(iommu->mmio_base + MMIO_CONTROL_OFFSET);
        ctrl &= ~CTRL_INV_TO_MASK;
        ctrl |= (timeout << CONTROL_INV_TIMEOUT) & CTRL_INV_TO_MASK;
-       writel(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
+       writeq(ctrl, iommu->mmio_base + MMIO_CONTROL_OFFSET);
 }
 
 /* Function to enable the hardware */
@@ -827,6 +828,19 @@ static int iommu_init_ga(struct amd_iommu *iommu)
        return ret;
 }
 
+static void iommu_enable_xt(struct amd_iommu *iommu)
+{
+#ifdef CONFIG_IRQ_REMAP
+       /*
+        * XT mode (32-bit APIC destination ID) requires
+        * GA mode (128-bit IRTE support) as a prerequisite.
+        */
+       if (AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir) &&
+           amd_iommu_xt_mode == IRQ_REMAP_X2APIC_MODE)
+               iommu_feature_enable(iommu, CONTROL_XT_EN);
+#endif /* CONFIG_IRQ_REMAP */
+}
+
 static void iommu_enable_gt(struct amd_iommu *iommu)
 {
        if (!iommu_feature(iommu, FEATURE_GT))
@@ -1507,6 +1521,8 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
                        iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET;
                if (((h->efr_attr & (0x1 << IOMMU_FEAT_GASUP_SHIFT)) == 0))
                        amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY;
+               if (((h->efr_attr & (0x1 << IOMMU_FEAT_XTSUP_SHIFT)) == 0))
+                       amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE;
                break;
        case 0x11:
        case 0x40:
@@ -1516,6 +1532,8 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
                        iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET;
                if (((h->efr_reg & (0x1 << IOMMU_EFR_GASUP_SHIFT)) == 0))
                        amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY;
+               if (((h->efr_reg & (0x1 << IOMMU_EFR_XTSUP_SHIFT)) == 0))
+                       amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE;
                break;
        default:
                return -EINVAL;
@@ -1832,6 +1850,8 @@ static void print_iommu_info(void)
                pr_info("AMD-Vi: Interrupt remapping enabled\n");
                if (AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir))
                        pr_info("AMD-Vi: virtual APIC enabled\n");
+               if (amd_iommu_xt_mode == IRQ_REMAP_X2APIC_MODE)
+                       pr_info("AMD-Vi: X2APIC enabled\n");
        }
 }
 
@@ -2168,6 +2188,7 @@ static void early_enable_iommu(struct amd_iommu *iommu)
        iommu_enable_event_buffer(iommu);
        iommu_set_exclusion_range(iommu);
        iommu_enable_ga(iommu);
+       iommu_enable_xt(iommu);
        iommu_enable(iommu);
        iommu_flush_all_caches(iommu);
 }
@@ -2212,6 +2233,7 @@ static void early_enable_iommus(void)
                        iommu_enable_command_buffer(iommu);
                        iommu_enable_event_buffer(iommu);
                        iommu_enable_ga(iommu);
+                       iommu_enable_xt(iommu);
                        iommu_set_device_table(iommu);
                        iommu_flush_all_caches(iommu);
                }
@@ -2691,8 +2713,7 @@ int __init amd_iommu_enable(void)
                return ret;
 
        irq_remapping_enabled = 1;
-
-       return 0;
+       return amd_iommu_xt_mode;
 }
 
 void amd_iommu_disable(void)
@@ -2721,6 +2742,7 @@ int __init amd_iommu_enable_faulting(void)
  */
 static int __init amd_iommu_init(void)
 {
+       struct amd_iommu *iommu;
        int ret;
 
        ret = iommu_go_to_state(IOMMU_INITIALIZED);
@@ -2730,14 +2752,15 @@ static int __init amd_iommu_init(void)
                        disable_iommus();
                        free_iommu_resources();
                } else {
-                       struct amd_iommu *iommu;
-
                        uninit_device_table_dma();
                        for_each_iommu(iommu)
                                iommu_flush_all_caches(iommu);
                }
        }
 
+       for_each_iommu(iommu)
+               amd_iommu_debugfs_setup(iommu);
+
        return ret;
 }
 
index 640c286a0ab9c40109d68efb9dfb13376959fc63..a8cd0296fb16a3d8522c90ad44db26e99bcdf883 100644 (file)
@@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void);
 extern void amd_iommu_init_notifier(void);
 extern int amd_iommu_init_api(void);
 
+#ifdef CONFIG_AMD_IOMMU_DEBUGFS
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu);
+#else
+static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {}
+#endif
+
 /* Needed for interrupt remapping */
 extern int amd_iommu_prepare(void);
 extern int amd_iommu_enable(void);
index 986cbe0cc189701e9a08005ceb57eb6a0a9f9aeb..e2b342e65a7b86ea75f8c1b8bb8826ac0e7b3018 100644 (file)
 #define CONTROL_GAM_EN          0x19ULL
 #define CONTROL_GALOG_EN        0x1CULL
 #define CONTROL_GAINT_EN        0x1DULL
+#define CONTROL_XT_EN           0x32ULL
 
 #define CTRL_INV_TO_MASK       (7 << CONTROL_INV_TIMEOUT)
 #define CTRL_INV_TO_NONE       0
 #define IOMMU_CAP_EFR     27
 
 /* IOMMU Feature Reporting Field (for IVHD type 10h */
+#define IOMMU_FEAT_XTSUP_SHIFT 0
 #define IOMMU_FEAT_GASUP_SHIFT 6
 
 /* IOMMU Extended Feature Register (EFR) */
+#define IOMMU_EFR_XTSUP_SHIFT  2
 #define IOMMU_EFR_GASUP_SHIFT  7
 
 #define MAX_DOMAIN_ID 65536
@@ -437,7 +440,6 @@ extern struct kmem_cache *amd_iommu_irq_cache;
 #define APERTURE_RANGE_INDEX(a)        ((a) >> APERTURE_RANGE_SHIFT)
 #define APERTURE_PAGE_INDEX(a) (((a) >> 21) & 0x3fULL)
 
-
 /*
  * This struct is used to pass information about
  * incoming PPR faults around.
@@ -594,6 +596,11 @@ struct amd_iommu {
 
        u32 flags;
        volatile u64 __aligned(8) cmd_sem;
+
+#ifdef CONFIG_AMD_IOMMU_DEBUGFS
+       /* DebugFS Info */
+       struct dentry *debugfs;
+#endif
 };
 
 static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)
@@ -810,6 +817,9 @@ union irte {
        } fields;
 };
 
+#define APICID_TO_IRTE_DEST_LO(x)    (x & 0xffffff)
+#define APICID_TO_IRTE_DEST_HI(x)    ((x >> 24) & 0xff)
+
 union irte_ga_lo {
        u64 val;
 
@@ -823,8 +833,8 @@ union irte_ga_lo {
                    dm          : 1,
                    /* ------ */
                    guest_mode  : 1,
-                   destination : 8,
-                   rsvd        : 48;
+                   destination : 24,
+                   ga_tag      : 32;
        } fields_remap;
 
        /* For guest vAPIC */
@@ -837,8 +847,7 @@ union irte_ga_lo {
                    is_run      : 1,
                    /* ------ */
                    guest_mode  : 1,
-                   destination : 8,
-                   rsvd2       : 16,
+                   destination : 24,
                    ga_tag      : 32;
        } fields_vapic;
 };
@@ -849,7 +858,8 @@ union irte_ga_hi {
                u64 vector      : 8,
                    rsvd_1      : 4,
                    ga_root_ptr : 40,
-                   rsvd_2      : 12;
+                   rsvd_2      : 4,
+                   destination : 8;
        } fields;
 };
 
index 22bdabd3d8e089dff04c6bb0ca80a84b41de2c1e..5059d09f32020a43edaebc8420b5e4ef8969b888 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/acpi_iort.h>
 #include <linux/bitfield.h>
 #include <linux/bitops.h>
+#include <linux/crash_dump.h>
 #include <linux/delay.h>
 #include <linux/dma-iommu.h>
 #include <linux/err.h>
 #define MSI_IOVA_BASE                  0x8000000
 #define MSI_IOVA_LENGTH                        0x100000
 
-static bool disable_bypass;
+static bool disable_bypass = 1;
 module_param_named(disable_bypass, disable_bypass, bool, S_IRUGO);
 MODULE_PARM_DESC(disable_bypass,
        "Disable bypass streams such that incoming transactions from devices that are not attached to an iommu domain will report an abort back to the device and will not be allowed to pass through the SMMU.");
@@ -1301,6 +1302,7 @@ static irqreturn_t arm_smmu_priq_thread(int irq, void *dev)
 
        /* Sync our overflow flag, as we believe we're up to speed */
        q->cons = Q_OVF(q, q->prod) | Q_WRP(q, q->cons) | Q_IDX(q, q->cons);
+       writel(q->cons, q->cons_reg);
        return IRQ_HANDLED;
 }
 
@@ -1997,7 +1999,6 @@ static struct iommu_ops arm_smmu_ops = {
        .attach_dev             = arm_smmu_attach_dev,
        .map                    = arm_smmu_map,
        .unmap                  = arm_smmu_unmap,
-       .map_sg                 = default_iommu_map_sg,
        .flush_iotlb_all        = arm_smmu_iotlb_sync,
        .iotlb_sync             = arm_smmu_iotlb_sync,
        .iova_to_phys           = arm_smmu_iova_to_phys,
@@ -2211,8 +2212,12 @@ static int arm_smmu_update_gbpa(struct arm_smmu_device *smmu, u32 set, u32 clr)
        reg &= ~clr;
        reg |= set;
        writel_relaxed(reg | GBPA_UPDATE, gbpa);
-       return readl_relaxed_poll_timeout(gbpa, reg, !(reg & GBPA_UPDATE),
-                                         1, ARM_SMMU_POLL_TIMEOUT_US);
+       ret = readl_relaxed_poll_timeout(gbpa, reg, !(reg & GBPA_UPDATE),
+                                        1, ARM_SMMU_POLL_TIMEOUT_US);
+
+       if (ret)
+               dev_err(smmu->dev, "GBPA not responding to update\n");
+       return ret;
 }
 
 static void arm_smmu_free_msis(void *data)
@@ -2392,8 +2397,15 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
 
        /* Clear CR0 and sync (disables SMMU and queue processing) */
        reg = readl_relaxed(smmu->base + ARM_SMMU_CR0);
-       if (reg & CR0_SMMUEN)
+       if (reg & CR0_SMMUEN) {
+               if (is_kdump_kernel()) {
+                       arm_smmu_update_gbpa(smmu, GBPA_ABORT, 0);
+                       arm_smmu_device_disable(smmu);
+                       return -EBUSY;
+               }
+
                dev_warn(smmu->dev, "SMMU currently enabled! Resetting...\n");
+       }
 
        ret = arm_smmu_device_disable(smmu);
        if (ret)
@@ -2491,10 +2503,8 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
                enables |= CR0_SMMUEN;
        } else {
                ret = arm_smmu_update_gbpa(smmu, 0, GBPA_ABORT);
-               if (ret) {
-                       dev_err(smmu->dev, "GBPA not responding to update\n");
+               if (ret)
                        return ret;
-               }
        }
        ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0,
                                      ARM_SMMU_CR0ACK);
index c73cfce1ccc0aede67eadba8525825e48f553941..fd1b80ef9490d2f4044f0704e9ebc5843d21b2bf 100644 (file)
@@ -1562,7 +1562,6 @@ static struct iommu_ops arm_smmu_ops = {
        .attach_dev             = arm_smmu_attach_dev,
        .map                    = arm_smmu_map,
        .unmap                  = arm_smmu_unmap,
-       .map_sg                 = default_iommu_map_sg,
        .flush_iotlb_all        = arm_smmu_iotlb_sync,
        .iotlb_sync             = arm_smmu_iotlb_sync,
        .iova_to_phys           = arm_smmu_iova_to_phys,
@@ -2103,12 +2102,16 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
        if (err)
                return err;
 
-       if (smmu->version == ARM_SMMU_V2 &&
-           smmu->num_context_banks != smmu->num_context_irqs) {
-               dev_err(dev,
-                       "found only %d context interrupt(s) but %d required\n",
-                       smmu->num_context_irqs, smmu->num_context_banks);
-               return -ENODEV;
+       if (smmu->version == ARM_SMMU_V2) {
+               if (smmu->num_context_banks > smmu->num_context_irqs) {
+                       dev_err(dev,
+                             "found only %d context irq(s) but %d required\n",
+                             smmu->num_context_irqs, smmu->num_context_banks);
+                       return -ENODEV;
+               }
+
+               /* Ignore superfluous interrupts */
+               smmu->num_context_irqs = smmu->num_context_banks;
        }
 
        for (i = 0; i < smmu->num_global_irqs; ++i) {
index 75456b5aa825fac7a5f81c8fe366d47618acc1cc..d9c748b6f9e452bf521626d4c1174af8694558bf 100644 (file)
@@ -1339,8 +1339,8 @@ void qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
        qi_submit_sync(&desc, iommu);
 }
 
-void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 qdep,
-                       u64 addr, unsigned mask)
+void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid,
+                       u16 qdep, u64 addr, unsigned mask)
 {
        struct qi_desc desc;
 
@@ -1355,7 +1355,7 @@ void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 qdep,
                qdep = 0;
 
        desc.low = QI_DEV_IOTLB_SID(sid) | QI_DEV_IOTLB_QDEP(qdep) |
-                  QI_DIOTLB_TYPE;
+                  QI_DIOTLB_TYPE | QI_DEV_IOTLB_PFSID(pfsid);
 
        qi_submit_sync(&desc, iommu);
 }
index b128cb4372d3503bc695e2e3b919623536c21c38..1bd0cd7168dfc92d2dcf7da7c78efc06c78b5f3b 100644 (file)
@@ -1332,7 +1332,6 @@ static const struct iommu_ops exynos_iommu_ops = {
        .detach_dev = exynos_iommu_detach_device,
        .map = exynos_iommu_map,
        .unmap = exynos_iommu_unmap,
-       .map_sg = default_iommu_map_sg,
        .iova_to_phys = exynos_iommu_iova_to_phys,
        .device_group = generic_device_group,
        .add_device = exynos_iommu_add_device,
index 6a237d18fabff7f5c9c5172eec046194b46bf4ac..5f3f10cf9d9d0fecb1fc5747c60cbe9d4f9034b1 100644 (file)
@@ -52,6 +52,7 @@
 #include <asm/iommu.h>
 
 #include "irq_remapping.h"
+#include "intel-pasid.h"
 
 #define ROOT_SIZE              VTD_PAGE_SIZE
 #define CONTEXT_SIZE           VTD_PAGE_SIZE
@@ -379,60 +380,6 @@ static int hw_pass_through = 1;
        for (idx = 0; idx < g_num_of_iommus; idx++)             \
                if (domain->iommu_refcnt[idx])
 
-struct dmar_domain {
-       int     nid;                    /* node id */
-
-       unsigned        iommu_refcnt[DMAR_UNITS_SUPPORTED];
-                                       /* Refcount of devices per iommu */
-
-
-       u16             iommu_did[DMAR_UNITS_SUPPORTED];
-                                       /* Domain ids per IOMMU. Use u16 since
-                                        * domain ids are 16 bit wide according
-                                        * to VT-d spec, section 9.3 */
-
-       bool has_iotlb_device;
-       struct list_head devices;       /* all devices' list */
-       struct iova_domain iovad;       /* iova's that belong to this domain */
-
-       struct dma_pte  *pgd;           /* virtual address */
-       int             gaw;            /* max guest address width */
-
-       /* adjusted guest address width, 0 is level 2 30-bit */
-       int             agaw;
-
-       int             flags;          /* flags to find out type of domain */
-
-       int             iommu_coherency;/* indicate coherency of iommu access */
-       int             iommu_snooping; /* indicate snooping control feature*/
-       int             iommu_count;    /* reference count of iommu */
-       int             iommu_superpage;/* Level of superpages supported:
-                                          0 == 4KiB (no superpages), 1 == 2MiB,
-                                          2 == 1GiB, 3 == 512GiB, 4 == 1TiB */
-       u64             max_addr;       /* maximum mapped address */
-
-       struct iommu_domain domain;     /* generic domain data structure for
-                                          iommu core */
-};
-
-/* PCI domain-device relationship */
-struct device_domain_info {
-       struct list_head link;  /* link to domain siblings */
-       struct list_head global; /* link to global list */
-       u8 bus;                 /* PCI bus number */
-       u8 devfn;               /* PCI devfn number */
-       u8 pasid_supported:3;
-       u8 pasid_enabled:1;
-       u8 pri_supported:1;
-       u8 pri_enabled:1;
-       u8 ats_supported:1;
-       u8 ats_enabled:1;
-       u8 ats_qdep;
-       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          */
@@ -523,6 +470,27 @@ EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
 static DEFINE_SPINLOCK(device_domain_lock);
 static LIST_HEAD(device_domain_list);
 
+/*
+ * Iterate over elements in device_domain_list and call the specified
+ * callback @fn against each element. This helper should only be used
+ * in the context where the device_domain_lock has already been holden.
+ */
+int for_each_device_domain(int (*fn)(struct device_domain_info *info,
+                                    void *data), void *data)
+{
+       int ret = 0;
+       struct device_domain_info *info;
+
+       assert_spin_locked(&device_domain_lock);
+       list_for_each_entry(info, &device_domain_list, global) {
+               ret = fn(info, data);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 const struct iommu_ops intel_iommu_ops;
 
 static bool translation_pre_enabled(struct intel_iommu *iommu)
@@ -629,7 +597,7 @@ static void set_iommu_domain(struct intel_iommu *iommu, u16 did,
                domains[did & 0xff] = domain;
 }
 
-static inline void *alloc_pgtable_page(int node)
+void *alloc_pgtable_page(int node)
 {
        struct page *page;
        void *vaddr = NULL;
@@ -640,7 +608,7 @@ static inline void *alloc_pgtable_page(int node)
        return vaddr;
 }
 
-static inline void free_pgtable_page(void *vaddr)
+void free_pgtable_page(void *vaddr)
 {
        free_page((unsigned long)vaddr);
 }
@@ -723,7 +691,7 @@ int iommu_calculate_agaw(struct intel_iommu *iommu)
 }
 
 /* This functionin only returns single iommu in a domain */
-static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
+struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
 {
        int iommu_id;
 
@@ -1501,6 +1469,20 @@ static void iommu_enable_dev_iotlb(struct device_domain_info *info)
                return;
 
        pdev = to_pci_dev(info->dev);
+       /* For IOMMU that supports device IOTLB throttling (DIT), we assign
+        * PFSID to the invalidation desc of a VF such that IOMMU HW can gauge
+        * queue depth at PF level. If DIT is not set, PFSID will be treated as
+        * reserved, which should be set to 0.
+        */
+       if (!ecap_dit(info->iommu->ecap))
+               info->pfsid = 0;
+       else {
+               struct pci_dev *pf_pdev;
+
+               /* pdev will be returned if device is not a vf */
+               pf_pdev = pci_physfn(pdev);
+               info->pfsid = PCI_DEVID(pf_pdev->bus->number, pf_pdev->devfn);
+       }
 
 #ifdef CONFIG_INTEL_IOMMU_SVM
        /* The PCIe spec, in its wisdom, declares that the behaviour of
@@ -1566,7 +1548,8 @@ static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
 
                sid = info->bus << 8 | info->devfn;
                qdep = info->ats_qdep;
-               qi_flush_dev_iotlb(info->iommu, sid, qdep, addr, mask);
+               qi_flush_dev_iotlb(info->iommu, sid, info->pfsid,
+                               qdep, addr, mask);
        }
        spin_unlock_irqrestore(&device_domain_lock, flags);
 }
@@ -1800,7 +1783,7 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
        if (pasid_enabled(iommu)) {
                if (ecap_prs(iommu->ecap))
                        intel_svm_finish_prq(iommu);
-               intel_svm_free_pasid_tables(iommu);
+               intel_svm_exit(iommu);
        }
 #endif
 }
@@ -2495,6 +2478,7 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
        info->dev = dev;
        info->domain = domain;
        info->iommu = iommu;
+       info->pasid_table = NULL;
 
        if (dev && dev_is_pci(dev)) {
                struct pci_dev *pdev = to_pci_dev(info->dev);
@@ -2552,6 +2536,15 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
        list_add(&info->global, &device_domain_list);
        if (dev)
                dev->archdata.iommu = info;
+
+       if (dev && dev_is_pci(dev) && info->pasid_supported) {
+               ret = intel_pasid_alloc_table(dev);
+               if (ret) {
+                       __dmar_remove_one_dev_info(info);
+                       spin_unlock_irqrestore(&device_domain_lock, flags);
+                       return NULL;
+               }
+       }
        spin_unlock_irqrestore(&device_domain_lock, flags);
 
        if (dev && domain_context_mapping(domain, dev)) {
@@ -3304,6 +3297,18 @@ static int __init init_dmars(void)
        }
 
        for_each_active_iommu(iommu, drhd) {
+               /*
+                * Find the max pasid size of all IOMMU's in the system.
+                * We need to ensure the system pasid table is no bigger
+                * than the smallest supported.
+                */
+               if (pasid_enabled(iommu)) {
+                       u32 temp = 2 << ecap_pss(iommu->ecap);
+
+                       intel_pasid_max_id = min_t(u32, temp,
+                                                  intel_pasid_max_id);
+               }
+
                g_iommus[iommu->seq_id] = iommu;
 
                intel_iommu_init_qi(iommu);
@@ -3359,7 +3364,7 @@ static int __init init_dmars(void)
                        hw_pass_through = 0;
 #ifdef CONFIG_INTEL_IOMMU_SVM
                if (pasid_enabled(iommu))
-                       intel_svm_alloc_pasid_tables(iommu);
+                       intel_svm_init(iommu);
 #endif
        }
 
@@ -3526,7 +3531,7 @@ static unsigned long intel_alloc_iova(struct device *dev,
        return iova_pfn;
 }
 
-static struct dmar_domain *get_valid_domain_for_dev(struct device *dev)
+struct dmar_domain *get_valid_domain_for_dev(struct device *dev)
 {
        struct dmar_domain *domain, *tmp;
        struct dmar_rmrr_unit *rmrr;
@@ -4354,7 +4359,7 @@ static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
 
 #ifdef CONFIG_INTEL_IOMMU_SVM
        if (pasid_enabled(iommu))
-               intel_svm_alloc_pasid_tables(iommu);
+               intel_svm_init(iommu);
 #endif
 
        if (dmaru->ignored) {
@@ -4906,6 +4911,7 @@ static void __dmar_remove_one_dev_info(struct device_domain_info *info)
        if (info->dev) {
                iommu_disable_dev_iotlb(info);
                domain_context_clear(iommu, info->dev);
+               intel_pasid_free_table(info->dev);
        }
 
        unlink_domain_info(info);
@@ -5231,22 +5237,16 @@ static void intel_iommu_put_resv_regions(struct device *dev,
 
 #ifdef CONFIG_INTEL_IOMMU_SVM
 #define MAX_NR_PASID_BITS (20)
-static inline unsigned long intel_iommu_get_pts(struct intel_iommu *iommu)
+static inline unsigned long intel_iommu_get_pts(struct device *dev)
 {
-       /*
-        * Convert ecap_pss to extend context entry pts encoding, also
-        * respect the soft pasid_max value set by the iommu.
-        * - number of PASID bits = ecap_pss + 1
-        * - number of PASID table entries = 2^(pts + 5)
-        * Therefore, pts = ecap_pss - 4
-        * e.g. KBL ecap_pss = 0x13, PASID has 20 bits, pts = 15
-        */
-       if (ecap_pss(iommu->ecap) < 5)
+       int pts, max_pasid;
+
+       max_pasid = intel_pasid_get_dev_max_id(dev);
+       pts = find_first_bit((unsigned long *)&max_pasid, MAX_NR_PASID_BITS);
+       if (pts < 5)
                return 0;
 
-       /* pasid_max is encoded as actual number of entries not the bits */
-       return find_first_bit((unsigned long *)&iommu->pasid_max,
-                       MAX_NR_PASID_BITS) - 5;
+       return pts - 5;
 }
 
 int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev)
@@ -5282,8 +5282,8 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sd
        if (!(ctx_lo & CONTEXT_PASIDE)) {
                if (iommu->pasid_state_table)
                        context[1].hi = (u64)virt_to_phys(iommu->pasid_state_table);
-               context[1].lo = (u64)virt_to_phys(iommu->pasid_table) |
-                       intel_iommu_get_pts(iommu);
+               context[1].lo = (u64)virt_to_phys(info->pasid_table->table) |
+                       intel_iommu_get_pts(sdev->dev);
 
                wmb();
                /* CONTEXT_TT_MULTI_LEVEL and CONTEXT_TT_DEV_IOTLB are both
@@ -5350,11 +5350,6 @@ struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
                return NULL;
        }
 
-       if (!iommu->pasid_table) {
-               dev_err(dev, "PASID not enabled on IOMMU; cannot enable SVM\n");
-               return NULL;
-       }
-
        return iommu;
 }
 #endif /* CONFIG_INTEL_IOMMU_SVM */
@@ -5367,7 +5362,6 @@ const struct iommu_ops intel_iommu_ops = {
        .detach_dev             = intel_iommu_detach_device,
        .map                    = intel_iommu_map,
        .unmap                  = intel_iommu_unmap,
-       .map_sg                 = default_iommu_map_sg,
        .iova_to_phys           = intel_iommu_iova_to_phys,
        .add_device             = intel_iommu_add_device,
        .remove_device          = intel_iommu_remove_device,
diff --git a/drivers/iommu/intel-pasid.c b/drivers/iommu/intel-pasid.c
new file mode 100644 (file)
index 0000000..fe95c9b
--- /dev/null
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * intel-pasid.c - PASID idr, table and entry manipulation
+ *
+ * Copyright (C) 2018 Intel Corporation
+ *
+ * Author: Lu Baolu <baolu.lu@linux.intel.com>
+ */
+
+#define pr_fmt(fmt)    "DMAR: " fmt
+
+#include <linux/dmar.h>
+#include <linux/intel-iommu.h>
+#include <linux/iommu.h>
+#include <linux/memory.h>
+#include <linux/pci.h>
+#include <linux/pci-ats.h>
+#include <linux/spinlock.h>
+
+#include "intel-pasid.h"
+
+/*
+ * Intel IOMMU system wide PASID name space:
+ */
+static DEFINE_SPINLOCK(pasid_lock);
+u32 intel_pasid_max_id = PASID_MAX;
+static DEFINE_IDR(pasid_idr);
+
+int intel_pasid_alloc_id(void *ptr, int start, int end, gfp_t gfp)
+{
+       int ret, min, max;
+
+       min = max_t(int, start, PASID_MIN);
+       max = min_t(int, end, intel_pasid_max_id);
+
+       WARN_ON(in_interrupt());
+       idr_preload(gfp);
+       spin_lock(&pasid_lock);
+       ret = idr_alloc(&pasid_idr, ptr, min, max, GFP_ATOMIC);
+       spin_unlock(&pasid_lock);
+       idr_preload_end();
+
+       return ret;
+}
+
+void intel_pasid_free_id(int pasid)
+{
+       spin_lock(&pasid_lock);
+       idr_remove(&pasid_idr, pasid);
+       spin_unlock(&pasid_lock);
+}
+
+void *intel_pasid_lookup_id(int pasid)
+{
+       void *p;
+
+       spin_lock(&pasid_lock);
+       p = idr_find(&pasid_idr, pasid);
+       spin_unlock(&pasid_lock);
+
+       return p;
+}
+
+/*
+ * Per device pasid table management:
+ */
+static inline void
+device_attach_pasid_table(struct device_domain_info *info,
+                         struct pasid_table *pasid_table)
+{
+       info->pasid_table = pasid_table;
+       list_add(&info->table, &pasid_table->dev);
+}
+
+static inline void
+device_detach_pasid_table(struct device_domain_info *info,
+                         struct pasid_table *pasid_table)
+{
+       info->pasid_table = NULL;
+       list_del(&info->table);
+}
+
+struct pasid_table_opaque {
+       struct pasid_table      **pasid_table;
+       int                     segment;
+       int                     bus;
+       int                     devfn;
+};
+
+static int search_pasid_table(struct device_domain_info *info, void *opaque)
+{
+       struct pasid_table_opaque *data = opaque;
+
+       if (info->iommu->segment == data->segment &&
+           info->bus == data->bus &&
+           info->devfn == data->devfn &&
+           info->pasid_table) {
+               *data->pasid_table = info->pasid_table;
+               return 1;
+       }
+
+       return 0;
+}
+
+static int get_alias_pasid_table(struct pci_dev *pdev, u16 alias, void *opaque)
+{
+       struct pasid_table_opaque *data = opaque;
+
+       data->segment = pci_domain_nr(pdev->bus);
+       data->bus = PCI_BUS_NUM(alias);
+       data->devfn = alias & 0xff;
+
+       return for_each_device_domain(&search_pasid_table, data);
+}
+
+/*
+ * Allocate a pasid table for @dev. It should be called in a
+ * single-thread context.
+ */
+int intel_pasid_alloc_table(struct device *dev)
+{
+       struct device_domain_info *info;
+       struct pasid_table *pasid_table;
+       struct pasid_table_opaque data;
+       struct page *pages;
+       size_t size, count;
+       int ret, order;
+
+       info = dev->archdata.iommu;
+       if (WARN_ON(!info || !dev_is_pci(dev) ||
+                   !info->pasid_supported || info->pasid_table))
+               return -EINVAL;
+
+       /* DMA alias device already has a pasid table, use it: */
+       data.pasid_table = &pasid_table;
+       ret = pci_for_each_dma_alias(to_pci_dev(dev),
+                                    &get_alias_pasid_table, &data);
+       if (ret)
+               goto attach_out;
+
+       pasid_table = kzalloc(sizeof(*pasid_table), GFP_ATOMIC);
+       if (!pasid_table)
+               return -ENOMEM;
+       INIT_LIST_HEAD(&pasid_table->dev);
+
+       size = sizeof(struct pasid_entry);
+       count = min_t(int, pci_max_pasids(to_pci_dev(dev)), intel_pasid_max_id);
+       order = get_order(size * count);
+       pages = alloc_pages_node(info->iommu->node,
+                                GFP_ATOMIC | __GFP_ZERO,
+                                order);
+       if (!pages)
+               return -ENOMEM;
+
+       pasid_table->table = page_address(pages);
+       pasid_table->order = order;
+       pasid_table->max_pasid = count;
+
+attach_out:
+       device_attach_pasid_table(info, pasid_table);
+
+       return 0;
+}
+
+void intel_pasid_free_table(struct device *dev)
+{
+       struct device_domain_info *info;
+       struct pasid_table *pasid_table;
+
+       info = dev->archdata.iommu;
+       if (!info || !dev_is_pci(dev) ||
+           !info->pasid_supported || !info->pasid_table)
+               return;
+
+       pasid_table = info->pasid_table;
+       device_detach_pasid_table(info, pasid_table);
+
+       if (!list_empty(&pasid_table->dev))
+               return;
+
+       free_pages((unsigned long)pasid_table->table, pasid_table->order);
+       kfree(pasid_table);
+}
+
+struct pasid_table *intel_pasid_get_table(struct device *dev)
+{
+       struct device_domain_info *info;
+
+       info = dev->archdata.iommu;
+       if (!info)
+               return NULL;
+
+       return info->pasid_table;
+}
+
+int intel_pasid_get_dev_max_id(struct device *dev)
+{
+       struct device_domain_info *info;
+
+       info = dev->archdata.iommu;
+       if (!info || !info->pasid_table)
+               return 0;
+
+       return info->pasid_table->max_pasid;
+}
+
+struct pasid_entry *intel_pasid_get_entry(struct device *dev, int pasid)
+{
+       struct pasid_table *pasid_table;
+       struct pasid_entry *entries;
+
+       pasid_table = intel_pasid_get_table(dev);
+       if (WARN_ON(!pasid_table || pasid < 0 ||
+                   pasid >= intel_pasid_get_dev_max_id(dev)))
+               return NULL;
+
+       entries = pasid_table->table;
+
+       return &entries[pasid];
+}
+
+/*
+ * Interfaces for PASID table entry manipulation:
+ */
+static inline void pasid_clear_entry(struct pasid_entry *pe)
+{
+       WRITE_ONCE(pe->val, 0);
+}
+
+void intel_pasid_clear_entry(struct device *dev, int pasid)
+{
+       struct pasid_entry *pe;
+
+       pe = intel_pasid_get_entry(dev, pasid);
+       if (WARN_ON(!pe))
+               return;
+
+       pasid_clear_entry(pe);
+}
diff --git a/drivers/iommu/intel-pasid.h b/drivers/iommu/intel-pasid.h
new file mode 100644 (file)
index 0000000..1c05ed6
--- /dev/null
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * intel-pasid.h - PASID idr, table and entry header
+ *
+ * Copyright (C) 2018 Intel Corporation
+ *
+ * Author: Lu Baolu <baolu.lu@linux.intel.com>
+ */
+
+#ifndef __INTEL_PASID_H
+#define __INTEL_PASID_H
+
+#define PASID_MIN                      0x1
+#define PASID_MAX                      0x100000
+
+struct pasid_entry {
+       u64 val;
+};
+
+/* The representative of a PASID table */
+struct pasid_table {
+       void                    *table;         /* pasid table pointer */
+       int                     order;          /* page order of pasid table */
+       int                     max_pasid;      /* max pasid */
+       struct list_head        dev;            /* device list */
+};
+
+extern u32 intel_pasid_max_id;
+int intel_pasid_alloc_id(void *ptr, int start, int end, gfp_t gfp);
+void intel_pasid_free_id(int pasid);
+void *intel_pasid_lookup_id(int pasid);
+int intel_pasid_alloc_table(struct device *dev);
+void intel_pasid_free_table(struct device *dev);
+struct pasid_table *intel_pasid_get_table(struct device *dev);
+int intel_pasid_get_dev_max_id(struct device *dev);
+struct pasid_entry *intel_pasid_get_entry(struct device *dev, int pasid);
+void intel_pasid_clear_entry(struct device *dev, int pasid);
+
+#endif /* __INTEL_PASID_H */
index 7d65aab36a9695e7f4ef932a8d3530f83acd2e08..4a03e50909520e5eb40d6245fa3e1affda769780 100644 (file)
 #include <linux/mm_types.h>
 #include <asm/page.h>
 
+#include "intel-pasid.h"
+
 #define PASID_ENTRY_P          BIT_ULL(0)
 #define PASID_ENTRY_FLPM_5LP   BIT_ULL(9)
 #define PASID_ENTRY_SRE                BIT_ULL(11)
 
 static irqreturn_t prq_event_thread(int irq, void *d);
 
-struct pasid_entry {
-       u64 val;
-};
-
 struct pasid_state_entry {
        u64 val;
 };
 
-int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu)
+int intel_svm_init(struct intel_iommu *iommu)
 {
        struct page *pages;
        int order;
@@ -66,15 +64,6 @@ int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu)
                iommu->pasid_max = 0x20000;
 
        order = get_order(sizeof(struct pasid_entry) * iommu->pasid_max);
-       pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
-       if (!pages) {
-               pr_warn("IOMMU: %s: Failed to allocate PASID table\n",
-                       iommu->name);
-               return -ENOMEM;
-       }
-       iommu->pasid_table = page_address(pages);
-       pr_info("%s: Allocated order %d PASID table.\n", iommu->name, order);
-
        if (ecap_dis(iommu->ecap)) {
                /* Just making it explicit... */
                BUILD_BUG_ON(sizeof(struct pasid_entry) != sizeof(struct pasid_state_entry));
@@ -86,24 +75,18 @@ int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu)
                                iommu->name);
        }
 
-       idr_init(&iommu->pasid_idr);
-
        return 0;
 }
 
-int intel_svm_free_pasid_tables(struct intel_iommu *iommu)
+int intel_svm_exit(struct intel_iommu *iommu)
 {
        int order = get_order(sizeof(struct pasid_entry) * iommu->pasid_max);
 
-       if (iommu->pasid_table) {
-               free_pages((unsigned long)iommu->pasid_table, order);
-               iommu->pasid_table = NULL;
-       }
        if (iommu->pasid_state_table) {
                free_pages((unsigned long)iommu->pasid_state_table, order);
                iommu->pasid_state_table = NULL;
        }
-       idr_destroy(&iommu->pasid_idr);
+
        return 0;
 }
 
@@ -279,11 +262,9 @@ static void intel_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
         * page) so that we end up taking a fault that the hardware really
         * *has* to handle gracefully without affecting other processes.
         */
-       svm->iommu->pasid_table[svm->pasid].val = 0;
-       wmb();
-
        rcu_read_lock();
        list_for_each_entry_rcu(sdev, &svm->devs, list) {
+               intel_pasid_clear_entry(sdev->dev, svm->pasid);
                intel_flush_pasid_dev(svm, sdev, svm->pasid);
                intel_flush_svm_range_dev(svm, sdev, 0, -1, 0, !svm->mm);
        }
@@ -299,10 +280,12 @@ static const struct mmu_notifier_ops intel_mmuops = {
 };
 
 static DEFINE_MUTEX(pasid_mutex);
+static LIST_HEAD(global_svm_list);
 
 int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ops *ops)
 {
        struct intel_iommu *iommu = intel_svm_device_to_iommu(dev);
+       struct pasid_entry *entry;
        struct intel_svm_dev *sdev;
        struct intel_svm *svm = NULL;
        struct mm_struct *mm = NULL;
@@ -310,7 +293,7 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
        int pasid_max;
        int ret;
 
-       if (WARN_ON(!iommu || !iommu->pasid_table))
+       if (!iommu)
                return -EINVAL;
 
        if (dev_is_pci(dev)) {
@@ -330,13 +313,13 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
 
        mutex_lock(&pasid_mutex);
        if (pasid && !(flags & SVM_FLAG_PRIVATE_PASID)) {
-               int i;
+               struct intel_svm *t;
 
-               idr_for_each_entry(&iommu->pasid_idr, svm, i) {
-                       if (svm->mm != mm ||
-                           (svm->flags & SVM_FLAG_PRIVATE_PASID))
+               list_for_each_entry(t, &global_svm_list, list) {
+                       if (t->mm != mm || (t->flags & SVM_FLAG_PRIVATE_PASID))
                                continue;
 
+                       svm = t;
                        if (svm->pasid >= pasid_max) {
                                dev_warn(dev,
                                         "Limited PASID width. Cannot use existing PASID %d\n",
@@ -388,13 +371,13 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
                }
                svm->iommu = iommu;
 
-               if (pasid_max > iommu->pasid_max)
-                       pasid_max = iommu->pasid_max;
+               if (pasid_max > intel_pasid_max_id)
+                       pasid_max = intel_pasid_max_id;
 
                /* Do not use PASID 0 in caching mode (virtualised IOMMU) */
-               ret = idr_alloc(&iommu->pasid_idr, svm,
-                               !!cap_caching_mode(iommu->cap),
-                               pasid_max - 1, GFP_KERNEL);
+               ret = intel_pasid_alloc_id(svm,
+                                          !!cap_caching_mode(iommu->cap),
+                                          pasid_max - 1, GFP_KERNEL);
                if (ret < 0) {
                        kfree(svm);
                        kfree(sdev);
@@ -405,11 +388,12 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
                svm->mm = mm;
                svm->flags = flags;
                INIT_LIST_HEAD_RCU(&svm->devs);
+               INIT_LIST_HEAD(&svm->list);
                ret = -ENOMEM;
                if (mm) {
                        ret = mmu_notifier_register(&svm->notifier, mm);
                        if (ret) {
-                               idr_remove(&svm->iommu->pasid_idr, svm->pasid);
+                               intel_pasid_free_id(svm->pasid);
                                kfree(svm);
                                kfree(sdev);
                                goto out;
@@ -421,7 +405,8 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
                if (cpu_feature_enabled(X86_FEATURE_LA57))
                        pasid_entry_val |= PASID_ENTRY_FLPM_5LP;
 
-               iommu->pasid_table[svm->pasid].val = pasid_entry_val;
+               entry = intel_pasid_get_entry(dev, svm->pasid);
+               entry->val = pasid_entry_val;
 
                wmb();
 
@@ -431,6 +416,8 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
                 */
                if (cap_caching_mode(iommu->cap))
                        intel_flush_pasid_dev(svm, sdev, svm->pasid);
+
+               list_add_tail(&svm->list, &global_svm_list);
        }
        list_add_rcu(&sdev->list, &svm->devs);
 
@@ -454,10 +441,10 @@ int intel_svm_unbind_mm(struct device *dev, int pasid)
 
        mutex_lock(&pasid_mutex);
        iommu = intel_svm_device_to_iommu(dev);
-       if (!iommu || !iommu->pasid_table)
+       if (!iommu)
                goto out;
 
-       svm = idr_find(&iommu->pasid_idr, pasid);
+       svm = intel_pasid_lookup_id(pasid);
        if (!svm)
                goto out;
 
@@ -477,15 +464,15 @@ int intel_svm_unbind_mm(struct device *dev, int pasid)
                                intel_flush_pasid_dev(svm, sdev, svm->pasid);
                                intel_flush_svm_range_dev(svm, sdev, 0, -1, 0, !svm->mm);
                                kfree_rcu(sdev, rcu);
+                               intel_pasid_clear_entry(dev, svm->pasid);
 
                                if (list_empty(&svm->devs)) {
-                                       svm->iommu->pasid_table[svm->pasid].val = 0;
-                                       wmb();
-
-                                       idr_remove(&svm->iommu->pasid_idr, svm->pasid);
+                                       intel_pasid_free_id(svm->pasid);
                                        if (svm->mm)
                                                mmu_notifier_unregister(&svm->notifier, svm->mm);
 
+                                       list_del(&svm->list);
+
                                        /* We mandate that no page faults may be outstanding
                                         * for the PASID when intel_svm_unbind_mm() is called.
                                         * If that is not obeyed, subtle errors will happen.
@@ -512,10 +499,10 @@ int intel_svm_is_pasid_valid(struct device *dev, int pasid)
 
        mutex_lock(&pasid_mutex);
        iommu = intel_svm_device_to_iommu(dev);
-       if (!iommu || !iommu->pasid_table)
+       if (!iommu)
                goto out;
 
-       svm = idr_find(&iommu->pasid_idr, pasid);
+       svm = intel_pasid_lookup_id(pasid);
        if (!svm)
                goto out;
 
@@ -614,7 +601,7 @@ static irqreturn_t prq_event_thread(int irq, void *d)
 
                if (!svm || svm->pasid != req->pasid) {
                        rcu_read_lock();
-                       svm = idr_find(&iommu->pasid_idr, req->pasid);
+                       svm = intel_pasid_lookup_id(req->pasid);
                        /* It *can't* go away, because the driver is not permitted
                         * to unbind the mm while any page faults are outstanding.
                         * So we only need RCU to protect the internal idr code. */
index 50e3a9fcf43e1fd4f1512bc49a21b5dfe39b88ae..b5948ba6b3b369edf0096127302e986cf7a439bc 100644 (file)
@@ -192,6 +192,7 @@ static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp,
 {
        struct io_pgtable_cfg *cfg = &data->iop.cfg;
        struct device *dev = cfg->iommu_dev;
+       phys_addr_t phys;
        dma_addr_t dma;
        size_t size = ARM_V7S_TABLE_SIZE(lvl);
        void *table = NULL;
@@ -200,6 +201,10 @@ static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp,
                table = (void *)__get_dma_pages(__GFP_ZERO, get_order(size));
        else if (lvl == 2)
                table = kmem_cache_zalloc(data->l2_tables, gfp | GFP_DMA);
+       phys = virt_to_phys(table);
+       if (phys != (arm_v7s_iopte)phys)
+               /* Doesn't fit in PTE */
+               goto out_free;
        if (table && !(cfg->quirks & IO_PGTABLE_QUIRK_NO_DMA)) {
                dma = dma_map_single(dev, table, size, DMA_TO_DEVICE);
                if (dma_mapping_error(dev, dma))
@@ -209,7 +214,7 @@ static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp,
                 * address directly, so if the DMA layer suggests otherwise by
                 * translating or truncating them, that bodes very badly...
                 */
-               if (dma != virt_to_phys(table))
+               if (dma != phys)
                        goto out_unmap;
        }
        kmemleak_ignore(table);
index 010a254305dd48f60555f4895db7fe4ef9a82c71..88641b4560bc8e87117bdbf1d8b5b1d2117f8d30 100644 (file)
@@ -237,7 +237,8 @@ static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
        void *pages;
 
        VM_BUG_ON((gfp & __GFP_HIGHMEM));
-       p = alloc_pages_node(dev_to_node(dev), gfp | __GFP_ZERO, order);
+       p = alloc_pages_node(dev ? dev_to_node(dev) : NUMA_NO_NODE,
+                            gfp | __GFP_ZERO, order);
        if (!p)
                return NULL;
 
diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c
new file mode 100644 (file)
index 0000000..3b1bf88
--- /dev/null
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IOMMU debugfs core infrastructure
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.hook@amd.com>
+ */
+
+#include <linux/pci.h>
+#include <linux/iommu.h>
+#include <linux/debugfs.h>
+
+struct dentry *iommu_debugfs_dir;
+
+/**
+ * iommu_debugfs_setup - create the top-level iommu directory in debugfs
+ *
+ * Provide base enablement for using debugfs to expose internal data of an
+ * IOMMU driver. When called, this function creates the
+ * /sys/kernel/debug/iommu directory.
+ *
+ * Emit a strong warning at boot time to indicate that this feature is
+ * enabled.
+ *
+ * This function is called from iommu_init; drivers may then call
+ * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific
+ * directory to be used to expose internal data.
+ */
+void iommu_debugfs_setup(void)
+{
+       if (!iommu_debugfs_dir) {
+               iommu_debugfs_dir = debugfs_create_dir("iommu", NULL);
+               pr_warn("\n");
+               pr_warn("*************************************************************\n");
+               pr_warn("**     NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE    **\n");
+               pr_warn("**                                                         **\n");
+               pr_warn("**  IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL  **\n");
+               pr_warn("**                                                         **\n");
+               pr_warn("** This means that this kernel is built to expose internal **\n");
+               pr_warn("** IOMMU data structures, which may compromise security on **\n");
+               pr_warn("** your system.                                            **\n");
+               pr_warn("**                                                         **\n");
+               pr_warn("** If you see this message and you are not debugging the   **\n");
+               pr_warn("** kernel, report this immediately to your vendor!         **\n");
+               pr_warn("**                                                         **\n");
+               pr_warn("**     NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE    **\n");
+               pr_warn("*************************************************************\n");
+       }
+}
+
+/**
+ * iommu_debugfs_new_driver_dir - create a vendor directory under debugfs/iommu
+ * @vendor: name of the vendor-specific subdirectory to create
+ *
+ * This function is called by an IOMMU driver to create the top-level debugfs
+ * directory for that driver.
+ *
+ * Return: upon success, a pointer to the dentry for the new directory.
+ *         NULL in case of failure.
+ */
+struct dentry *iommu_debugfs_new_driver_dir(const char *vendor)
+{
+       return debugfs_create_dir(vendor, iommu_debugfs_dir);
+}
+EXPORT_SYMBOL_GPL(iommu_debugfs_new_driver_dir);
index 63b37563db7e8b9de552319ad076d0d6d893ae52..8c15c598029934484e26520aa4aa7aa703a04ca3 100644 (file)
 
 static struct kset *iommu_group_kset;
 static DEFINE_IDA(iommu_group_ida);
+#ifdef CONFIG_IOMMU_DEFAULT_PASSTHROUGH
+static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_IDENTITY;
+#else
 static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_DMA;
+#endif
 
 struct iommu_callback_data {
        const struct iommu_ops *ops;
@@ -294,11 +298,39 @@ static ssize_t iommu_group_show_resv_regions(struct iommu_group *group,
        return (str - buf);
 }
 
+static ssize_t iommu_group_show_type(struct iommu_group *group,
+                                    char *buf)
+{
+       char *type = "unknown\n";
+
+       if (group->default_domain) {
+               switch (group->default_domain->type) {
+               case IOMMU_DOMAIN_BLOCKED:
+                       type = "blocked\n";
+                       break;
+               case IOMMU_DOMAIN_IDENTITY:
+                       type = "identity\n";
+                       break;
+               case IOMMU_DOMAIN_UNMANAGED:
+                       type = "unmanaged\n";
+                       break;
+               case IOMMU_DOMAIN_DMA:
+                       type = "DMA";
+                       break;
+               }
+       }
+       strcpy(buf, type);
+
+       return strlen(type);
+}
+
 static IOMMU_GROUP_ATTR(name, S_IRUGO, iommu_group_show_name, NULL);
 
 static IOMMU_GROUP_ATTR(reserved_regions, 0444,
                        iommu_group_show_resv_regions, NULL);
 
+static IOMMU_GROUP_ATTR(type, 0444, iommu_group_show_type, NULL);
+
 static void iommu_group_release(struct kobject *kobj)
 {
        struct iommu_group *group = to_iommu_group(kobj);
@@ -380,6 +412,10 @@ struct iommu_group *iommu_group_alloc(void)
        if (ret)
                return ERR_PTR(ret);
 
+       ret = iommu_group_create_file(group, &iommu_group_attr_type);
+       if (ret)
+               return ERR_PTR(ret);
+
        pr_debug("Allocated group %d\n", group->id);
 
        return group;
@@ -1637,8 +1673,8 @@ size_t iommu_unmap_fast(struct iommu_domain *domain,
 }
 EXPORT_SYMBOL_GPL(iommu_unmap_fast);
 
-size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
-                        struct scatterlist *sg, unsigned int nents, int prot)
+size_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
+                   struct scatterlist *sg, unsigned int nents, int prot)
 {
        struct scatterlist *s;
        size_t mapped = 0;
@@ -1678,7 +1714,7 @@ out_err:
        return 0;
 
 }
-EXPORT_SYMBOL_GPL(default_iommu_map_sg);
+EXPORT_SYMBOL_GPL(iommu_map_sg);
 
 int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr,
                               phys_addr_t paddr, u64 size, int prot)
@@ -1748,6 +1784,8 @@ static int __init iommu_init(void)
                                               NULL, kernel_kobj);
        BUG_ON(!iommu_group_kset);
 
+       iommu_debugfs_setup();
+
        return 0;
 }
 core_initcall(iommu_init);
index f026aa16d5f1c0d2575251d283112f3bd3181441..22b94f8a9a04fb34e1d288b3adb2690d4b070f1a 100644 (file)
@@ -47,6 +47,7 @@ struct ipmmu_features {
        unsigned int number_of_contexts;
        bool setup_imbuscr;
        bool twobit_imttbcr_sl0;
+       bool reserved_context;
 };
 
 struct ipmmu_vmsa_device {
@@ -73,7 +74,7 @@ struct ipmmu_vmsa_domain {
        struct io_pgtable_ops *iop;
 
        unsigned int context_id;
-       spinlock_t lock;                        /* Protects mappings */
+       struct mutex mutex;                     /* Protects mappings */
 };
 
 static struct ipmmu_vmsa_domain *to_vmsa_domain(struct iommu_domain *dom)
@@ -194,7 +195,9 @@ static struct ipmmu_vmsa_device *to_ipmmu(struct device *dev)
 #define IMPMBA(n)                      (0x0280 + ((n) * 4))
 #define IMPMBD(n)                      (0x02c0 + ((n) * 4))
 
-#define IMUCTR(n)                      (0x0300 + ((n) * 16))
+#define IMUCTR(n)                      ((n) < 32 ? IMUCTR0(n) : IMUCTR32(n))
+#define IMUCTR0(n)                     (0x0300 + ((n) * 16))
+#define IMUCTR32(n)                    (0x0600 + (((n) - 32) * 16))
 #define IMUCTR_FIXADDEN                        (1 << 31)
 #define IMUCTR_FIXADD_MASK             (0xff << 16)
 #define IMUCTR_FIXADD_SHIFT            16
@@ -204,7 +207,9 @@ static struct ipmmu_vmsa_device *to_ipmmu(struct device *dev)
 #define IMUCTR_FLUSH                   (1 << 1)
 #define IMUCTR_MMUEN                   (1 << 0)
 
-#define IMUASID(n)                     (0x0308 + ((n) * 16))
+#define IMUASID(n)                     ((n) < 32 ? IMUASID0(n) : IMUASID32(n))
+#define IMUASID0(n)                    (0x0308 + ((n) * 16))
+#define IMUASID32(n)                   (0x0608 + (((n) - 32) * 16))
 #define IMUASID_ASID8_MASK             (0xff << 8)
 #define IMUASID_ASID8_SHIFT            8
 #define IMUASID_ASID0_MASK             (0xff << 0)
@@ -595,7 +600,7 @@ static struct iommu_domain *__ipmmu_domain_alloc(unsigned type)
        if (!domain)
                return NULL;
 
-       spin_lock_init(&domain->lock);
+       mutex_init(&domain->mutex);
 
        return &domain->io_domain;
 }
@@ -641,7 +646,6 @@ static int ipmmu_attach_device(struct iommu_domain *io_domain,
        struct iommu_fwspec *fwspec = dev->iommu_fwspec;
        struct ipmmu_vmsa_device *mmu = to_ipmmu(dev);
        struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
-       unsigned long flags;
        unsigned int i;
        int ret = 0;
 
@@ -650,7 +654,7 @@ static int ipmmu_attach_device(struct iommu_domain *io_domain,
                return -ENXIO;
        }
 
-       spin_lock_irqsave(&domain->lock, flags);
+       mutex_lock(&domain->mutex);
 
        if (!domain->mmu) {
                /* The domain hasn't been used yet, initialize it. */
@@ -674,7 +678,7 @@ static int ipmmu_attach_device(struct iommu_domain *io_domain,
        } else
                dev_info(dev, "Reusing IPMMU context %u\n", domain->context_id);
 
-       spin_unlock_irqrestore(&domain->lock, flags);
+       mutex_unlock(&domain->mutex);
 
        if (ret < 0)
                return ret;
@@ -756,8 +760,12 @@ static bool ipmmu_slave_whitelist(struct device *dev)
        return false;
 }
 
-static const struct soc_device_attribute soc_r8a7795[] = {
+static const struct soc_device_attribute soc_rcar_gen3[] = {
        { .soc_id = "r8a7795", },
+       { .soc_id = "r8a7796", },
+       { .soc_id = "r8a77965", },
+       { .soc_id = "r8a77970", },
+       { .soc_id = "r8a77995", },
        { /* sentinel */ }
 };
 
@@ -765,7 +773,7 @@ static int ipmmu_of_xlate(struct device *dev,
                          struct of_phandle_args *spec)
 {
        /* For R-Car Gen3 use a white list to opt-in slave devices */
-       if (soc_device_match(soc_r8a7795) && !ipmmu_slave_whitelist(dev))
+       if (soc_device_match(soc_rcar_gen3) && !ipmmu_slave_whitelist(dev))
                return -ENODEV;
 
        iommu_fwspec_add_ids(dev, spec->args, 1);
@@ -889,7 +897,6 @@ static const struct iommu_ops ipmmu_ops = {
        .unmap = ipmmu_unmap,
        .flush_iotlb_all = ipmmu_iotlb_sync,
        .iotlb_sync = ipmmu_iotlb_sync,
-       .map_sg = default_iommu_map_sg,
        .iova_to_phys = ipmmu_iova_to_phys,
        .add_device = ipmmu_add_device,
        .remove_device = ipmmu_remove_device,
@@ -917,14 +924,16 @@ static const struct ipmmu_features ipmmu_features_default = {
        .number_of_contexts = 1, /* software only tested with one context */
        .setup_imbuscr = true,
        .twobit_imttbcr_sl0 = false,
+       .reserved_context = false,
 };
 
-static const struct ipmmu_features ipmmu_features_r8a7795 = {
+static const struct ipmmu_features ipmmu_features_rcar_gen3 = {
        .use_ns_alias_offset = false,
        .has_cache_leaf_nodes = true,
        .number_of_contexts = 8,
        .setup_imbuscr = false,
        .twobit_imttbcr_sl0 = true,
+       .reserved_context = true,
 };
 
 static const struct of_device_id ipmmu_of_ids[] = {
@@ -933,7 +942,19 @@ static const struct of_device_id ipmmu_of_ids[] = {
                .data = &ipmmu_features_default,
        }, {
                .compatible = "renesas,ipmmu-r8a7795",
-               .data = &ipmmu_features_r8a7795,
+               .data = &ipmmu_features_rcar_gen3,
+       }, {
+               .compatible = "renesas,ipmmu-r8a7796",
+               .data = &ipmmu_features_rcar_gen3,
+       }, {
+               .compatible = "renesas,ipmmu-r8a77965",
+               .data = &ipmmu_features_rcar_gen3,
+       }, {
+               .compatible = "renesas,ipmmu-r8a77970",
+               .data = &ipmmu_features_rcar_gen3,
+       }, {
+               .compatible = "renesas,ipmmu-r8a77995",
+               .data = &ipmmu_features_rcar_gen3,
        }, {
                /* Terminator */
        },
@@ -955,7 +976,7 @@ static int ipmmu_probe(struct platform_device *pdev)
        }
 
        mmu->dev = &pdev->dev;
-       mmu->num_utlbs = 32;
+       mmu->num_utlbs = 48;
        spin_lock_init(&mmu->lock);
        bitmap_zero(mmu->ctx, IPMMU_CTX_MAX);
        mmu->features = of_device_get_match_data(&pdev->dev);
@@ -1018,6 +1039,11 @@ static int ipmmu_probe(struct platform_device *pdev)
                }
 
                ipmmu_device_reset(mmu);
+
+               if (mmu->features->reserved_context) {
+                       dev_info(&pdev->dev, "IPMMU context 0 is reserved\n");
+                       set_bit(0, mmu->ctx);
+               }
        }
 
        /*
@@ -1081,12 +1107,19 @@ static struct platform_driver ipmmu_driver = {
 
 static int __init ipmmu_init(void)
 {
+       struct device_node *np;
        static bool setup_done;
        int ret;
 
        if (setup_done)
                return 0;
 
+       np = of_find_matching_node(NULL, ipmmu_of_ids);
+       if (!np)
+               return 0;
+
+       of_node_put(np);
+
        ret = platform_driver_register(&ipmmu_driver);
        if (ret < 0)
                return ret;
index 27377742600deb449c64cfe4d6b5ed88eca67a74..fc5f0b53adaf3c8ec4c072ed7ada204ca14aa06f 100644 (file)
@@ -395,20 +395,15 @@ static int msm_iommu_add_device(struct device *dev)
        struct msm_iommu_dev *iommu;
        struct iommu_group *group;
        unsigned long flags;
-       int ret = 0;
 
        spin_lock_irqsave(&msm_iommu_lock, flags);
-
        iommu = find_iommu_for_dev(dev);
+       spin_unlock_irqrestore(&msm_iommu_lock, flags);
+
        if (iommu)
                iommu_device_link(&iommu->iommu, dev);
        else
-               ret = -ENODEV;
-
-       spin_unlock_irqrestore(&msm_iommu_lock, flags);
-
-       if (ret)
-               return ret;
+               return -ENODEV;
 
        group = iommu_group_get_for_dev(dev);
        if (IS_ERR(group))
@@ -425,13 +420,12 @@ static void msm_iommu_remove_device(struct device *dev)
        unsigned long flags;
 
        spin_lock_irqsave(&msm_iommu_lock, flags);
-
        iommu = find_iommu_for_dev(dev);
+       spin_unlock_irqrestore(&msm_iommu_lock, flags);
+
        if (iommu)
                iommu_device_unlink(&iommu->iommu, dev);
 
-       spin_unlock_irqrestore(&msm_iommu_lock, flags);
-
        iommu_group_remove_device(dev);
 }
 
@@ -708,7 +702,6 @@ static struct iommu_ops msm_iommu_ops = {
        .detach_dev = msm_iommu_detach_dev,
        .map = msm_iommu_map,
        .unmap = msm_iommu_unmap,
-       .map_sg = default_iommu_map_sg,
        .iova_to_phys = msm_iommu_iova_to_phys,
        .add_device = msm_iommu_add_device,
        .remove_device = msm_iommu_remove_device,
index f2832a10fcea29befea161da78adda8e3ae3472c..f9f69f7111a91e99c1552e16533afac7d0d5f275 100644 (file)
@@ -495,7 +495,6 @@ static struct iommu_ops mtk_iommu_ops = {
        .detach_dev     = mtk_iommu_detach_device,
        .map            = mtk_iommu_map,
        .unmap          = mtk_iommu_unmap,
-       .map_sg         = default_iommu_map_sg,
        .flush_iotlb_all = mtk_iommu_iotlb_sync,
        .iotlb_sync     = mtk_iommu_iotlb_sync,
        .iova_to_phys   = mtk_iommu_iova_to_phys,
index a7c2a973784f3d4209d9b34de328a66102fee75f..676c029494e44cc4a8eaf9af26e47d5e9ba40e02 100644 (file)
@@ -531,7 +531,6 @@ static struct iommu_ops mtk_iommu_ops = {
        .detach_dev     = mtk_iommu_detach_device,
        .map            = mtk_iommu_map,
        .unmap          = mtk_iommu_unmap,
-       .map_sg         = default_iommu_map_sg,
        .iova_to_phys   = mtk_iommu_iova_to_phys,
        .add_device     = mtk_iommu_add_device,
        .remove_device  = mtk_iommu_remove_device,
index af4a8e7fcd27453f160788c93c660f7cf39ff3ab..d2fb347aa4ffcbe5885a3b083b431aa09b6d93d1 100644 (file)
@@ -550,7 +550,7 @@ static u32 *iopte_alloc(struct omap_iommu *obj, u32 *iopgd,
 
 pte_ready:
        iopte = iopte_offset(iopgd, da);
-       *pt_dma = virt_to_phys(iopte);
+       *pt_dma = iopgd_page_paddr(iopgd);
        dev_vdbg(obj->dev,
                 "%s: da:%08x pgd:%p *pgd:%08x pte:%p *pte:%08x\n",
                 __func__, da, iopgd, *iopgd, iopte, *iopte);
@@ -738,7 +738,7 @@ static size_t iopgtable_clear_entry_core(struct omap_iommu *obj, u32 da)
                }
                bytes *= nent;
                memset(iopte, 0, nent * sizeof(*iopte));
-               pt_dma = virt_to_phys(iopte);
+               pt_dma = iopgd_page_paddr(iopgd);
                flush_iopte_range(obj->dev, pt_dma, pt_offset, nent);
 
                /*
@@ -1548,7 +1548,6 @@ static const struct iommu_ops omap_iommu_ops = {
        .detach_dev     = omap_iommu_detach_dev,
        .map            = omap_iommu_map,
        .unmap          = omap_iommu_unmap,
-       .map_sg         = default_iommu_map_sg,
        .iova_to_phys   = omap_iommu_iova_to_phys,
        .add_device     = omap_iommu_add_device,
        .remove_device  = omap_iommu_remove_device,
index b48aee82d14b8a661ce4b00a4f1fc5a3e3108f0f..ee70e9921cf167dc80a5aac17e3b5139ec5f5c06 100644 (file)
@@ -590,7 +590,6 @@ static const struct iommu_ops qcom_iommu_ops = {
        .detach_dev     = qcom_iommu_detach_dev,
        .map            = qcom_iommu_map,
        .unmap          = qcom_iommu_unmap,
-       .map_sg         = default_iommu_map_sg,
        .flush_iotlb_all = qcom_iommu_iotlb_sync,
        .iotlb_sync     = qcom_iommu_iotlb_sync,
        .iova_to_phys   = qcom_iommu_iova_to_phys,
index de8d3bf91b23dc259e71176c59df5fc3ad0606b2..258115b10fa9e448129d84a0663ab99d51c64ee5 100644 (file)
@@ -521,10 +521,11 @@ static irqreturn_t rk_iommu_irq(int irq, void *dev_id)
        u32 int_status;
        dma_addr_t iova;
        irqreturn_t ret = IRQ_NONE;
-       int i;
+       int i, err;
 
-       if (WARN_ON(!pm_runtime_get_if_in_use(iommu->dev)))
-               return 0;
+       err = pm_runtime_get_if_in_use(iommu->dev);
+       if (WARN_ON_ONCE(err <= 0))
+               return ret;
 
        if (WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks)))
                goto out;
@@ -620,11 +621,15 @@ static void rk_iommu_zap_iova(struct rk_iommu_domain *rk_domain,
        spin_lock_irqsave(&rk_domain->iommus_lock, flags);
        list_for_each(pos, &rk_domain->iommus) {
                struct rk_iommu *iommu;
+               int ret;
 
                iommu = list_entry(pos, struct rk_iommu, node);
 
                /* Only zap TLBs of IOMMUs that are powered on. */
-               if (pm_runtime_get_if_in_use(iommu->dev)) {
+               ret = pm_runtime_get_if_in_use(iommu->dev);
+               if (WARN_ON_ONCE(ret < 0))
+                       continue;
+               if (ret) {
                        WARN_ON(clk_bulk_enable(iommu->num_clocks,
                                                iommu->clocks));
                        rk_iommu_zap_lines(iommu, iova, size);
@@ -891,6 +896,7 @@ static void rk_iommu_detach_device(struct iommu_domain *domain,
        struct rk_iommu *iommu;
        struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
        unsigned long flags;
+       int ret;
 
        /* Allow 'virtual devices' (eg drm) to detach from domain */
        iommu = rk_iommu_from_dev(dev);
@@ -909,7 +915,9 @@ static void rk_iommu_detach_device(struct iommu_domain *domain,
        list_del_init(&iommu->node);
        spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
 
-       if (pm_runtime_get_if_in_use(iommu->dev)) {
+       ret = pm_runtime_get_if_in_use(iommu->dev);
+       WARN_ON_ONCE(ret < 0);
+       if (ret > 0) {
                rk_iommu_disable(iommu);
                pm_runtime_put(iommu->dev);
        }
@@ -946,7 +954,8 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
        list_add_tail(&iommu->node, &rk_domain->iommus);
        spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
 
-       if (!pm_runtime_get_if_in_use(iommu->dev))
+       ret = pm_runtime_get_if_in_use(iommu->dev);
+       if (!ret || WARN_ON_ONCE(ret < 0))
                return 0;
 
        ret = rk_iommu_enable(iommu);
@@ -1110,7 +1119,6 @@ static const struct iommu_ops rk_iommu_ops = {
        .detach_dev = rk_iommu_detach_device,
        .map = rk_iommu_map,
        .unmap = rk_iommu_unmap,
-       .map_sg = default_iommu_map_sg,
        .add_device = rk_iommu_add_device,
        .remove_device = rk_iommu_remove_device,
        .iova_to_phys = rk_iommu_iova_to_phys,
@@ -1152,17 +1160,6 @@ static int rk_iommu_probe(struct platform_device *pdev)
        if (iommu->num_mmu == 0)
                return PTR_ERR(iommu->bases[0]);
 
-       i = 0;
-       while ((irq = platform_get_irq(pdev, i++)) != -ENXIO) {
-               if (irq < 0)
-                       return irq;
-
-               err = devm_request_irq(iommu->dev, irq, rk_iommu_irq,
-                                      IRQF_SHARED, dev_name(dev), iommu);
-               if (err)
-                       return err;
-       }
-
        iommu->reset_disabled = device_property_read_bool(dev,
                                        "rockchip,disable-mmu-reset");
 
@@ -1219,6 +1216,19 @@ static int rk_iommu_probe(struct platform_device *pdev)
 
        pm_runtime_enable(dev);
 
+       i = 0;
+       while ((irq = platform_get_irq(pdev, i++)) != -ENXIO) {
+               if (irq < 0)
+                       return irq;
+
+               err = devm_request_irq(iommu->dev, irq, rk_iommu_irq,
+                                      IRQF_SHARED, dev_name(dev), iommu);
+               if (err) {
+                       pm_runtime_disable(dev);
+                       goto err_remove_sysfs;
+               }
+       }
+
        return 0;
 err_remove_sysfs:
        iommu_device_sysfs_remove(&iommu->iommu);
index a004f6da35f21f0d751eeefce10c65de3a3c08a0..7b1361d57a17f043c809d5515591d1f1568862bc 100644 (file)
@@ -377,7 +377,6 @@ static const struct iommu_ops gart_iommu_ops = {
        .remove_device  = gart_iommu_remove_device,
        .device_group   = generic_device_group,
        .map            = gart_iommu_map,
-       .map_sg         = default_iommu_map_sg,
        .unmap          = gart_iommu_unmap,
        .iova_to_phys   = gart_iommu_iova_to_phys,
        .pgsize_bitmap  = GART_IOMMU_PGSIZES,
index 44d40bc771b516d52b91928f5441748918b557fa..0d03341317c466be5f71d6dd7cae5d53939eef26 100644 (file)
@@ -876,7 +876,6 @@ static const struct iommu_ops tegra_smmu_ops = {
        .device_group = tegra_smmu_device_group,
        .map = tegra_smmu_map,
        .unmap = tegra_smmu_unmap,
-       .map_sg = default_iommu_map_sg,
        .iova_to_phys = tegra_smmu_iova_to_phys,
        .of_xlate = tegra_smmu_of_xlate,
        .pgsize_bitmap = SZ_4K,
index faf734ff4cf3bc69c2a27d8b0ef1555530584fd1..0f6e30e9009da533c6a4bc6c3cf5e79fe2ae748c 100644 (file)
@@ -217,6 +217,7 @@ static int bcm7038_l1_set_affinity(struct irq_data *d,
        return 0;
 }
 
+#ifdef CONFIG_SMP
 static void bcm7038_l1_cpu_offline(struct irq_data *d)
 {
        struct cpumask *mask = irq_data_get_affinity_mask(d);
@@ -241,6 +242,7 @@ static void bcm7038_l1_cpu_offline(struct irq_data *d)
        }
        irq_set_affinity_locked(d, &new_affinity, false);
 }
+#endif
 
 static int __init bcm7038_l1_init_one(struct device_node *dn,
                                      unsigned int idx,
@@ -293,7 +295,9 @@ static struct irq_chip bcm7038_l1_irq_chip = {
        .irq_mask               = bcm7038_l1_mask,
        .irq_unmask             = bcm7038_l1_unmask,
        .irq_set_affinity       = bcm7038_l1_set_affinity,
+#ifdef CONFIG_SMP
        .irq_cpu_offline        = bcm7038_l1_cpu_offline,
+#endif
 };
 
 static int bcm7038_l1_map(struct irq_domain *d, unsigned int virq,
index 316a57530f6d108ace5345f0e4077e8f20771924..c2df341ff6fafd83df6463669c9ad6a1ceac56c9 100644 (file)
@@ -1439,6 +1439,7 @@ static struct irq_chip its_irq_chip = {
  * The consequence of the above is that allocation is cost is low, but
  * freeing is expensive. We assumes that freeing rarely occurs.
  */
+#define ITS_MAX_LPI_NRBITS     16 /* 64K LPIs */
 
 static DEFINE_MUTEX(lpi_range_lock);
 static LIST_HEAD(lpi_range_list);
@@ -1625,7 +1626,8 @@ static int __init its_alloc_lpi_tables(void)
 {
        phys_addr_t paddr;
 
-       lpi_id_bits = GICD_TYPER_ID_BITS(gic_rdists->gicd_typer);
+       lpi_id_bits = min_t(u32, GICD_TYPER_ID_BITS(gic_rdists->gicd_typer),
+                               ITS_MAX_LPI_NRBITS);
        gic_rdists->prop_page = its_allocate_prop_table(GFP_NOWAIT);
        if (!gic_rdists->prop_page) {
                pr_err("Failed to allocate PROPBASE\n");
index e214181b77b7720568c072c0b0cb07bc81766565..d5912f1ec8848d19ff93161102d6690eb7bb43d2 100644 (file)
@@ -861,7 +861,9 @@ static struct irq_chip gic_chip = {
        .irq_set_affinity       = gic_set_affinity,
        .irq_get_irqchip_state  = gic_irq_get_irqchip_state,
        .irq_set_irqchip_state  = gic_irq_set_irqchip_state,
-       .flags                  = IRQCHIP_SET_TYPE_MASKED,
+       .flags                  = IRQCHIP_SET_TYPE_MASKED |
+                                 IRQCHIP_SKIP_SET_WAKE |
+                                 IRQCHIP_MASK_ON_SUSPEND,
 };
 
 static struct irq_chip gic_eoimode1_chip = {
@@ -874,7 +876,9 @@ static struct irq_chip gic_eoimode1_chip = {
        .irq_get_irqchip_state  = gic_irq_get_irqchip_state,
        .irq_set_irqchip_state  = gic_irq_set_irqchip_state,
        .irq_set_vcpu_affinity  = gic_irq_set_vcpu_affinity,
-       .flags                  = IRQCHIP_SET_TYPE_MASKED,
+       .flags                  = IRQCHIP_SET_TYPE_MASKED |
+                                 IRQCHIP_SKIP_SET_WAKE |
+                                 IRQCHIP_MASK_ON_SUSPEND,
 };
 
 #define GIC_ID_NR      (1U << GICD_TYPER_ID_BITS(gic_data.rdists.gicd_typer))
index aed31afb02169ca165271ea742a036ca71ac9879..85234d4566386c67677c1f06be3ff77bde24b1b8 100644 (file)
@@ -12,7 +12,7 @@
 #include <asm/io.h>
 
 static void *intc_baseaddr;
-#define IPRA ((unsigned long)intc_baseaddr)
+#define IPRA (intc_baseaddr)
 
 static const unsigned char ipr_table[] = {
        0x03, 0x02, 0x01, 0x00, 0x13, 0x12, 0x11, 0x10, /* 16 - 23 */
@@ -34,7 +34,7 @@ static const unsigned char ipr_table[] = {
 static void h8s_disable_irq(struct irq_data *data)
 {
        int pos;
-       unsigned int addr;
+       void __iomem *addr;
        unsigned short pri;
        int irq = data->irq;
 
@@ -48,7 +48,7 @@ static void h8s_disable_irq(struct irq_data *data)
 static void h8s_enable_irq(struct irq_data *data)
 {
        int pos;
-       unsigned int addr;
+       void __iomem *addr;
        unsigned short pri;
        int irq = data->irq;
 
index f6fd57ebe6e6468f3ce98ec90cb1b7de5b9e6bfc..c19766fe8a1ae9c8a1573d304119fe36a5540f90 100644 (file)
@@ -250,7 +250,7 @@ static int s3c_irqext0_type(struct irq_data *data, unsigned int type)
        void __iomem *gpcon_reg;
        unsigned long gpcon_offset, extint_offset;
 
-       if ((data->hwirq >= 0) && (data->hwirq <= 3)) {
+       if (data->hwirq <= 3) {
                gpcon_reg = S3C2410_GPFCON;
                extint_reg = S3C24XX_EXTINT0;
                gpcon_offset = (data->hwirq) * 2;
index 3df527fcf4e154b44bed2cc3c65787fef503db6c..0a2088e12d96fdf5525b48613ac818e5061064c9 100644 (file)
@@ -603,17 +603,24 @@ stm32_exti_host_data *stm32_exti_host_init(const struct stm32_exti_drv_data *dd,
                                        sizeof(struct stm32_exti_chip_data),
                                        GFP_KERNEL);
        if (!host_data->chips_data)
-               return NULL;
+               goto free_host_data;
 
        host_data->base = of_iomap(node, 0);
        if (!host_data->base) {
                pr_err("%pOF: Unable to map registers\n", node);
-               return NULL;
+               goto free_chips_data;
        }
 
        stm32_host_data = host_data;
 
        return host_data;
+
+free_chips_data:
+       kfree(host_data->chips_data);
+free_host_data:
+       kfree(host_data);
+
+       return NULL;
 }
 
 static struct
@@ -665,10 +672,8 @@ static int __init stm32_exti_init(const struct stm32_exti_drv_data *drv_data,
        struct irq_domain *domain;
 
        host_data = stm32_exti_host_init(drv_data, node);
-       if (!host_data) {
-               ret = -ENOMEM;
-               goto out_free_mem;
-       }
+       if (!host_data)
+               return -ENOMEM;
 
        domain = irq_domain_add_linear(node, drv_data->bank_nr * IRQS_PER_BANK,
                                       &irq_exti_domain_ops, NULL);
@@ -725,7 +730,6 @@ out_free_domain:
        irq_domain_remove(domain);
 out_unmap:
        iounmap(host_data->base);
-out_free_mem:
        kfree(host_data->chips_data);
        kfree(host_data);
        return ret;
@@ -752,10 +756,8 @@ __init stm32_exti_hierarchy_init(const struct stm32_exti_drv_data *drv_data,
        }
 
        host_data = stm32_exti_host_init(drv_data, node);
-       if (!host_data) {
-               ret = -ENOMEM;
-               goto out_free_mem;
-       }
+       if (!host_data)
+               return -ENOMEM;
 
        for (i = 0; i < drv_data->bank_nr; i++)
                stm32_exti_chip_init(host_data, i, node);
@@ -777,7 +779,6 @@ __init stm32_exti_hierarchy_init(const struct stm32_exti_drv_data *drv_data,
 
 out_unmap:
        iounmap(host_data->base);
-out_free_mem:
        kfree(host_data->chips_data);
        kfree(host_data);
        return ret;
index 0c085303a58302cc982f69e52b0a5ea8e5c60c25..580e2d72b9ba42e9e5887296a73d0d5279a496a0 100644 (file)
@@ -205,8 +205,7 @@ static int __init tangox_irq_init(void __iomem *base, struct resource *baseres,
 
        tangox_irq_domain_init(dom);
 
-       irq_set_chained_handler(irq, tangox_irq_handler);
-       irq_set_handler_data(irq, dom);
+       irq_set_chained_handler_and_data(irq, tangox_irq_handler, dom);
 
        return 0;
 }
index a15a9510c90439b11072fe5cc88f6f4656414388..e539500752d463f6051fce31085866dbd4abc853 100644 (file)
@@ -98,14 +98,12 @@ static void xtensa_mx_irq_unmask(struct irq_data *d)
 
 static void xtensa_mx_irq_enable(struct irq_data *d)
 {
-       variant_irq_enable(d->hwirq);
        xtensa_mx_irq_unmask(d);
 }
 
 static void xtensa_mx_irq_disable(struct irq_data *d)
 {
        xtensa_mx_irq_mask(d);
-       variant_irq_disable(d->hwirq);
 }
 
 static void xtensa_mx_irq_ack(struct irq_data *d)
index f728755fa2922019e6b117105f3a9b9dfe0fc3e9..000cb5462bcf40a379b8703b59d96e2b90460d22 100644 (file)
@@ -55,14 +55,12 @@ static void xtensa_irq_unmask(struct irq_data *d)
 
 static void xtensa_irq_enable(struct irq_data *d)
 {
-       variant_irq_enable(d->hwirq);
        xtensa_irq_unmask(d);
 }
 
 static void xtensa_irq_disable(struct irq_data *d)
 {
        xtensa_irq_mask(d);
-       variant_irq_disable(d->hwirq);
 }
 
 static void xtensa_irq_ack(struct irq_data *d)
index 68dcbcb4fc5bc2b33682d1bee513747656067d18..8c744578122a3e229079571b7bce093380c90662 100644 (file)
@@ -432,7 +432,6 @@ static struct i2c_driver g4fan_driver = {
        .driver = {
                .name   = "therm_windtunnel",
        },
-       .attach_adapter = do_attach,
        .probe          = do_probe,
        .remove         = do_remove,
        .id_table       = therm_windtunnel_id,
@@ -445,7 +444,29 @@ static struct i2c_driver g4fan_driver = {
 
 static int therm_of_probe(struct platform_device *dev)
 {
-       return i2c_add_driver( &g4fan_driver );
+       struct i2c_adapter *adap;
+       int ret, i = 0;
+
+       adap = i2c_get_adapter(0);
+       if (!adap)
+               return -EPROBE_DEFER;
+
+       ret = i2c_add_driver(&g4fan_driver);
+       if (ret) {
+               i2c_put_adapter(adap);
+               return ret;
+       }
+
+       /* We assume Macs have consecutive I2C bus numbers starting at 0 */
+       while (adap) {
+               do_attach(adap);
+               if (x.running)
+                       return 0;
+               i2c_put_adapter(adap);
+               adap = i2c_get_adapter(++i);
+       }
+
+       return -ENODEV;
 }
 
 static int
index 17bf109c58e9e4206dd055e81a571bfb79236fd4..f6e0a8b3a61ed34b7b36e02c639c5e7507c23857 100644 (file)
@@ -1,7 +1,8 @@
 
 config BCACHE
        tristate "Block device as cache"
-       ---help---
+       select CRC64
+       help
        Allows a block device to be used as cache for other devices; uses
        a btree for indexing and the layout is optimized for SSDs.
 
@@ -10,7 +11,7 @@ config BCACHE
 config BCACHE_DEBUG
        bool "Bcache debugging"
        depends on BCACHE
-       ---help---
+       help
        Don't select this option unless you're a developer
 
        Enables extra debugging tools, allows expensive runtime checks to be
@@ -20,7 +21,7 @@ config BCACHE_CLOSURES_DEBUG
        bool "Debug closures"
        depends on BCACHE
        select DEBUG_FS
-       ---help---
+       help
        Keeps all active closures in a linked list and provides a debugfs
        interface to list them, which makes it possible to see asynchronous
        operations that get stuck.
index 7fa2631b422c89a160a6e49165bcf639d7d235e2..7a28232d868bd1b2c20081149d1ef6f3afec786a 100644 (file)
@@ -87,8 +87,8 @@ void bch_rescale_priorities(struct cache_set *c, int sectors)
 {
        struct cache *ca;
        struct bucket *b;
-       unsigned next = c->nbuckets * c->sb.bucket_size / 1024;
-       unsigned i;
+       unsigned int next = c->nbuckets * c->sb.bucket_size / 1024;
+       unsigned int i;
        int r;
 
        atomic_sub(sectors, &c->rescale);
@@ -169,7 +169,7 @@ static void bch_invalidate_one_bucket(struct cache *ca, struct bucket *b)
 
 #define bucket_prio(b)                                                 \
 ({                                                                     \
-       unsigned min_prio = (INITIAL_PRIO - ca->set->min_prio) / 8;     \
+       unsigned int min_prio = (INITIAL_PRIO - ca->set->min_prio) / 8; \
                                                                        \
        (b->prio - ca->set->min_prio + min_prio) * GC_SECTORS_USED(b);  \
 })
@@ -244,6 +244,7 @@ static void invalidate_buckets_random(struct cache *ca)
 
        while (!fifo_full(&ca->free_inc)) {
                size_t n;
+
                get_random_bytes(&n, sizeof(n));
 
                n %= (size_t) (ca->sb.nbuckets - ca->sb.first_bucket);
@@ -301,7 +302,7 @@ do {                                                                        \
 
 static int bch_allocator_push(struct cache *ca, long bucket)
 {
-       unsigned i;
+       unsigned int i;
 
        /* Prios/gens are actually the most important reserve */
        if (fifo_push(&ca->free[RESERVE_PRIO], bucket))
@@ -385,7 +386,7 @@ out:
 
 /* Allocation */
 
-long bch_bucket_alloc(struct cache *ca, unsigned reserve, bool wait)
+long bch_bucket_alloc(struct cache *ca, unsigned int reserve, bool wait)
 {
        DEFINE_WAIT(w);
        struct bucket *b;
@@ -421,7 +422,7 @@ out:
        if (expensive_debug_checks(ca->set)) {
                size_t iter;
                long i;
-               unsigned j;
+               unsigned int j;
 
                for (iter = 0; iter < prio_buckets(ca) * 2; iter++)
                        BUG_ON(ca->prio_buckets[iter] == (uint64_t) r);
@@ -470,14 +471,14 @@ void __bch_bucket_free(struct cache *ca, struct bucket *b)
 
 void bch_bucket_free(struct cache_set *c, struct bkey *k)
 {
-       unsigned i;
+       unsigned int i;
 
        for (i = 0; i < KEY_PTRS(k); i++)
                __bch_bucket_free(PTR_CACHE(c, k, i),
                                  PTR_BUCKET(c, k, i));
 }
 
-int __bch_bucket_alloc_set(struct cache_set *c, unsigned reserve,
+int __bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve,
                           struct bkey *k, int n, bool wait)
 {
        int i;
@@ -510,10 +511,11 @@ err:
        return -1;
 }
 
-int bch_bucket_alloc_set(struct cache_set *c, unsigned reserve,
+int bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve,
                         struct bkey *k, int n, bool wait)
 {
        int ret;
+
        mutex_lock(&c->bucket_lock);
        ret = __bch_bucket_alloc_set(c, reserve, k, n, wait);
        mutex_unlock(&c->bucket_lock);
@@ -524,8 +526,8 @@ int bch_bucket_alloc_set(struct cache_set *c, unsigned reserve,
 
 struct open_bucket {
        struct list_head        list;
-       unsigned                last_write_point;
-       unsigned                sectors_free;
+       unsigned int            last_write_point;
+       unsigned int            sectors_free;
        BKEY_PADDED(key);
 };
 
@@ -556,7 +558,7 @@ struct open_bucket {
  */
 static struct open_bucket *pick_data_bucket(struct cache_set *c,
                                            const struct bkey *search,
-                                           unsigned write_point,
+                                           unsigned int write_point,
                                            struct bkey *alloc)
 {
        struct open_bucket *ret, *ret_task = NULL;
@@ -595,12 +597,16 @@ found:
  *
  * If s->writeback is true, will not fail.
  */
-bool bch_alloc_sectors(struct cache_set *c, struct bkey *k, unsigned sectors,
-                      unsigned write_point, unsigned write_prio, bool wait)
+bool bch_alloc_sectors(struct cache_set *c,
+                      struct bkey *k,
+                      unsigned int sectors,
+                      unsigned int write_point,
+                      unsigned int write_prio,
+                      bool wait)
 {
        struct open_bucket *b;
        BKEY_PADDED(key) alloc;
-       unsigned i;
+       unsigned int i;
 
        /*
         * We might have to allocate a new bucket, which we can't do with a
@@ -613,7 +619,7 @@ bool bch_alloc_sectors(struct cache_set *c, struct bkey *k, unsigned sectors,
        spin_lock(&c->data_bucket_lock);
 
        while (!(b = pick_data_bucket(c, k, write_point, &alloc.key))) {
-               unsigned watermark = write_prio
+               unsigned int watermark = write_prio
                        ? RESERVE_MOVINGGC
                        : RESERVE_NONE;
 
@@ -702,6 +708,7 @@ int bch_open_buckets_alloc(struct cache_set *c)
 
        for (i = 0; i < MAX_OPEN_BUCKETS; i++) {
                struct open_bucket *b = kzalloc(sizeof(*b), GFP_KERNEL);
+
                if (!b)
                        return -ENOMEM;
 
index 05f82ff6f016ebc348381cefda2258b23101b4af..83504dd8100ab2a80d7f0e737e50266de41add32 100644 (file)
@@ -252,7 +252,7 @@ struct bcache_device {
        struct kobject          kobj;
 
        struct cache_set        *c;
-       unsigned                id;
+       unsigned int            id;
 #define BCACHEDEVNAME_SIZE     12
        char                    name[BCACHEDEVNAME_SIZE];
 
@@ -264,18 +264,19 @@ struct bcache_device {
 #define BCACHE_DEV_UNLINK_DONE         2
 #define BCACHE_DEV_WB_RUNNING          3
 #define BCACHE_DEV_RATE_DW_RUNNING     4
-       unsigned                nr_stripes;
-       unsigned                stripe_size;
+       unsigned int            nr_stripes;
+       unsigned int            stripe_size;
        atomic_t                *stripe_sectors_dirty;
        unsigned long           *full_dirty_stripes;
 
        struct bio_set          bio_split;
 
-       unsigned                data_csum:1;
+       unsigned int            data_csum:1;
 
-       int (*cache_miss)(struct btree *, struct search *,
-                         struct bio *, unsigned);
-       int (*ioctl) (struct bcache_device *, fmode_t, unsigned, unsigned long);
+       int (*cache_miss)(struct btree *b, struct search *s,
+                         struct bio *bio, unsigned int sectors);
+       int (*ioctl)(struct bcache_device *d, fmode_t mode,
+                    unsigned int cmd, unsigned long arg);
 };
 
 struct io {
@@ -284,7 +285,7 @@ struct io {
        struct list_head        lru;
 
        unsigned long           jiffies;
-       unsigned                sequential;
+       unsigned int            sequential;
        sector_t                last;
 };
 
@@ -358,18 +359,18 @@ struct cached_dev {
        struct cache_accounting accounting;
 
        /* The rest of this all shows up in sysfs */
-       unsigned                sequential_cutoff;
-       unsigned                readahead;
+       unsigned int            sequential_cutoff;
+       unsigned int            readahead;
 
-       unsigned                io_disable:1;
-       unsigned                verify:1;
-       unsigned                bypass_torture_test:1;
+       unsigned int            io_disable:1;
+       unsigned int            verify:1;
+       unsigned int            bypass_torture_test:1;
 
-       unsigned                partial_stripes_expensive:1;
-       unsigned                writeback_metadata:1;
-       unsigned                writeback_running:1;
+       unsigned int            partial_stripes_expensive:1;
+       unsigned int            writeback_metadata:1;
+       unsigned int            writeback_running:1;
        unsigned char           writeback_percent;
-       unsigned                writeback_delay;
+       unsigned int            writeback_delay;
 
        uint64_t                writeback_rate_target;
        int64_t                 writeback_rate_proportional;
@@ -377,16 +378,16 @@ struct cached_dev {
        int64_t                 writeback_rate_integral_scaled;
        int32_t                 writeback_rate_change;
 
-       unsigned                writeback_rate_update_seconds;
-       unsigned                writeback_rate_i_term_inverse;
-       unsigned                writeback_rate_p_term_inverse;
-       unsigned                writeback_rate_minimum;
+       unsigned int            writeback_rate_update_seconds;
+       unsigned int            writeback_rate_i_term_inverse;
+       unsigned int            writeback_rate_p_term_inverse;
+       unsigned int            writeback_rate_minimum;
 
        enum stop_on_failure    stop_when_cache_set_failed;
 #define DEFAULT_CACHED_DEV_ERROR_LIMIT 64
        atomic_t                io_errors;
-       unsigned                error_limit;
-       unsigned                offline_seconds;
+       unsigned int            error_limit;
+       unsigned int            offline_seconds;
 
        char                    backing_dev_name[BDEVNAME_SIZE];
 };
@@ -447,7 +448,7 @@ struct cache {
         * until a gc finishes - otherwise we could pointlessly burn a ton of
         * cpu
         */
-       unsigned                invalidate_needs_gc;
+       unsigned int            invalidate_needs_gc;
 
        bool                    discard; /* Get rid of? */
 
@@ -472,7 +473,7 @@ struct gc_stat {
 
        size_t                  nkeys;
        uint64_t                data;   /* sectors */
-       unsigned                in_use; /* percent */
+       unsigned int            in_use; /* percent */
 };
 
 /*
@@ -518,7 +519,7 @@ struct cache_set {
        int                     caches_loaded;
 
        struct bcache_device    **devices;
-       unsigned                devices_max_used;
+       unsigned int            devices_max_used;
        atomic_t                attached_dev_nr;
        struct list_head        cached_devs;
        uint64_t                cached_dev_sectors;
@@ -548,7 +549,7 @@ struct cache_set {
         * Default number of pages for a new btree node - may be less than a
         * full bucket
         */
-       unsigned                btree_pages;
+       unsigned int            btree_pages;
 
        /*
         * Lists of struct btrees; lru is the list for structs that have memory
@@ -571,7 +572,7 @@ struct cache_set {
        struct list_head        btree_cache_freed;
 
        /* Number of elements in btree_cache + btree_cache_freeable lists */
-       unsigned                btree_cache_used;
+       unsigned int            btree_cache_used;
 
        /*
         * If we need to allocate memory for a new btree node and that
@@ -613,8 +614,8 @@ struct cache_set {
        uint16_t                min_prio;
 
        /*
-        * max(gen - last_gc) for all buckets. When it gets too big we have to gc
-        * to keep gens from wrapping around.
+        * max(gen - last_gc) for all buckets. When it gets too big we have to
+        * gc to keep gens from wrapping around.
         */
        uint8_t                 need_gc;
        struct gc_stat          gc_stats;
@@ -649,7 +650,7 @@ struct cache_set {
        struct mutex            verify_lock;
 #endif
 
-       unsigned                nr_uuids;
+       unsigned int            nr_uuids;
        struct uuid_entry       *uuids;
        BKEY_PADDED(uuid_bucket);
        struct closure          uuid_write;
@@ -670,12 +671,12 @@ struct cache_set {
        struct journal          journal;
 
 #define CONGESTED_MAX          1024
-       unsigned                congested_last_us;
+       unsigned int            congested_last_us;
        atomic_t                congested;
 
        /* The rest of this all shows up in sysfs */
-       unsigned                congested_read_threshold_us;
-       unsigned                congested_write_threshold_us;
+       unsigned int            congested_read_threshold_us;
+       unsigned int            congested_write_threshold_us;
 
        struct time_stats       btree_gc_time;
        struct time_stats       btree_split_time;
@@ -694,16 +695,16 @@ struct cache_set {
                ON_ERROR_PANIC,
        }                       on_error;
 #define DEFAULT_IO_ERROR_LIMIT 8
-       unsigned                error_limit;
-       unsigned                error_decay;
+       unsigned int            error_limit;
+       unsigned int            error_decay;
 
        unsigned short          journal_delay_ms;
        bool                    expensive_debug_checks;
-       unsigned                verify:1;
-       unsigned                key_merging_disabled:1;
-       unsigned                gc_always_rewrite:1;
-       unsigned                shrinker_disabled:1;
-       unsigned                copy_gc_enabled:1;
+       unsigned int            verify:1;
+       unsigned int            key_merging_disabled:1;
+       unsigned int            gc_always_rewrite:1;
+       unsigned int            shrinker_disabled:1;
+       unsigned int            copy_gc_enabled:1;
 
 #define BUCKET_HASH_BITS       12
        struct hlist_head       bucket_hash[1 << BUCKET_HASH_BITS];
@@ -712,7 +713,7 @@ struct cache_set {
 };
 
 struct bbio {
-       unsigned                submit_time_us;
+       unsigned int            submit_time_us;
        union {
                struct bkey     key;
                uint64_t        _pad[3];
@@ -729,10 +730,10 @@ struct bbio {
 
 #define btree_bytes(c)         ((c)->btree_pages * PAGE_SIZE)
 #define btree_blocks(b)                                                        \
-       ((unsigned) (KEY_SIZE(&b->key) >> (b)->c->block_bits))
+       ((unsigned int) (KEY_SIZE(&b->key) >> (b)->c->block_bits))
 
 #define btree_default_blocks(c)                                                \
-       ((unsigned) ((PAGE_SECTORS * (c)->btree_pages) >> (c)->block_bits))
+       ((unsigned int) ((PAGE_SECTORS * (c)->btree_pages) >> (c)->block_bits))
 
 #define bucket_pages(c)                ((c)->sb.bucket_size / PAGE_SECTORS)
 #define bucket_bytes(c)                ((c)->sb.bucket_size << 9)
@@ -761,21 +762,21 @@ static inline sector_t bucket_remainder(struct cache_set *c, sector_t s)
 
 static inline struct cache *PTR_CACHE(struct cache_set *c,
                                      const struct bkey *k,
-                                     unsigned ptr)
+                                     unsigned int ptr)
 {
        return c->cache[PTR_DEV(k, ptr)];
 }
 
 static inline size_t PTR_BUCKET_NR(struct cache_set *c,
                                   const struct bkey *k,
-                                  unsigned ptr)
+                                  unsigned int ptr)
 {
        return sector_to_bucket(c, PTR_OFFSET(k, ptr));
 }
 
 static inline struct bucket *PTR_BUCKET(struct cache_set *c,
                                        const struct bkey *k,
-                                       unsigned ptr)
+                                       unsigned int ptr)
 {
        return PTR_CACHE(c, k, ptr)->buckets + PTR_BUCKET_NR(c, k, ptr);
 }
@@ -783,17 +784,18 @@ static inline struct bucket *PTR_BUCKET(struct cache_set *c,
 static inline uint8_t gen_after(uint8_t a, uint8_t b)
 {
        uint8_t r = a - b;
+
        return r > 128U ? 0 : r;
 }
 
 static inline uint8_t ptr_stale(struct cache_set *c, const struct bkey *k,
-                               unsigned i)
+                               unsigned int i)
 {
        return gen_after(PTR_BUCKET(c, k, i)->gen, PTR_GEN(k, i));
 }
 
 static inline bool ptr_available(struct cache_set *c, const struct bkey *k,
-                                unsigned i)
+                                unsigned int i)
 {
        return (PTR_DEV(k, i) < MAX_CACHES_PER_SET) && PTR_CACHE(c, k, i);
 }
@@ -879,16 +881,16 @@ static inline uint8_t bucket_gc_gen(struct bucket *b)
 #define BUCKET_GC_GEN_MAX      96U
 
 #define kobj_attribute_write(n, fn)                                    \
-       static struct kobj_attribute ksysfs_##n = __ATTR(n, S_IWUSR, NULL, fn)
+       static struct kobj_attribute ksysfs_##n = __ATTR(n, 0200, NULL, fn)
 
 #define kobj_attribute_rw(n, show, store)                              \
        static struct kobj_attribute ksysfs_##n =                       \
-               __ATTR(n, S_IWUSR|S_IRUSR, show, store)
+               __ATTR(n, 0600, show, store)
 
 static inline void wake_up_allocators(struct cache_set *c)
 {
        struct cache *ca;
-       unsigned i;
+       unsigned int i;
 
        for_each_cache(ca, c, i)
                wake_up_process(ca->alloc_thread);
@@ -924,40 +926,43 @@ static inline void wait_for_kthread_stop(void)
 /* Forward declarations */
 
 void bch_count_backing_io_errors(struct cached_dev *dc, struct bio *bio);
-void bch_count_io_errors(struct cache *, blk_status_t, int, const char *);
-void bch_bbio_count_io_errors(struct cache_set *, struct bio *,
-                             blk_status_t, const char *);
-void bch_bbio_endio(struct cache_set *, struct bio *, blk_status_t,
-               const char *);
-void bch_bbio_free(struct bio *, struct cache_set *);
-struct bio *bch_bbio_alloc(struct cache_set *);
-
-void __bch_submit_bbio(struct bio *, struct cache_set *);
-void bch_submit_bbio(struct bio *, struct cache_set *, struct bkey *, unsigned);
-
-uint8_t bch_inc_gen(struct cache *, struct bucket *);
-void bch_rescale_priorities(struct cache_set *, int);
-
-bool bch_can_invalidate_bucket(struct cache *, struct bucket *);
-void __bch_invalidate_one_bucket(struct cache *, struct bucket *);
-
-void __bch_bucket_free(struct cache *, struct bucket *);
-void bch_bucket_free(struct cache_set *, struct bkey *);
-
-long bch_bucket_alloc(struct cache *, unsigned, bool);
-int __bch_bucket_alloc_set(struct cache_set *, unsigned,
-                          struct bkey *, int, bool);
-int bch_bucket_alloc_set(struct cache_set *, unsigned,
-                        struct bkey *, int, bool);
-bool bch_alloc_sectors(struct cache_set *, struct bkey *, unsigned,
-                      unsigned, unsigned, bool);
+void bch_count_io_errors(struct cache *ca, blk_status_t error,
+                        int is_read, const char *m);
+void bch_bbio_count_io_errors(struct cache_set *c, struct bio *bio,
+                             blk_status_t error, const char *m);
+void bch_bbio_endio(struct cache_set *c, struct bio *bio,
+                   blk_status_t error, const char *m);
+void bch_bbio_free(struct bio *bio, struct cache_set *c);
+struct bio *bch_bbio_alloc(struct cache_set *c);
+
+void __bch_submit_bbio(struct bio *bio, struct cache_set *c);
+void bch_submit_bbio(struct bio *bio, struct cache_set *c,
+                    struct bkey *k, unsigned int ptr);
+
+uint8_t bch_inc_gen(struct cache *ca, struct bucket *b);
+void bch_rescale_priorities(struct cache_set *c, int sectors);
+
+bool bch_can_invalidate_bucket(struct cache *ca, struct bucket *b);
+void __bch_invalidate_one_bucket(struct cache *ca, struct bucket *b);
+
+void __bch_bucket_free(struct cache *ca, struct bucket *b);
+void bch_bucket_free(struct cache_set *c, struct bkey *k);
+
+long bch_bucket_alloc(struct cache *ca, unsigned int reserve, bool wait);
+int __bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve,
+                          struct bkey *k, int n, bool wait);
+int bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve,
+                        struct bkey *k, int n, bool wait);
+bool bch_alloc_sectors(struct cache_set *c, struct bkey *k,
+                      unsigned int sectors, unsigned int write_point,
+                      unsigned int write_prio, bool wait);
 bool bch_cached_dev_error(struct cached_dev *dc);
 
 __printf(2, 3)
-bool bch_cache_set_error(struct cache_set *, const char *, ...);
+bool bch_cache_set_error(struct cache_set *c, const char *fmt, ...);
 
-void bch_prio_write(struct cache *);
-void bch_write_bdev_super(struct cached_dev *, struct closure *);
+void bch_prio_write(struct cache *ca);
+void bch_write_bdev_super(struct cached_dev *dc, struct closure *parent);
 
 extern struct workqueue_struct *bcache_wq;
 extern struct mutex bch_register_lock;
@@ -969,30 +974,31 @@ extern struct kobj_type bch_cache_set_ktype;
 extern struct kobj_type bch_cache_set_internal_ktype;
 extern struct kobj_type bch_cache_ktype;
 
-void bch_cached_dev_release(struct kobject *);
-void bch_flash_dev_release(struct kobject *);
-void bch_cache_set_release(struct kobject *);
-void bch_cache_release(struct kobject *);
+void bch_cached_dev_release(struct kobject *kobj);
+void bch_flash_dev_release(struct kobject *kobj);
+void bch_cache_set_release(struct kobject *kobj);
+void bch_cache_release(struct kobject *kobj);
 
-int bch_uuid_write(struct cache_set *);
-void bcache_write_super(struct cache_set *);
+int bch_uuid_write(struct cache_set *c);
+void bcache_write_super(struct cache_set *c);
 
 int bch_flash_dev_create(struct cache_set *c, uint64_t size);
 
-int bch_cached_dev_attach(struct cached_dev *, struct cache_set *, uint8_t *);
-void bch_cached_dev_detach(struct cached_dev *);
-void bch_cached_dev_run(struct cached_dev *);
-void bcache_device_stop(struct bcache_device *);
-
-void bch_cache_set_unregister(struct cache_set *);
-void bch_cache_set_stop(struct cache_set *);
-
-struct cache_set *bch_cache_set_alloc(struct cache_sb *);
-void bch_btree_cache_free(struct cache_set *);
-int bch_btree_cache_alloc(struct cache_set *);
-void bch_moving_init_cache_set(struct cache_set *);
-int bch_open_buckets_alloc(struct cache_set *);
-void bch_open_buckets_free(struct cache_set *);
+int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c,
+                         uint8_t *set_uuid);
+void bch_cached_dev_detach(struct cached_dev *dc);
+void bch_cached_dev_run(struct cached_dev *dc);
+void bcache_device_stop(struct bcache_device *d);
+
+void bch_cache_set_unregister(struct cache_set *c);
+void bch_cache_set_stop(struct cache_set *c);
+
+struct cache_set *bch_cache_set_alloc(struct cache_sb *sb);
+void bch_btree_cache_free(struct cache_set *c);
+int bch_btree_cache_alloc(struct cache_set *c);
+void bch_moving_init_cache_set(struct cache_set *c);
+int bch_open_buckets_alloc(struct cache_set *c);
+void bch_open_buckets_free(struct cache_set *c);
 
 int bch_cache_allocator_start(struct cache *ca);
 
index 596c93b44e9b37ba9d7b1d96acc5aa20cb53d76a..8f07fa6e17394b5c0c54f7250f960f7361fd2111 100644 (file)
 
 #ifdef CONFIG_BCACHE_DEBUG
 
-void bch_dump_bset(struct btree_keys *b, struct bset *i, unsigned set)
+void bch_dump_bset(struct btree_keys *b, struct bset *i, unsigned int set)
 {
        struct bkey *k, *next;
 
        for (k = i->start; k < bset_bkey_last(i); k = next) {
                next = bkey_next(k);
 
-               printk(KERN_ERR "block %u key %u/%u: ", set,
-                      (unsigned) ((u64 *) k - i->d), i->keys);
+               pr_err("block %u key %u/%u: ", set,
+                      (unsigned int) ((u64 *) k - i->d), i->keys);
 
                if (b->ops->key_dump)
                        b->ops->key_dump(b, k);
                else
-                       printk("%llu:%llu\n", KEY_INODE(k), KEY_OFFSET(k));
+                       pr_err("%llu:%llu\n", KEY_INODE(k), KEY_OFFSET(k));
 
                if (next < bset_bkey_last(i) &&
                    bkey_cmp(k, b->ops->is_extents ?
                             &START_KEY(next) : next) > 0)
-                       printk(KERN_ERR "Key skipped backwards\n");
+                       pr_err("Key skipped backwards\n");
        }
 }
 
 void bch_dump_bucket(struct btree_keys *b)
 {
-       unsigned i;
+       unsigned int i;
 
        console_lock();
        for (i = 0; i <= b->nsets; i++)
@@ -53,7 +53,7 @@ void bch_dump_bucket(struct btree_keys *b)
 
 int __bch_count_data(struct btree_keys *b)
 {
-       unsigned ret = 0;
+       unsigned int ret = 0;
        struct btree_iter iter;
        struct bkey *k;
 
@@ -128,7 +128,7 @@ static inline void bch_btree_iter_next_check(struct btree_iter *iter) {}
 
 /* Keylists */
 
-int __bch_keylist_realloc(struct keylist *l, unsigned u64s)
+int __bch_keylist_realloc(struct keylist *l, unsigned int u64s)
 {
        size_t oldsize = bch_keylist_nkeys(l);
        size_t newsize = oldsize + u64s;
@@ -180,7 +180,7 @@ void bch_keylist_pop_front(struct keylist *l)
 /* Key/pointer manipulation */
 
 void bch_bkey_copy_single_ptr(struct bkey *dest, const struct bkey *src,
-                             unsigned i)
+                             unsigned int i)
 {
        BUG_ON(i > KEY_PTRS(src));
 
@@ -194,7 +194,7 @@ void bch_bkey_copy_single_ptr(struct bkey *dest, const struct bkey *src,
 
 bool __bch_cut_front(const struct bkey *where, struct bkey *k)
 {
-       unsigned i, len = 0;
+       unsigned int i, len = 0;
 
        if (bkey_cmp(where, &START_KEY(k)) <= 0)
                return false;
@@ -214,7 +214,7 @@ bool __bch_cut_front(const struct bkey *where, struct bkey *k)
 
 bool __bch_cut_back(const struct bkey *where, struct bkey *k)
 {
-       unsigned len = 0;
+       unsigned int len = 0;
 
        if (bkey_cmp(where, k) >= 0)
                return false;
@@ -240,9 +240,9 @@ bool __bch_cut_back(const struct bkey *where, struct bkey *k)
 #define BKEY_MANTISSA_MASK     ((1 << BKEY_MANTISSA_BITS) - 1)
 
 struct bkey_float {
-       unsigned        exponent:BKEY_EXPONENT_BITS;
-       unsigned        m:BKEY_MID_BITS;
-       unsigned        mantissa:BKEY_MANTISSA_BITS;
+       unsigned int    exponent:BKEY_EXPONENT_BITS;
+       unsigned int    m:BKEY_MID_BITS;
+       unsigned int    mantissa:BKEY_MANTISSA_BITS;
 } __packed;
 
 /*
@@ -311,7 +311,9 @@ void bch_btree_keys_free(struct btree_keys *b)
 }
 EXPORT_SYMBOL(bch_btree_keys_free);
 
-int bch_btree_keys_alloc(struct btree_keys *b, unsigned page_order, gfp_t gfp)
+int bch_btree_keys_alloc(struct btree_keys *b,
+                        unsigned int page_order,
+                        gfp_t gfp)
 {
        struct bset_tree *t = b->set;
 
@@ -345,7 +347,7 @@ EXPORT_SYMBOL(bch_btree_keys_alloc);
 void bch_btree_keys_init(struct btree_keys *b, const struct btree_keys_ops *ops,
                         bool *expensive_debug_checks)
 {
-       unsigned i;
+       unsigned int i;
 
        b->ops = ops;
        b->expensive_debug_checks = expensive_debug_checks;
@@ -370,7 +372,7 @@ EXPORT_SYMBOL(bch_btree_keys_init);
  * return array index next to j when does in-order traverse
  * of a binary tree which is stored in a linear array
  */
-static unsigned inorder_next(unsigned j, unsigned size)
+static unsigned int inorder_next(unsigned int j, unsigned int size)
 {
        if (j * 2 + 1 < size) {
                j = j * 2 + 1;
@@ -387,7 +389,7 @@ static unsigned inorder_next(unsigned j, unsigned size)
  * return array index previous to j when does in-order traverse
  * of a binary tree which is stored in a linear array
  */
-static unsigned inorder_prev(unsigned j, unsigned size)
+static unsigned int inorder_prev(unsigned int j, unsigned int size)
 {
        if (j * 2 < size) {
                j = j * 2;
@@ -400,7 +402,8 @@ static unsigned inorder_prev(unsigned j, unsigned size)
        return j;
 }
 
-/* I have no idea why this code works... and I'm the one who wrote it
+/*
+ * I have no idea why this code works... and I'm the one who wrote it
  *
  * However, I do know what it does:
  * Given a binary tree constructed in an array (i.e. how you normally implement
@@ -413,10 +416,12 @@ static unsigned inorder_prev(unsigned j, unsigned size)
  * extra is a function of size:
  *   extra = (size - rounddown_pow_of_two(size - 1)) << 1;
  */
-static unsigned __to_inorder(unsigned j, unsigned size, unsigned extra)
+static unsigned int __to_inorder(unsigned int j,
+                                 unsigned int size,
+                                 unsigned int extra)
 {
-       unsigned b = fls(j);
-       unsigned shift = fls(size - 1) - b;
+       unsigned int b = fls(j);
+       unsigned int shift = fls(size - 1) - b;
 
        j  ^= 1U << (b - 1);
        j <<= 1;
@@ -433,14 +438,16 @@ static unsigned __to_inorder(unsigned j, unsigned size, unsigned extra)
  * Return the cacheline index in bset_tree->data, where j is index
  * from a linear array which stores the auxiliar binary tree
  */
-static unsigned to_inorder(unsigned j, struct bset_tree *t)
+static unsigned int to_inorder(unsigned int j, struct bset_tree *t)
 {
        return __to_inorder(j, t->size, t->extra);
 }
 
-static unsigned __inorder_to_tree(unsigned j, unsigned size, unsigned extra)
+static unsigned int __inorder_to_tree(unsigned int j,
+                                     unsigned int size,
+                                     unsigned int extra)
 {
-       unsigned shift;
+       unsigned int shift;
 
        if (j > extra)
                j += j - extra;
@@ -457,7 +464,7 @@ static unsigned __inorder_to_tree(unsigned j, unsigned size, unsigned extra)
  * Return an index from a linear array which stores the auxiliar binary
  * tree, j is the cacheline index of t->data.
  */
-static unsigned inorder_to_tree(unsigned j, struct bset_tree *t)
+static unsigned int inorder_to_tree(unsigned int j, struct bset_tree *t)
 {
        return __inorder_to_tree(j, t->size, t->extra);
 }
@@ -468,14 +475,15 @@ void inorder_test(void)
        unsigned long done = 0;
        ktime_t start = ktime_get();
 
-       for (unsigned size = 2;
+       for (unsigned int size = 2;
             size < 65536000;
             size++) {
-               unsigned extra = (size - rounddown_pow_of_two(size - 1)) << 1;
-               unsigned i = 1, j = rounddown_pow_of_two(size - 1);
+               unsigned int extra =
+                       (size - rounddown_pow_of_two(size - 1)) << 1;
+               unsigned int i = 1, j = rounddown_pow_of_two(size - 1);
 
                if (!(size % 4096))
-                       printk(KERN_NOTICE "loop %u, %llu per us\n", size,
+                       pr_notice("loop %u, %llu per us\n", size,
                               done / ktime_us_delta(ktime_get(), start));
 
                while (1) {
@@ -518,30 +526,31 @@ void inorder_test(void)
  * of the previous key so we can walk backwards to it from t->tree[j]'s key.
  */
 
-static struct bkey *cacheline_to_bkey(struct bset_tree *t, unsigned cacheline,
-                                     unsigned offset)
+static struct bkey *cacheline_to_bkey(struct bset_tree *t,
+                                     unsigned int cacheline,
+                                     unsigned int offset)
 {
        return ((void *) t->data) + cacheline * BSET_CACHELINE + offset * 8;
 }
 
-static unsigned bkey_to_cacheline(struct bset_tree *t, struct bkey *k)
+static unsigned int bkey_to_cacheline(struct bset_tree *t, struct bkey *k)
 {
        return ((void *) k - (void *) t->data) / BSET_CACHELINE;
 }
 
-static unsigned bkey_to_cacheline_offset(struct bset_tree *t,
-                                        unsigned cacheline,
+static unsigned int bkey_to_cacheline_offset(struct bset_tree *t,
+                                        unsigned int cacheline,
                                         struct bkey *k)
 {
        return (u64 *) k - (u64 *) cacheline_to_bkey(t, cacheline, 0);
 }
 
-static struct bkey *tree_to_bkey(struct bset_tree *t, unsigned j)
+static struct bkey *tree_to_bkey(struct bset_tree *t, unsigned int j)
 {
        return cacheline_to_bkey(t, to_inorder(j, t), t->tree[j].m);
 }
 
-static struct bkey *tree_to_prev_bkey(struct bset_tree *t, unsigned j)
+static struct bkey *tree_to_prev_bkey(struct bset_tree *t, unsigned int j)
 {
        return (void *) (((uint64_t *) tree_to_bkey(t, j)) - t->prev[j]);
 }
@@ -550,7 +559,7 @@ static struct bkey *tree_to_prev_bkey(struct bset_tree *t, unsigned j)
  * For the write set - the one we're currently inserting keys into - we don't
  * maintain a full search tree, we just keep a simple lookup table in t->prev.
  */
-static struct bkey *table_to_bkey(struct bset_tree *t, unsigned cacheline)
+static struct bkey *table_to_bkey(struct bset_tree *t, unsigned int cacheline)
 {
        return cacheline_to_bkey(t, cacheline, t->prev[cacheline]);
 }
@@ -576,14 +585,15 @@ static inline uint64_t shrd128(uint64_t high, uint64_t low, uint8_t shift)
  * See make_bfloat() to check when most significant bit of f->exponent
  * is set or not.
  */
-static inline unsigned bfloat_mantissa(const struct bkey *k,
+static inline unsigned int bfloat_mantissa(const struct bkey *k,
                                       struct bkey_float *f)
 {
        const uint64_t *p = &k->low - (f->exponent >> 6);
+
        return shrd128(p[-1], p[0], f->exponent & 63) & BKEY_MANTISSA_MASK;
 }
 
-static void make_bfloat(struct bset_tree *t, unsigned j)
+static void make_bfloat(struct bset_tree *t, unsigned int j)
 {
        struct bkey_float *f = &t->tree[j];
        struct bkey *m = tree_to_bkey(t, j);
@@ -631,7 +641,7 @@ static void make_bfloat(struct bset_tree *t, unsigned j)
 static void bset_alloc_tree(struct btree_keys *b, struct bset_tree *t)
 {
        if (t != b->set) {
-               unsigned j = roundup(t[-1].size,
+               unsigned int j = roundup(t[-1].size,
                                     64 / sizeof(struct bkey_float));
 
                t->tree = t[-1].tree + j;
@@ -686,13 +696,13 @@ void bch_bset_build_written_tree(struct btree_keys *b)
 {
        struct bset_tree *t = bset_tree_last(b);
        struct bkey *prev = NULL, *k = t->data->start;
-       unsigned j, cacheline = 1;
+       unsigned int j, cacheline = 1;
 
        b->last_set_unwritten = 0;
 
        bset_alloc_tree(b, t);
 
-       t->size = min_t(unsigned,
+       t->size = min_t(unsigned int,
                        bkey_to_cacheline(t, bset_bkey_last(t->data)),
                        b->set->tree + btree_keys_cachelines(b) - t->tree);
 
@@ -732,7 +742,7 @@ EXPORT_SYMBOL(bch_bset_build_written_tree);
 void bch_bset_fix_invalidated_key(struct btree_keys *b, struct bkey *k)
 {
        struct bset_tree *t;
-       unsigned inorder, j = 1;
+       unsigned int inorder, j = 1;
 
        for (t = b->set; t <= bset_tree_last(b); t++)
                if (k < bset_bkey_last(t->data))
@@ -779,14 +789,15 @@ static void bch_bset_fix_lookup_table(struct btree_keys *b,
                                      struct bset_tree *t,
                                      struct bkey *k)
 {
-       unsigned shift = bkey_u64s(k);
-       unsigned j = bkey_to_cacheline(t, k);
+       unsigned int shift = bkey_u64s(k);
+       unsigned int j = bkey_to_cacheline(t, k);
 
        /* We're getting called from btree_split() or btree_gc, just bail out */
        if (!t->size)
                return;
 
-       /* k is the key we just inserted; we need to find the entry in the
+       /*
+        * k is the key we just inserted; we need to find the entry in the
         * lookup table for the first key that is strictly greater than k:
         * it's either k's cacheline or the next one
         */
@@ -794,7 +805,8 @@ static void bch_bset_fix_lookup_table(struct btree_keys *b,
               table_to_bkey(t, j) <= k)
                j++;
 
-       /* Adjust all the lookup table entries, and find a new key for any that
+       /*
+        * Adjust all the lookup table entries, and find a new key for any that
         * have gotten too big
         */
        for (; j < t->size; j++) {
@@ -819,7 +831,8 @@ static void bch_bset_fix_lookup_table(struct btree_keys *b,
             k != bset_bkey_last(t->data);
             k = bkey_next(k))
                if (t->size == bkey_to_cacheline(t, k)) {
-                       t->prev[t->size] = bkey_to_cacheline_offset(t, t->size, k);
+                       t->prev[t->size] =
+                               bkey_to_cacheline_offset(t, t->size, k);
                        t->size++;
                }
 }
@@ -867,10 +880,10 @@ void bch_bset_insert(struct btree_keys *b, struct bkey *where,
 }
 EXPORT_SYMBOL(bch_bset_insert);
 
-unsigned bch_btree_insert_key(struct btree_keys *b, struct bkey *k,
+unsigned int bch_btree_insert_key(struct btree_keys *b, struct bkey *k,
                              struct bkey *replace_key)
 {
-       unsigned status = BTREE_INSERT_STATUS_NO_INSERT;
+       unsigned int status = BTREE_INSERT_STATUS_NO_INSERT;
        struct bset *i = bset_tree_last(b)->data;
        struct bkey *m, *prev = NULL;
        struct btree_iter iter;
@@ -922,10 +935,10 @@ struct bset_search_iter {
 static struct bset_search_iter bset_search_write_set(struct bset_tree *t,
                                                     const struct bkey *search)
 {
-       unsigned li = 0, ri = t->size;
+       unsigned int li = 0, ri = t->size;
 
        while (li + 1 != ri) {
-               unsigned m = (li + ri) >> 1;
+               unsigned int m = (li + ri) >> 1;
 
                if (bkey_cmp(table_to_bkey(t, m), search) > 0)
                        ri = m;
@@ -944,7 +957,7 @@ static struct bset_search_iter bset_search_tree(struct bset_tree *t,
 {
        struct bkey *l, *r;
        struct bkey_float *f;
-       unsigned inorder, j, n = 1;
+       unsigned int inorder, j, n = 1;
 
        do {
                /*
@@ -958,7 +971,8 @@ static struct bset_search_iter bset_search_tree(struct bset_tree *t,
                 *              p = 0;
                 * but a branch instruction is avoided.
                 */
-               unsigned p = n << 4;
+               unsigned int p = n << 4;
+
                p &= ((int) (p - t->size)) >> 31;
 
                prefetch(&t->tree[p]);
@@ -978,7 +992,7 @@ static struct bset_search_iter bset_search_tree(struct bset_tree *t,
                 * to work  - that's done in make_bfloat()
                 */
                if (likely(f->exponent != 127))
-                       n = j * 2 + (((unsigned)
+                       n = j * 2 + (((unsigned int)
                                      (f->mantissa -
                                       bfloat_mantissa(search, f))) >> 31);
                else
@@ -1109,6 +1123,7 @@ static struct bkey *__bch_btree_iter_init(struct btree_keys *b,
                                          struct bset_tree *start)
 {
        struct bkey *ret = NULL;
+
        iter->size = ARRAY_SIZE(iter->data);
        iter->used = 0;
 
@@ -1184,7 +1199,8 @@ void bch_bset_sort_state_free(struct bset_sort_state *state)
        mempool_exit(&state->pool);
 }
 
-int bch_bset_sort_state_init(struct bset_sort_state *state, unsigned page_order)
+int bch_bset_sort_state_init(struct bset_sort_state *state,
+                            unsigned int page_order)
 {
        spin_lock_init(&state->time.lock);
 
@@ -1237,7 +1253,7 @@ static void btree_mergesort(struct btree_keys *b, struct bset *out,
 }
 
 static void __btree_sort(struct btree_keys *b, struct btree_iter *iter,
-                        unsigned start, unsigned order, bool fixup,
+                        unsigned int start, unsigned int order, bool fixup,
                         struct bset_sort_state *state)
 {
        uint64_t start_time;
@@ -1288,7 +1304,7 @@ static void __btree_sort(struct btree_keys *b, struct btree_iter *iter,
                bch_time_stats_update(&state->time, start_time);
 }
 
-void bch_btree_sort_partial(struct btree_keys *b, unsigned start,
+void bch_btree_sort_partial(struct btree_keys *b, unsigned int start,
                            struct bset_sort_state *state)
 {
        size_t order = b->page_order, keys = 0;
@@ -1298,7 +1314,7 @@ void bch_btree_sort_partial(struct btree_keys *b, unsigned start,
        __bch_btree_iter_init(b, &iter, NULL, &b->set[start]);
 
        if (start) {
-               unsigned i;
+               unsigned int i;
 
                for (i = start; i <= b->nsets; i++)
                        keys += b->set[i].data->keys;
@@ -1323,8 +1339,8 @@ void bch_btree_sort_into(struct btree_keys *b, struct btree_keys *new,
                         struct bset_sort_state *state)
 {
        uint64_t start_time = local_clock();
-
        struct btree_iter iter;
+
        bch_btree_iter_init(b, &iter, NULL);
 
        btree_mergesort(b, new->set->data, &iter, false, true);
@@ -1338,7 +1354,7 @@ void bch_btree_sort_into(struct btree_keys *b, struct btree_keys *new,
 
 void bch_btree_sort_lazy(struct btree_keys *b, struct bset_sort_state *state)
 {
-       unsigned crit = SORT_CRIT;
+       unsigned int crit = SORT_CRIT;
        int i;
 
        /* Don't sort if nothing to do */
@@ -1367,7 +1383,7 @@ EXPORT_SYMBOL(bch_btree_sort_lazy);
 
 void bch_btree_keys_stats(struct btree_keys *b, struct bset_stats *stats)
 {
-       unsigned i;
+       unsigned int i;
 
        for (i = 0; i <= b->nsets; i++) {
                struct bset_tree *t = &b->set[i];
index b867f2200495b6edf47231597d978b508572f694..bac76aabca6d7977abfecfaee4d884719f3699f4 100644 (file)
@@ -163,10 +163,10 @@ struct bset_tree {
         */
 
        /* size of the binary tree and prev array */
-       unsigned                size;
+       unsigned int            size;
 
        /* function of size - precalculated for to_inorder() */
-       unsigned                extra;
+       unsigned int            extra;
 
        /* copy of the last key in the set */
        struct bkey             end;
@@ -187,18 +187,25 @@ struct bset_tree {
 };
 
 struct btree_keys_ops {
-       bool            (*sort_cmp)(struct btree_iter_set,
-                                   struct btree_iter_set);
-       struct bkey     *(*sort_fixup)(struct btree_iter *, struct bkey *);
-       bool            (*insert_fixup)(struct btree_keys *, struct bkey *,
-                                       struct btree_iter *, struct bkey *);
-       bool            (*key_invalid)(struct btree_keys *,
-                                      const struct bkey *);
-       bool            (*key_bad)(struct btree_keys *, const struct bkey *);
-       bool            (*key_merge)(struct btree_keys *,
-                                    struct bkey *, struct bkey *);
-       void            (*key_to_text)(char *, size_t, const struct bkey *);
-       void            (*key_dump)(struct btree_keys *, const struct bkey *);
+       bool            (*sort_cmp)(struct btree_iter_set l,
+                                   struct btree_iter_set r);
+       struct bkey     *(*sort_fixup)(struct btree_iter *iter,
+                                      struct bkey *tmp);
+       bool            (*insert_fixup)(struct btree_keys *b,
+                                       struct bkey *insert,
+                                       struct btree_iter *iter,
+                                       struct bkey *replace_key);
+       bool            (*key_invalid)(struct btree_keys *bk,
+                                      const struct bkey *k);
+       bool            (*key_bad)(struct btree_keys *bk,
+                                  const struct bkey *k);
+       bool            (*key_merge)(struct btree_keys *bk,
+                                    struct bkey *l, struct bkey *r);
+       void            (*key_to_text)(char *buf,
+                                      size_t size,
+                                      const struct bkey *k);
+       void            (*key_dump)(struct btree_keys *keys,
+                                   const struct bkey *k);
 
        /*
         * Only used for deciding whether to use START_KEY(k) or just the key
@@ -211,7 +218,7 @@ struct btree_keys {
        const struct btree_keys_ops     *ops;
        uint8_t                 page_order;
        uint8_t                 nsets;
-       unsigned                last_set_unwritten:1;
+       unsigned int            last_set_unwritten:1;
        bool                    *expensive_debug_checks;
 
        /*
@@ -239,12 +246,14 @@ static inline bool bkey_written(struct btree_keys *b, struct bkey *k)
        return !b->last_set_unwritten || k < b->set[b->nsets].data->start;
 }
 
-static inline unsigned bset_byte_offset(struct btree_keys *b, struct bset *i)
+static inline unsigned int bset_byte_offset(struct btree_keys *b,
+                                           struct bset *i)
 {
        return ((size_t) i) - ((size_t) b->set->data);
 }
 
-static inline unsigned bset_sector_offset(struct btree_keys *b, struct bset *i)
+static inline unsigned int bset_sector_offset(struct btree_keys *b,
+                                             struct bset *i)
 {
        return bset_byte_offset(b, i) >> 9;
 }
@@ -273,25 +282,27 @@ static inline size_t bch_btree_keys_u64s_remaining(struct btree_keys *b)
 }
 
 static inline struct bset *bset_next_set(struct btree_keys *b,
-                                        unsigned block_bytes)
+                                        unsigned int block_bytes)
 {
        struct bset *i = bset_tree_last(b)->data;
 
        return ((void *) i) + roundup(set_bytes(i), block_bytes);
 }
 
-void bch_btree_keys_free(struct btree_keys *);
-int bch_btree_keys_alloc(struct btree_keys *, unsigned, gfp_t);
-void bch_btree_keys_init(struct btree_keys *, const struct btree_keys_ops *,
-                        bool *);
-
-void bch_bset_init_next(struct btree_keys *, struct bset *, uint64_t);
-void bch_bset_build_written_tree(struct btree_keys *);
-void bch_bset_fix_invalidated_key(struct btree_keys *, struct bkey *);
-bool bch_bkey_try_merge(struct btree_keys *, struct bkey *, struct bkey *);
-void bch_bset_insert(struct btree_keys *, struct bkey *, struct bkey *);
-unsigned bch_btree_insert_key(struct btree_keys *, struct bkey *,
-                             struct bkey *);
+void bch_btree_keys_free(struct btree_keys *b);
+int bch_btree_keys_alloc(struct btree_keys *b, unsigned int page_order,
+                        gfp_t gfp);
+void bch_btree_keys_init(struct btree_keys *b, const struct btree_keys_ops *ops,
+                        bool *expensive_debug_checks);
+
+void bch_bset_init_next(struct btree_keys *b, struct bset *i, uint64_t magic);
+void bch_bset_build_written_tree(struct btree_keys *b);
+void bch_bset_fix_invalidated_key(struct btree_keys *b, struct bkey *k);
+bool bch_bkey_try_merge(struct btree_keys *b, struct bkey *l, struct bkey *r);
+void bch_bset_insert(struct btree_keys *b, struct bkey *where,
+                    struct bkey *insert);
+unsigned int bch_btree_insert_key(struct btree_keys *b, struct bkey *k,
+                             struct bkey *replace_key);
 
 enum {
        BTREE_INSERT_STATUS_NO_INSERT = 0,
@@ -313,18 +324,21 @@ struct btree_iter {
        } data[MAX_BSETS];
 };
 
-typedef bool (*ptr_filter_fn)(struct btree_keys *, const struct bkey *);
+typedef bool (*ptr_filter_fn)(struct btree_keys *b, const struct bkey *k);
 
-struct bkey *bch_btree_iter_next(struct btree_iter *);
-struct bkey *bch_btree_iter_next_filter(struct btree_iter *,
-                                       struct btree_keys *, ptr_filter_fn);
+struct bkey *bch_btree_iter_next(struct btree_iter *iter);
+struct bkey *bch_btree_iter_next_filter(struct btree_iter *iter,
+                                       struct btree_keys *b,
+                                       ptr_filter_fn fn);
 
-void bch_btree_iter_push(struct btree_iter *, struct bkey *, struct bkey *);
-struct bkey *bch_btree_iter_init(struct btree_keys *, struct btree_iter *,
-                                struct bkey *);
+void bch_btree_iter_push(struct btree_iter *iter, struct bkey *k,
+                        struct bkey *end);
+struct bkey *bch_btree_iter_init(struct btree_keys *b,
+                                struct btree_iter *iter,
+                                struct bkey *search);
 
-struct bkey *__bch_bset_search(struct btree_keys *, struct bset_tree *,
-                              const struct bkey *);
+struct bkey *__bch_bset_search(struct btree_keys *b, struct bset_tree *t,
+                              const struct bkey *search);
 
 /*
  * Returns the first key that is strictly greater than search
@@ -349,21 +363,23 @@ static inline struct bkey *bch_bset_search(struct btree_keys *b,
 struct bset_sort_state {
        mempool_t               pool;
 
-       unsigned                page_order;
-       unsigned                crit_factor;
+       unsigned int            page_order;
+       unsigned int            crit_factor;
 
        struct time_stats       time;
 };
 
-void bch_bset_sort_state_free(struct bset_sort_state *);
-int bch_bset_sort_state_init(struct bset_sort_state *, unsigned);
-void bch_btree_sort_lazy(struct btree_keys *, struct bset_sort_state *);
-void bch_btree_sort_into(struct btree_keys *, struct btree_keys *,
-                        struct bset_sort_state *);
-void bch_btree_sort_and_fix_extents(struct btree_keys *, struct btree_iter *,
-                                   struct bset_sort_state *);
-void bch_btree_sort_partial(struct btree_keys *, unsigned,
-                           struct bset_sort_state *);
+void bch_bset_sort_state_free(struct bset_sort_state *state);
+int bch_bset_sort_state_init(struct bset_sort_state *state,
+                            unsigned int page_order);
+void bch_btree_sort_lazy(struct btree_keys *b, struct bset_sort_state *state);
+void bch_btree_sort_into(struct btree_keys *b, struct btree_keys *new,
+                        struct bset_sort_state *state);
+void bch_btree_sort_and_fix_extents(struct btree_keys *b,
+                                   struct btree_iter *iter,
+                                   struct bset_sort_state *state);
+void bch_btree_sort_partial(struct btree_keys *b, unsigned int start,
+                           struct bset_sort_state *state);
 
 static inline void bch_btree_sort(struct btree_keys *b,
                                  struct bset_sort_state *state)
@@ -377,13 +393,13 @@ struct bset_stats {
        size_t floats, failed;
 };
 
-void bch_btree_keys_stats(struct btree_keys *, struct bset_stats *);
+void bch_btree_keys_stats(struct btree_keys *b, struct bset_stats *state);
 
 /* Bkey utility code */
 
 #define bset_bkey_last(i)      bkey_idx((struct bkey *) (i)->d, (i)->keys)
 
-static inline struct bkey *bset_bkey_idx(struct bset *i, unsigned idx)
+static inline struct bkey *bset_bkey_idx(struct bset *i, unsigned int idx)
 {
        return bkey_idx(i->start, idx);
 }
@@ -401,10 +417,10 @@ static __always_inline int64_t bkey_cmp(const struct bkey *l,
                : (int64_t) KEY_OFFSET(l) - (int64_t) KEY_OFFSET(r);
 }
 
-void bch_bkey_copy_single_ptr(struct bkey *, const struct bkey *,
-                             unsigned);
-bool __bch_cut_front(const struct bkey *, struct bkey *);
-bool __bch_cut_back(const struct bkey *, struct bkey *);
+void bch_bkey_copy_single_ptr(struct bkey *dest, const struct bkey *src,
+                             unsigned int i);
+bool __bch_cut_front(const struct bkey *where, struct bkey *k);
+bool __bch_cut_back(const struct bkey *where, struct bkey *k);
 
 static inline bool bch_cut_front(const struct bkey *where, struct bkey *k)
 {
@@ -522,18 +538,20 @@ static inline size_t bch_keylist_bytes(struct keylist *l)
        return bch_keylist_nkeys(l) * sizeof(uint64_t);
 }
 
-struct bkey *bch_keylist_pop(struct keylist *);
-void bch_keylist_pop_front(struct keylist *);
-int __bch_keylist_realloc(struct keylist *, unsigned);
+struct bkey *bch_keylist_pop(struct keylist *l);
+void bch_keylist_pop_front(struct keylist *l);
+int __bch_keylist_realloc(struct keylist *l, unsigned int u64s);
 
 /* Debug stuff */
 
 #ifdef CONFIG_BCACHE_DEBUG
 
-int __bch_count_data(struct btree_keys *);
-void __printf(2, 3) __bch_check_keys(struct btree_keys *, const char *, ...);
-void bch_dump_bset(struct btree_keys *, struct bset *, unsigned);
-void bch_dump_bucket(struct btree_keys *);
+int __bch_count_data(struct btree_keys *b);
+void __printf(2, 3) __bch_check_keys(struct btree_keys *b,
+                                    const char *fmt,
+                                    ...);
+void bch_dump_bset(struct btree_keys *b, struct bset *i, unsigned int set);
+void bch_dump_bucket(struct btree_keys *b);
 
 #else
 
@@ -541,7 +559,7 @@ static inline int __bch_count_data(struct btree_keys *b) { return -1; }
 static inline void __printf(2, 3)
        __bch_check_keys(struct btree_keys *b, const char *fmt, ...) {}
 static inline void bch_dump_bucket(struct btree_keys *b) {}
-void bch_dump_bset(struct btree_keys *, struct bset *, unsigned);
+void bch_dump_bset(struct btree_keys *b, struct bset *i, unsigned int set);
 
 #endif
 
index c19f7716df8800b95184f25f629349109fcfbc20..e7d4817681f223f456330f9c63eb6e958f2b9a76 100644 (file)
@@ -183,7 +183,7 @@ static void bch_btree_init_next(struct btree *b)
 
 void bkey_put(struct cache_set *c, struct bkey *k)
 {
-       unsigned i;
+       unsigned int i;
 
        for (i = 0; i < KEY_PTRS(k); i++)
                if (ptr_available(c, k, i))
@@ -287,6 +287,7 @@ err:
 static void btree_node_read_endio(struct bio *bio)
 {
        struct closure *cl = bio->bi_private;
+
        closure_put(cl);
 }
 
@@ -435,7 +436,10 @@ static void do_btree_node_write(struct btree *b)
 
                continue_at(cl, btree_node_write_done, NULL);
        } else {
-               /* No problem for multipage bvec since the bio is just allocated */
+               /*
+                * No problem for multipage bvec since the bio is
+                * just allocated
+                */
                b->bio->bi_vcnt = 0;
                bch_bio_map(b->bio, i);
 
@@ -479,7 +483,7 @@ void __bch_btree_node_write(struct btree *b, struct closure *parent)
 
 void bch_btree_node_write(struct btree *b, struct closure *parent)
 {
-       unsigned nsets = b->keys.nsets;
+       unsigned int nsets = b->keys.nsets;
 
        lockdep_assert_held(&b->lock);
 
@@ -581,7 +585,7 @@ static void mca_bucket_free(struct btree *b)
        list_move(&b->list, &b->c->btree_cache_freeable);
 }
 
-static unsigned btree_order(struct bkey *k)
+static unsigned int btree_order(struct bkey *k)
 {
        return ilog2(KEY_SIZE(k) / PAGE_SECTORS ?: 1);
 }
@@ -589,7 +593,7 @@ static unsigned btree_order(struct bkey *k)
 static void mca_data_alloc(struct btree *b, struct bkey *k, gfp_t gfp)
 {
        if (!bch_btree_keys_alloc(&b->keys,
-                                 max_t(unsigned,
+                                 max_t(unsigned int,
                                        ilog2(b->c->btree_pages),
                                        btree_order(k)),
                                  gfp)) {
@@ -604,6 +608,7 @@ static struct btree *mca_bucket_alloc(struct cache_set *c,
                                      struct bkey *k, gfp_t gfp)
 {
        struct btree *b = kzalloc(sizeof(struct btree), gfp);
+
        if (!b)
                return NULL;
 
@@ -620,7 +625,7 @@ static struct btree *mca_bucket_alloc(struct cache_set *c,
        return b;
 }
 
-static int mca_reap(struct btree *b, unsigned min_order, bool flush)
+static int mca_reap(struct btree *b, unsigned int min_order, bool flush)
 {
        struct closure cl;
 
@@ -746,6 +751,7 @@ void bch_btree_cache_free(struct cache_set *c)
 {
        struct btree *b;
        struct closure cl;
+
        closure_init_stack(&cl);
 
        if (c->shrink.list.next)
@@ -786,7 +792,7 @@ void bch_btree_cache_free(struct cache_set *c)
 
 int bch_btree_cache_alloc(struct cache_set *c)
 {
-       unsigned i;
+       unsigned int i;
 
        for (i = 0; i < mca_reserve(c); i++)
                if (!mca_bucket_alloc(c, &ZERO_KEY, GFP_KERNEL))
@@ -1124,6 +1130,7 @@ static struct btree *btree_node_alloc_replacement(struct btree *b,
                                                  struct btree_op *op)
 {
        struct btree *n = bch_btree_node_alloc(b->c, op, b->level, b->parent);
+
        if (!IS_ERR_OR_NULL(n)) {
                mutex_lock(&n->write_lock);
                bch_btree_sort_into(&b->keys, &n->keys, &b->c->sort);
@@ -1136,7 +1143,7 @@ static struct btree *btree_node_alloc_replacement(struct btree *b,
 
 static void make_btree_freeing_key(struct btree *b, struct bkey *k)
 {
-       unsigned i;
+       unsigned int i;
 
        mutex_lock(&b->c->bucket_lock);
 
@@ -1157,7 +1164,7 @@ static int btree_check_reserve(struct btree *b, struct btree_op *op)
 {
        struct cache_set *c = b->c;
        struct cache *ca;
-       unsigned i, reserve = (c->root->level - b->level) * 2 + 1;
+       unsigned int i, reserve = (c->root->level - b->level) * 2 + 1;
 
        mutex_lock(&c->bucket_lock);
 
@@ -1181,7 +1188,7 @@ static uint8_t __bch_btree_mark_key(struct cache_set *c, int level,
                                    struct bkey *k)
 {
        uint8_t stale = 0;
-       unsigned i;
+       unsigned int i;
        struct bucket *g;
 
        /*
@@ -1219,7 +1226,7 @@ static uint8_t __bch_btree_mark_key(struct cache_set *c, int level,
                        SET_GC_MARK(g, GC_MARK_RECLAIMABLE);
 
                /* guard against overflow */
-               SET_GC_SECTORS_USED(g, min_t(unsigned,
+               SET_GC_SECTORS_USED(g, min_t(unsigned int,
                                             GC_SECTORS_USED(g) + KEY_SIZE(k),
                                             MAX_GC_SECTORS_USED));
 
@@ -1233,7 +1240,7 @@ static uint8_t __bch_btree_mark_key(struct cache_set *c, int level,
 
 void bch_initial_mark_key(struct cache_set *c, int level, struct bkey *k)
 {
-       unsigned i;
+       unsigned int i;
 
        for (i = 0; i < KEY_PTRS(k); i++)
                if (ptr_available(c, k, i) &&
@@ -1259,7 +1266,7 @@ void bch_update_bucket_in_use(struct cache_set *c, struct gc_stat *stats)
 static bool btree_gc_mark_node(struct btree *b, struct gc_stat *gc)
 {
        uint8_t stale = 0;
-       unsigned keys = 0, good_keys = 0;
+       unsigned int keys = 0, good_keys = 0;
        struct bkey *k;
        struct btree_iter iter;
        struct bset_tree *t;
@@ -1302,16 +1309,18 @@ static bool btree_gc_mark_node(struct btree *b, struct gc_stat *gc)
 
 struct gc_merge_info {
        struct btree    *b;
-       unsigned        keys;
+       unsigned int    keys;
 };
 
-static int bch_btree_insert_node(struct btree *, struct btree_op *,
-                                struct keylist *, atomic_t *, struct bkey *);
+static int bch_btree_insert_node(struct btree *b, struct btree_op *op,
+                                struct keylist *insert_keys,
+                                atomic_t *journal_ref,
+                                struct bkey *replace_key);
 
 static int btree_gc_coalesce(struct btree *b, struct btree_op *op,
                             struct gc_stat *gc, struct gc_merge_info *r)
 {
-       unsigned i, nodes = 0, keys = 0, blocks;
+       unsigned int i, nodes = 0, keys = 0, blocks;
        struct btree *new_nodes[GC_MERGE_NODES];
        struct keylist keylist;
        struct closure cl;
@@ -1511,11 +1520,11 @@ static int btree_gc_rewrite_node(struct btree *b, struct btree_op *op,
        return -EINTR;
 }
 
-static unsigned btree_gc_count_keys(struct btree *b)
+static unsigned int btree_gc_count_keys(struct btree *b)
 {
        struct bkey *k;
        struct btree_iter iter;
-       unsigned ret = 0;
+       unsigned int ret = 0;
 
        for_each_key_filter(&b->keys, k, &iter, bch_ptr_bad)
                ret += bkey_u64s(k);
@@ -1678,7 +1687,7 @@ static void btree_gc_start(struct cache_set *c)
 {
        struct cache *ca;
        struct bucket *b;
-       unsigned i;
+       unsigned int i;
 
        if (!c->gc_mark_valid)
                return;
@@ -1704,7 +1713,7 @@ static void bch_btree_gc_finish(struct cache_set *c)
 {
        struct bucket *b;
        struct cache *ca;
-       unsigned i;
+       unsigned int i;
 
        mutex_lock(&c->bucket_lock);
 
@@ -1722,7 +1731,7 @@ static void bch_btree_gc_finish(struct cache_set *c)
                struct bcache_device *d = c->devices[i];
                struct cached_dev *dc;
                struct keybuf_key *w, *n;
-               unsigned j;
+               unsigned int j;
 
                if (!d || UUID_FLASH_ONLY(&c->uuids[i]))
                        continue;
@@ -1814,7 +1823,7 @@ static void bch_btree_gc(struct cache_set *c)
 static bool gc_should_run(struct cache_set *c)
 {
        struct cache *ca;
-       unsigned i;
+       unsigned int i;
 
        for_each_cache(ca, c, i)
                if (ca->invalidate_needs_gc)
@@ -1905,7 +1914,7 @@ void bch_initial_gc_finish(struct cache_set *c)
 {
        struct cache *ca;
        struct bucket *b;
-       unsigned i;
+       unsigned int i;
 
        bch_btree_gc_finish(c);
 
@@ -1945,7 +1954,7 @@ void bch_initial_gc_finish(struct cache_set *c)
 static bool btree_insert_key(struct btree *b, struct bkey *k,
                             struct bkey *replace_key)
 {
-       unsigned status;
+       unsigned int status;
 
        BUG_ON(bkey_cmp(k, &b->key) > 0);
 
@@ -2044,7 +2053,7 @@ static int btree_split(struct btree *b, struct btree_op *op,
                           block_bytes(n1->c)) > (btree_blocks(b) * 4) / 5;
 
        if (split) {
-               unsigned keys = 0;
+               unsigned int keys = 0;
 
                trace_bcache_btree_node_split(b, btree_bset_first(n1)->keys);
 
@@ -2222,10 +2231,10 @@ int bch_btree_insert_check_key(struct btree *b, struct btree_op *op,
                rw_lock(true, b, b->level);
 
                if (b->key.ptr[0] != btree_ptr ||
-                   b->seq != seq + 1) {
+                   b->seq != seq + 1) {
                        op->lock = b->level;
                        goto out;
-               }
+               }
        }
 
        SET_KEY_PTRS(check_key, 1);
@@ -2300,7 +2309,7 @@ int bch_btree_insert(struct cache_set *c, struct keylist *keys,
 
 void bch_btree_set_root(struct btree *b)
 {
-       unsigned i;
+       unsigned int i;
        struct closure cl;
 
        closure_init_stack(&cl);
@@ -2412,7 +2421,7 @@ static inline int keybuf_nonoverlapping_cmp(struct keybuf_key *l,
 
 struct refill {
        struct btree_op op;
-       unsigned        nr_found;
+       unsigned int    nr_found;
        struct keybuf   *buf;
        struct bkey     *end;
        keybuf_pred_fn  *pred;
@@ -2488,6 +2497,7 @@ void bch_refill_keybuf(struct cache_set *c, struct keybuf *buf,
 
        if (!RB_EMPTY_ROOT(&buf->keys)) {
                struct keybuf_key *w;
+
                w = RB_FIRST(&buf->keys, struct keybuf_key, node);
                buf->start      = START_KEY(&w->key);
 
@@ -2519,6 +2529,7 @@ bool bch_keybuf_check_overlapping(struct keybuf *buf, struct bkey *start,
 {
        bool ret = false;
        struct keybuf_key *p, *w, s;
+
        s.key = *start;
 
        if (bkey_cmp(end, &buf->start) <= 0 ||
@@ -2545,6 +2556,7 @@ bool bch_keybuf_check_overlapping(struct keybuf *buf, struct bkey *start,
 struct keybuf_key *bch_keybuf_next(struct keybuf *buf)
 {
        struct keybuf_key *w;
+
        spin_lock(&buf->lock);
 
        w = RB_FIRST(&buf->keys, struct keybuf_key, node);
index 68e9d926134da9391558236a18f90cdeef474a88..a68d6c55783bd97eaf49d5744c9422f8af24be07 100644 (file)
@@ -184,7 +184,7 @@ static inline struct bset *btree_bset_last(struct btree *b)
        return bset_tree_last(&b->keys)->data;
 }
 
-static inline unsigned bset_block_offset(struct btree *b, struct bset *i)
+static inline unsigned int bset_block_offset(struct btree *b, struct bset *i)
 {
        return bset_sector_offset(&b->keys, i) >> b->c->block_bits;
 }
@@ -213,7 +213,7 @@ struct btree_op {
        /* Btree level at which we start taking write locks */
        short                   lock;
 
-       unsigned                insert_collision:1;
+       unsigned int            insert_collision:1;
 };
 
 static inline void bch_btree_op_init(struct btree_op *op, int write_lock_level)
@@ -238,26 +238,28 @@ static inline void rw_unlock(bool w, struct btree *b)
        (w ? up_write : up_read)(&b->lock);
 }
 
-void bch_btree_node_read_done(struct btree *);
-void __bch_btree_node_write(struct btree *, struct closure *);
-void bch_btree_node_write(struct btree *, struct closure *);
-
-void bch_btree_set_root(struct btree *);
-struct btree *__bch_btree_node_alloc(struct cache_set *, struct btree_op *,
-                                    int, bool, struct btree *);
-struct btree *bch_btree_node_get(struct cache_set *, struct btree_op *,
-                                struct bkey *, int, bool, struct btree *);
-
-int bch_btree_insert_check_key(struct btree *, struct btree_op *,
-                              struct bkey *);
-int bch_btree_insert(struct cache_set *, struct keylist *,
-                    atomic_t *, struct bkey *);
-
-int bch_gc_thread_start(struct cache_set *);
-void bch_initial_gc_finish(struct cache_set *);
-void bch_moving_gc(struct cache_set *);
-int bch_btree_check(struct cache_set *);
-void bch_initial_mark_key(struct cache_set *, int, struct bkey *);
+void bch_btree_node_read_done(struct btree *b);
+void __bch_btree_node_write(struct btree *b, struct closure *parent);
+void bch_btree_node_write(struct btree *b, struct closure *parent);
+
+void bch_btree_set_root(struct btree *b);
+struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op,
+                                    int level, bool wait,
+                                    struct btree *parent);
+struct btree *bch_btree_node_get(struct cache_set *c, struct btree_op *op,
+                                struct bkey *k, int level, bool write,
+                                struct btree *parent);
+
+int bch_btree_insert_check_key(struct btree *b, struct btree_op *op,
+                              struct bkey *check_key);
+int bch_btree_insert(struct cache_set *c, struct keylist *keys,
+                    atomic_t *journal_ref, struct bkey *replace_key);
+
+int bch_gc_thread_start(struct cache_set *c);
+void bch_initial_gc_finish(struct cache_set *c);
+void bch_moving_gc(struct cache_set *c);
+int bch_btree_check(struct cache_set *c);
+void bch_initial_mark_key(struct cache_set *c, int level, struct bkey *k);
 
 static inline void wake_up_gc(struct cache_set *c)
 {
@@ -272,9 +274,9 @@ static inline void wake_up_gc(struct cache_set *c)
 
 #define MAP_END_KEY    1
 
-typedef int (btree_map_nodes_fn)(struct btree_op *, struct btree *);
-int __bch_btree_map_nodes(struct btree_op *, struct cache_set *,
-                         struct bkey *, btree_map_nodes_fn *, int);
+typedef int (btree_map_nodes_fn)(struct btree_op *b_op, struct btree *b);
+int __bch_btree_map_nodes(struct btree_op *op, struct cache_set *c,
+                         struct bkey *from, btree_map_nodes_fn *fn, int flags);
 
 static inline int bch_btree_map_nodes(struct btree_op *op, struct cache_set *c,
                                      struct bkey *from, btree_map_nodes_fn *fn)
@@ -290,21 +292,23 @@ static inline int bch_btree_map_leaf_nodes(struct btree_op *op,
        return __bch_btree_map_nodes(op, c, from, fn, MAP_LEAF_NODES);
 }
 
-typedef int (btree_map_keys_fn)(struct btree_op *, struct btree *,
-                               struct bkey *);
-int bch_btree_map_keys(struct btree_op *, struct cache_set *,
-                      struct bkey *, btree_map_keys_fn *, int);
-
-typedef bool (keybuf_pred_fn)(struct keybuf *, struct bkey *);
-
-void bch_keybuf_init(struct keybuf *);
-void bch_refill_keybuf(struct cache_set *, struct keybuf *,
-                      struct bkey *, keybuf_pred_fn *);
-bool bch_keybuf_check_overlapping(struct keybuf *, struct bkey *,
-                                 struct bkey *);
-void bch_keybuf_del(struct keybuf *, struct keybuf_key *);
-struct keybuf_key *bch_keybuf_next(struct keybuf *);
-struct keybuf_key *bch_keybuf_next_rescan(struct cache_set *, struct keybuf *,
-                                         struct bkey *, keybuf_pred_fn *);
+typedef int (btree_map_keys_fn)(struct btree_op *op, struct btree *b,
+                               struct bkey *k);
+int bch_btree_map_keys(struct btree_op *op, struct cache_set *c,
+                      struct bkey *from, btree_map_keys_fn *fn, int flags);
+
+typedef bool (keybuf_pred_fn)(struct keybuf *buf, struct bkey *k);
+
+void bch_keybuf_init(struct keybuf *buf);
+void bch_refill_keybuf(struct cache_set *c, struct keybuf *buf,
+                      struct bkey *end, keybuf_pred_fn *pred);
+bool bch_keybuf_check_overlapping(struct keybuf *buf, struct bkey *start,
+                                 struct bkey *end);
+void bch_keybuf_del(struct keybuf *buf, struct keybuf_key *w);
+struct keybuf_key *bch_keybuf_next(struct keybuf *buf);
+struct keybuf_key *bch_keybuf_next_rescan(struct cache_set *c,
+                                         struct keybuf *buf,
+                                         struct bkey *end,
+                                         keybuf_pred_fn *pred);
 void bch_update_bucket_in_use(struct cache_set *c, struct gc_stat *stats);
 #endif
index 618253683d409e0a29db0832ec853b5af4930d29..73f5319295bc9c1c8a3caf47ac7b7ab4ee5cfcdd 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Asynchronous refcounty things
  *
@@ -162,12 +163,13 @@ static struct dentry *closure_debug;
 static int debug_seq_show(struct seq_file *f, void *data)
 {
        struct closure *cl;
+
        spin_lock_irq(&closure_list_lock);
 
        list_for_each_entry(cl, &closure_list, all) {
                int r = atomic_read(&cl->remaining);
 
-               seq_printf(f, "%p: %pF -> %pf p %p r %i ",
+               seq_printf(f, "%p: %pS -> %pS p %p r %i ",
                           cl, (void *) cl->ip, cl->fn, cl->parent,
                           r & CLOSURE_REMAINING_MASK);
 
@@ -177,7 +179,7 @@ static int debug_seq_show(struct seq_file *f, void *data)
                           r & CLOSURE_RUNNING  ? "R" : "");
 
                if (r & CLOSURE_WAITING)
-                       seq_printf(f, " W %pF\n",
+                       seq_printf(f, " W %pS\n",
                                   (void *) cl->waiting_on);
 
                seq_printf(f, "\n");
index 7c2c5bc7c88b12f1ca7067f0f77c086dc54ef594..eca0d496b6869e78c76c3774ad819612f27661a9 100644 (file)
@@ -159,7 +159,7 @@ struct closure {
 #define CLOSURE_MAGIC_DEAD     0xc054dead
 #define CLOSURE_MAGIC_ALIVE    0xc054a11e
 
-       unsigned                magic;
+       unsigned int            magic;
        struct list_head        all;
        unsigned long           ip;
        unsigned long           waiting_on;
@@ -289,10 +289,12 @@ static inline void closure_init_stack(struct closure *cl)
 }
 
 /**
- * closure_wake_up - wake up all closures on a wait list.
+ * closure_wake_up - wake up all closures on a wait list,
+ *                  with memory barrier
  */
 static inline void closure_wake_up(struct closure_waitlist *list)
 {
+       /* Memory barrier for the wait list */
        smp_mb();
        __closure_wake_up(list);
 }
index 12034c07257b87ab82800ed3b2d60c72d7c49e33..06da66b2488ae8f5371fcfeb92c7b336d24e78ca 100644 (file)
@@ -67,34 +67,35 @@ void bch_btree_verify(struct btree *b)
        if (inmemory->keys != sorted->keys ||
            memcmp(inmemory->start,
                   sorted->start,
-                  (void *) bset_bkey_last(inmemory) - (void *) inmemory->start)) {
+                  (void *) bset_bkey_last(inmemory) -
+                  (void *) inmemory->start)) {
                struct bset *i;
-               unsigned j;
+               unsigned int j;
 
                console_lock();
 
-               printk(KERN_ERR "*** in memory:\n");
+               pr_err("*** in memory:\n");
                bch_dump_bset(&b->keys, inmemory, 0);
 
-               printk(KERN_ERR "*** read back in:\n");
+               pr_err("*** read back in:\n");
                bch_dump_bset(&v->keys, sorted, 0);
 
                for_each_written_bset(b, ondisk, i) {
-                       unsigned block = ((void *) i - (void *) ondisk) /
+                       unsigned int block = ((void *) i - (void *) ondisk) /
                                block_bytes(b->c);
 
-                       printk(KERN_ERR "*** on disk block %u:\n", block);
+                       pr_err("*** on disk block %u:\n", block);
                        bch_dump_bset(&b->keys, i, block);
                }
 
-               printk(KERN_ERR "*** block %zu not written\n",
+               pr_err("*** block %zu not written\n",
                       ((void *) i - (void *) ondisk) / block_bytes(b->c));
 
                for (j = 0; j < inmemory->keys; j++)
                        if (inmemory->d[j] != sorted->d[j])
                                break;
 
-               printk(KERN_ERR "b->written %u\n", b->written);
+               pr_err("b->written %u\n", b->written);
 
                console_unlock();
                panic("verify failed at %u\n", j);
@@ -176,9 +177,9 @@ static ssize_t bch_dump_read(struct file *file, char __user *buf,
 
        while (size) {
                struct keybuf_key *w;
-               unsigned bytes = min(i->bytes, size);
-
+               unsigned int bytes = min(i->bytes, size);
                int err = copy_to_user(buf, i->buf, bytes);
+
                if (err)
                        return err;
 
@@ -237,8 +238,8 @@ void bch_debug_init_cache_set(struct cache_set *c)
 {
        if (!IS_ERR_OR_NULL(bcache_debug)) {
                char name[50];
-               snprintf(name, 50, "bcache-%pU", c->sb.set_uuid);
 
+               snprintf(name, 50, "bcache-%pU", c->sb.set_uuid);
                c->debug = debugfs_create_file(name, 0400, bcache_debug, c,
                                               &cache_set_debug_ops);
        }
index acc48d3fa274d9d031f13b3609ec41cd0e307478..fb3d4dff4b26ea7ad5e088d1e67e65ebe1992903 100644 (file)
@@ -8,8 +8,8 @@ struct cache_set;
 
 #ifdef CONFIG_BCACHE_DEBUG
 
-void bch_btree_verify(struct btree *);
-void bch_data_verify(struct cached_dev *, struct bio *);
+void bch_btree_verify(struct btree *b);
+void bch_data_verify(struct cached_dev *dc, struct bio *bio);
 
 #define expensive_debug_checks(c)      ((c)->expensive_debug_checks)
 #define key_merging_disabled(c)                ((c)->key_merging_disabled)
@@ -27,7 +27,7 @@ static inline void bch_data_verify(struct cached_dev *dc, struct bio *bio) {}
 #endif
 
 #ifdef CONFIG_DEBUG_FS
-void bch_debug_init_cache_set(struct cache_set *);
+void bch_debug_init_cache_set(struct cache_set *c);
 #else
 static inline void bch_debug_init_cache_set(struct cache_set *c) {}
 #endif
index 1d096742eb41a01444e7c6412951af5440a6fd28..c809724e6571e4be1d61ed0198a471ec8889c044 100644 (file)
@@ -46,7 +46,7 @@ static bool bch_key_sort_cmp(struct btree_iter_set l,
 
 static bool __ptr_invalid(struct cache_set *c, const struct bkey *k)
 {
-       unsigned i;
+       unsigned int i;
 
        for (i = 0; i < KEY_PTRS(k); i++)
                if (ptr_available(c, k, i)) {
@@ -67,7 +67,7 @@ static bool __ptr_invalid(struct cache_set *c, const struct bkey *k)
 
 static const char *bch_ptr_status(struct cache_set *c, const struct bkey *k)
 {
-       unsigned i;
+       unsigned int i;
 
        for (i = 0; i < KEY_PTRS(k); i++)
                if (ptr_available(c, k, i)) {
@@ -96,7 +96,7 @@ static const char *bch_ptr_status(struct cache_set *c, const struct bkey *k)
 
 void bch_extent_to_text(char *buf, size_t size, const struct bkey *k)
 {
-       unsigned i = 0;
+       unsigned int i = 0;
        char *out = buf, *end = buf + size;
 
 #define p(...) (out += scnprintf(out, end - out, __VA_ARGS__))
@@ -126,22 +126,22 @@ void bch_extent_to_text(char *buf, size_t size, const struct bkey *k)
 static void bch_bkey_dump(struct btree_keys *keys, const struct bkey *k)
 {
        struct btree *b = container_of(keys, struct btree, keys);
-       unsigned j;
+       unsigned int j;
        char buf[80];
 
        bch_extent_to_text(buf, sizeof(buf), k);
-       printk(" %s", buf);
+       pr_err(" %s", buf);
 
        for (j = 0; j < KEY_PTRS(k); j++) {
                size_t n = PTR_BUCKET_NR(b->c, k, j);
-               printk(" bucket %zu", n);
 
+               pr_err(" bucket %zu", n);
                if (n >= b->c->sb.first_bucket && n < b->c->sb.nbuckets)
-                       printk(" prio %i",
+                       pr_err(" prio %i",
                               PTR_BUCKET(b->c, k, j)->prio);
        }
 
-       printk(" %s\n", bch_ptr_status(b->c, k));
+       pr_err(" %s\n", bch_ptr_status(b->c, k));
 }
 
 /* Btree ptrs */
@@ -166,12 +166,13 @@ bad:
 static bool bch_btree_ptr_invalid(struct btree_keys *bk, const struct bkey *k)
 {
        struct btree *b = container_of(bk, struct btree, keys);
+
        return __bch_btree_ptr_invalid(b->c, k);
 }
 
 static bool btree_ptr_bad_expensive(struct btree *b, const struct bkey *k)
 {
-       unsigned i;
+       unsigned int i;
        char buf[80];
        struct bucket *g;
 
@@ -204,7 +205,7 @@ err:
 static bool bch_btree_ptr_bad(struct btree_keys *bk, const struct bkey *k)
 {
        struct btree *b = container_of(bk, struct btree, keys);
-       unsigned i;
+       unsigned int i;
 
        if (!bkey_cmp(k, &ZERO_KEY) ||
            !KEY_PTRS(k) ||
@@ -327,13 +328,14 @@ static bool bch_extent_insert_fixup(struct btree_keys *b,
        struct cache_set *c = container_of(b, struct btree, keys)->c;
 
        uint64_t old_offset;
-       unsigned old_size, sectors_found = 0;
+       unsigned int old_size, sectors_found = 0;
 
        BUG_ON(!KEY_OFFSET(insert));
        BUG_ON(!KEY_SIZE(insert));
 
        while (1) {
                struct bkey *k = bch_btree_iter_next(iter);
+
                if (!k)
                        break;
 
@@ -363,7 +365,7 @@ static bool bch_extent_insert_fixup(struct btree_keys *b,
                         * k might have been split since we inserted/found the
                         * key we're replacing
                         */
-                       unsigned i;
+                       unsigned int i;
                        uint64_t offset = KEY_START(k) -
                                KEY_START(replace_key);
 
@@ -498,11 +500,12 @@ bad:
 static bool bch_extent_invalid(struct btree_keys *bk, const struct bkey *k)
 {
        struct btree *b = container_of(bk, struct btree, keys);
+
        return __bch_extent_invalid(b->c, k);
 }
 
 static bool bch_extent_bad_expensive(struct btree *b, const struct bkey *k,
-                                    unsigned ptr)
+                                    unsigned int ptr)
 {
        struct bucket *g = PTR_BUCKET(b->c, k, ptr);
        char buf[80];
@@ -534,7 +537,7 @@ err:
 static bool bch_extent_bad(struct btree_keys *bk, const struct bkey *k)
 {
        struct btree *b = container_of(bk, struct btree, keys);
-       unsigned i, stale;
+       unsigned int i, stale;
 
        if (!KEY_PTRS(k) ||
            bch_extent_invalid(bk, k))
@@ -574,10 +577,12 @@ static uint64_t merge_chksums(struct bkey *l, struct bkey *r)
                ~((uint64_t)1 << 63);
 }
 
-static bool bch_extent_merge(struct btree_keys *bk, struct bkey *l, struct bkey *r)
+static bool bch_extent_merge(struct btree_keys *bk,
+                            struct bkey *l,
+                            struct bkey *r)
 {
        struct btree *b = container_of(bk, struct btree, keys);
-       unsigned i;
+       unsigned int i;
 
        if (key_merging_disabled(b->c))
                return false;
index 0cd3575afa1d0b68f6845dd7bebd4e041889b4f1..4d667e05bb73e8cdd389e67fc5489554a583bbaf 100644 (file)
@@ -8,8 +8,8 @@ extern const struct btree_keys_ops bch_extent_keys_ops;
 struct bkey;
 struct cache_set;
 
-void bch_extent_to_text(char *, size_t, const struct bkey *);
-bool __bch_btree_ptr_invalid(struct cache_set *, const struct bkey *);
-bool __bch_extent_invalid(struct cache_set *, const struct bkey *);
+void bch_extent_to_text(char *buf, size_t size, const struct bkey *k);
+bool __bch_btree_ptr_invalid(struct cache_set *c, const struct bkey *k);
+bool __bch_extent_invalid(struct cache_set *c, const struct bkey *k);
 
 #endif /* _BCACHE_EXTENTS_H */
index 9612873afee2c3df0b61b4034f0d0232cf2259dd..c250979683194c69f8ea1b9585e13907c877eb3a 100644 (file)
@@ -17,6 +17,7 @@
 void bch_bbio_free(struct bio *bio, struct cache_set *c)
 {
        struct bbio *b = container_of(bio, struct bbio, bio);
+
        mempool_free(b, &c->bio_meta);
 }
 
@@ -42,9 +43,10 @@ void __bch_submit_bbio(struct bio *bio, struct cache_set *c)
 }
 
 void bch_submit_bbio(struct bio *bio, struct cache_set *c,
-                    struct bkey *k, unsigned ptr)
+                    struct bkey *k, unsigned int ptr)
 {
        struct bbio *b = container_of(bio, struct bbio, bio);
+
        bch_bkey_copy_single_ptr(&b->key, k, ptr);
        __bch_submit_bbio(bio, c);
 }
@@ -52,7 +54,7 @@ void bch_submit_bbio(struct bio *bio, struct cache_set *c,
 /* IO errors */
 void bch_count_backing_io_errors(struct cached_dev *dc, struct bio *bio)
 {
-       unsigned errors;
+       unsigned int errors;
 
        WARN_ONCE(!dc, "NULL pointer of struct cached_dev");
 
@@ -75,16 +77,16 @@ void bch_count_io_errors(struct cache *ca,
         */
 
        if (ca->set->error_decay) {
-               unsigned count = atomic_inc_return(&ca->io_count);
+               unsigned int count = atomic_inc_return(&ca->io_count);
 
                while (count > ca->set->error_decay) {
-                       unsigned errors;
-                       unsigned old = count;
-                       unsigned new = count - ca->set->error_decay;
+                       unsigned int errors;
+                       unsigned int old = count;
+                       unsigned int new = count - ca->set->error_decay;
 
                        /*
                         * First we subtract refresh from count; each time we
-                        * succesfully do so, we rescale the errors once:
+                        * successfully do so, we rescale the errors once:
                         */
 
                        count = atomic_cmpxchg(&ca->io_count, old, new);
@@ -104,7 +106,7 @@ void bch_count_io_errors(struct cache *ca,
        }
 
        if (error) {
-               unsigned errors = atomic_add_return(1 << IO_ERROR_SHIFT,
+               unsigned int errors = atomic_add_return(1 << IO_ERROR_SHIFT,
                                                    &ca->io_errors);
                errors >>= IO_ERROR_SHIFT;
 
@@ -126,18 +128,18 @@ void bch_bbio_count_io_errors(struct cache_set *c, struct bio *bio,
        struct cache *ca = PTR_CACHE(c, &b->key, 0);
        int is_read = (bio_data_dir(bio) == READ ? 1 : 0);
 
-       unsigned threshold = op_is_write(bio_op(bio))
+       unsigned int threshold = op_is_write(bio_op(bio))
                ? c->congested_write_threshold_us
                : c->congested_read_threshold_us;
 
        if (threshold) {
-               unsigned t = local_clock_us();
-
+               unsigned int t = local_clock_us();
                int us = t - b->submit_time_us;
                int congested = atomic_read(&c->congested);
 
                if (us > (int) threshold) {
                        int ms = us / 1024;
+
                        c->congested_last_us = t;
 
                        ms = min(ms, CONGESTED_MAX + congested);
index 10748c626a1dd8835f3c86044b488830a19d348c..6116bbf870d8ef9004717bf5d04803895d085bab 100644 (file)
 static void journal_read_endio(struct bio *bio)
 {
        struct closure *cl = bio->bi_private;
+
        closure_put(cl);
 }
 
 static int journal_read_bucket(struct cache *ca, struct list_head *list,
-                              unsigned bucket_index)
+                              unsigned int bucket_index)
 {
        struct journal_device *ja = &ca->journal;
        struct bio *bio = &ja->bio;
@@ -40,7 +41,7 @@ static int journal_read_bucket(struct cache *ca, struct list_head *list,
        struct journal_replay *i;
        struct jset *j, *data = ca->set->journal.w[0].data;
        struct closure cl;
-       unsigned len, left, offset = 0;
+       unsigned int len, left, offset = 0;
        int ret = 0;
        sector_t bucket = bucket_to_sector(ca->set, ca->sb.d[bucket_index]);
 
@@ -50,7 +51,7 @@ static int journal_read_bucket(struct cache *ca, struct list_head *list,
 
        while (offset < ca->sb.bucket_size) {
 reread:                left = ca->sb.bucket_size - offset;
-               len = min_t(unsigned, left, PAGE_SECTORS << JSET_BITS);
+               len = min_t(unsigned int, left, PAGE_SECTORS << JSET_BITS);
 
                bio_reset(bio);
                bio->bi_iter.bi_sector  = bucket + offset;
@@ -154,12 +155,12 @@ int bch_journal_read(struct cache_set *c, struct list_head *list)
        })
 
        struct cache *ca;
-       unsigned iter;
+       unsigned int iter;
 
        for_each_cache(ca, c, iter) {
                struct journal_device *ja = &ca->journal;
                DECLARE_BITMAP(bitmap, SB_JOURNAL_BUCKETS);
-               unsigned i, l, r, m;
+               unsigned int i, l, r, m;
                uint64_t seq;
 
                bitmap_zero(bitmap, SB_JOURNAL_BUCKETS);
@@ -192,7 +193,8 @@ int bch_journal_read(struct cache_set *c, struct list_head *list)
 
                for (l = find_first_zero_bit(bitmap, ca->sb.njournal_buckets);
                     l < ca->sb.njournal_buckets;
-                    l = find_next_zero_bit(bitmap, ca->sb.njournal_buckets, l + 1))
+                    l = find_next_zero_bit(bitmap, ca->sb.njournal_buckets,
+                                           l + 1))
                        if (read_bucket(l))
                                goto bsearch;
 
@@ -304,7 +306,7 @@ void bch_journal_mark(struct cache_set *c, struct list_head *list)
                     k < bset_bkey_last(&i->j);
                     k = bkey_next(k))
                        if (!__bch_extent_invalid(c, k)) {
-                               unsigned j;
+                               unsigned int j;
 
                                for (j = 0; j < KEY_PTRS(k); j++)
                                        if (ptr_available(c, k, j))
@@ -492,7 +494,7 @@ static void journal_reclaim(struct cache_set *c)
        struct bkey *k = &c->journal.key;
        struct cache *ca;
        uint64_t last_seq;
-       unsigned iter, n = 0;
+       unsigned int iter, n = 0;
        atomic_t p __maybe_unused;
 
        atomic_long_inc(&c->reclaim);
@@ -526,7 +528,7 @@ static void journal_reclaim(struct cache_set *c)
 
        for_each_cache(ca, c, iter) {
                struct journal_device *ja = &ca->journal;
-               unsigned next = (ja->cur_idx + 1) % ca->sb.njournal_buckets;
+               unsigned int next = (ja->cur_idx + 1) % ca->sb.njournal_buckets;
 
                /* No space available on this device */
                if (next == ja->discard_idx)
@@ -580,7 +582,7 @@ static void journal_write_endio(struct bio *bio)
        closure_put(&w->c->journal.io);
 }
 
-static void journal_write(struct closure *);
+static void journal_write(struct closure *cl);
 
 static void journal_write_done(struct closure *cl)
 {
@@ -609,11 +611,12 @@ static void journal_write_unlocked(struct closure *cl)
        struct cache *ca;
        struct journal_write *w = c->journal.cur;
        struct bkey *k = &c->journal.key;
-       unsigned i, sectors = set_blocks(w->data, block_bytes(c)) *
+       unsigned int i, sectors = set_blocks(w->data, block_bytes(c)) *
                c->sb.block_size;
 
        struct bio *bio;
        struct bio_list list;
+
        bio_list_init(&list);
 
        if (!w->need_write) {
@@ -705,7 +708,7 @@ static void journal_try_write(struct cache_set *c)
 }
 
 static struct journal_write *journal_wait_for_write(struct cache_set *c,
-                                                   unsigned nkeys)
+                                                   unsigned int nkeys)
        __acquires(&c->journal.lock)
 {
        size_t sectors;
index b5788199188feac0a2626be4a360c5d0fc7da368..66f0facff84bcb5c0b5fe4199cb8b3a9bfe87ba4 100644 (file)
@@ -110,7 +110,7 @@ struct journal {
        struct delayed_work     work;
 
        /* Number of blocks free in the bucket(s) we're currently writing to */
-       unsigned                blocks_free;
+       unsigned int            blocks_free;
        uint64_t                seq;
        DECLARE_FIFO(atomic_t, pin);
 
@@ -131,13 +131,13 @@ struct journal_device {
        uint64_t                seq[SB_JOURNAL_BUCKETS];
 
        /* Journal bucket we're currently writing to */
-       unsigned                cur_idx;
+       unsigned int            cur_idx;
 
        /* Last journal bucket that still contains an open journal entry */
-       unsigned                last_idx;
+       unsigned int            last_idx;
 
        /* Next journal bucket to be discarded */
-       unsigned                discard_idx;
+       unsigned int            discard_idx;
 
 #define DISCARD_READY          0
 #define DISCARD_IN_FLIGHT      1
@@ -167,14 +167,16 @@ struct cache_set;
 struct btree_op;
 struct keylist;
 
-atomic_t *bch_journal(struct cache_set *, struct keylist *, struct closure *);
-void bch_journal_next(struct journal *);
-void bch_journal_mark(struct cache_set *, struct list_head *);
-void bch_journal_meta(struct cache_set *, struct closure *);
-int bch_journal_read(struct cache_set *, struct list_head *);
-int bch_journal_replay(struct cache_set *, struct list_head *);
-
-void bch_journal_free(struct cache_set *);
-int bch_journal_alloc(struct cache_set *);
+atomic_t *bch_journal(struct cache_set *c,
+                     struct keylist *keys,
+                     struct closure *parent);
+void bch_journal_next(struct journal *j);
+void bch_journal_mark(struct cache_set *c, struct list_head *list);
+void bch_journal_meta(struct cache_set *c, struct closure *cl);
+int bch_journal_read(struct cache_set *c, struct list_head *list);
+int bch_journal_replay(struct cache_set *c, struct list_head *list);
+
+void bch_journal_free(struct cache_set *c);
+int bch_journal_alloc(struct cache_set *c);
 
 #endif /* _BCACHE_JOURNAL_H */
index a24c3a95b2c0de85dd4582fadd12f719816c2038..7891fb512736dc82b780311e4d4df33351aad473 100644 (file)
@@ -23,7 +23,7 @@ static bool moving_pred(struct keybuf *buf, struct bkey *k)
 {
        struct cache_set *c = container_of(buf, struct cache_set,
                                           moving_gc_keys);
-       unsigned i;
+       unsigned int i;
 
        for (i = 0; i < KEY_PTRS(k); i++)
                if (ptr_available(c, k, i) &&
@@ -38,6 +38,7 @@ static bool moving_pred(struct keybuf *buf, struct bkey *k)
 static void moving_io_destructor(struct closure *cl)
 {
        struct moving_io *io = container_of(cl, struct moving_io, cl);
+
        kfree(io);
 }
 
@@ -186,9 +187,10 @@ static bool bucket_cmp(struct bucket *l, struct bucket *r)
        return GC_SECTORS_USED(l) < GC_SECTORS_USED(r);
 }
 
-static unsigned bucket_heap_top(struct cache *ca)
+static unsigned int bucket_heap_top(struct cache *ca)
 {
        struct bucket *b;
+
        return (b = heap_peek(&ca->heap)) ? GC_SECTORS_USED(b) : 0;
 }
 
@@ -196,7 +198,7 @@ void bch_moving_gc(struct cache_set *c)
 {
        struct cache *ca;
        struct bucket *b;
-       unsigned i;
+       unsigned int i;
 
        if (!c->copy_gc_enabled)
                return;
@@ -204,9 +206,9 @@ void bch_moving_gc(struct cache_set *c)
        mutex_lock(&c->bucket_lock);
 
        for_each_cache(ca, c, i) {
-               unsigned sectors_to_move = 0;
-               unsigned reserve_sectors = ca->sb.bucket_size *
-                       fifo_used(&ca->free[RESERVE_MOVINGGC]);
+               unsigned int sectors_to_move = 0;
+               unsigned int reserve_sectors = ca->sb.bucket_size *
+                            fifo_used(&ca->free[RESERVE_MOVINGGC]);
 
                ca->heap.used = 0;
 
index 7dbe8b6316a0038670e9c73f9d6c3b583a1554a2..51be355a3309fe993e4e14c0c5ac8d3e9955b45c 100644 (file)
@@ -25,9 +25,9 @@
 
 struct kmem_cache *bch_search_cache;
 
-static void bch_data_insert_start(struct closure *);
+static void bch_data_insert_start(struct closure *cl);
 
-static unsigned cache_mode(struct cached_dev *dc)
+static unsigned int cache_mode(struct cached_dev *dc)
 {
        return BDEV_CACHE_MODE(&dc->sb);
 }
@@ -45,6 +45,7 @@ static void bio_csum(struct bio *bio, struct bkey *k)
 
        bio_for_each_segment(bv, bio, iter) {
                void *d = kmap(bv.bv_page) + bv.bv_offset;
+
                csum = bch_crc64_update(csum, d, bv.bv_len);
                kunmap(bv.bv_page);
        }
@@ -98,7 +99,7 @@ static void bch_data_insert_keys(struct closure *cl)
        closure_return(cl);
 }
 
-static int bch_keylist_realloc(struct keylist *l, unsigned u64s,
+static int bch_keylist_realloc(struct keylist *l, unsigned int u64s,
                               struct cache_set *c)
 {
        size_t oldsize = bch_keylist_nkeys(l);
@@ -125,7 +126,7 @@ static void bch_data_invalidate(struct closure *cl)
                 bio_sectors(bio), (uint64_t) bio->bi_iter.bi_sector);
 
        while (bio_sectors(bio)) {
-               unsigned sectors = min(bio_sectors(bio),
+               unsigned int sectors = min(bio_sectors(bio),
                                       1U << (KEY_SIZE_BITS - 1));
 
                if (bch_keylist_realloc(&op->insert_keys, 2, op->c))
@@ -135,7 +136,9 @@ static void bch_data_invalidate(struct closure *cl)
                bio->bi_iter.bi_size    -= sectors << 9;
 
                bch_keylist_add(&op->insert_keys,
-                               &KEY(op->inode, bio->bi_iter.bi_sector, sectors));
+                               &KEY(op->inode,
+                                    bio->bi_iter.bi_sector,
+                                    sectors));
        }
 
        op->insert_data_done = true;
@@ -151,7 +154,7 @@ static void bch_data_insert_error(struct closure *cl)
 
        /*
         * Our data write just errored, which means we've got a bunch of keys to
-        * insert that point to data that wasn't succesfully written.
+        * insert that point to data that wasn't successfully written.
         *
         * We don't have to insert those keys but we still have to invalidate
         * that region of the cache - so, if we just strip off all the pointers
@@ -211,7 +214,7 @@ static void bch_data_insert_start(struct closure *cl)
        bio->bi_opf &= ~(REQ_PREFLUSH|REQ_FUA);
 
        do {
-               unsigned i;
+               unsigned int i;
                struct bkey *k;
                struct bio_set *split = &op->c->bio_split;
 
@@ -328,7 +331,7 @@ void bch_data_insert(struct closure *cl)
 
 /* Congested? */
 
-unsigned bch_get_congested(struct cache_set *c)
+unsigned int bch_get_congested(struct cache_set *c)
 {
        int i;
        long rand;
@@ -372,8 +375,8 @@ static struct hlist_head *iohash(struct cached_dev *dc, uint64_t k)
 static bool check_should_bypass(struct cached_dev *dc, struct bio *bio)
 {
        struct cache_set *c = dc->disk.c;
-       unsigned mode = cache_mode(dc);
-       unsigned sectors, congested = bch_get_congested(c);
+       unsigned int mode = cache_mode(dc);
+       unsigned int sectors, congested = bch_get_congested(c);
        struct task_struct *task = current;
        struct io *i;
 
@@ -469,11 +472,11 @@ struct search {
        struct bio              *cache_miss;
        struct bcache_device    *d;
 
-       unsigned                insert_bio_sectors;
-       unsigned                recoverable:1;
-       unsigned                write:1;
-       unsigned                read_dirty_data:1;
-       unsigned                cache_missed:1;
+       unsigned int            insert_bio_sectors;
+       unsigned int            recoverable:1;
+       unsigned int            write:1;
+       unsigned int            read_dirty_data:1;
+       unsigned int            cache_missed:1;
 
        unsigned long           start_time;
 
@@ -514,20 +517,20 @@ static int cache_lookup_fn(struct btree_op *op, struct btree *b, struct bkey *k)
        struct search *s = container_of(op, struct search, op);
        struct bio *n, *bio = &s->bio.bio;
        struct bkey *bio_key;
-       unsigned ptr;
+       unsigned int ptr;
 
        if (bkey_cmp(k, &KEY(s->iop.inode, bio->bi_iter.bi_sector, 0)) <= 0)
                return MAP_CONTINUE;
 
        if (KEY_INODE(k) != s->iop.inode ||
            KEY_START(k) > bio->bi_iter.bi_sector) {
-               unsigned bio_sectors = bio_sectors(bio);
-               unsigned sectors = KEY_INODE(k) == s->iop.inode
+               unsigned int bio_sectors = bio_sectors(bio);
+               unsigned int sectors = KEY_INODE(k) == s->iop.inode
                        ? min_t(uint64_t, INT_MAX,
                                KEY_START(k) - bio->bi_iter.bi_sector)
                        : INT_MAX;
-
                int ret = s->d->cache_miss(b, s, bio, sectors);
+
                if (ret != MAP_CONTINUE)
                        return ret;
 
@@ -623,6 +626,7 @@ static void request_endio(struct bio *bio)
 
        if (bio->bi_status) {
                struct search *s = container_of(cl, struct search, cl);
+
                s->iop.status = bio->bi_status;
                /* Only cache read errors are recoverable */
                s->recoverable = false;
@@ -813,7 +817,8 @@ static void cached_dev_read_done(struct closure *cl)
 
        if (s->iop.bio) {
                bio_reset(s->iop.bio);
-               s->iop.bio->bi_iter.bi_sector = s->cache_miss->bi_iter.bi_sector;
+               s->iop.bio->bi_iter.bi_sector =
+                       s->cache_miss->bi_iter.bi_sector;
                bio_copy_dev(s->iop.bio, s->cache_miss);
                s->iop.bio->bi_iter.bi_size = s->insert_bio_sectors << 9;
                bch_bio_map(s->iop.bio, NULL);
@@ -856,10 +861,10 @@ static void cached_dev_read_done_bh(struct closure *cl)
 }
 
 static int cached_dev_cache_miss(struct btree *b, struct search *s,
-                                struct bio *bio, unsigned sectors)
+                                struct bio *bio, unsigned int sectors)
 {
        int ret = MAP_CONTINUE;
-       unsigned reada = 0;
+       unsigned int reada = 0;
        struct cached_dev *dc = container_of(s->d, struct cached_dev, disk);
        struct bio *miss, *cache_bio;
 
@@ -1212,6 +1217,7 @@ static int cached_dev_ioctl(struct bcache_device *d, fmode_t mode,
                            unsigned int cmd, unsigned long arg)
 {
        struct cached_dev *dc = container_of(d, struct cached_dev, disk);
+
        return __blkdev_driver_ioctl(dc->bdev, mode, cmd, arg);
 }
 
@@ -1226,7 +1232,7 @@ static int cached_dev_congested(void *data, int bits)
                return 1;
 
        if (cached_dev_get(dc)) {
-               unsigned i;
+               unsigned int i;
                struct cache *ca;
 
                for_each_cache(ca, d->c, i) {
@@ -1253,9 +1259,9 @@ void bch_cached_dev_request_init(struct cached_dev *dc)
 /* Flash backed devices */
 
 static int flash_dev_cache_miss(struct btree *b, struct search *s,
-                               struct bio *bio, unsigned sectors)
+                               struct bio *bio, unsigned int sectors)
 {
-       unsigned bytes = min(sectors, bio_sectors(bio)) << 9;
+       unsigned int bytes = min(sectors, bio_sectors(bio)) << 9;
 
        swap(bio->bi_iter.bi_size, bytes);
        zero_fill_bio(bio);
@@ -1338,7 +1344,7 @@ static int flash_dev_congested(void *data, int bits)
        struct bcache_device *d = data;
        struct request_queue *q;
        struct cache *ca;
-       unsigned i;
+       unsigned int i;
        int ret = 0;
 
        for_each_cache(ca, d->c, i) {
@@ -1361,8 +1367,7 @@ void bch_flash_dev_request_init(struct bcache_device *d)
 
 void bch_request_exit(void)
 {
-       if (bch_search_cache)
-               kmem_cache_destroy(bch_search_cache);
+       kmem_cache_destroy(bch_search_cache);
 }
 
 int __init bch_request_init(void)
index dea0886b81c1740de564a64581eb9b3deff46dd3..aa055cfeb0998cbc0b1c65203376bd5b9d4bbfc3 100644 (file)
@@ -8,7 +8,7 @@ struct data_insert_op {
        struct bio              *bio;
        struct workqueue_struct *wq;
 
-       unsigned                inode;
+       unsigned int            inode;
        uint16_t                write_point;
        uint16_t                write_prio;
        blk_status_t            status;
@@ -17,15 +17,15 @@ struct data_insert_op {
                uint16_t        flags;
 
        struct {
-               unsigned        bypass:1;
-               unsigned        writeback:1;
-               unsigned        flush_journal:1;
-               unsigned        csum:1;
+               unsigned int    bypass:1;
+               unsigned int    writeback:1;
+               unsigned int    flush_journal:1;
+               unsigned int    csum:1;
 
-               unsigned        replace:1;
-               unsigned        replace_collision:1;
+               unsigned int    replace:1;
+               unsigned int    replace_collision:1;
 
-               unsigned        insert_data_done:1;
+               unsigned int    insert_data_done:1;
        };
        };
 
@@ -33,7 +33,7 @@ struct data_insert_op {
        BKEY_PADDED(replace_key);
 };
 
-unsigned bch_get_congested(struct cache_set *);
+unsigned int bch_get_congested(struct cache_set *c);
 void bch_data_insert(struct closure *cl);
 
 void bch_cached_dev_request_init(struct cached_dev *dc);
index be119326297b6324ff17a7d63e94a8c761139ba2..894410f3f829c8fdfbbca244e5c97e91b423f13d 100644 (file)
  * stored left shifted by 16, and scaled back in the sysfs show() function.
  */
 
-static const unsigned DAY_RESCALE              = 288;
-static const unsigned HOUR_RESCALE             = 12;
-static const unsigned FIVE_MINUTE_RESCALE      = 1;
-static const unsigned accounting_delay         = (HZ * 300) / 22;
-static const unsigned accounting_weight                = 32;
+static const unsigned int DAY_RESCALE          = 288;
+static const unsigned int HOUR_RESCALE         = 12;
+static const unsigned int FIVE_MINUTE_RESCALE  = 1;
+static const unsigned int accounting_delay     = (HZ * 300) / 22;
+static const unsigned int accounting_weight    = 32;
 
 /* sysfs reading/writing */
 
@@ -152,7 +152,7 @@ static void scale_accounting(struct timer_list *t)
        struct cache_accounting *acc = from_timer(acc, t, timer);
 
 #define move_stat(name) do {                                           \
-       unsigned t = atomic_xchg(&acc->collector.name, 0);              \
+       unsigned int t = atomic_xchg(&acc->collector.name, 0);          \
        t <<= 16;                                                       \
        acc->five_minute.name += t;                                     \
        acc->hour.name += t;                                            \
@@ -200,6 +200,7 @@ void bch_mark_cache_accounting(struct cache_set *c, struct bcache_device *d,
                               bool hit, bool bypass)
 {
        struct cached_dev *dc = container_of(d, struct cached_dev, disk);
+
        mark_cache_stats(&dc->accounting.collector, hit, bypass);
        mark_cache_stats(&c->accounting.collector, hit, bypass);
 }
@@ -207,6 +208,7 @@ void bch_mark_cache_accounting(struct cache_set *c, struct bcache_device *d,
 void bch_mark_cache_readahead(struct cache_set *c, struct bcache_device *d)
 {
        struct cached_dev *dc = container_of(d, struct cached_dev, disk);
+
        atomic_inc(&dc->accounting.collector.cache_readaheads);
        atomic_inc(&c->accounting.collector.cache_readaheads);
 }
@@ -214,6 +216,7 @@ void bch_mark_cache_readahead(struct cache_set *c, struct bcache_device *d)
 void bch_mark_cache_miss_collision(struct cache_set *c, struct bcache_device *d)
 {
        struct cached_dev *dc = container_of(d, struct cached_dev, disk);
+
        atomic_inc(&dc->accounting.collector.cache_miss_collisions);
        atomic_inc(&c->accounting.collector.cache_miss_collisions);
 }
index 0b70f9de0c037adddef78d58cc46eb8633b00329..abfaabf7e7fcf8fee33c8370074551bf5fc91768 100644 (file)
@@ -23,7 +23,7 @@ struct cache_stats {
        unsigned long cache_miss_collisions;
        unsigned long sectors_bypassed;
 
-       unsigned                rescale;
+       unsigned int            rescale;
 };
 
 struct cache_accounting {
@@ -53,10 +53,13 @@ void bch_cache_accounting_clear(struct cache_accounting *acc);
 
 void bch_cache_accounting_destroy(struct cache_accounting *acc);
 
-void bch_mark_cache_accounting(struct cache_set *, struct bcache_device *,
-                              bool, bool);
-void bch_mark_cache_readahead(struct cache_set *, struct bcache_device *);
-void bch_mark_cache_miss_collision(struct cache_set *, struct bcache_device *);
-void bch_mark_sectors_bypassed(struct cache_set *, struct cached_dev *, int);
+void bch_mark_cache_accounting(struct cache_set *c, struct bcache_device *d,
+                              bool hit, bool bypass);
+void bch_mark_cache_readahead(struct cache_set *c, struct bcache_device *d);
+void bch_mark_cache_miss_collision(struct cache_set *c,
+                                  struct bcache_device *d);
+void bch_mark_sectors_bypassed(struct cache_set *c,
+                              struct cached_dev *dc,
+                              int sectors);
 
 #endif /* _BCACHE_STATS_H_ */
index 55a37641aa95a511f175fbb5b0b0fe3463954a0f..94c756c66bd7216a6d83b67eaef891269f965467 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * bcache setup/teardown code, and some metadata io - read a superblock and
  * figure out what to do with it.
@@ -61,7 +62,7 @@ static const char *read_super(struct cache_sb *sb, struct block_device *bdev,
        const char *err;
        struct cache_sb *s;
        struct buffer_head *bh = __bread(bdev, 1, SB_SIZE);
-       unsigned i;
+       unsigned int i;
 
        if (!bh)
                return "IO error";
@@ -149,7 +150,8 @@ static const char *read_super(struct cache_sb *sb, struct block_device *bdev,
                        goto err;
 
                err = "Invalid superblock: device too small";
-               if (get_capacity(bdev->bd_disk) < sb->bucket_size * sb->nbuckets)
+               if (get_capacity(bdev->bd_disk) <
+                   sb->bucket_size * sb->nbuckets)
                        goto err;
 
                err = "Bad UUID";
@@ -202,7 +204,7 @@ static void write_bdev_super_endio(struct bio *bio)
 static void __write_super(struct cache_sb *sb, struct bio *bio)
 {
        struct cache_sb *out = page_address(bio_first_page_all(bio));
-       unsigned i;
+       unsigned int i;
 
        bio->bi_iter.bi_sector  = SB_SECTOR;
        bio->bi_iter.bi_size    = SB_SIZE;
@@ -282,7 +284,7 @@ void bcache_write_super(struct cache_set *c)
 {
        struct closure *cl = &c->sb_write;
        struct cache *ca;
-       unsigned i;
+       unsigned int i;
 
        down(&c->sb_write_mutex);
        closure_init(cl, &c->cl);
@@ -334,7 +336,7 @@ static void uuid_io(struct cache_set *c, int op, unsigned long op_flags,
 {
        struct closure *cl = &c->uuid_write;
        struct uuid_entry *u;
-       unsigned i;
+       unsigned int i;
        char buf[80];
 
        BUG_ON(!parent);
@@ -415,8 +417,8 @@ static int __uuid_write(struct cache_set *c)
 {
        BKEY_PADDED(key) k;
        struct closure cl;
-       closure_init_stack(&cl);
 
+       closure_init_stack(&cl);
        lockdep_assert_held(&bch_register_lock);
 
        if (bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, 1, true))
@@ -456,6 +458,7 @@ static struct uuid_entry *uuid_find(struct cache_set *c, const char *uuid)
 static struct uuid_entry *uuid_find_empty(struct cache_set *c)
 {
        static const char zero_uuid[16] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+
        return uuid_find(c, zero_uuid);
 }
 
@@ -463,8 +466,8 @@ static struct uuid_entry *uuid_find_empty(struct cache_set *c)
  * Bucket priorities/gens:
  *
  * For each bucket, we store on disk its
  * 8 bit gen
  * 16 bit priority
*   8 bit gen
 16 bit priority
  *
  * See alloc.c for an explanation of the gen. The priority is used to implement
  * lru (and in the future other) cache replacement policies; for most purposes
@@ -587,7 +590,7 @@ static void prio_read(struct cache *ca, uint64_t bucket)
        struct prio_set *p = ca->disk_buckets;
        struct bucket_disk *d = p->data + prios_per_bucket(ca), *end = d;
        struct bucket *b;
-       unsigned bucket_nr = 0;
+       unsigned int bucket_nr = 0;
 
        for (b = ca->buckets;
             b < ca->buckets + ca->sb.nbuckets;
@@ -599,7 +602,8 @@ static void prio_read(struct cache *ca, uint64_t bucket)
 
                        prio_io(ca, bucket, REQ_OP_READ, 0);
 
-                       if (p->csum != bch_crc64(&p->magic, bucket_bytes(ca) - 8))
+                       if (p->csum !=
+                           bch_crc64(&p->magic, bucket_bytes(ca) - 8))
                                pr_warn("bad csum reading priorities");
 
                        if (p->magic != pset_magic(&ca->sb))
@@ -619,6 +623,7 @@ static void prio_read(struct cache *ca, uint64_t bucket)
 static int open_dev(struct block_device *b, fmode_t mode)
 {
        struct bcache_device *d = b->bd_disk->private_data;
+
        if (test_bit(BCACHE_DEV_CLOSING, &d->flags))
                return -ENXIO;
 
@@ -629,6 +634,7 @@ static int open_dev(struct block_device *b, fmode_t mode)
 static void release_dev(struct gendisk *b, fmode_t mode)
 {
        struct bcache_device *d = b->private_data;
+
        closure_put(&d->cl);
 }
 
@@ -662,7 +668,7 @@ static void bcache_device_unlink(struct bcache_device *d)
        lockdep_assert_held(&bch_register_lock);
 
        if (d->c && !test_and_set_bit(BCACHE_DEV_UNLINK_DONE, &d->flags)) {
-               unsigned i;
+               unsigned int i;
                struct cache *ca;
 
                sysfs_remove_link(&d->c->kobj, d->name);
@@ -676,7 +682,7 @@ static void bcache_device_unlink(struct bcache_device *d)
 static void bcache_device_link(struct bcache_device *d, struct cache_set *c,
                               const char *name)
 {
-       unsigned i;
+       unsigned int i;
        struct cache *ca;
 
        for_each_cache(ca, d->c, i)
@@ -715,7 +721,7 @@ static void bcache_device_detach(struct bcache_device *d)
 }
 
 static void bcache_device_attach(struct bcache_device *d, struct cache_set *c,
-                                unsigned id)
+                                unsigned int id)
 {
        d->id = id;
        d->c = c;
@@ -762,7 +768,7 @@ static void bcache_device_free(struct bcache_device *d)
        closure_debug_destroy(&d->cl);
 }
 
-static int bcache_device_init(struct bcache_device *d, unsigned block_size,
+static int bcache_device_init(struct bcache_device *d, unsigned int block_size,
                              sector_t sectors)
 {
        struct request_queue *q;
@@ -778,7 +784,7 @@ static int bcache_device_init(struct bcache_device *d, unsigned block_size,
 
        if (!d->nr_stripes || d->nr_stripes > max_stripes) {
                pr_err("nr_stripes too large or invalid: %u (start sector beyond end of disk?)",
-                       (unsigned)d->nr_stripes);
+                       (unsigned int)d->nr_stripes);
                return -ENOMEM;
        }
 
@@ -919,6 +925,7 @@ void bch_cached_dev_run(struct cached_dev *dc)
        if (!d->c &&
            BDEV_STATE(&dc->sb) != BDEV_STATE_NONE) {
                struct closure cl;
+
                closure_init_stack(&cl);
 
                SET_BDEV_STATE(&dc->sb, BDEV_STATE_STALE);
@@ -928,8 +935,10 @@ void bch_cached_dev_run(struct cached_dev *dc)
 
        add_disk(d->disk);
        bd_link_disk_holder(dc->bdev, dc->disk.disk);
-       /* won't show up in the uevent file, use udevadm monitor -e instead
-        * only class / kset properties are persistent */
+       /*
+        * won't show up in the uevent file, use udevadm monitor -e instead
+        * only class / kset properties are persistent
+        */
        kobject_uevent_env(&disk_to_dev(d->disk)->kobj, KOBJ_CHANGE, env);
        kfree(env[1]);
        kfree(env[2]);
@@ -976,6 +985,7 @@ static void cached_dev_detach_finish(struct work_struct *w)
 {
        struct cached_dev *dc = container_of(w, struct cached_dev, detach);
        struct closure cl;
+
        closure_init_stack(&cl);
 
        BUG_ON(!test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags));
@@ -1097,12 +1107,14 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c,
                }
        }
 
-       /* Deadlocks since we're called via sysfs...
-       sysfs_remove_file(&dc->kobj, &sysfs_attach);
+       /*
+        * Deadlocks since we're called via sysfs...
+        * sysfs_remove_file(&dc->kobj, &sysfs_attach);
         */
 
        if (bch_is_zero(u->uuid, 16)) {
                struct closure cl;
+
                closure_init_stack(&cl);
 
                memcpy(u->uuid, dc->sb.uuid, 16);
@@ -1124,11 +1136,11 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c,
        list_move(&dc->list, &c->cached_devs);
        calc_cached_dev_sectors(c);
 
-       smp_wmb();
        /*
         * dc->c must be set before dc->count != 0 - paired with the mb in
         * cached_dev_get()
         */
+       smp_wmb();
        refcount_set(&dc->count, 1);
 
        /* Block writeback thread, but spawn it */
@@ -1212,7 +1224,7 @@ static void cached_dev_flush(struct closure *cl)
        continue_at(cl, cached_dev_free, system_wq);
 }
 
-static int cached_dev_init(struct cached_dev *dc, unsigned block_size)
+static int cached_dev_init(struct cached_dev *dc, unsigned int block_size)
 {
        int ret;
        struct io *io;
@@ -1320,6 +1332,7 @@ void bch_flash_dev_release(struct kobject *kobj)
 static void flash_dev_free(struct closure *cl)
 {
        struct bcache_device *d = container_of(cl, struct bcache_device, cl);
+
        mutex_lock(&bch_register_lock);
        atomic_long_sub(bcache_dev_sectors_dirty(d),
                        &d->c->flash_dev_dirty_sectors);
@@ -1459,17 +1472,18 @@ bool bch_cache_set_error(struct cache_set *c, const char *fmt, ...)
        if (test_and_set_bit(CACHE_SET_IO_DISABLE, &c->flags))
                pr_info("CACHE_SET_IO_DISABLE already set");
 
-       /* XXX: we can be called from atomic context
-       acquire_console_sem();
-       */
+       /*
+        * XXX: we can be called from atomic context
+        * acquire_console_sem();
+        */
 
-       printk(KERN_ERR "bcache: error on %pU: ", c->sb.set_uuid);
+       pr_err("bcache: error on %pU: ", c->sb.set_uuid);
 
        va_start(args, fmt);
        vprintk(fmt, args);
        va_end(args);
 
-       printk(", disabling caching\n");
+       pr_err(", disabling caching\n");
 
        if (c->on_error == ON_ERROR_PANIC)
                panic("panic forced after error\n");
@@ -1481,6 +1495,7 @@ bool bch_cache_set_error(struct cache_set *c, const char *fmt, ...)
 void bch_cache_set_release(struct kobject *kobj)
 {
        struct cache_set *c = container_of(kobj, struct cache_set, kobj);
+
        kfree(c);
        module_put(THIS_MODULE);
 }
@@ -1489,7 +1504,7 @@ static void cache_set_free(struct closure *cl)
 {
        struct cache_set *c = container_of(cl, struct cache_set, cl);
        struct cache *ca;
-       unsigned i;
+       unsigned int i;
 
        if (!IS_ERR_OR_NULL(c->debug))
                debugfs_remove(c->debug);
@@ -1532,7 +1547,7 @@ static void cache_set_flush(struct closure *cl)
        struct cache_set *c = container_of(cl, struct cache_set, caching);
        struct cache *ca;
        struct btree *b;
-       unsigned i;
+       unsigned int i;
 
        bch_cache_accounting_destroy(&c->accounting);
 
@@ -1671,6 +1686,7 @@ struct cache_set *bch_cache_set_alloc(struct cache_sb *sb)
 {
        int iter_size;
        struct cache_set *c = kzalloc(sizeof(struct cache_set), GFP_KERNEL);
+
        if (!c)
                return NULL;
 
@@ -1731,8 +1747,8 @@ struct cache_set *bch_cache_set_alloc(struct cache_sb *sb)
        if (!(c->devices = kcalloc(c->nr_uuids, sizeof(void *), GFP_KERNEL)) ||
            mempool_init_slab_pool(&c->search, 32, bch_search_cache) ||
            mempool_init_kmalloc_pool(&c->bio_meta, 2,
-                                     sizeof(struct bbio) + sizeof(struct bio_vec) *
-                                     bucket_pages(c)) ||
+                               sizeof(struct bbio) + sizeof(struct bio_vec) *
+                               bucket_pages(c)) ||
            mempool_init_kmalloc_pool(&c->fill_iter, 1, iter_size) ||
            bioset_init(&c->bio_split, 4, offsetof(struct bbio, bio),
                        BIOSET_NEED_BVECS|BIOSET_NEED_RESCUER) ||
@@ -1762,7 +1778,7 @@ static void run_cache_set(struct cache_set *c)
        struct cached_dev *dc, *t;
        struct cache *ca;
        struct closure cl;
-       unsigned i;
+       unsigned int i;
 
        closure_init_stack(&cl);
 
@@ -1804,7 +1820,9 @@ static void run_cache_set(struct cache_set *c)
                        goto err;
 
                err = "error reading btree root";
-               c->root = bch_btree_node_get(c, NULL, k, j->btree_level, true, NULL);
+               c->root = bch_btree_node_get(c, NULL, k,
+                                            j->btree_level,
+                                            true, NULL);
                if (IS_ERR_OR_NULL(c->root))
                        goto err;
 
@@ -1853,7 +1871,7 @@ static void run_cache_set(struct cache_set *c)
                pr_notice("invalidating existing data");
 
                for_each_cache(ca, c, i) {
-                       unsigned j;
+                       unsigned int j;
 
                        ca->sb.keys = clamp_t(int, ca->sb.nbuckets >> 7,
                                              2, SB_JOURNAL_BUCKETS);
@@ -1998,7 +2016,7 @@ err:
 void bch_cache_release(struct kobject *kobj)
 {
        struct cache *ca = container_of(kobj, struct cache, kobj);
-       unsigned i;
+       unsigned int i;
 
        if (ca->set) {
                BUG_ON(ca->set->cache[ca->sb.nr_this_dev] != ca);
@@ -2098,7 +2116,9 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page,
                goto err;
        }
 
-       if (kobject_add(&ca->kobj, &part_to_dev(bdev->bd_part)->kobj, "bcache")) {
+       if (kobject_add(&ca->kobj,
+                       &part_to_dev(bdev->bd_part)->kobj,
+                       "bcache")) {
                err = "error calling kobject_add";
                ret = -ENOMEM;
                goto out;
@@ -2127,13 +2147,14 @@ err:
 
 /* Global interfaces/init */
 
-static ssize_t register_bcache(struct kobject *, struct kobj_attribute *,
-                              const char *, size_t);
+static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
+                              const char *buffer, size_t size);
 
 kobj_attribute_write(register,         register_bcache);
 kobj_attribute_write(register_quiet,   register_bcache);
 
-static bool bch_is_open_backing(struct block_device *bdev) {
+static bool bch_is_open_backing(struct block_device *bdev)
+{
        struct cache_set *c, *tc;
        struct cached_dev *dc, *t;
 
@@ -2147,10 +2168,11 @@ static bool bch_is_open_backing(struct block_device *bdev) {
        return false;
 }
 
-static bool bch_is_open_cache(struct block_device *bdev) {
+static bool bch_is_open_cache(struct block_device *bdev)
+{
        struct cache_set *c, *tc;
        struct cache *ca;
-       unsigned i;
+       unsigned int i;
 
        list_for_each_entry_safe(c, tc, &bch_cache_sets, list)
                for_each_cache(ca, c, i)
@@ -2159,7 +2181,8 @@ static bool bch_is_open_cache(struct block_device *bdev) {
        return false;
 }
 
-static bool bch_is_open(struct block_device *bdev) {
+static bool bch_is_open(struct block_device *bdev)
+{
        return bch_is_open_cache(bdev) || bch_is_open_backing(bdev);
 }
 
@@ -2216,6 +2239,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
        err = "failed to register device";
        if (SB_IS_BDEV(sb)) {
                struct cached_dev *dc = kzalloc(sizeof(*dc), GFP_KERNEL);
+
                if (!dc)
                        goto err_close;
 
@@ -2224,6 +2248,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
                mutex_unlock(&bch_register_lock);
        } else {
                struct cache *ca = kzalloc(sizeof(*ca), GFP_KERNEL);
+
                if (!ca)
                        goto err_close;
 
index 81d3520b0702d169ffe69ab480b6edec0998e9ff..150cf4f4cf749d8725de356f4b56357b2f8a4198 100644 (file)
@@ -130,8 +130,10 @@ rw_attribute(btree_shrinker_disabled);
 rw_attribute(copy_gc_enabled);
 rw_attribute(size);
 
-static ssize_t bch_snprint_string_list(char *buf, size_t size, const char * const list[],
-                           size_t selected)
+static ssize_t bch_snprint_string_list(char *buf,
+                                      size_t size,
+                                      const char * const list[],
+                                      size_t selected)
 {
        char *out = buf;
        size_t i;
@@ -148,7 +150,7 @@ SHOW(__bch_cached_dev)
 {
        struct cached_dev *dc = container_of(kobj, struct cached_dev,
                                             disk.kobj);
-       const char *states[] = { "no cache", "clean", "dirty", "inconsistent" };
+       char const *states[] = { "no cache", "clean", "dirty", "inconsistent" };
        int wb = dc->writeback_running;
 
 #define var(stat)              (dc->stat)
@@ -307,7 +309,7 @@ STORE(__cached_dev)
                if (v < 0)
                        return v;
 
-               if ((unsigned) v != BDEV_CACHE_MODE(&dc->sb)) {
+               if ((unsigned int) v != BDEV_CACHE_MODE(&dc->sb)) {
                        SET_BDEV_CACHE_MODE(&dc->sb, v);
                        bch_write_bdev_super(dc, NULL);
                }
@@ -341,8 +343,9 @@ STORE(__cached_dev)
                add_uevent_var(env, "DRIVER=bcache");
                add_uevent_var(env, "CACHED_UUID=%pU", dc->sb.uuid),
                add_uevent_var(env, "CACHED_LABEL=%s", buf);
-               kobject_uevent_env(
-                       &disk_to_dev(dc->disk.disk)->kobj, KOBJ_CHANGE, env->envp);
+               kobject_uevent_env(&disk_to_dev(dc->disk.disk)->kobj,
+                                  KOBJ_CHANGE,
+                                  env->envp);
                kfree(env);
        }
 
@@ -459,6 +462,7 @@ STORE(__bch_flash_dev)
 
        if (attr == &sysfs_size) {
                uint64_t v;
+
                strtoi_h_or_return(buf, v);
 
                u->sectors = v >> 9;
@@ -533,9 +537,9 @@ static int bch_bset_print_stats(struct cache_set *c, char *buf)
                        op.stats.floats, op.stats.failed);
 }
 
-static unsigned bch_root_usage(struct cache_set *c)
+static unsigned int bch_root_usage(struct cache_set *c)
 {
-       unsigned bytes = 0;
+       unsigned int bytes = 0;
        struct bkey *k;
        struct btree *b;
        struct btree_iter iter;
@@ -570,9 +574,9 @@ static size_t bch_cache_size(struct cache_set *c)
        return ret;
 }
 
-static unsigned bch_cache_max_chain(struct cache_set *c)
+static unsigned int bch_cache_max_chain(struct cache_set *c)
 {
-       unsigned ret = 0;
+       unsigned int ret = 0;
        struct hlist_head *h;
 
        mutex_lock(&c->bucket_lock);
@@ -580,7 +584,7 @@ static unsigned bch_cache_max_chain(struct cache_set *c)
        for (h = c->bucket_hash;
             h < c->bucket_hash + (1 << BUCKET_HASH_BITS);
             h++) {
-               unsigned i = 0;
+               unsigned int i = 0;
                struct hlist_node *p;
 
                hlist_for_each(p, h)
@@ -593,13 +597,13 @@ static unsigned bch_cache_max_chain(struct cache_set *c)
        return ret;
 }
 
-static unsigned bch_btree_used(struct cache_set *c)
+static unsigned int bch_btree_used(struct cache_set *c)
 {
        return div64_u64(c->gc_stats.key_bytes * 100,
                         (c->gc_stats.nodes ?: 1) * btree_bytes(c));
 }
 
-static unsigned bch_average_key_size(struct cache_set *c)
+static unsigned int bch_average_key_size(struct cache_set *c)
 {
        return c->gc_stats.nkeys
                ? div64_u64(c->gc_stats.data, c->gc_stats.nkeys)
@@ -703,6 +707,7 @@ STORE(__bch_cache_set)
        if (attr == &sysfs_flash_vol_create) {
                int r;
                uint64_t v;
+
                strtoi_h_or_return(buf, v);
 
                r = bch_flash_dev_create(c, v);
@@ -736,6 +741,7 @@ STORE(__bch_cache_set)
 
        if (attr == &sysfs_prune_cache) {
                struct shrink_control sc;
+
                sc.gfp_mask = GFP_KERNEL;
                sc.nr_to_scan = strtoul_or_return(buf);
                c->shrink.scan_objects(&c->shrink, &sc);
@@ -789,12 +795,14 @@ STORE_LOCKED(bch_cache_set)
 SHOW(bch_cache_set_internal)
 {
        struct cache_set *c = container_of(kobj, struct cache_set, internal);
+
        return bch_cache_set_show(&c->kobj, attr, buf);
 }
 
 STORE(bch_cache_set_internal)
 {
        struct cache_set *c = container_of(kobj, struct cache_set, internal);
+
        return bch_cache_set_store(&c->kobj, attr, buf, size);
 }
 
@@ -996,7 +1004,7 @@ STORE(__bch_cache)
                if (v < 0)
                        return v;
 
-               if ((unsigned) v != CACHE_REPLACEMENT(&ca->sb)) {
+               if ((unsigned int) v != CACHE_REPLACEMENT(&ca->sb)) {
                        mutex_lock(&ca->set->bucket_lock);
                        SET_CACHE_REPLACEMENT(&ca->sb, v);
                        mutex_unlock(&ca->set->bucket_lock);
index b54fe9602529ebda4ab71e7d306617137290cf39..3fe82425859c233761189483dd11bfb4ee81bb41 100644 (file)
@@ -44,9 +44,9 @@ STORE(fn)                                                             \
        static struct attribute sysfs_##_name =                         \
                { .name = #_name, .mode = _mode }
 
-#define write_attribute(n)     __sysfs_attribute(n, S_IWUSR)
-#define read_attribute(n)      __sysfs_attribute(n, S_IRUGO)
-#define rw_attribute(n)                __sysfs_attribute(n, S_IRUGO|S_IWUSR)
+#define write_attribute(n)     __sysfs_attribute(n, 0200)
+#define read_attribute(n)      __sysfs_attribute(n, 0444)
+#define rw_attribute(n)                __sysfs_attribute(n, 0644)
 
 #define sysfs_printf(file, fmt, ...)                                   \
 do {                                                                   \
index b15256bcf0e7568e761a8afcae08659cb7a3a95e..20eddeac1531a93d4a2bd3077b4645e600e342b1 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * random utiility code, for bcache but in theory not specific to bcache
  *
@@ -133,6 +134,7 @@ bool bch_is_zero(const char *p, size_t n)
 int bch_parse_uuid(const char *s, char *uuid)
 {
        size_t i, j, x;
+
        memset(uuid, 0, 16);
 
        for (i = 0, j = 0;
@@ -279,134 +281,3 @@ int bch_bio_alloc_pages(struct bio *bio, gfp_t gfp_mask)
 
        return 0;
 }
-
-/*
- * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group (Any
- * use permitted, subject to terms of PostgreSQL license; see.)
-
- * If we have a 64-bit integer type, then a 64-bit CRC looks just like the
- * usual sort of implementation. (See Ross Williams' excellent introduction
- * A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS, available from
- * ftp://ftp.rocksoft.com/papers/crc_v3.txt or several other net sites.)
- * If we have no working 64-bit type, then fake it with two 32-bit registers.
- *
- * The present implementation is a normal (not "reflected", in Williams'
- * terms) 64-bit CRC, using initial all-ones register contents and a final
- * bit inversion. The chosen polynomial is borrowed from the DLT1 spec
- * (ECMA-182, available from http://www.ecma.ch/ecma1/STAND/ECMA-182.HTM):
- *
- * x^64 + x^62 + x^57 + x^55 + x^54 + x^53 + x^52 + x^47 + x^46 + x^45 +
- * x^40 + x^39 + x^38 + x^37 + x^35 + x^33 + x^32 + x^31 + x^29 + x^27 +
- * x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 +
- * x^7 + x^4 + x + 1
-*/
-
-static const uint64_t crc_table[256] = {
-       0x0000000000000000ULL, 0x42F0E1EBA9EA3693ULL, 0x85E1C3D753D46D26ULL,
-       0xC711223CFA3E5BB5ULL, 0x493366450E42ECDFULL, 0x0BC387AEA7A8DA4CULL,
-       0xCCD2A5925D9681F9ULL, 0x8E224479F47CB76AULL, 0x9266CC8A1C85D9BEULL,
-       0xD0962D61B56FEF2DULL, 0x17870F5D4F51B498ULL, 0x5577EEB6E6BB820BULL,
-       0xDB55AACF12C73561ULL, 0x99A54B24BB2D03F2ULL, 0x5EB4691841135847ULL,
-       0x1C4488F3E8F96ED4ULL, 0x663D78FF90E185EFULL, 0x24CD9914390BB37CULL,
-       0xE3DCBB28C335E8C9ULL, 0xA12C5AC36ADFDE5AULL, 0x2F0E1EBA9EA36930ULL,
-       0x6DFEFF5137495FA3ULL, 0xAAEFDD6DCD770416ULL, 0xE81F3C86649D3285ULL,
-       0xF45BB4758C645C51ULL, 0xB6AB559E258E6AC2ULL, 0x71BA77A2DFB03177ULL,
-       0x334A9649765A07E4ULL, 0xBD68D2308226B08EULL, 0xFF9833DB2BCC861DULL,
-       0x388911E7D1F2DDA8ULL, 0x7A79F00C7818EB3BULL, 0xCC7AF1FF21C30BDEULL,
-       0x8E8A101488293D4DULL, 0x499B3228721766F8ULL, 0x0B6BD3C3DBFD506BULL,
-       0x854997BA2F81E701ULL, 0xC7B97651866BD192ULL, 0x00A8546D7C558A27ULL,
-       0x4258B586D5BFBCB4ULL, 0x5E1C3D753D46D260ULL, 0x1CECDC9E94ACE4F3ULL,
-       0xDBFDFEA26E92BF46ULL, 0x990D1F49C77889D5ULL, 0x172F5B3033043EBFULL,
-       0x55DFBADB9AEE082CULL, 0x92CE98E760D05399ULL, 0xD03E790CC93A650AULL,
-       0xAA478900B1228E31ULL, 0xE8B768EB18C8B8A2ULL, 0x2FA64AD7E2F6E317ULL,
-       0x6D56AB3C4B1CD584ULL, 0xE374EF45BF6062EEULL, 0xA1840EAE168A547DULL,
-       0x66952C92ECB40FC8ULL, 0x2465CD79455E395BULL, 0x3821458AADA7578FULL,
-       0x7AD1A461044D611CULL, 0xBDC0865DFE733AA9ULL, 0xFF3067B657990C3AULL,
-       0x711223CFA3E5BB50ULL, 0x33E2C2240A0F8DC3ULL, 0xF4F3E018F031D676ULL,
-       0xB60301F359DBE0E5ULL, 0xDA050215EA6C212FULL, 0x98F5E3FE438617BCULL,
-       0x5FE4C1C2B9B84C09ULL, 0x1D14202910527A9AULL, 0x93366450E42ECDF0ULL,
-       0xD1C685BB4DC4FB63ULL, 0x16D7A787B7FAA0D6ULL, 0x5427466C1E109645ULL,
-       0x4863CE9FF6E9F891ULL, 0x0A932F745F03CE02ULL, 0xCD820D48A53D95B7ULL,
-       0x8F72ECA30CD7A324ULL, 0x0150A8DAF8AB144EULL, 0x43A04931514122DDULL,
-       0x84B16B0DAB7F7968ULL, 0xC6418AE602954FFBULL, 0xBC387AEA7A8DA4C0ULL,
-       0xFEC89B01D3679253ULL, 0x39D9B93D2959C9E6ULL, 0x7B2958D680B3FF75ULL,
-       0xF50B1CAF74CF481FULL, 0xB7FBFD44DD257E8CULL, 0x70EADF78271B2539ULL,
-       0x321A3E938EF113AAULL, 0x2E5EB66066087D7EULL, 0x6CAE578BCFE24BEDULL,
-       0xABBF75B735DC1058ULL, 0xE94F945C9C3626CBULL, 0x676DD025684A91A1ULL,
-       0x259D31CEC1A0A732ULL, 0xE28C13F23B9EFC87ULL, 0xA07CF2199274CA14ULL,
-       0x167FF3EACBAF2AF1ULL, 0x548F120162451C62ULL, 0x939E303D987B47D7ULL,
-       0xD16ED1D631917144ULL, 0x5F4C95AFC5EDC62EULL, 0x1DBC74446C07F0BDULL,
-       0xDAAD56789639AB08ULL, 0x985DB7933FD39D9BULL, 0x84193F60D72AF34FULL,
-       0xC6E9DE8B7EC0C5DCULL, 0x01F8FCB784FE9E69ULL, 0x43081D5C2D14A8FAULL,
-       0xCD2A5925D9681F90ULL, 0x8FDAB8CE70822903ULL, 0x48CB9AF28ABC72B6ULL,
-       0x0A3B7B1923564425ULL, 0x70428B155B4EAF1EULL, 0x32B26AFEF2A4998DULL,
-       0xF5A348C2089AC238ULL, 0xB753A929A170F4ABULL, 0x3971ED50550C43C1ULL,
-       0x7B810CBBFCE67552ULL, 0xBC902E8706D82EE7ULL, 0xFE60CF6CAF321874ULL,
-       0xE224479F47CB76A0ULL, 0xA0D4A674EE214033ULL, 0x67C58448141F1B86ULL,
-       0x253565A3BDF52D15ULL, 0xAB1721DA49899A7FULL, 0xE9E7C031E063ACECULL,
-       0x2EF6E20D1A5DF759ULL, 0x6C0603E6B3B7C1CAULL, 0xF6FAE5C07D3274CDULL,
-       0xB40A042BD4D8425EULL, 0x731B26172EE619EBULL, 0x31EBC7FC870C2F78ULL,
-       0xBFC9838573709812ULL, 0xFD39626EDA9AAE81ULL, 0x3A28405220A4F534ULL,
-       0x78D8A1B9894EC3A7ULL, 0x649C294A61B7AD73ULL, 0x266CC8A1C85D9BE0ULL,
-       0xE17DEA9D3263C055ULL, 0xA38D0B769B89F6C6ULL, 0x2DAF4F0F6FF541ACULL,
-       0x6F5FAEE4C61F773FULL, 0xA84E8CD83C212C8AULL, 0xEABE6D3395CB1A19ULL,
-       0x90C79D3FEDD3F122ULL, 0xD2377CD44439C7B1ULL, 0x15265EE8BE079C04ULL,
-       0x57D6BF0317EDAA97ULL, 0xD9F4FB7AE3911DFDULL, 0x9B041A914A7B2B6EULL,
-       0x5C1538ADB04570DBULL, 0x1EE5D94619AF4648ULL, 0x02A151B5F156289CULL,
-       0x4051B05E58BC1E0FULL, 0x87409262A28245BAULL, 0xC5B073890B687329ULL,
-       0x4B9237F0FF14C443ULL, 0x0962D61B56FEF2D0ULL, 0xCE73F427ACC0A965ULL,
-       0x8C8315CC052A9FF6ULL, 0x3A80143F5CF17F13ULL, 0x7870F5D4F51B4980ULL,
-       0xBF61D7E80F251235ULL, 0xFD913603A6CF24A6ULL, 0x73B3727A52B393CCULL,
-       0x31439391FB59A55FULL, 0xF652B1AD0167FEEAULL, 0xB4A25046A88DC879ULL,
-       0xA8E6D8B54074A6ADULL, 0xEA16395EE99E903EULL, 0x2D071B6213A0CB8BULL,
-       0x6FF7FA89BA4AFD18ULL, 0xE1D5BEF04E364A72ULL, 0xA3255F1BE7DC7CE1ULL,
-       0x64347D271DE22754ULL, 0x26C49CCCB40811C7ULL, 0x5CBD6CC0CC10FAFCULL,
-       0x1E4D8D2B65FACC6FULL, 0xD95CAF179FC497DAULL, 0x9BAC4EFC362EA149ULL,
-       0x158E0A85C2521623ULL, 0x577EEB6E6BB820B0ULL, 0x906FC95291867B05ULL,
-       0xD29F28B9386C4D96ULL, 0xCEDBA04AD0952342ULL, 0x8C2B41A1797F15D1ULL,
-       0x4B3A639D83414E64ULL, 0x09CA82762AAB78F7ULL, 0x87E8C60FDED7CF9DULL,
-       0xC51827E4773DF90EULL, 0x020905D88D03A2BBULL, 0x40F9E43324E99428ULL,
-       0x2CFFE7D5975E55E2ULL, 0x6E0F063E3EB46371ULL, 0xA91E2402C48A38C4ULL,
-       0xEBEEC5E96D600E57ULL, 0x65CC8190991CB93DULL, 0x273C607B30F68FAEULL,
-       0xE02D4247CAC8D41BULL, 0xA2DDA3AC6322E288ULL, 0xBE992B5F8BDB8C5CULL,
-       0xFC69CAB42231BACFULL, 0x3B78E888D80FE17AULL, 0x7988096371E5D7E9ULL,
-       0xF7AA4D1A85996083ULL, 0xB55AACF12C735610ULL, 0x724B8ECDD64D0DA5ULL,
-       0x30BB6F267FA73B36ULL, 0x4AC29F2A07BFD00DULL, 0x08327EC1AE55E69EULL,
-       0xCF235CFD546BBD2BULL, 0x8DD3BD16FD818BB8ULL, 0x03F1F96F09FD3CD2ULL,
-       0x41011884A0170A41ULL, 0x86103AB85A2951F4ULL, 0xC4E0DB53F3C36767ULL,
-       0xD8A453A01B3A09B3ULL, 0x9A54B24BB2D03F20ULL, 0x5D45907748EE6495ULL,
-       0x1FB5719CE1045206ULL, 0x919735E51578E56CULL, 0xD367D40EBC92D3FFULL,
-       0x1476F63246AC884AULL, 0x568617D9EF46BED9ULL, 0xE085162AB69D5E3CULL,
-       0xA275F7C11F7768AFULL, 0x6564D5FDE549331AULL, 0x279434164CA30589ULL,
-       0xA9B6706FB8DFB2E3ULL, 0xEB46918411358470ULL, 0x2C57B3B8EB0BDFC5ULL,
-       0x6EA7525342E1E956ULL, 0x72E3DAA0AA188782ULL, 0x30133B4B03F2B111ULL,
-       0xF7021977F9CCEAA4ULL, 0xB5F2F89C5026DC37ULL, 0x3BD0BCE5A45A6B5DULL,
-       0x79205D0E0DB05DCEULL, 0xBE317F32F78E067BULL, 0xFCC19ED95E6430E8ULL,
-       0x86B86ED5267CDBD3ULL, 0xC4488F3E8F96ED40ULL, 0x0359AD0275A8B6F5ULL,
-       0x41A94CE9DC428066ULL, 0xCF8B0890283E370CULL, 0x8D7BE97B81D4019FULL,
-       0x4A6ACB477BEA5A2AULL, 0x089A2AACD2006CB9ULL, 0x14DEA25F3AF9026DULL,
-       0x562E43B4931334FEULL, 0x913F6188692D6F4BULL, 0xD3CF8063C0C759D8ULL,
-       0x5DEDC41A34BBEEB2ULL, 0x1F1D25F19D51D821ULL, 0xD80C07CD676F8394ULL,
-       0x9AFCE626CE85B507ULL,
-};
-
-uint64_t bch_crc64_update(uint64_t crc, const void *_data, size_t len)
-{
-       const unsigned char *data = _data;
-
-       while (len--) {
-               int i = ((int) (crc >> 56) ^ *data++) & 0xFF;
-               crc = crc_table[i] ^ (crc << 8);
-       }
-
-       return crc;
-}
-
-uint64_t bch_crc64(const void *data, size_t len)
-{
-       uint64_t crc = 0xffffffffffffffffULL;
-
-       crc = bch_crc64_update(crc, data, len);
-
-       return crc ^ 0xffffffffffffffffULL;
-}
index f7b0133c9d2f1aacd08dec33af2924df8594ebc9..00aab6abcfe4fd3bb4e625780de0badee109dbf0 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/ratelimit.h>
 #include <linux/vmalloc.h>
 #include <linux/workqueue.h>
+#include <linux/crc64.h>
 
 #include "closure.h"
 
@@ -288,10 +289,10 @@ do {                                                                      \
 #define ANYSINT_MAX(t)                                                 \
        ((((t) 1 << (sizeof(t) * 8 - 2)) - (t) 1) * (t) 2 + (t) 1)
 
-int bch_strtoint_h(const char *, int *);
-int bch_strtouint_h(const char *, unsigned int *);
-int bch_strtoll_h(const char *, long long *);
-int bch_strtoull_h(const char *, unsigned long long *);
+int bch_strtoint_h(const char *cp, int *res);
+int bch_strtouint_h(const char *cp, unsigned int *res);
+int bch_strtoll_h(const char *cp, long long *res);
+int bch_strtoull_h(const char *cp, unsigned long long *res);
 
 static inline int bch_strtol_h(const char *cp, long *res)
 {
@@ -347,7 +348,7 @@ static inline int bch_strtoul_h(const char *cp, long *res)
        snprintf(buf, size,                                             \
                __builtin_types_compatible_p(typeof(var), int)          \
                     ? "%i\n" :                                         \
-               __builtin_types_compatible_p(typeof(var), unsigned)     \
+               __builtin_types_compatible_p(typeof(var), unsigned int) \
                     ? "%u\n" :                                         \
                __builtin_types_compatible_p(typeof(var), long)         \
                     ? "%li\n" :                                        \
@@ -379,7 +380,7 @@ struct time_stats {
 
 void bch_time_stats_update(struct time_stats *stats, uint64_t time);
 
-static inline unsigned local_clock_us(void)
+static inline unsigned int local_clock_us(void)
 {
        return local_clock() >> 10;
 }
@@ -402,7 +403,8 @@ do {                                                                        \
        __print_time_stat(stats, name,                                  \
                          average_duration,     duration_units);        \
        sysfs_print(name ## _ ##max_duration ## _ ## duration_units,    \
-                       div_u64((stats)->max_duration, NSEC_PER_ ## duration_units));\
+                       div_u64((stats)->max_duration,                  \
+                               NSEC_PER_ ## duration_units));          \
                                                                        \
        sysfs_print(name ## _last_ ## frequency_units, (stats)->last    \
                    ? div_s64(local_clock() - (stats)->last,            \
@@ -542,10 +544,27 @@ dup:                                                                      \
 #define RB_PREV(ptr, member)                                           \
        container_of_or_null(rb_prev(&(ptr)->member), typeof(*ptr), member)
 
+static inline uint64_t bch_crc64(const void *p, size_t len)
+{
+       uint64_t crc = 0xffffffffffffffffULL;
+
+       crc = crc64_be(crc, p, len);
+       return crc ^ 0xffffffffffffffffULL;
+}
+
+static inline uint64_t bch_crc64_update(uint64_t crc,
+                                       const void *p,
+                                       size_t len)
+{
+       crc = crc64_be(crc, p, len);
+       return crc;
+}
+
 /* Does linear interpolation between powers of two */
-static inline unsigned fract_exp_two(unsigned x, unsigned fract_bits)
+static inline unsigned int fract_exp_two(unsigned int x,
+                                        unsigned int fract_bits)
 {
-       unsigned fract = x & ~(~0 << fract_bits);
+       unsigned int fract = x & ~(~0 << fract_bits);
 
        x >>= fract_bits;
        x   = 1 << x;
@@ -561,8 +580,4 @@ static inline sector_t bdev_sectors(struct block_device *bdev)
 {
        return bdev->bd_inode->i_size >> 9;
 }
-
-uint64_t bch_crc64_update(uint64_t, const void *, size_t);
-uint64_t bch_crc64(const void *, size_t);
-
 #endif /* _BCACHE_UTIL_H */
index 481d4cf38ac0e9ea2e04e10303b86524de5021c4..08c3a9f9676c9e89649b56f765fb378973149a62 100644 (file)
@@ -215,7 +215,8 @@ static void update_writeback_rate(struct work_struct *work)
        smp_mb();
 }
 
-static unsigned writeback_delay(struct cached_dev *dc, unsigned sectors)
+static unsigned int writeback_delay(struct cached_dev *dc,
+                                   unsigned int sectors)
 {
        if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) ||
            !dc->writeback_percent)
@@ -249,6 +250,7 @@ static void dirty_init(struct keybuf_key *w)
 static void dirty_io_destructor(struct closure *cl)
 {
        struct dirty_io *io = container_of(cl, struct dirty_io, cl);
+
        kfree(io);
 }
 
@@ -263,7 +265,7 @@ static void write_dirty_finish(struct closure *cl)
        /* This is kind of a dumb way of signalling errors. */
        if (KEY_DIRTY(&w->key)) {
                int ret;
-               unsigned i;
+               unsigned int i;
                struct keylist keys;
 
                bch_keylist_init(&keys);
@@ -377,7 +379,7 @@ static void read_dirty_submit(struct closure *cl)
 
 static void read_dirty(struct cached_dev *dc)
 {
-       unsigned delay = 0;
+       unsigned int delay = 0;
        struct keybuf_key *next, *keys[MAX_WRITEBACKS_IN_PASS], *w;
        size_t size;
        int nk, i;
@@ -442,7 +444,8 @@ static void read_dirty(struct cached_dev *dc)
 
                        io = kzalloc(sizeof(struct dirty_io) +
                                     sizeof(struct bio_vec) *
-                                    DIV_ROUND_UP(KEY_SIZE(&w->key), PAGE_SECTORS),
+                                    DIV_ROUND_UP(KEY_SIZE(&w->key),
+                                                 PAGE_SECTORS),
                                     GFP_KERNEL);
                        if (!io)
                                goto err;
@@ -465,7 +468,8 @@ static void read_dirty(struct cached_dev *dc)
 
                        down(&dc->in_flight);
 
-                       /* We've acquired a semaphore for the maximum
+                       /*
+                        * We've acquired a semaphore for the maximum
                         * simultaneous number of writebacks; from here
                         * everything happens asynchronously.
                         */
@@ -498,11 +502,11 @@ err:
 
 /* Scan for dirty data */
 
-void bcache_dev_sectors_dirty_add(struct cache_set *c, unsigned inode,
+void bcache_dev_sectors_dirty_add(struct cache_set *c, unsigned int inode,
                                  uint64_t offset, int nr_sectors)
 {
        struct bcache_device *d = c->devices[inode];
-       unsigned stripe_offset, stripe, sectors_dirty;
+       unsigned int stripe_offset, stripe, sectors_dirty;
 
        if (!d)
                return;
@@ -514,7 +518,7 @@ void bcache_dev_sectors_dirty_add(struct cache_set *c, unsigned inode,
        stripe_offset = offset & (d->stripe_size - 1);
 
        while (nr_sectors) {
-               int s = min_t(unsigned, abs(nr_sectors),
+               int s = min_t(unsigned int, abs(nr_sectors),
                              d->stripe_size - stripe_offset);
 
                if (nr_sectors < 0)
@@ -538,7 +542,9 @@ void bcache_dev_sectors_dirty_add(struct cache_set *c, unsigned inode,
 
 static bool dirty_pred(struct keybuf *buf, struct bkey *k)
 {
-       struct cached_dev *dc = container_of(buf, struct cached_dev, writeback_keys);
+       struct cached_dev *dc = container_of(buf,
+                                            struct cached_dev,
+                                            writeback_keys);
 
        BUG_ON(KEY_INODE(k) != dc->disk.id);
 
@@ -548,7 +554,7 @@ static bool dirty_pred(struct keybuf *buf, struct bkey *k)
 static void refill_full_stripes(struct cached_dev *dc)
 {
        struct keybuf *buf = &dc->writeback_keys;
-       unsigned start_stripe, stripe, next_stripe;
+       unsigned int start_stripe, stripe, next_stripe;
        bool wrapped = false;
 
        stripe = offset_to_stripe(&dc->disk, KEY_OFFSET(&buf->last_scanned));
@@ -679,8 +685,10 @@ static int bch_writeback_thread(void *arg)
                         * data on cache. BCACHE_DEV_DETACHING flag is set in
                         * bch_cached_dev_detach().
                         */
-                       if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags))
+                       if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags)) {
+                               up_write(&dc->writeback_lock);
                                break;
+                       }
                }
 
                up_write(&dc->writeback_lock);
@@ -688,7 +696,7 @@ static int bch_writeback_thread(void *arg)
                read_dirty(dc);
 
                if (searched_full_index) {
-                       unsigned delay = dc->writeback_delay * HZ;
+                       unsigned int delay = dc->writeback_delay * HZ;
 
                        while (delay &&
                               !kthread_should_stop() &&
@@ -712,7 +720,7 @@ static int bch_writeback_thread(void *arg)
 
 struct sectors_dirty_init {
        struct btree_op op;
-       unsigned        inode;
+       unsigned int    inode;
        size_t          count;
        struct bkey     start;
 };
index 3745d7004c478c5612bdb19137145ce2ab96ba79..d2b9fdbc8994905e48dba5f2126cbea983ae602a 100644 (file)
@@ -28,7 +28,7 @@ static inline uint64_t bcache_dev_sectors_dirty(struct bcache_device *d)
        return ret;
 }
 
-static inline unsigned offset_to_stripe(struct bcache_device *d,
+static inline unsigned int offset_to_stripe(struct bcache_device *d,
                                        uint64_t offset)
 {
        do_div(offset, d->stripe_size);
@@ -37,9 +37,9 @@ static inline unsigned offset_to_stripe(struct bcache_device *d,
 
 static inline bool bcache_dev_stripe_dirty(struct cached_dev *dc,
                                           uint64_t offset,
-                                          unsigned nr_sectors)
+                                          unsigned int nr_sectors)
 {
-       unsigned stripe = offset_to_stripe(&dc->disk, offset);
+       unsigned int stripe = offset_to_stripe(&dc->disk, offset);
 
        while (1) {
                if (atomic_read(dc->disk.stripe_sectors_dirty + stripe))
@@ -54,9 +54,9 @@ static inline bool bcache_dev_stripe_dirty(struct cached_dev *dc,
 }
 
 static inline bool should_writeback(struct cached_dev *dc, struct bio *bio,
-                                   unsigned cache_mode, bool would_skip)
+                                   unsigned int cache_mode, bool would_skip)
 {
-       unsigned in_use = dc->disk.c->gc_stats.in_use;
+       unsigned int in_use = dc->disk.c->gc_stats.in_use;
 
        if (cache_mode != CACHE_MODE_WRITEBACK ||
            test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) ||
@@ -96,10 +96,11 @@ static inline void bch_writeback_add(struct cached_dev *dc)
        }
 }
 
-void bcache_dev_sectors_dirty_add(struct cache_set *, unsigned, uint64_t, int);
+void bcache_dev_sectors_dirty_add(struct cache_set *c, unsigned int inode,
+                                 uint64_t offset, int nr_sectors);
 
-void bch_sectors_dirty_init(struct bcache_device *);
-void bch_cached_dev_writeback_init(struct cached_dev *);
-int bch_cached_dev_writeback_start(struct cached_dev *);
+void bch_sectors_dirty_init(struct bcache_device *d);
+void bch_cached_dev_writeback_init(struct cached_dev *dc);
+int bch_cached_dev_writeback_start(struct cached_dev *dc);
 
 #endif
index 3a28a68f184ca5baccaa541ad68fd60eade09df7..5f1f80d424dd370f306e15033e12bb77de72f3b7 100644 (file)
@@ -268,9 +268,8 @@ static int persistent_memory_claim(struct dm_writecache *wc)
                i = 0;
                do {
                        long daa;
-                       void *dummy_addr;
                        daa = dax_direct_access(wc->ssd_dev->dax_dev, i, p - i,
-                                               &dummy_addr, &pfn);
+                                               NULL, &pfn);
                        if (daa <= 0) {
                                r = daa ? daa : -EINVAL;
                                goto err3;
index 94329e03001ec8d0ca15ff4ad0d04e7fdebd0b5d..0b2af6e74fc375ed163824fa9cdaf84d1b9ffd95 100644 (file)
@@ -1276,18 +1276,18 @@ static int resync_info_update(struct mddev *mddev, sector_t lo, sector_t hi)
 static int resync_finish(struct mddev *mddev)
 {
        struct md_cluster_info *cinfo = mddev->cluster_info;
+       int ret = 0;
 
        clear_bit(MD_RESYNCING_REMOTE, &mddev->recovery);
-       dlm_unlock_sync(cinfo->resync_lockres);
 
        /*
         * If resync thread is interrupted so we can't say resync is finished,
         * another node will launch resync thread to continue.
         */
-       if (test_bit(MD_CLOSING, &mddev->flags))
-               return 0;
-       else
-               return resync_info_update(mddev, 0, 0);
+       if (!test_bit(MD_CLOSING, &mddev->flags))
+               ret = resync_info_update(mddev, 0, 0);
+       dlm_unlock_sync(cinfo->resync_lockres);
+       return ret;
 }
 
 static int area_resyncing(struct mddev *mddev, int direction,
index 9818980494914eb72e085173fc015e012afb5dce..d6f7978b4449e92aba522035941ff51137e2ce38 100644 (file)
@@ -4529,11 +4529,12 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
                allow_barrier(conf);
        }
 
+       raise_barrier(conf, 0);
 read_more:
        /* Now schedule reads for blocks from sector_nr to last */
        r10_bio = raid10_alloc_init_r10buf(conf);
        r10_bio->state = 0;
-       raise_barrier(conf, sectors_done != 0);
+       raise_barrier(conf, 1);
        atomic_set(&r10_bio->remaining, 0);
        r10_bio->mddev = mddev;
        r10_bio->sector = sector_nr;
@@ -4629,6 +4630,8 @@ read_more:
        if (sector_nr <= last)
                goto read_more;
 
+       lower_barrier(conf);
+
        /* Now that we have done the whole section we can
         * update reshape_progress
         */
index a001808a2b77da16bc2ae3c1d4aa32b5f944a939..bfb81140706140a53af24ccf90420e6cc107cef1 100644 (file)
@@ -46,6 +46,11 @@ extern int ppl_modify_log(struct r5conf *conf, struct md_rdev *rdev, bool add);
 extern void ppl_quiesce(struct r5conf *conf, int quiesce);
 extern int ppl_handle_flush_request(struct r5l_log *log, struct bio *bio);
 
+static inline bool raid5_has_log(struct r5conf *conf)
+{
+       return test_bit(MD_HAS_JOURNAL, &conf->mddev->flags);
+}
+
 static inline bool raid5_has_ppl(struct r5conf *conf)
 {
        return test_bit(MD_HAS_PPL, &conf->mddev->flags);
index 4ce0d7502fad84ac9422b6fc00404136340397ac..e4e98f47865def0449979058c6c7e51228b9b42b 100644 (file)
@@ -733,7 +733,7 @@ static bool stripe_can_batch(struct stripe_head *sh)
 {
        struct r5conf *conf = sh->raid_conf;
 
-       if (conf->log || raid5_has_ppl(conf))
+       if (raid5_has_log(conf) || raid5_has_ppl(conf))
                return false;
        return test_bit(STRIPE_BATCH_READY, &sh->state) &&
                !test_bit(STRIPE_BITMAP_PENDING, &sh->state) &&
@@ -7737,7 +7737,7 @@ static int raid5_resize(struct mddev *mddev, sector_t sectors)
        sector_t newsize;
        struct r5conf *conf = mddev->private;
 
-       if (conf->log || raid5_has_ppl(conf))
+       if (raid5_has_log(conf) || raid5_has_ppl(conf))
                return -EINVAL;
        sectors &= ~((sector_t)conf->chunk_sectors - 1);
        newsize = raid5_size(mddev, sectors, mddev->raid_disks);
@@ -7788,7 +7788,7 @@ static int check_reshape(struct mddev *mddev)
 {
        struct r5conf *conf = mddev->private;
 
-       if (conf->log || raid5_has_ppl(conf))
+       if (raid5_has_log(conf) || raid5_has_ppl(conf))
                return -EINVAL;
        if (mddev->delta_disks == 0 &&
            mddev->new_layout == mddev->layout &&
index f3acbb57d48cebb4f59ea93562e79a7aea50b867..35a93b251aaba854da304dc18d8fd5436d7efe6f 100644 (file)
@@ -1311,10 +1311,10 @@ static int af9013_wregs(struct i2c_client *client, u8 cmd, u16 reg,
        memcpy(&buf[3], val, len);
 
        if (lock)
-               i2c_lock_adapter(client->adapter);
+               i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT);
        ret = __i2c_transfer(client->adapter, msg, 1);
        if (lock)
-               i2c_unlock_adapter(client->adapter);
+               i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT);
        if (ret < 0) {
                goto err;
        } else if (ret != 1) {
@@ -1352,10 +1352,10 @@ static int af9013_rregs(struct i2c_client *client, u8 cmd, u16 reg,
        buf[2] = cmd;
 
        if (lock)
-               i2c_lock_adapter(client->adapter);
+               i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT);
        ret = __i2c_transfer(client->adapter, msg, 2);
        if (lock)
-               i2c_unlock_adapter(client->adapter);
+               i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT);
        if (ret < 0) {
                goto err;
        } else if (ret != 2) {
index f1886945a7bc39940011333a89e9fae72343abf6..84ac3f73f8fe4859c7f73f81b8fac1266b2c8240 100644 (file)
@@ -213,7 +213,7 @@ static inline u32 log10times100(u32 value)
 
 static int drxk_i2c_lock(struct drxk_state *state)
 {
-       i2c_lock_adapter(state->i2c);
+       i2c_lock_bus(state->i2c, I2C_LOCK_SEGMENT);
        state->drxk_i2c_exclusive_lock = true;
 
        return 0;
@@ -224,7 +224,7 @@ static void drxk_i2c_unlock(struct drxk_state *state)
        if (!state->drxk_i2c_exclusive_lock)
                return;
 
-       i2c_unlock_adapter(state->i2c);
+       i2c_unlock_bus(state->i2c, I2C_LOCK_SEGMENT);
        state->drxk_i2c_exclusive_lock = false;
 }
 
index adc9046d5a90f3b849d06d1c0547fe3e68802e5e..c0659568471b8d3663b3cde025199f842eb4cbb0 100644 (file)
@@ -24,9 +24,9 @@ static int rtl2830_bulk_write(struct i2c_client *client, unsigned int reg,
        struct rtl2830_dev *dev = i2c_get_clientdata(client);
        int ret;
 
-       i2c_lock_adapter(client->adapter);
+       i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT);
        ret = regmap_bulk_write(dev->regmap, reg, val, val_count);
-       i2c_unlock_adapter(client->adapter);
+       i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT);
        return ret;
 }
 
@@ -36,9 +36,9 @@ static int rtl2830_update_bits(struct i2c_client *client, unsigned int reg,
        struct rtl2830_dev *dev = i2c_get_clientdata(client);
        int ret;
 
-       i2c_lock_adapter(client->adapter);
+       i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT);
        ret = regmap_update_bits(dev->regmap, reg, mask, val);
-       i2c_unlock_adapter(client->adapter);
+       i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT);
        return ret;
 }
 
@@ -48,9 +48,9 @@ static int rtl2830_bulk_read(struct i2c_client *client, unsigned int reg,
        struct rtl2830_dev *dev = i2c_get_clientdata(client);
        int ret;
 
-       i2c_lock_adapter(client->adapter);
+       i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT);
        ret = regmap_bulk_read(dev->regmap, reg, val, val_count);
-       i2c_unlock_adapter(client->adapter);
+       i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT);
        return ret;
 }
 
index d402e4b722ca01d526f471444e4ad5c194316184..e506f66657bbfeba72b15c6e7cd29fb4e66d00c4 100644 (file)
@@ -329,7 +329,7 @@ static int tda1004x_do_upload(struct tda1004x_state *state,
        tda1004x_write_byteI(state, dspCodeCounterReg, 0);
        fw_msg.addr = state->config->demod_address;
 
-       i2c_lock_adapter(state->i2c);
+       i2c_lock_bus(state->i2c, I2C_LOCK_SEGMENT);
        buf[0] = dspCodeInReg;
        while (pos != len) {
                // work out how much to send this time
@@ -342,14 +342,14 @@ static int tda1004x_do_upload(struct tda1004x_state *state,
                fw_msg.len = tx_size + 1;
                if (__i2c_transfer(state->i2c, &fw_msg, 1) != 1) {
                        printk(KERN_ERR "tda1004x: Error during firmware upload\n");
-                       i2c_unlock_adapter(state->i2c);
+                       i2c_unlock_bus(state->i2c, I2C_LOCK_SEGMENT);
                        return -EIO;
                }
                pos += tx_size;
 
                dprintk("%s: fw_pos=0x%x\n", __func__, pos);
        }
-       i2c_unlock_adapter(state->i2c);
+       i2c_unlock_bus(state->i2c, I2C_LOCK_SEGMENT);
 
        /* give the DSP a chance to settle 03/10/05 Hac */
        msleep(100);
index fcdf3d5dc4b6c0722bdd3481ad2536529982605a..3bae24b15eaa4cbd5e25485121e50ddcb5991af2 100644 (file)
@@ -585,18 +585,12 @@ int __must_check media_device_register_entity(struct media_device *mdev,
        entity->num_links = 0;
        entity->num_backlinks = 0;
 
-       if (!ida_pre_get(&mdev->entity_internal_idx, GFP_KERNEL))
-               return -ENOMEM;
-
-       mutex_lock(&mdev->graph_mutex);
-
-       ret = ida_get_new_above(&mdev->entity_internal_idx, 1,
-                               &entity->internal_idx);
-       if (ret < 0) {
-               mutex_unlock(&mdev->graph_mutex);
+       ret = ida_alloc_min(&mdev->entity_internal_idx, 1, GFP_KERNEL);
+       if (ret < 0)
                return ret;
-       }
+       entity->internal_idx = ret;
 
+       mutex_lock(&mdev->graph_mutex);
        mdev->entity_internal_idx_max =
                max(mdev->entity_internal_idx_max, entity->internal_idx);
 
@@ -642,7 +636,7 @@ static void __media_device_unregister_entity(struct media_entity *entity)
        struct media_interface *intf;
        unsigned int i;
 
-       ida_simple_remove(&mdev->entity_internal_idx, entity->internal_idx);
+       ida_free(&mdev->entity_internal_idx, entity->internal_idx);
 
        /* Remove all interface links pointing to this entity */
        list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) {
index 7e81cd887c134dd39eba5c6f40af83dafbd94d9b..054b3b747dae9abcd2e46f02c5523cc11d833113 100644 (file)
@@ -225,7 +225,7 @@ static int __tda18271_write_regs(struct dvb_frontend *fe, int idx, int len,
         */
        if (lock_i2c) {
                tda18271_i2c_gate_ctrl(fe, 1);
-               i2c_lock_adapter(priv->i2c_props.adap);
+               i2c_lock_bus(priv->i2c_props.adap, I2C_LOCK_SEGMENT);
        }
        while (len) {
                if (max > len)
@@ -246,7 +246,7 @@ static int __tda18271_write_regs(struct dvb_frontend *fe, int idx, int len,
                len -= max;
        }
        if (lock_i2c) {
-               i2c_unlock_adapter(priv->i2c_props.adap);
+               i2c_unlock_bus(priv->i2c_props.adap, I2C_LOCK_SEGMENT);
                tda18271_i2c_gate_ctrl(fe, 0);
        }
 
@@ -300,7 +300,7 @@ int tda18271_init_regs(struct dvb_frontend *fe)
         * as those could cause bad things
         */
        tda18271_i2c_gate_ctrl(fe, 1);
-       i2c_lock_adapter(priv->i2c_props.adap);
+       i2c_lock_bus(priv->i2c_props.adap, I2C_LOCK_SEGMENT);
 
        /* initialize registers */
        switch (priv->id) {
@@ -516,7 +516,7 @@ int tda18271_init_regs(struct dvb_frontend *fe)
        /* synchronize */
        __tda18271_write_regs(fe, R_EP1, 1, false);
 
-       i2c_unlock_adapter(priv->i2c_props.adap);
+       i2c_unlock_bus(priv->i2c_props.adap, I2C_LOCK_SEGMENT);
        tda18271_i2c_gate_ctrl(fe, 0);
 
        return 0;
index bb93cc53554e63cc279d58cf44c2733a46c28368..bd25faf6d13d319db73d399b98f7163332dbd895 100644 (file)
@@ -672,13 +672,6 @@ static int tegra_mc_probe(struct platform_device *pdev)
                return err;
        }
 
-       err = tegra_mc_reset_setup(mc);
-       if (err < 0) {
-               dev_err(&pdev->dev, "failed to register reset controller: %d\n",
-                       err);
-               return err;
-       }
-
        mc->irq = platform_get_irq(pdev, 0);
        if (mc->irq < 0) {
                dev_err(&pdev->dev, "interrupt not specified\n");
@@ -697,13 +690,16 @@ static int tegra_mc_probe(struct platform_device *pdev)
                return err;
        }
 
+       err = tegra_mc_reset_setup(mc);
+       if (err < 0)
+               dev_err(&pdev->dev, "failed to register reset controller: %d\n",
+                       err);
+
        if (IS_ENABLED(CONFIG_TEGRA_IOMMU_SMMU)) {
                mc->smmu = tegra_smmu_probe(&pdev->dev, mc->soc->smmu, mc);
-               if (IS_ERR(mc->smmu)) {
+               if (IS_ERR(mc->smmu))
                        dev_err(&pdev->dev, "failed to probe SMMU: %ld\n",
                                PTR_ERR(mc->smmu));
-                       return PTR_ERR(mc->smmu);
-               }
        }
 
        return 0;
index 31112f622b884f2577d46caec86b2b63370e81de..475e5b3790edb4085055fcd38df2f6d77d98388d 100644 (file)
@@ -411,7 +411,7 @@ static int aemif_probe(struct platform_device *pdev)
                        if (ret < 0)
                                goto error;
                }
-       } else {
+       } else if (pdata) {
                for (i = 0; i < pdata->num_sub_devices; i++) {
                        pdata->sub_devices[i].dev.parent = dev;
                        ret = platform_device_register(&pdata->sub_devices[i]);
index 632651f4b6e88f844a5bc51754fbd71d7670025e..2250d03ea17f63f5ad79b8e860aeb6c1383a6047 100644 (file)
@@ -249,6 +249,34 @@ static const struct of_device_id ti_emif_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, ti_emif_of_match);
 
+#ifdef CONFIG_PM_SLEEP
+static int ti_emif_resume(struct device *dev)
+{
+       unsigned long tmp =
+                       __raw_readl((void *)emif_instance->ti_emif_sram_virt);
+
+       /*
+        * Check to see if what we are copying is already present in the
+        * first byte at the destination, only copy if it is not which
+        * indicates we have lost context and sram no longer contains
+        * the PM code
+        */
+       if (tmp != ti_emif_sram)
+               ti_emif_push_sram(dev, emif_instance);
+
+       return 0;
+}
+
+static int ti_emif_suspend(struct device *dev)
+{
+       /*
+        * The contents will be present in DDR hence no need to
+        * explicitly save
+        */
+       return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
 static int ti_emif_probe(struct platform_device *pdev)
 {
        int ret;
@@ -308,12 +336,17 @@ static int ti_emif_remove(struct platform_device *pdev)
        return 0;
 }
 
+static const struct dev_pm_ops ti_emif_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(ti_emif_suspend, ti_emif_resume)
+};
+
 static struct platform_driver ti_emif_driver = {
        .probe = ti_emif_probe,
        .remove = ti_emif_remove,
        .driver = {
                .name = KBUILD_MODNAME,
                .of_match_table = of_match_ptr(ti_emif_of_match),
+               .pm = &ti_emif_pm_ops,
        },
 };
 module_platform_driver(ti_emif_driver);
index 84e313107233ee8b1e86f0610be093eaa5e1637d..7b9052ea74134a2694f8485f48cb589e9624b793 100644 (file)
@@ -146,14 +146,14 @@ int pm860x_page_reg_write(struct i2c_client *i2c, int reg,
        unsigned char zero;
        int ret;
 
-       i2c_lock_adapter(i2c->adapter);
+       i2c_lock_bus(i2c->adapter, I2C_LOCK_SEGMENT);
        read_device(i2c, 0xFA, 0, &zero);
        read_device(i2c, 0xFB, 0, &zero);
        read_device(i2c, 0xFF, 0, &zero);
        ret = write_device(i2c, reg, 1, &data);
        read_device(i2c, 0xFE, 0, &zero);
        read_device(i2c, 0xFC, 0, &zero);
-       i2c_unlock_adapter(i2c->adapter);
+       i2c_unlock_bus(i2c->adapter, I2C_LOCK_SEGMENT);
        return ret;
 }
 EXPORT_SYMBOL(pm860x_page_reg_write);
@@ -164,14 +164,14 @@ int pm860x_page_bulk_read(struct i2c_client *i2c, int reg,
        unsigned char zero = 0;
        int ret;
 
-       i2c_lock_adapter(i2c->adapter);
+       i2c_lock_bus(i2c->adapter, I2C_LOCK_SEGMENT);
        read_device(i2c, 0xfa, 0, &zero);
        read_device(i2c, 0xfb, 0, &zero);
        read_device(i2c, 0xff, 0, &zero);
        ret = read_device(i2c, reg, count, buf);
        read_device(i2c, 0xFE, 0, &zero);
        read_device(i2c, 0xFC, 0, &zero);
-       i2c_unlock_adapter(i2c->adapter);
+       i2c_unlock_bus(i2c->adapter, I2C_LOCK_SEGMENT);
        return ret;
 }
 EXPORT_SYMBOL(pm860x_page_bulk_read);
index 4d4acf763b655c72353ce4e9d2bbff9d962dd957..2c43fd09d602fd0abddf3996213eb1446a894b46 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/gfp.h>
 
 static DEFINE_IDA(cb710_ida);
-static DEFINE_SPINLOCK(cb710_ida_lock);
 
 void cb710_pci_update_config_reg(struct pci_dev *pdev,
        int reg, uint32_t mask, uint32_t xor)
@@ -205,7 +204,6 @@ static int cb710_probe(struct pci_dev *pdev,
        const struct pci_device_id *ent)
 {
        struct cb710_chip *chip;
-       unsigned long flags;
        u32 val;
        int err;
        int n = 0;
@@ -256,18 +254,10 @@ static int cb710_probe(struct pci_dev *pdev,
        if (err)
                return err;
 
-       do {
-               if (!ida_pre_get(&cb710_ida, GFP_KERNEL))
-                       return -ENOMEM;
-
-               spin_lock_irqsave(&cb710_ida_lock, flags);
-               err = ida_get_new(&cb710_ida, &chip->platform_id);
-               spin_unlock_irqrestore(&cb710_ida_lock, flags);
-
-               if (err && err != -EAGAIN)
-                       return err;
-       } while (err);
-
+       err = ida_alloc(&cb710_ida, GFP_KERNEL);
+       if (err < 0)
+               return err;
+       chip->platform_id = err;
 
        dev_info(&pdev->dev, "id %d, IO 0x%p, IRQ %d\n",
                chip->platform_id, chip->iobase, pdev->irq);
@@ -308,7 +298,6 @@ unreg_mmc:
 static void cb710_remove_one(struct pci_dev *pdev)
 {
        struct cb710_chip *chip = pci_get_drvdata(pdev);
-       unsigned long flags;
 
        cb710_unregister_slot(chip, CB710_SLOT_SM);
        cb710_unregister_slot(chip, CB710_SLOT_MS);
@@ -317,9 +306,7 @@ static void cb710_remove_one(struct pci_dev *pdev)
        BUG_ON(atomic_read(&chip->slot_refs_count) != 0);
 #endif
 
-       spin_lock_irqsave(&cb710_ida_lock, flags);
-       ida_remove(&cb710_ida, chip->platform_id);
-       spin_unlock_irqrestore(&cb710_ida_lock, flags);
+       ida_free(&cb710_ida, chip->platform_id);
 }
 
 static const struct pci_device_id cb710_pci_tbl[] = {
index f5cc517d113154106e7cef474782eacaf47b3952..7e50e1d6f58c22b914f39ae7f5e419a53d689b37 100644 (file)
@@ -478,6 +478,23 @@ static void at24_properties_to_pdata(struct device *dev,
        if (device_property_present(dev, "no-read-rollover"))
                chip->flags |= AT24_FLAG_NO_RDROL;
 
+       err = device_property_read_u32(dev, "address-width", &val);
+       if (!err) {
+               switch (val) {
+               case 8:
+                       if (chip->flags & AT24_FLAG_ADDR16)
+                               dev_warn(dev, "Override address width to be 8, while default is 16\n");
+                       chip->flags &= ~AT24_FLAG_ADDR16;
+                       break;
+               case 16:
+                       chip->flags |= AT24_FLAG_ADDR16;
+                       break;
+               default:
+                       dev_warn(dev, "Bad \"address-width\" property: %u\n",
+                                val);
+               }
+       }
+
        err = device_property_read_u32(dev, "size", &val);
        if (!err)
                chip->byte_len = val;
index 63d6246d6dff3caf8b6f7099257f902d50d2de20..6369aeaa70562e92325813857e2ba5c59aadcecb 100644 (file)
@@ -200,15 +200,18 @@ static void scif_mmu_notifier_release(struct mmu_notifier *mn,
        schedule_work(&scif_info.misc_work);
 }
 
-static void scif_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
+static int scif_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
                                                     struct mm_struct *mm,
                                                     unsigned long start,
-                                                    unsigned long end)
+                                                    unsigned long end,
+                                                    bool blockable)
 {
        struct scif_mmu_notif   *mmn;
 
        mmn = container_of(mn, struct scif_mmu_notif, ep_mmu_notifier);
        scif_rma_destroy_tcw(mmn, start, end - start);
+
+       return 0;
 }
 
 static void scif_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
index a3454eb56fbf57e3a3868c514cdd72affd578cc4..be28f05bfafa9ee41a53c642f0e384812ea88adf 100644 (file)
@@ -219,9 +219,10 @@ void gru_flush_all_tlb(struct gru_state *gru)
 /*
  * MMUOPS notifier callout functions
  */
-static void gru_invalidate_range_start(struct mmu_notifier *mn,
+static int gru_invalidate_range_start(struct mmu_notifier *mn,
                                       struct mm_struct *mm,
-                                      unsigned long start, unsigned long end)
+                                      unsigned long start, unsigned long end,
+                                      bool blockable)
 {
        struct gru_mm_struct *gms = container_of(mn, struct gru_mm_struct,
                                                 ms_notifier);
@@ -231,6 +232,8 @@ static void gru_invalidate_range_start(struct mmu_notifier *mn,
        gru_dbg(grudev, "gms %p, start 0x%lx, end 0x%lx, act %d\n", gms,
                start, end, atomic_read(&gms->ms_range_active));
        gru_flush_tlb_range(gms, start, end - start);
+
+       return 0;
 }
 
 static void gru_invalidate_range_end(struct mmu_notifier *mn,
index 648eb6743ed58890f356212ed60a81ca5e6dd43c..6edffeed99534935f320b5b3d6e941dad15a968d 100644 (file)
@@ -238,10 +238,6 @@ static void mmc_mq_exit_request(struct blk_mq_tag_set *set, struct request *req,
        mmc_exit_request(mq->queue, req);
 }
 
-/*
- * We use BLK_MQ_F_BLOCKING and have only 1 hardware queue, which means requests
- * will not be dispatched in parallel.
- */
 static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
                                    const struct blk_mq_queue_data *bd)
 {
@@ -264,7 +260,7 @@ static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
 
        spin_lock_irq(q->queue_lock);
 
-       if (mq->recovery_needed) {
+       if (mq->recovery_needed || mq->busy) {
                spin_unlock_irq(q->queue_lock);
                return BLK_STS_RESOURCE;
        }
@@ -291,6 +287,9 @@ static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
                break;
        }
 
+       /* Parallel dispatch of requests is not supported at the moment */
+       mq->busy = true;
+
        mq->in_flight[issue_type] += 1;
        get_card = (mmc_tot_in_flight(mq) == 1);
        cqe_retune_ok = (mmc_cqe_qcnt(mq) == 1);
@@ -333,9 +332,12 @@ static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
                mq->in_flight[issue_type] -= 1;
                if (mmc_tot_in_flight(mq) == 0)
                        put_card = true;
+               mq->busy = false;
                spin_unlock_irq(q->queue_lock);
                if (put_card)
                        mmc_put_card(card, &mq->ctx);
+       } else {
+               WRITE_ONCE(mq->busy, false);
        }
 
        return ret;
index 17e59d50b4960298630404e7dbe4a687eb8e9a19..9bf3c924507552caf0bf50a3118944e0390bc044 100644 (file)
@@ -81,6 +81,7 @@ struct mmc_queue {
        unsigned int            cqe_busy;
 #define MMC_CQE_DCMD_BUSY      BIT(0)
 #define MMC_CQE_QUEUE_FULL     BIT(1)
+       bool                    busy;
        bool                    use_cqe;
        bool                    recovery_needed;
        bool                    in_recovery;
index 294de177632c6e25a2024d42f8fbdd926043a80f..61e4e2a213c9637f73faeda61dc585c7922faab8 100644 (file)
@@ -217,7 +217,7 @@ static void goldfish_mmc_xfer_done(struct goldfish_mmc_host *host,
                         * We don't really have DMA, so we need
                         * to copy from our platform driver buffer
                         */
-                       sg_copy_to_buffer(data->sg, 1, host->virt_base,
+                       sg_copy_from_buffer(data->sg, 1, host->virt_base,
                                        data->sg->length);
                }
                host->data->bytes_xfered += data->sg->length;
@@ -393,7 +393,7 @@ static void goldfish_mmc_prepare_data(struct goldfish_mmc_host *host,
                 * We don't really have DMA, so we need to copy to our
                 * platform driver buffer
                 */
-               sg_copy_from_buffer(data->sg, 1, host->virt_base,
+               sg_copy_to_buffer(data->sg, 1, host->virt_base,
                                data->sg->length);
        }
 }
index 5aa2c9404e926db1af2e17452a64cf5a08e4156b..be53044086c76f7291224c33ed10c734ece7e897 100644 (file)
@@ -1976,7 +1976,7 @@ static void atmci_read_data_pio(struct atmel_mci *host)
        do {
                value = atmci_readl(host, ATMCI_RDR);
                if (likely(offset + 4 <= sg->length)) {
-                       sg_pcopy_to_buffer(sg, 1, &value, sizeof(u32), offset);
+                       sg_pcopy_from_buffer(sg, 1, &value, sizeof(u32), offset);
 
                        offset += 4;
                        nbytes += 4;
@@ -1993,7 +1993,7 @@ static void atmci_read_data_pio(struct atmel_mci *host)
                } else {
                        unsigned int remaining = sg->length - offset;
 
-                       sg_pcopy_to_buffer(sg, 1, &value, remaining, offset);
+                       sg_pcopy_from_buffer(sg, 1, &value, remaining, offset);
                        nbytes += remaining;
 
                        flush_dcache_page(sg_page(sg));
@@ -2003,7 +2003,7 @@ static void atmci_read_data_pio(struct atmel_mci *host)
                                goto done;
 
                        offset = 4 - remaining;
-                       sg_pcopy_to_buffer(sg, 1, (u8 *)&value + remaining,
+                       sg_pcopy_from_buffer(sg, 1, (u8 *)&value + remaining,
                                        offset, 0);
                        nbytes += offset;
                }
@@ -2042,7 +2042,7 @@ static void atmci_write_data_pio(struct atmel_mci *host)
 
        do {
                if (likely(offset + 4 <= sg->length)) {
-                       sg_pcopy_from_buffer(sg, 1, &value, sizeof(u32), offset);
+                       sg_pcopy_to_buffer(sg, 1, &value, sizeof(u32), offset);
                        atmci_writel(host, ATMCI_TDR, value);
 
                        offset += 4;
@@ -2059,7 +2059,7 @@ static void atmci_write_data_pio(struct atmel_mci *host)
                        unsigned int remaining = sg->length - offset;
 
                        value = 0;
-                       sg_pcopy_from_buffer(sg, 1, &value, remaining, offset);
+                       sg_pcopy_to_buffer(sg, 1, &value, remaining, offset);
                        nbytes += remaining;
 
                        host->sg = sg = sg_next(sg);
@@ -2070,7 +2070,7 @@ static void atmci_write_data_pio(struct atmel_mci *host)
                        }
 
                        offset = 4 - remaining;
-                       sg_pcopy_from_buffer(sg, 1, (u8 *)&value + remaining,
+                       sg_pcopy_to_buffer(sg, 1, (u8 *)&value + remaining,
                                        offset, 0);
                        atmci_writel(host, ATMCI_TDR, value);
                        nbytes += offset;
index 35cc0de6be67a5159a572612ab028ae43d1a84bc..ca0b43973769c9f80b4771914b5b74016b54bf84 100644 (file)
 /* DM_CM_RST */
 #define RST_DTRANRST1          BIT(9)
 #define RST_DTRANRST0          BIT(8)
-#define RST_RESERVED_BITS      GENMASK_ULL(32, 0)
+#define RST_RESERVED_BITS      GENMASK_ULL(31, 0)
 
 /* DM_CM_INFO1 and DM_CM_INFO1_MASK */
 #define INFO1_CLEAR            0
+#define INFO1_MASK_CLEAR       GENMASK_ULL(31, 0)
 #define INFO1_DTRANEND1                BIT(17)
 #define INFO1_DTRANEND0                BIT(16)
 
 /* DM_CM_INFO2 and DM_CM_INFO2_MASK */
+#define INFO2_MASK_CLEAR       GENMASK_ULL(31, 0)
 #define INFO2_DTRANERR1                BIT(17)
 #define INFO2_DTRANERR0                BIT(16)
 
@@ -252,6 +254,12 @@ renesas_sdhi_internal_dmac_request_dma(struct tmio_mmc_host *host,
 {
        struct renesas_sdhi *priv = host_to_priv(host);
 
+       /* Disable DMAC interrupts, we don't use them */
+       renesas_sdhi_internal_dmac_dm_write(host, DM_CM_INFO1_MASK,
+                                           INFO1_MASK_CLEAR);
+       renesas_sdhi_internal_dmac_dm_write(host, DM_CM_INFO2_MASK,
+                                           INFO2_MASK_CLEAR);
+
        /* Each value is set to non-zero to assume "enabling" each DMA */
        host->chan_rx = host->chan_tx = (void *)0xdeadbeaf;
 
index ca18612c42014288d48c9ac8180a4b5be88e9a06..67b2065e7a19cace554463a74871ab676c221906 100644 (file)
@@ -1338,6 +1338,11 @@ int denali_init(struct denali_nand_info *denali)
 
        denali_enable_irq(denali);
        denali_reset_banks(denali);
+       if (!denali->max_banks) {
+               /* Error out earlier if no chip is found for some reasons. */
+               ret = -ENODEV;
+               goto disable_irq;
+       }
 
        denali->active_bank = DENALI_INVALID_BANK;
 
index a3f04315c05c54e6332a269603184cac0fc89dd4..427fcbc1b71c0551a107b0d8734bdec808a792c4 100644 (file)
@@ -1218,7 +1218,7 @@ static int docg4_resume(struct platform_device *pdev)
        return 0;
 }
 
-static void __init init_mtd_structs(struct mtd_info *mtd)
+static void init_mtd_structs(struct mtd_info *mtd)
 {
        /* initialize mtd and nand data structures */
 
@@ -1290,7 +1290,7 @@ static void __init init_mtd_structs(struct mtd_info *mtd)
 
 }
 
-static int __init read_id_reg(struct mtd_info *mtd)
+static int read_id_reg(struct mtd_info *mtd)
 {
        struct nand_chip *nand = mtd_to_nand(mtd);
        struct docg4_priv *doc = nand_get_controller_data(nand);
index 45c329694a5e1479b8387da1eba1f57e5302f4d8..22547d7a84eaaf0108f07ce1ada68d66d58c8d35 100644 (file)
@@ -367,6 +367,10 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf,
                        return count;
                }
 
+               /*
+                * We voluntarily do not take into account the skip_check flag
+                * as we want to make sure what we wrote was correctly written.
+                */
                err = ubi_check_volume(ubi, vol->vol_id);
                if (err < 0)
                        return err;
@@ -622,6 +626,13 @@ static int verify_mkvol_req(const struct ubi_device *ubi,
            req->vol_type != UBI_STATIC_VOLUME)
                goto bad;
 
+       if (req->flags & ~UBI_VOL_VALID_FLGS)
+               goto bad;
+
+       if (req->flags & UBI_VOL_SKIP_CRC_CHECK_FLG &&
+           req->vol_type != UBI_STATIC_VOLUME)
+               goto bad;
+
        if (req->alignment > ubi->leb_size)
                goto bad;
 
index d4b2e874449869629437828e6e8f8b01cce1ee74..e9e9ecbcedcc384aee39a7b3e08f9d23cffd39aa 100644 (file)
@@ -202,7 +202,7 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode)
        desc->mode = mode;
 
        mutex_lock(&ubi->ckvol_mutex);
-       if (!vol->checked) {
+       if (!vol->checked && !vol->skip_check) {
                /* This is the first open - check the volume */
                err = ubi_check_volume(ubi, vol_id);
                if (err < 0) {
index 195ff8ca821175eab37079cbc66e1f02ed35913a..b5fe8f82281b8f5884bad6250512d3cb90682227 100644 (file)
@@ -45,6 +45,11 @@ enum {
  * Volume flags used in the volume table record.
  *
  * @UBI_VTBL_AUTORESIZE_FLG: auto-resize this volume
+ * @UBI_VTBL_SKIP_CRC_CHECK_FLG: skip the CRC check done on a static volume at
+ *                              open time. Should only be set on volumes that
+ *                              are used by upper layers doing this kind of
+ *                              check. Main use-case for this flag is
+ *                              boot-time reduction
  *
  * %UBI_VTBL_AUTORESIZE_FLG flag can be set only for one volume in the volume
  * table. UBI automatically re-sizes the volume which has this flag and makes
@@ -76,6 +81,7 @@ enum {
  */
 enum {
        UBI_VTBL_AUTORESIZE_FLG = 0x01,
+       UBI_VTBL_SKIP_CRC_CHECK_FLG = 0x02,
 };
 
 /*
index f5ba97c46160ac18ba73e46d7277b64ebddbf41e..d47b9e436e6730af38e414821c0348f1e5ac7550 100644 (file)
@@ -327,6 +327,9 @@ struct ubi_eba_leb_desc {
  *           atomic LEB change
  *
  * @eba_tbl: EBA table of this volume (LEB->PEB mapping)
+ * @skip_check: %1 if CRC check of this static volume should be skipped.
+ *             Directly reflects the presence of the
+ *             %UBI_VTBL_SKIP_CRC_CHECK_FLG flag in the vtbl entry
  * @checked: %1 if this static volume was checked
  * @corrupted: %1 if the volume is corrupted (static volumes only)
  * @upd_marker: %1 if the update marker is set for this volume
@@ -374,6 +377,7 @@ struct ubi_volume {
        void *upd_buf;
 
        struct ubi_eba_table *eba_tbl;
+       unsigned int skip_check:1;
        unsigned int checked:1;
        unsigned int corrupted:1;
        unsigned int upd_marker:1;
index 0be516780e929daa3ff31c9d73c30bbd38493da4..729588b94e41ede3a6326134a2e1ade6f8762a6e 100644 (file)
@@ -174,6 +174,9 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
        vol->dev.class = &ubi_class;
        vol->dev.groups = volume_dev_groups;
 
+       if (req->flags & UBI_VOL_SKIP_CRC_CHECK_FLG)
+               vol->skip_check = 1;
+
        spin_lock(&ubi->volumes_lock);
        if (vol_id == UBI_VOL_NUM_AUTO) {
                /* Find unused volume ID */
@@ -299,6 +302,10 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
                vtbl_rec.vol_type = UBI_VID_DYNAMIC;
        else
                vtbl_rec.vol_type = UBI_VID_STATIC;
+
+       if (vol->skip_check)
+               vtbl_rec.flags |= UBI_VTBL_SKIP_CRC_CHECK_FLG;
+
        memcpy(vtbl_rec.name, vol->name, vol->name_len);
 
        err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
@@ -733,6 +740,11 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id)
                        ubi_err(ubi, "bad used_bytes");
                        goto fail;
                }
+
+               if (vol->skip_check) {
+                       ubi_err(ubi, "bad skip_check");
+                       goto fail;
+               }
        } else {
                if (vol->used_ebs < 0 || vol->used_ebs > vol->reserved_pebs) {
                        ubi_err(ubi, "bad used_ebs");
index 94d7a865b135a926501ab87e050fd3f325841488..1bc82154bb18f6b3e03df72d725778d7dea12227 100644 (file)
@@ -560,6 +560,9 @@ static int init_volumes(struct ubi_device *ubi,
                vol->name[vol->name_len] = '\0';
                vol->vol_id = i;
 
+               if (vtbl[i].flags & UBI_VTBL_SKIP_CRC_CHECK_FLG)
+                       vol->skip_check = 1;
+
                if (vtbl[i].flags & UBI_VTBL_AUTORESIZE_FLG) {
                        /* Auto re-size flag may be set only for one volume */
                        if (ubi->autoresize_vol_id != -1) {
@@ -578,6 +581,16 @@ static int init_volumes(struct ubi_device *ubi,
                vol->ubi = ubi;
                reserved_pebs += vol->reserved_pebs;
 
+               /*
+                * We use ubi->peb_count and not vol->reserved_pebs because
+                * we want to keep the code simple. Otherwise we'd have to
+                * resize/check the bitmap upon volume resize too.
+                * Allocating a few bytes more does not hurt.
+                */
+               err = ubi_fastmap_init_checkmap(vol, ubi->peb_count);
+               if (err)
+                       return err;
+
                /*
                 * In case of dynamic volume UBI knows nothing about how many
                 * data is stored there. So assume the whole volume is used.
@@ -620,16 +633,6 @@ static int init_volumes(struct ubi_device *ubi,
                        (long long)(vol->used_ebs - 1) * vol->usable_leb_size;
                vol->used_bytes += av->last_data_size;
                vol->last_eb_bytes = av->last_data_size;
-
-               /*
-                * We use ubi->peb_count and not vol->reserved_pebs because
-                * we want to keep the code simple. Otherwise we'd have to
-                * resize/check the bitmap upon volume resize too.
-                * Allocating a few bytes more does not hurt.
-                */
-               err = ubi_fastmap_init_checkmap(vol, ubi->peb_count);
-               if (err)
-                       return err;
        }
 
        /* And add the layout volume */
index 8bb1e38b1681a32f2175c649b756791694f08105..cecbb1d1f587f936b0d2960739c911fc28f05d51 100644 (file)
@@ -5913,12 +5913,12 @@ unsigned int bnxt_get_max_func_cp_rings(struct bnxt *bp)
        return bp->hw_resc.max_cp_rings;
 }
 
-void bnxt_set_max_func_cp_rings(struct bnxt *bp, unsigned int max)
+unsigned int bnxt_get_max_func_cp_rings_for_en(struct bnxt *bp)
 {
-       bp->hw_resc.max_cp_rings = max;
+       return bp->hw_resc.max_cp_rings - bnxt_get_ulp_msix_num(bp);
 }
 
-unsigned int bnxt_get_max_func_irqs(struct bnxt *bp)
+static unsigned int bnxt_get_max_func_irqs(struct bnxt *bp)
 {
        struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
 
@@ -6684,6 +6684,8 @@ static int bnxt_hwrm_if_change(struct bnxt *bp, bool up)
                hw_resc->resv_rx_rings = 0;
                hw_resc->resv_hw_ring_grps = 0;
                hw_resc->resv_vnics = 0;
+               bp->tx_nr_rings = 0;
+               bp->rx_nr_rings = 0;
        }
        return rc;
 }
@@ -8629,7 +8631,8 @@ static void _bnxt_get_max_rings(struct bnxt *bp, int *max_rx, int *max_tx,
 
        *max_tx = hw_resc->max_tx_rings;
        *max_rx = hw_resc->max_rx_rings;
-       *max_cp = min_t(int, hw_resc->max_irqs, hw_resc->max_cp_rings);
+       *max_cp = min_t(int, bnxt_get_max_func_cp_rings_for_en(bp),
+                       hw_resc->max_irqs);
        *max_cp = min_t(int, *max_cp, hw_resc->max_stat_ctxs);
        max_ring_grps = hw_resc->max_hw_ring_grps;
        if (BNXT_CHIP_TYPE_NITRO_A0(bp) && BNXT_PF(bp)) {
@@ -8769,20 +8772,25 @@ static int bnxt_init_dflt_ring_mode(struct bnxt *bp)
        if (bp->tx_nr_rings)
                return 0;
 
+       bnxt_ulp_irq_stop(bp);
+       bnxt_clear_int_mode(bp);
        rc = bnxt_set_dflt_rings(bp, true);
        if (rc) {
                netdev_err(bp->dev, "Not enough rings available.\n");
-               return rc;
+               goto init_dflt_ring_err;
        }
        rc = bnxt_init_int_mode(bp);
        if (rc)
-               return rc;
+               goto init_dflt_ring_err;
+
        bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
        if (bnxt_rfs_supported(bp) && bnxt_rfs_capable(bp)) {
                bp->flags |= BNXT_FLAG_RFS;
                bp->dev->features |= NETIF_F_NTUPLE;
        }
-       return 0;
+init_dflt_ring_err:
+       bnxt_ulp_irq_restart(bp, rc);
+       return rc;
 }
 
 int bnxt_restore_pf_fw_resources(struct bnxt *bp)
index fefa011320e0f461047cd397e363d220b5401357..bde384630a75f9aaa723a6976ba1b891465cd9e2 100644 (file)
@@ -1481,8 +1481,7 @@ int bnxt_hwrm_set_coal(struct bnxt *);
 unsigned int bnxt_get_max_func_stat_ctxs(struct bnxt *bp);
 void bnxt_set_max_func_stat_ctxs(struct bnxt *bp, unsigned int max);
 unsigned int bnxt_get_max_func_cp_rings(struct bnxt *bp);
-void bnxt_set_max_func_cp_rings(struct bnxt *bp, unsigned int max);
-unsigned int bnxt_get_max_func_irqs(struct bnxt *bp);
+unsigned int bnxt_get_max_func_cp_rings_for_en(struct bnxt *bp);
 int bnxt_get_avail_msix(struct bnxt *bp, int num);
 int bnxt_reserve_rings(struct bnxt *bp);
 void bnxt_tx_disable(struct bnxt *bp);
index 6d583bcd2a81b2f813128ac08b2f55c19feb8545..fcd085a9853a96e694bcbb3847d554d41f1a014c 100644 (file)
@@ -451,7 +451,7 @@ static int bnxt_hwrm_func_vf_resc_cfg(struct bnxt *bp, int num_vfs)
 
        bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_RESOURCE_CFG, -1, -1);
 
-       vf_cp_rings = hw_resc->max_cp_rings - bp->cp_nr_rings;
+       vf_cp_rings = bnxt_get_max_func_cp_rings_for_en(bp) - bp->cp_nr_rings;
        vf_stat_ctx = hw_resc->max_stat_ctxs - bp->num_stat_ctxs;
        if (bp->flags & BNXT_FLAG_AGG_RINGS)
                vf_rx_rings = hw_resc->max_rx_rings - bp->rx_nr_rings * 2;
@@ -549,7 +549,8 @@ static int bnxt_hwrm_func_cfg(struct bnxt *bp, int num_vfs)
        max_stat_ctxs = hw_resc->max_stat_ctxs;
 
        /* Remaining rings are distributed equally amongs VF's for now */
-       vf_cp_rings = (hw_resc->max_cp_rings - bp->cp_nr_rings) / num_vfs;
+       vf_cp_rings = (bnxt_get_max_func_cp_rings_for_en(bp) -
+                      bp->cp_nr_rings) / num_vfs;
        vf_stat_ctx = (max_stat_ctxs - bp->num_stat_ctxs) / num_vfs;
        if (bp->flags & BNXT_FLAG_AGG_RINGS)
                vf_rx_rings = (hw_resc->max_rx_rings - bp->rx_nr_rings * 2) /
@@ -643,7 +644,7 @@ static int bnxt_sriov_enable(struct bnxt *bp, int *num_vfs)
         */
        vfs_supported = *num_vfs;
 
-       avail_cp = hw_resc->max_cp_rings - bp->cp_nr_rings;
+       avail_cp = bnxt_get_max_func_cp_rings_for_en(bp) - bp->cp_nr_rings;
        avail_stat = hw_resc->max_stat_ctxs - bp->num_stat_ctxs;
        avail_cp = min_t(int, avail_cp, avail_stat);
 
index 139d96c5a02355f557d586f5edcab1712c048036..092c817f8f11cdda48fe8233fb04b7de2a76586a 100644 (file)
@@ -110,16 +110,14 @@ static int bnxt_tc_parse_actions(struct bnxt *bp,
                                 struct tcf_exts *tc_exts)
 {
        const struct tc_action *tc_act;
-       LIST_HEAD(tc_actions);
-       int rc;
+       int i, rc;
 
        if (!tcf_exts_has_actions(tc_exts)) {
                netdev_info(bp->dev, "no actions");
                return -EINVAL;
        }
 
-       tcf_exts_to_list(tc_exts, &tc_actions);
-       list_for_each_entry(tc_act, &tc_actions, list) {
+       tcf_exts_for_each_action(i, tc_act, tc_exts) {
                /* Drop action */
                if (is_tcf_gact_shot(tc_act)) {
                        actions->flags |= BNXT_TC_ACTION_FLAG_DROP;
index c37b2842f972ced2fb363513368c94b3e42b6815..beee61292d5e522bae0842e5e76253eeb4e1d1f4 100644 (file)
@@ -169,7 +169,6 @@ static int bnxt_req_msix_vecs(struct bnxt_en_dev *edev, int ulp_id,
                edev->ulp_tbl[ulp_id].msix_requested = avail_msix;
        }
        bnxt_fill_msix_vecs(bp, ent);
-       bnxt_set_max_func_cp_rings(bp, max_cp_rings - avail_msix);
        edev->flags |= BNXT_EN_FLAG_MSIX_REQUESTED;
        return avail_msix;
 }
@@ -178,7 +177,6 @@ static int bnxt_free_msix_vecs(struct bnxt_en_dev *edev, int ulp_id)
 {
        struct net_device *dev = edev->net;
        struct bnxt *bp = netdev_priv(dev);
-       int max_cp_rings, msix_requested;
 
        ASSERT_RTNL();
        if (ulp_id != BNXT_ROCE_ULP)
@@ -187,9 +185,6 @@ static int bnxt_free_msix_vecs(struct bnxt_en_dev *edev, int ulp_id)
        if (!(edev->flags & BNXT_EN_FLAG_MSIX_REQUESTED))
                return 0;
 
-       max_cp_rings = bnxt_get_max_func_cp_rings(bp);
-       msix_requested = edev->ulp_tbl[ulp_id].msix_requested;
-       bnxt_set_max_func_cp_rings(bp, max_cp_rings + msix_requested);
        edev->ulp_tbl[ulp_id].msix_requested = 0;
        edev->flags &= ~BNXT_EN_FLAG_MSIX_REQUESTED;
        if (netif_running(dev)) {
@@ -220,21 +215,6 @@ int bnxt_get_ulp_msix_base(struct bnxt *bp)
        return 0;
 }
 
-void bnxt_subtract_ulp_resources(struct bnxt *bp, int ulp_id)
-{
-       ASSERT_RTNL();
-       if (bnxt_ulp_registered(bp->edev, ulp_id)) {
-               struct bnxt_en_dev *edev = bp->edev;
-               unsigned int msix_req, max;
-
-               msix_req = edev->ulp_tbl[ulp_id].msix_requested;
-               max = bnxt_get_max_func_cp_rings(bp);
-               bnxt_set_max_func_cp_rings(bp, max - msix_req);
-               max = bnxt_get_max_func_stat_ctxs(bp);
-               bnxt_set_max_func_stat_ctxs(bp, max - 1);
-       }
-}
-
 static int bnxt_send_msg(struct bnxt_en_dev *edev, int ulp_id,
                         struct bnxt_fw_msg *fw_msg)
 {
index df48ac71729f51d897da9a134d0a1f923b13aeaa..d9bea37cd211f5ce85642f7c6a2f489f51f909b5 100644 (file)
@@ -90,7 +90,6 @@ static inline bool bnxt_ulp_registered(struct bnxt_en_dev *edev, int ulp_id)
 
 int bnxt_get_ulp_msix_num(struct bnxt *bp);
 int bnxt_get_ulp_msix_base(struct bnxt *bp);
-void bnxt_subtract_ulp_resources(struct bnxt *bp, int ulp_id);
 void bnxt_ulp_stop(struct bnxt *bp);
 void bnxt_ulp_start(struct bnxt *bp);
 void bnxt_ulp_sriov_cfg(struct bnxt *bp, int num_vfs);
index b773bc07edf7cf23154f883a96724bb0407ad303..14b49612aa8639816c1d4b58bdbf5d9ff1995248 100644 (file)
@@ -186,6 +186,9 @@ struct bcmgenet_mib_counters {
 #define UMAC_MAC1                      0x010
 #define UMAC_MAX_FRAME_LEN             0x014
 
+#define UMAC_MODE                      0x44
+#define  MODE_LINK_STATUS              (1 << 5)
+
 #define UMAC_EEE_CTRL                  0x064
 #define  EN_LPI_RX_PAUSE               (1 << 0)
 #define  EN_LPI_TX_PFC                 (1 << 1)
index 5333274a283cbf3d3e1f20c9e9a1905b4d3aa967..4241ae928d4abb4f61d39344e93d08603a2d2c86 100644 (file)
@@ -115,8 +115,14 @@ void bcmgenet_mii_setup(struct net_device *dev)
 static int bcmgenet_fixed_phy_link_update(struct net_device *dev,
                                          struct fixed_phy_status *status)
 {
-       if (dev && dev->phydev && status)
-               status->link = dev->phydev->link;
+       struct bcmgenet_priv *priv;
+       u32 reg;
+
+       if (dev && dev->phydev && status) {
+               priv = netdev_priv(dev);
+               reg = bcmgenet_umac_readl(priv, UMAC_MODE);
+               status->link = !!(reg & MODE_LINK_STATUS);
+       }
 
        return 0;
 }
index dc09f9a8a49bb160e29a829cfaa740a36fde2223..16e4ef7d71855c7ed10905c3fdcf8d3a255f20c4 100644 (file)
@@ -482,11 +482,6 @@ static int macb_mii_probe(struct net_device *dev)
 
        if (np) {
                if (of_phy_is_fixed_link(np)) {
-                       if (of_phy_register_fixed_link(np) < 0) {
-                               dev_err(&bp->pdev->dev,
-                                       "broken fixed-link specification\n");
-                               return -ENODEV;
-                       }
                        bp->phy_node = of_node_get(np);
                } else {
                        bp->phy_node = of_parse_phandle(np, "phy-handle", 0);
@@ -569,7 +564,7 @@ static int macb_mii_init(struct macb *bp)
 {
        struct macb_platform_data *pdata;
        struct device_node *np;
-       int err;
+       int err = -ENXIO;
 
        /* Enable management port */
        macb_writel(bp, NCR, MACB_BIT(MPE));
@@ -592,12 +587,23 @@ static int macb_mii_init(struct macb *bp)
        dev_set_drvdata(&bp->dev->dev, bp->mii_bus);
 
        np = bp->pdev->dev.of_node;
-       if (pdata)
-               bp->mii_bus->phy_mask = pdata->phy_mask;
+       if (np && of_phy_is_fixed_link(np)) {
+               if (of_phy_register_fixed_link(np) < 0) {
+                       dev_err(&bp->pdev->dev,
+                               "broken fixed-link specification %pOF\n", np);
+                       goto err_out_free_mdiobus;
+               }
+
+               err = mdiobus_register(bp->mii_bus);
+       } else {
+               if (pdata)
+                       bp->mii_bus->phy_mask = pdata->phy_mask;
+
+               err = of_mdiobus_register(bp->mii_bus, np);
+       }
 
-       err = of_mdiobus_register(bp->mii_bus, np);
        if (err)
-               goto err_out_free_mdiobus;
+               goto err_out_free_fixed_link;
 
        err = macb_mii_probe(bp->dev);
        if (err)
@@ -607,6 +613,7 @@ static int macb_mii_init(struct macb *bp)
 
 err_out_unregister_bus:
        mdiobus_unregister(bp->mii_bus);
+err_out_free_fixed_link:
        if (np && of_phy_is_fixed_link(np))
                of_phy_deregister_fixed_link(np);
 err_out_free_mdiobus:
@@ -642,7 +649,7 @@ static int macb_halt_tx(struct macb *bp)
                if (!(status & MACB_BIT(TGO)))
                        return 0;
 
-               usleep_range(10, 250);
+               udelay(250);
        } while (time_before(halt_time, timeout));
 
        return -ETIMEDOUT;
@@ -2028,14 +2035,17 @@ static void macb_reset_hw(struct macb *bp)
 {
        struct macb_queue *queue;
        unsigned int q;
+       u32 ctrl = macb_readl(bp, NCR);
 
        /* Disable RX and TX (XXX: Should we halt the transmission
         * more gracefully?)
         */
-       macb_writel(bp, NCR, 0);
+       ctrl &= ~(MACB_BIT(RE) | MACB_BIT(TE));
 
        /* Clear the stats registers (XXX: Update stats first?) */
-       macb_writel(bp, NCR, MACB_BIT(CLRSTAT));
+       ctrl |= MACB_BIT(CLRSTAT);
+
+       macb_writel(bp, NCR, ctrl);
 
        /* Clear all status flags */
        macb_writel(bp, TSR, -1);
@@ -2223,7 +2233,7 @@ static void macb_init_hw(struct macb *bp)
        }
 
        /* Enable TX and RX */
-       macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE) | MACB_BIT(MPE));
+       macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(RE) | MACB_BIT(TE));
 }
 
 /* The hash address register is 64 bits long and takes up two
index 623f73dd7738dbbb01b8f49649a4507d641b1d9a..c116f96956fe9370c7927070ee6c9196ba26582b 100644 (file)
@@ -417,10 +417,9 @@ static void cxgb4_process_flow_actions(struct net_device *in,
                                       struct ch_filter_specification *fs)
 {
        const struct tc_action *a;
-       LIST_HEAD(actions);
+       int i;
 
-       tcf_exts_to_list(cls->exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, cls->exts) {
                if (is_tcf_gact_ok(a)) {
                        fs->action = FILTER_PASS;
                } else if (is_tcf_gact_shot(a)) {
@@ -591,10 +590,9 @@ static int cxgb4_validate_flow_actions(struct net_device *dev,
        bool act_redir = false;
        bool act_pedit = false;
        bool act_vlan = false;
-       LIST_HEAD(actions);
+       int i;
 
-       tcf_exts_to_list(cls->exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, cls->exts) {
                if (is_tcf_gact_ok(a)) {
                        /* Do nothing */
                } else if (is_tcf_gact_shot(a)) {
index 18eb2aedd4cb0a2659a479f7f50c62f13f32c78d..c7d2b4dc7568e72e56a393171a42769ac46e6177 100644 (file)
@@ -93,14 +93,13 @@ static int fill_action_fields(struct adapter *adap,
        unsigned int num_actions = 0;
        const struct tc_action *a;
        struct tcf_exts *exts;
-       LIST_HEAD(actions);
+       int i;
 
        exts = cls->knode.exts;
        if (!tcf_exts_has_actions(exts))
                return -EINVAL;
 
-       tcf_exts_to_list(exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, exts) {
                /* Don't allow more than one action per rule. */
                if (num_actions)
                        return -EINVAL;
index fa5b30f547f6620a6e761860be6afa341dc185c8..08a750fb60c49d397c61845130e153fe1e3b0b3e 100644 (file)
@@ -220,10 +220,10 @@ struct hnae_desc_cb {
 
        /* priv data for the desc, e.g. skb when use with ip stack*/
        void *priv;
-       u16 page_offset;
-       u16 reuse_flag;
+       u32 page_offset;
+       u32 length;     /* length of the buffer */
 
-       u16 length;     /* length of the buffer */
+       u16 reuse_flag;
 
        /* desc type, used by the ring user to mark the type of the priv data */
        u16 type;
@@ -486,6 +486,8 @@ struct hnae_ae_ops {
                        u8 *auto_neg, u16 *speed, u8 *duplex);
        void (*toggle_ring_irq)(struct hnae_ring *ring, u32 val);
        void (*adjust_link)(struct hnae_handle *handle, int speed, int duplex);
+       bool (*need_adjust_link)(struct hnae_handle *handle,
+                                int speed, int duplex);
        int (*set_loopback)(struct hnae_handle *handle,
                            enum hnae_loop loop_mode, int en);
        void (*get_ring_bdnum_limit)(struct hnae_queue *queue,
index e6aad30e7e69cd27c904542b29abaaec908bb9c7..b52029e26d15323b98811c5180a3d78ac288bf52 100644 (file)
@@ -155,6 +155,41 @@ static void hns_ae_put_handle(struct hnae_handle *handle)
                hns_ae_get_ring_pair(handle->qs[i])->used_by_vf = 0;
 }
 
+static int hns_ae_wait_flow_down(struct hnae_handle *handle)
+{
+       struct dsaf_device *dsaf_dev;
+       struct hns_ppe_cb *ppe_cb;
+       struct hnae_vf_cb *vf_cb;
+       int ret;
+       int i;
+
+       for (i = 0; i < handle->q_num; i++) {
+               ret = hns_rcb_wait_tx_ring_clean(handle->qs[i]);
+               if (ret)
+                       return ret;
+       }
+
+       ppe_cb = hns_get_ppe_cb(handle);
+       ret = hns_ppe_wait_tx_fifo_clean(ppe_cb);
+       if (ret)
+               return ret;
+
+       dsaf_dev = hns_ae_get_dsaf_dev(handle->dev);
+       if (!dsaf_dev)
+               return -EINVAL;
+       ret = hns_dsaf_wait_pkt_clean(dsaf_dev, handle->dport_id);
+       if (ret)
+               return ret;
+
+       vf_cb = hns_ae_get_vf_cb(handle);
+       ret = hns_mac_wait_fifo_clean(vf_cb->mac_cb);
+       if (ret)
+               return ret;
+
+       mdelay(10);
+       return 0;
+}
+
 static void hns_ae_ring_enable_all(struct hnae_handle *handle, int val)
 {
        int q_num = handle->q_num;
@@ -399,12 +434,41 @@ static int hns_ae_get_mac_info(struct hnae_handle *handle,
        return hns_mac_get_port_info(mac_cb, auto_neg, speed, duplex);
 }
 
+static bool hns_ae_need_adjust_link(struct hnae_handle *handle, int speed,
+                                   int duplex)
+{
+       struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
+
+       return hns_mac_need_adjust_link(mac_cb, speed, duplex);
+}
+
 static void hns_ae_adjust_link(struct hnae_handle *handle, int speed,
                               int duplex)
 {
        struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
 
-       hns_mac_adjust_link(mac_cb, speed, duplex);
+       switch (mac_cb->dsaf_dev->dsaf_ver) {
+       case AE_VERSION_1:
+               hns_mac_adjust_link(mac_cb, speed, duplex);
+               break;
+
+       case AE_VERSION_2:
+               /* chip need to clear all pkt inside */
+               hns_mac_disable(mac_cb, MAC_COMM_MODE_RX);
+               if (hns_ae_wait_flow_down(handle)) {
+                       hns_mac_enable(mac_cb, MAC_COMM_MODE_RX);
+                       break;
+               }
+
+               hns_mac_adjust_link(mac_cb, speed, duplex);
+               hns_mac_enable(mac_cb, MAC_COMM_MODE_RX);
+               break;
+
+       default:
+               break;
+       }
+
+       return;
 }
 
 static void hns_ae_get_ring_bdnum_limit(struct hnae_queue *queue,
@@ -902,6 +966,7 @@ static struct hnae_ae_ops hns_dsaf_ops = {
        .get_status = hns_ae_get_link_status,
        .get_info = hns_ae_get_mac_info,
        .adjust_link = hns_ae_adjust_link,
+       .need_adjust_link = hns_ae_need_adjust_link,
        .set_loopback = hns_ae_config_loopback,
        .get_ring_bdnum_limit = hns_ae_get_ring_bdnum_limit,
        .get_pauseparam = hns_ae_get_pauseparam,
index 5488c6e89f211d355ab33e0cda4033b84dcdccb3..09e4061d1fa60a80584b47cea3725374606a429d 100644 (file)
@@ -257,6 +257,16 @@ static void hns_gmac_get_pausefrm_cfg(void *mac_drv, u32 *rx_pause_en,
        *tx_pause_en = dsaf_get_bit(pause_en, GMAC_PAUSE_EN_TX_FDFC_B);
 }
 
+static bool hns_gmac_need_adjust_link(void *mac_drv, enum mac_speed speed,
+                                     int duplex)
+{
+       struct mac_driver *drv = (struct mac_driver *)mac_drv;
+       struct hns_mac_cb *mac_cb = drv->mac_cb;
+
+       return (mac_cb->speed != speed) ||
+               (mac_cb->half_duplex == duplex);
+}
+
 static int hns_gmac_adjust_link(void *mac_drv, enum mac_speed speed,
                                u32 full_duplex)
 {
@@ -309,6 +319,30 @@ static void hns_gmac_set_promisc(void *mac_drv, u8 en)
                hns_gmac_set_uc_match(mac_drv, en);
 }
 
+int hns_gmac_wait_fifo_clean(void *mac_drv)
+{
+       struct mac_driver *drv = (struct mac_driver *)mac_drv;
+       int wait_cnt;
+       u32 val;
+
+       wait_cnt = 0;
+       while (wait_cnt++ < HNS_MAX_WAIT_CNT) {
+               val = dsaf_read_dev(drv, GMAC_FIFO_STATE_REG);
+               /* bit5~bit0 is not send complete pkts */
+               if ((val & 0x3f) == 0)
+                       break;
+               usleep_range(100, 200);
+       }
+
+       if (wait_cnt >= HNS_MAX_WAIT_CNT) {
+               dev_err(drv->dev,
+                       "hns ge %d fifo was not idle.\n", drv->mac_id);
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
 static void hns_gmac_init(void *mac_drv)
 {
        u32 port;
@@ -690,6 +724,7 @@ void *hns_gmac_config(struct hns_mac_cb *mac_cb, struct mac_params *mac_param)
        mac_drv->mac_disable = hns_gmac_disable;
        mac_drv->mac_free = hns_gmac_free;
        mac_drv->adjust_link = hns_gmac_adjust_link;
+       mac_drv->need_adjust_link = hns_gmac_need_adjust_link;
        mac_drv->set_tx_auto_pause_frames = hns_gmac_set_tx_auto_pause_frames;
        mac_drv->config_max_frame_length = hns_gmac_config_max_frame_length;
        mac_drv->mac_pausefrm_cfg = hns_gmac_pause_frm_cfg;
@@ -717,6 +752,7 @@ void *hns_gmac_config(struct hns_mac_cb *mac_cb, struct mac_params *mac_param)
        mac_drv->get_strings = hns_gmac_get_strings;
        mac_drv->update_stats = hns_gmac_update_stats;
        mac_drv->set_promiscuous = hns_gmac_set_promisc;
+       mac_drv->wait_fifo_clean = hns_gmac_wait_fifo_clean;
 
        return (void *)mac_drv;
 }
index 1c2326bd76e24d301d5689dd163c588d811dc4e8..6ed6f142427e4b68434df612568a7fea2f0433bc 100644 (file)
@@ -114,6 +114,26 @@ int hns_mac_get_port_info(struct hns_mac_cb *mac_cb,
        return 0;
 }
 
+/**
+ *hns_mac_is_adjust_link - check is need change mac speed and duplex register
+ *@mac_cb: mac device
+ *@speed: phy device speed
+ *@duplex:phy device duplex
+ *
+ */
+bool hns_mac_need_adjust_link(struct hns_mac_cb *mac_cb, int speed, int duplex)
+{
+       struct mac_driver *mac_ctrl_drv;
+
+       mac_ctrl_drv = (struct mac_driver *)(mac_cb->priv.mac);
+
+       if (mac_ctrl_drv->need_adjust_link)
+               return mac_ctrl_drv->need_adjust_link(mac_ctrl_drv,
+                       (enum mac_speed)speed, duplex);
+       else
+               return true;
+}
+
 void hns_mac_adjust_link(struct hns_mac_cb *mac_cb, int speed, int duplex)
 {
        int ret;
@@ -430,6 +450,16 @@ int hns_mac_vm_config_bc_en(struct hns_mac_cb *mac_cb, u32 vmid, bool enable)
        return 0;
 }
 
+int hns_mac_wait_fifo_clean(struct hns_mac_cb *mac_cb)
+{
+       struct mac_driver *drv = hns_mac_get_drv(mac_cb);
+
+       if (drv->wait_fifo_clean)
+               return drv->wait_fifo_clean(drv);
+
+       return 0;
+}
+
 void hns_mac_reset(struct hns_mac_cb *mac_cb)
 {
        struct mac_driver *drv = hns_mac_get_drv(mac_cb);
@@ -998,6 +1028,20 @@ static int hns_mac_get_max_port_num(struct dsaf_device *dsaf_dev)
                return  DSAF_MAX_PORT_NUM;
 }
 
+void hns_mac_enable(struct hns_mac_cb *mac_cb, enum mac_commom_mode mode)
+{
+       struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
+
+       mac_ctrl_drv->mac_enable(mac_cb->priv.mac, mode);
+}
+
+void hns_mac_disable(struct hns_mac_cb *mac_cb, enum mac_commom_mode mode)
+{
+       struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
+
+       mac_ctrl_drv->mac_disable(mac_cb->priv.mac, mode);
+}
+
 /**
  * hns_mac_init - init mac
  * @dsaf_dev: dsa fabric device struct pointer
index bbc0a98e7ca3260c7f8b1b8cb7f7f203860bfdce..fbc75341bef760b82a1d7a10469d5649db91e366 100644 (file)
@@ -356,6 +356,9 @@ struct mac_driver {
        /*adjust mac mode of port,include speed and duplex*/
        int (*adjust_link)(void *mac_drv, enum mac_speed speed,
                           u32 full_duplex);
+       /* need adjust link */
+       bool (*need_adjust_link)(void *mac_drv, enum mac_speed speed,
+                                int duplex);
        /* config autoegotaite mode of port*/
        void (*set_an_mode)(void *mac_drv, u8 enable);
        /* config loopbank mode */
@@ -394,6 +397,7 @@ struct mac_driver {
        void (*get_info)(void *mac_drv, struct mac_info *mac_info);
 
        void (*update_stats)(void *mac_drv);
+       int (*wait_fifo_clean)(void *mac_drv);
 
        enum mac_mode mac_mode;
        u8 mac_id;
@@ -427,6 +431,7 @@ void *hns_xgmac_config(struct hns_mac_cb *mac_cb,
 
 int hns_mac_init(struct dsaf_device *dsaf_dev);
 void mac_adjust_link(struct net_device *net_dev);
+bool hns_mac_need_adjust_link(struct hns_mac_cb *mac_cb, int speed, int duplex);
 void hns_mac_get_link_status(struct hns_mac_cb *mac_cb,        u32 *link_status);
 int hns_mac_change_vf_addr(struct hns_mac_cb *mac_cb, u32 vmid, char *addr);
 int hns_mac_set_multi(struct hns_mac_cb *mac_cb,
@@ -463,5 +468,8 @@ int hns_mac_add_uc_addr(struct hns_mac_cb *mac_cb, u8 vf_id,
 int hns_mac_rm_uc_addr(struct hns_mac_cb *mac_cb, u8 vf_id,
                       const unsigned char *addr);
 int hns_mac_clr_multicast(struct hns_mac_cb *mac_cb, int vfn);
+void hns_mac_enable(struct hns_mac_cb *mac_cb, enum mac_commom_mode mode);
+void hns_mac_disable(struct hns_mac_cb *mac_cb, enum mac_commom_mode mode);
+int hns_mac_wait_fifo_clean(struct hns_mac_cb *mac_cb);
 
 #endif /* _HNS_DSAF_MAC_H */
index ca50c2553a9cb16c92e2d1dbfeaac7e03808fc71..e557a4ef5996c6772804ca746830af633a4adca9 100644 (file)
@@ -2727,6 +2727,35 @@ void hns_dsaf_set_promisc_tcam(struct dsaf_device *dsaf_dev,
        soft_mac_entry->index = enable ? entry_index : DSAF_INVALID_ENTRY_IDX;
 }
 
+int hns_dsaf_wait_pkt_clean(struct dsaf_device *dsaf_dev, int port)
+{
+       u32 val, val_tmp;
+       int wait_cnt;
+
+       if (port >= DSAF_SERVICE_NW_NUM)
+               return 0;
+
+       wait_cnt = 0;
+       while (wait_cnt++ < HNS_MAX_WAIT_CNT) {
+               val = dsaf_read_dev(dsaf_dev, DSAF_VOQ_IN_PKT_NUM_0_REG +
+                       (port + DSAF_XGE_NUM) * 0x40);
+               val_tmp = dsaf_read_dev(dsaf_dev, DSAF_VOQ_OUT_PKT_NUM_0_REG +
+                       (port + DSAF_XGE_NUM) * 0x40);
+               if (val == val_tmp)
+                       break;
+
+               usleep_range(100, 200);
+       }
+
+       if (wait_cnt >= HNS_MAX_WAIT_CNT) {
+               dev_err(dsaf_dev->dev, "hns dsaf clean wait timeout(%u - %u).\n",
+                       val, val_tmp);
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
 /**
  * dsaf_probe - probo dsaf dev
  * @pdev: dasf platform device
index 4507e8222683c112c05eeca4633e65990b789b8f..0e1cd99831a6083faa790aa80be1f6c635b15a50 100644 (file)
@@ -44,6 +44,8 @@ struct hns_mac_cb;
 #define DSAF_ROCE_CREDIT_CHN   8
 #define DSAF_ROCE_CHAN_MODE    3
 
+#define HNS_MAX_WAIT_CNT 10000
+
 enum dsaf_roce_port_mode {
        DSAF_ROCE_6PORT_MODE,
        DSAF_ROCE_4PORT_MODE,
@@ -463,5 +465,6 @@ int hns_dsaf_rm_mac_addr(
 
 int hns_dsaf_clr_mac_mc_port(struct dsaf_device *dsaf_dev,
                             u8 mac_id, u8 port_num);
+int hns_dsaf_wait_pkt_clean(struct dsaf_device *dsaf_dev, int port);
 
 #endif /* __HNS_DSAF_MAIN_H__ */
index d160d8c9e45ba60b3543643c13748272baada910..0942e4916d9d0d1b0b78958481ea099e66e59639 100644 (file)
@@ -275,6 +275,29 @@ static void hns_ppe_exc_irq_en(struct hns_ppe_cb *ppe_cb, int en)
        dsaf_write_dev(ppe_cb, PPE_INTEN_REG, msk_vlue & vld_msk);
 }
 
+int hns_ppe_wait_tx_fifo_clean(struct hns_ppe_cb *ppe_cb)
+{
+       int wait_cnt;
+       u32 val;
+
+       wait_cnt = 0;
+       while (wait_cnt++ < HNS_MAX_WAIT_CNT) {
+               val = dsaf_read_dev(ppe_cb, PPE_CURR_TX_FIFO0_REG) & 0x3ffU;
+               if (!val)
+                       break;
+
+               usleep_range(100, 200);
+       }
+
+       if (wait_cnt >= HNS_MAX_WAIT_CNT) {
+               dev_err(ppe_cb->dev, "hns ppe tx fifo clean wait timeout, still has %u pkt.\n",
+                       val);
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
 /**
  * ppe_init_hw - init ppe
  * @ppe_cb: ppe device
index 9d8e643e8aa6ff518ab68d4af4c42d292a37ae47..f670e63a5a018cd5b48b4a62093c104905aa4463 100644 (file)
@@ -100,6 +100,7 @@ struct ppe_common_cb {
 
 };
 
+int hns_ppe_wait_tx_fifo_clean(struct hns_ppe_cb *ppe_cb);
 int hns_ppe_init(struct dsaf_device *dsaf_dev);
 
 void hns_ppe_uninit(struct dsaf_device *dsaf_dev);
index 9d76e2e54f9df576b65702f720a79ab2a612dbb3..5d64519b9b1dc3cfd6e2c403126aa4ffa5832dfc 100644 (file)
@@ -66,6 +66,29 @@ void hns_rcb_wait_fbd_clean(struct hnae_queue **qs, int q_num, u32 flag)
                        "queue(%d) wait fbd(%d) clean fail!!\n", i, fbd_num);
 }
 
+int hns_rcb_wait_tx_ring_clean(struct hnae_queue *qs)
+{
+       u32 head, tail;
+       int wait_cnt;
+
+       tail = dsaf_read_dev(&qs->tx_ring, RCB_REG_TAIL);
+       wait_cnt = 0;
+       while (wait_cnt++ < HNS_MAX_WAIT_CNT) {
+               head = dsaf_read_dev(&qs->tx_ring, RCB_REG_HEAD);
+               if (tail == head)
+                       break;
+
+               usleep_range(100, 200);
+       }
+
+       if (wait_cnt >= HNS_MAX_WAIT_CNT) {
+               dev_err(qs->dev->dev, "rcb wait timeout, head not equal to tail.\n");
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
 /**
  *hns_rcb_reset_ring_hw - ring reset
  *@q: ring struct pointer
index 602816498c8dd0c4aecd20ae9f5df196d7944821..2319b772a271e519d6a69a0976713a19c60f4a8a 100644 (file)
@@ -136,6 +136,7 @@ void hns_rcbv2_int_clr_hw(struct hnae_queue *q, u32 flag);
 void hns_rcb_init_hw(struct ring_pair_cb *ring);
 void hns_rcb_reset_ring_hw(struct hnae_queue *q);
 void hns_rcb_wait_fbd_clean(struct hnae_queue **qs, int q_num, u32 flag);
+int hns_rcb_wait_tx_ring_clean(struct hnae_queue *qs);
 u32 hns_rcb_get_rx_coalesced_frames(
        struct rcb_common_cb *rcb_common, u32 port_idx);
 u32 hns_rcb_get_tx_coalesced_frames(
index 886cbbf25761aadc04c18573e9536ecd22e8095b..74d935d82cbc6050a287a07532024675ce75254e 100644 (file)
 #define RCB_RING_INTMSK_TX_OVERTIME_REG                0x000C4
 #define RCB_RING_INTSTS_TX_OVERTIME_REG                0x000C8
 
+#define GMAC_FIFO_STATE_REG                    0x0000UL
 #define GMAC_DUPLEX_TYPE_REG                   0x0008UL
 #define GMAC_FD_FC_TYPE_REG                    0x000CUL
 #define GMAC_TX_WATER_LINE_REG                 0x0010UL
index 9f2b552aee33998680c2dc2c72e81c28f99209f5..f56855e63c961333f20f842a3558a920d201ccc9 100644 (file)
@@ -406,113 +406,13 @@ out_net_tx_busy:
        return NETDEV_TX_BUSY;
 }
 
-/**
- * hns_nic_get_headlen - determine size of header for RSC/LRO/GRO/FCOE
- * @data: pointer to the start of the headers
- * @max: total length of section to find headers in
- *
- * This function is meant to determine the length of headers that will
- * be recognized by hardware for LRO, GRO, and RSC offloads.  The main
- * motivation of doing this is to only perform one pull for IPv4 TCP
- * packets so that we can do basic things like calculating the gso_size
- * based on the average data per packet.
- **/
-static unsigned int hns_nic_get_headlen(unsigned char *data, u32 flag,
-                                       unsigned int max_size)
-{
-       unsigned char *network;
-       u8 hlen;
-
-       /* this should never happen, but better safe than sorry */
-       if (max_size < ETH_HLEN)
-               return max_size;
-
-       /* initialize network frame pointer */
-       network = data;
-
-       /* set first protocol and move network header forward */
-       network += ETH_HLEN;
-
-       /* handle any vlan tag if present */
-       if (hnae_get_field(flag, HNS_RXD_VLAN_M, HNS_RXD_VLAN_S)
-               == HNS_RX_FLAG_VLAN_PRESENT) {
-               if ((typeof(max_size))(network - data) > (max_size - VLAN_HLEN))
-                       return max_size;
-
-               network += VLAN_HLEN;
-       }
-
-       /* handle L3 protocols */
-       if (hnae_get_field(flag, HNS_RXD_L3ID_M, HNS_RXD_L3ID_S)
-               == HNS_RX_FLAG_L3ID_IPV4) {
-               if ((typeof(max_size))(network - data) >
-                   (max_size - sizeof(struct iphdr)))
-                       return max_size;
-
-               /* access ihl as a u8 to avoid unaligned access on ia64 */
-               hlen = (network[0] & 0x0F) << 2;
-
-               /* verify hlen meets minimum size requirements */
-               if (hlen < sizeof(struct iphdr))
-                       return network - data;
-
-               /* record next protocol if header is present */
-       } else if (hnae_get_field(flag, HNS_RXD_L3ID_M, HNS_RXD_L3ID_S)
-               == HNS_RX_FLAG_L3ID_IPV6) {
-               if ((typeof(max_size))(network - data) >
-                   (max_size - sizeof(struct ipv6hdr)))
-                       return max_size;
-
-               /* record next protocol */
-               hlen = sizeof(struct ipv6hdr);
-       } else {
-               return network - data;
-       }
-
-       /* relocate pointer to start of L4 header */
-       network += hlen;
-
-       /* finally sort out TCP/UDP */
-       if (hnae_get_field(flag, HNS_RXD_L4ID_M, HNS_RXD_L4ID_S)
-               == HNS_RX_FLAG_L4ID_TCP) {
-               if ((typeof(max_size))(network - data) >
-                   (max_size - sizeof(struct tcphdr)))
-                       return max_size;
-
-               /* access doff as a u8 to avoid unaligned access on ia64 */
-               hlen = (network[12] & 0xF0) >> 2;
-
-               /* verify hlen meets minimum size requirements */
-               if (hlen < sizeof(struct tcphdr))
-                       return network - data;
-
-               network += hlen;
-       } else if (hnae_get_field(flag, HNS_RXD_L4ID_M, HNS_RXD_L4ID_S)
-               == HNS_RX_FLAG_L4ID_UDP) {
-               if ((typeof(max_size))(network - data) >
-                   (max_size - sizeof(struct udphdr)))
-                       return max_size;
-
-               network += sizeof(struct udphdr);
-       }
-
-       /* If everything has gone correctly network should be the
-        * data section of the packet and will be the end of the header.
-        * If not then it probably represents the end of the last recognized
-        * header.
-        */
-       if ((typeof(max_size))(network - data) < max_size)
-               return network - data;
-       else
-               return max_size;
-}
-
 static void hns_nic_reuse_page(struct sk_buff *skb, int i,
                               struct hnae_ring *ring, int pull_len,
                               struct hnae_desc_cb *desc_cb)
 {
        struct hnae_desc *desc;
-       int truesize, size;
+       u32 truesize;
+       int size;
        int last_offset;
        bool twobufs;
 
@@ -530,7 +430,7 @@ static void hns_nic_reuse_page(struct sk_buff *skb, int i,
        }
 
        skb_add_rx_frag(skb, i, desc_cb->priv, desc_cb->page_offset + pull_len,
-                       size - pull_len, truesize - pull_len);
+                       size - pull_len, truesize);
 
         /* avoid re-using remote pages,flag default unreuse */
        if (unlikely(page_to_nid(desc_cb->priv) != numa_node_id()))
@@ -695,7 +595,7 @@ static int hns_nic_poll_rx_skb(struct hns_nic_ring_data *ring_data,
        } else {
                ring->stats.seg_pkt_cnt++;
 
-               pull_len = hns_nic_get_headlen(va, bnum_flag, HNS_RX_HEAD_SIZE);
+               pull_len = eth_get_headlen(va, HNS_RX_HEAD_SIZE);
                memcpy(__skb_put(skb, pull_len), va,
                       ALIGN(pull_len, sizeof(long)));
 
@@ -1212,11 +1112,26 @@ static void hns_nic_adjust_link(struct net_device *ndev)
        struct hnae_handle *h = priv->ae_handle;
        int state = 1;
 
+       /* If there is no phy, do not need adjust link */
        if (ndev->phydev) {
-               h->dev->ops->adjust_link(h, ndev->phydev->speed,
-                                        ndev->phydev->duplex);
-               state = ndev->phydev->link;
+               /* When phy link down, do nothing */
+               if (ndev->phydev->link == 0)
+                       return;
+
+               if (h->dev->ops->need_adjust_link(h, ndev->phydev->speed,
+                                                 ndev->phydev->duplex)) {
+                       /* because Hi161X chip don't support to change gmac
+                        * speed and duplex with traffic. Delay 200ms to
+                        * make sure there is no more data in chip FIFO.
+                        */
+                       netif_carrier_off(ndev);
+                       msleep(200);
+                       h->dev->ops->adjust_link(h, ndev->phydev->speed,
+                                                ndev->phydev->duplex);
+                       netif_carrier_on(ndev);
+               }
        }
+
        state = state && h->dev->ops->get_status(h);
 
        if (state != priv->link) {
index 08f3c4743f747c7cbe020503d330821fe5427b68..774beda040a16a93a80db08e9383a2fe69a85eba 100644 (file)
@@ -243,7 +243,9 @@ static int hns_nic_set_link_ksettings(struct net_device *net_dev,
        }
 
        if (h->dev->ops->adjust_link) {
+               netif_carrier_off(net_dev);
                h->dev->ops->adjust_link(h, (int)speed, cmd->base.duplex);
+               netif_carrier_on(net_dev);
                return 0;
        }
 
index 3554dca7a680a2c970b37313222e517199007e82..955c4ab18b03bb300ec7beb8f8bcf953e817b2fc 100644 (file)
@@ -2019,7 +2019,8 @@ static void hns3_nic_reuse_page(struct sk_buff *skb, int i,
                                struct hns3_desc_cb *desc_cb)
 {
        struct hns3_desc *desc;
-       int truesize, size;
+       u32 truesize;
+       int size;
        int last_offset;
        bool twobufs;
 
index a02a96aee2a2bfdcb9ebb49ea56b40546df83ae8..cb450d7ec8c1665a9ae690a3e3a9b78843976cf4 100644 (file)
@@ -284,11 +284,11 @@ struct hns3_desc_cb {
 
        /* priv data for the desc, e.g. skb when use with ip stack*/
        void *priv;
-       u16 page_offset;
-       u16 reuse_flag;
-
+       u32 page_offset;
        u32 length;     /* length of the buffer */
 
+       u16 reuse_flag;
+
        /* desc type, used by the ring user to mark the type of the priv data */
        u16 type;
 };
index 354c0982847b8f1cc478e598f8bd068225aa1241..3726646863095dc145e8df1ccc5d082f9fd802bd 100644 (file)
@@ -494,9 +494,6 @@ static u32 __emac_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_s
        case 16384:
                ret |= EMAC_MR1_RFS_16K;
                break;
-       case 8192:
-               ret |= EMAC4_MR1_RFS_8K;
-               break;
        case 4096:
                ret |= EMAC_MR1_RFS_4K;
                break;
@@ -537,6 +534,9 @@ static u32 __emac4_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_
        case 16384:
                ret |= EMAC4_MR1_RFS_16K;
                break;
+       case 8192:
+               ret |= EMAC4_MR1_RFS_8K;
+               break;
        case 4096:
                ret |= EMAC4_MR1_RFS_4K;
                break;
index dafdd4ade705b346349ce4671910424fa7b28d15..4f0daf67b18df2dcf11d7a406ebc1982e0fee466 100644 (file)
@@ -1823,11 +1823,17 @@ static int do_reset(struct ibmvnic_adapter *adapter,
                        adapter->map_id = 1;
                        release_rx_pools(adapter);
                        release_tx_pools(adapter);
-                       init_rx_pools(netdev);
-                       init_tx_pools(netdev);
+                       rc = init_rx_pools(netdev);
+                       if (rc)
+                               return rc;
+                       rc = init_tx_pools(netdev);
+                       if (rc)
+                               return rc;
 
                        release_napi(adapter);
-                       init_napi(adapter);
+                       rc = init_napi(adapter);
+                       if (rc)
+                               return rc;
                } else {
                        rc = reset_tx_pools(adapter);
                        if (rc)
index bdb3f8e65ed470e314bf6b4f9b3b3b4e41b93e0f..2569a168334cbc6785f9e2909f5a68ac6450c9d6 100644 (file)
@@ -624,14 +624,14 @@ static int e1000_set_ringparam(struct net_device *netdev,
                adapter->tx_ring = tx_old;
                e1000_free_all_rx_resources(adapter);
                e1000_free_all_tx_resources(adapter);
-               kfree(tx_old);
-               kfree(rx_old);
                adapter->rx_ring = rxdr;
                adapter->tx_ring = txdr;
                err = e1000_up(adapter);
                if (err)
                        goto err_setup;
        }
+       kfree(tx_old);
+       kfree(rx_old);
 
        clear_bit(__E1000_RESETTING, &adapter->flags);
        return 0;
@@ -644,7 +644,8 @@ err_setup_rx:
 err_alloc_rx:
        kfree(txdr);
 err_alloc_tx:
-       e1000_up(adapter);
+       if (netif_running(adapter->netdev))
+               e1000_up(adapter);
 err_setup:
        clear_bit(__E1000_RESETTING, &adapter->flags);
        return err;
index abcd096ede14022ac6e022536a2db02de7e023da..5ff6caa83948c2c14a6b85070ddaba54e0c50c3a 100644 (file)
@@ -2013,7 +2013,7 @@ static void i40e_get_stat_strings(struct net_device *netdev, u8 *data)
        for (i = 0; i < I40E_MAX_USER_PRIORITY; i++)
                i40e_add_stat_strings(&data, i40e_gstrings_pfc_stats, i);
 
-       WARN_ONCE(p - data != i40e_get_stats_count(netdev) * ETH_GSTRING_LEN,
+       WARN_ONCE(data - p != i40e_get_stats_count(netdev) * ETH_GSTRING_LEN,
                  "stat strings count mismatch!");
 }
 
index f2c622e78802a751dc549e03b811825596d1a587..ac685ad4d8773125b059f1209d2b60747996b39b 100644 (file)
@@ -5122,15 +5122,17 @@ static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc,
                                       u8 *bw_share)
 {
        struct i40e_aqc_configure_vsi_tc_bw_data bw_data;
+       struct i40e_pf *pf = vsi->back;
        i40e_status ret;
        int i;
 
-       if (vsi->back->flags & I40E_FLAG_TC_MQPRIO)
+       /* There is no need to reset BW when mqprio mode is on.  */
+       if (pf->flags & I40E_FLAG_TC_MQPRIO)
                return 0;
-       if (!vsi->mqprio_qopt.qopt.hw) {
+       if (!vsi->mqprio_qopt.qopt.hw && !(pf->flags & I40E_FLAG_DCB_ENABLED)) {
                ret = i40e_set_bw_limit(vsi, vsi->seid, 0);
                if (ret)
-                       dev_info(&vsi->back->pdev->dev,
+                       dev_info(&pf->pdev->dev,
                                 "Failed to reset tx rate for vsi->seid %u\n",
                                 vsi->seid);
                return ret;
@@ -5139,12 +5141,11 @@ static int i40e_vsi_configure_bw_alloc(struct i40e_vsi *vsi, u8 enabled_tc,
        for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
                bw_data.tc_bw_credits[i] = bw_share[i];
 
-       ret = i40e_aq_config_vsi_tc_bw(&vsi->back->hw, vsi->seid, &bw_data,
-                                      NULL);
+       ret = i40e_aq_config_vsi_tc_bw(&pf->hw, vsi->seid, &bw_data, NULL);
        if (ret) {
-               dev_info(&vsi->back->pdev->dev,
+               dev_info(&pf->pdev->dev,
                         "AQ command Config VSI BW allocation per TC failed = %d\n",
-                        vsi->back->hw.aq.asq_last_status);
+                        pf->hw.aq.asq_last_status);
                return -EINVAL;
        }
 
index d8b5fff581e717e189ffe8f50dff4215ce8ec805..868f4a1d0f724379534791f74127261bba0c9682 100644 (file)
@@ -89,6 +89,13 @@ extern const char ice_drv_ver[];
 #define ice_for_each_rxq(vsi, i) \
        for ((i) = 0; (i) < (vsi)->num_rxq; (i)++)
 
+/* Macros for each allocated tx/rx ring whether used or not in a VSI */
+#define ice_for_each_alloc_txq(vsi, i) \
+       for ((i) = 0; (i) < (vsi)->alloc_txq; (i)++)
+
+#define ice_for_each_alloc_rxq(vsi, i) \
+       for ((i) = 0; (i) < (vsi)->alloc_rxq; (i)++)
+
 struct ice_tc_info {
        u16 qoffset;
        u16 qcount;
@@ -189,9 +196,9 @@ struct ice_vsi {
        struct list_head tmp_sync_list;         /* MAC filters to be synced */
        struct list_head tmp_unsync_list;       /* MAC filters to be unsynced */
 
-       bool irqs_ready;
-       bool current_isup;               /* Sync 'link up' logging */
-       bool stat_offsets_loaded;
+       u8 irqs_ready;
+       u8 current_isup;                 /* Sync 'link up' logging */
+       u8 stat_offsets_loaded;
 
        /* queue information */
        u8 tx_mapping_mode;              /* ICE_MAP_MODE_[CONTIG|SCATTER] */
@@ -262,7 +269,7 @@ struct ice_pf {
        struct ice_hw_port_stats stats;
        struct ice_hw_port_stats stats_prev;
        struct ice_hw hw;
-       bool stat_prev_loaded;  /* has previous stats been loaded */
+       u8 stat_prev_loaded;    /* has previous stats been loaded */
        char int_name[ICE_INT_NAME_STR_LEN];
 };
 
index 7541ec2270b3708d4e5e9362d0ae8a1f5e09318d..a0614f472658ac5305c6aff1e589d99dbdd1634a 100644 (file)
@@ -329,19 +329,19 @@ struct ice_aqc_vsi_props {
        /* VLAN section */
        __le16 pvid; /* VLANS include priority bits */
        u8 pvlan_reserved[2];
-       u8 port_vlan_flags;
-#define ICE_AQ_VSI_PVLAN_MODE_S        0
-#define ICE_AQ_VSI_PVLAN_MODE_M        (0x3 << ICE_AQ_VSI_PVLAN_MODE_S)
-#define ICE_AQ_VSI_PVLAN_MODE_UNTAGGED 0x1
-#define ICE_AQ_VSI_PVLAN_MODE_TAGGED   0x2
-#define ICE_AQ_VSI_PVLAN_MODE_ALL      0x3
+       u8 vlan_flags;
+#define ICE_AQ_VSI_VLAN_MODE_S 0
+#define ICE_AQ_VSI_VLAN_MODE_M (0x3 << ICE_AQ_VSI_VLAN_MODE_S)
+#define ICE_AQ_VSI_VLAN_MODE_UNTAGGED  0x1
+#define ICE_AQ_VSI_VLAN_MODE_TAGGED    0x2
+#define ICE_AQ_VSI_VLAN_MODE_ALL       0x3
 #define ICE_AQ_VSI_PVLAN_INSERT_PVID   BIT(2)
-#define ICE_AQ_VSI_PVLAN_EMOD_S        3
-#define ICE_AQ_VSI_PVLAN_EMOD_M        (0x3 << ICE_AQ_VSI_PVLAN_EMOD_S)
-#define ICE_AQ_VSI_PVLAN_EMOD_STR_BOTH (0x0 << ICE_AQ_VSI_PVLAN_EMOD_S)
-#define ICE_AQ_VSI_PVLAN_EMOD_STR_UP   (0x1 << ICE_AQ_VSI_PVLAN_EMOD_S)
-#define ICE_AQ_VSI_PVLAN_EMOD_STR      (0x2 << ICE_AQ_VSI_PVLAN_EMOD_S)
-#define ICE_AQ_VSI_PVLAN_EMOD_NOTHING  (0x3 << ICE_AQ_VSI_PVLAN_EMOD_S)
+#define ICE_AQ_VSI_VLAN_EMOD_S         3
+#define ICE_AQ_VSI_VLAN_EMOD_M         (0x3 << ICE_AQ_VSI_VLAN_EMOD_S)
+#define ICE_AQ_VSI_VLAN_EMOD_STR_BOTH  (0x0 << ICE_AQ_VSI_VLAN_EMOD_S)
+#define ICE_AQ_VSI_VLAN_EMOD_STR_UP    (0x1 << ICE_AQ_VSI_VLAN_EMOD_S)
+#define ICE_AQ_VSI_VLAN_EMOD_STR       (0x2 << ICE_AQ_VSI_VLAN_EMOD_S)
+#define ICE_AQ_VSI_VLAN_EMOD_NOTHING   (0x3 << ICE_AQ_VSI_VLAN_EMOD_S)
        u8 pvlan_reserved2[3];
        /* ingress egress up sections */
        __le32 ingress_table; /* bitmap, 3 bits per up */
@@ -594,6 +594,7 @@ struct ice_sw_rule_lg_act {
 #define ICE_LG_ACT_GENERIC_OFFSET_M    (0x7 << ICE_LG_ACT_GENERIC_OFFSET_S)
 #define ICE_LG_ACT_GENERIC_PRIORITY_S  22
 #define ICE_LG_ACT_GENERIC_PRIORITY_M  (0x7 << ICE_LG_ACT_GENERIC_PRIORITY_S)
+#define ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX        7
 
        /* Action = 7 - Set Stat count */
 #define ICE_LG_ACT_STAT_COUNT          0x7
index 71d032cc5fa7d7ee8d6af579ca3d0e7813de05b5..661beea6af795cd72abf3e609347c89b21d9902d 100644 (file)
@@ -45,6 +45,9 @@ static enum ice_status ice_set_mac_type(struct ice_hw *hw)
 /**
  * ice_clear_pf_cfg - Clear PF configuration
  * @hw: pointer to the hardware structure
+ *
+ * Clears any existing PF configuration (VSIs, VSI lists, switch rules, port
+ * configuration, flow director filters, etc.).
  */
 enum ice_status ice_clear_pf_cfg(struct ice_hw *hw)
 {
@@ -1483,7 +1486,7 @@ enum ice_status ice_get_link_status(struct ice_port_info *pi, bool *link_up)
        struct ice_phy_info *phy_info;
        enum ice_status status = 0;
 
-       if (!pi)
+       if (!pi || !link_up)
                return ICE_ERR_PARAM;
 
        phy_info = &pi->phy;
@@ -1619,20 +1622,23 @@ __ice_aq_get_set_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut,
        }
 
        /* LUT size is only valid for Global and PF table types */
-       if (lut_size == ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128) {
-               flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128_FLAG <<
-                         ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
-                        ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
-       } else if (lut_size == ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512) {
+       switch (lut_size) {
+       case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128:
+               break;
+       case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512:
                flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512_FLAG <<
                          ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
                         ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
-       } else if ((lut_size == ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K) &&
-                  (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF)) {
-               flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K_FLAG <<
-                         ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
-                        ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
-       } else {
+               break;
+       case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K:
+               if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF) {
+                       flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K_FLAG <<
+                                 ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
+                                ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
+                       break;
+               }
+               /* fall-through */
+       default:
                status = ICE_ERR_PARAM;
                goto ice_aq_get_set_rss_lut_exit;
        }
index 7c511f144ed60d92c16f0f526cfb5b03a3c2a59e..62be72fdc8f30c283b2385216f41ff15b87dc628 100644 (file)
@@ -597,10 +597,14 @@ static enum ice_status ice_init_check_adminq(struct ice_hw *hw)
        return 0;
 
 init_ctrlq_free_rq:
-       ice_shutdown_rq(hw, cq);
-       ice_shutdown_sq(hw, cq);
-       mutex_destroy(&cq->sq_lock);
-       mutex_destroy(&cq->rq_lock);
+       if (cq->rq.head) {
+               ice_shutdown_rq(hw, cq);
+               mutex_destroy(&cq->rq_lock);
+       }
+       if (cq->sq.head) {
+               ice_shutdown_sq(hw, cq);
+               mutex_destroy(&cq->sq_lock);
+       }
        return status;
 }
 
@@ -706,10 +710,14 @@ static void ice_shutdown_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)
                return;
        }
 
-       ice_shutdown_sq(hw, cq);
-       ice_shutdown_rq(hw, cq);
-       mutex_destroy(&cq->sq_lock);
-       mutex_destroy(&cq->rq_lock);
+       if (cq->sq.head) {
+               ice_shutdown_sq(hw, cq);
+               mutex_destroy(&cq->sq_lock);
+       }
+       if (cq->rq.head) {
+               ice_shutdown_rq(hw, cq);
+               mutex_destroy(&cq->rq_lock);
+       }
 }
 
 /**
@@ -1057,8 +1065,11 @@ ice_clean_rq_elem(struct ice_hw *hw, struct ice_ctl_q_info *cq,
 
 clean_rq_elem_out:
        /* Set pending if needed, unlock and return */
-       if (pending)
+       if (pending) {
+               /* re-read HW head to calculate actual pending messages */
+               ntu = (u16)(rd32(hw, cq->rq.head) & cq->rq.head_mask);
                *pending = (u16)((ntc > ntu ? cq->rq.count : 0) + (ntu - ntc));
+       }
 clean_rq_elem_err:
        mutex_unlock(&cq->rq_lock);
 
index 1db304c01d100604560a5d4ac8216b093a7f92d6..c71a9b528d6d558eca4a97a4511e445b00aa5bf1 100644 (file)
@@ -26,7 +26,7 @@ static int ice_q_stats_len(struct net_device *netdev)
 {
        struct ice_netdev_priv *np = netdev_priv(netdev);
 
-       return ((np->vsi->num_txq + np->vsi->num_rxq) *
+       return ((np->vsi->alloc_txq + np->vsi->alloc_rxq) *
                (sizeof(struct ice_q_stats) / sizeof(u64)));
 }
 
@@ -218,7 +218,7 @@ static void ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
                        p += ETH_GSTRING_LEN;
                }
 
-               ice_for_each_txq(vsi, i) {
+               ice_for_each_alloc_txq(vsi, i) {
                        snprintf(p, ETH_GSTRING_LEN,
                                 "tx-queue-%u.tx_packets", i);
                        p += ETH_GSTRING_LEN;
@@ -226,7 +226,7 @@ static void ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
                        p += ETH_GSTRING_LEN;
                }
 
-               ice_for_each_rxq(vsi, i) {
+               ice_for_each_alloc_rxq(vsi, i) {
                        snprintf(p, ETH_GSTRING_LEN,
                                 "rx-queue-%u.rx_packets", i);
                        p += ETH_GSTRING_LEN;
@@ -253,6 +253,24 @@ static int ice_get_sset_count(struct net_device *netdev, int sset)
 {
        switch (sset) {
        case ETH_SS_STATS:
+               /* The number (and order) of strings reported *must* remain
+                * constant for a given netdevice. This function must not
+                * report a different number based on run time parameters
+                * (such as the number of queues in use, or the setting of
+                * a private ethtool flag). This is due to the nature of the
+                * ethtool stats API.
+                *
+                * User space programs such as ethtool must make 3 separate
+                * ioctl requests, one for size, one for the strings, and
+                * finally one for the stats. Since these cross into
+                * user space, changes to the number or size could result in
+                * undefined memory access or incorrect string<->value
+                * correlations for statistics.
+                *
+                * Even if it appears to be safe, changes to the size or
+                * order of strings will suffer from race conditions and are
+                * not safe.
+                */
                return ICE_ALL_STATS_LEN(netdev);
        default:
                return -EOPNOTSUPP;
@@ -280,18 +298,26 @@ ice_get_ethtool_stats(struct net_device *netdev,
        /* populate per queue stats */
        rcu_read_lock();
 
-       ice_for_each_txq(vsi, j) {
+       ice_for_each_alloc_txq(vsi, j) {
                ring = READ_ONCE(vsi->tx_rings[j]);
-               if (!ring)
-                       continue;
-               data[i++] = ring->stats.pkts;
-               data[i++] = ring->stats.bytes;
+               if (ring) {
+                       data[i++] = ring->stats.pkts;
+                       data[i++] = ring->stats.bytes;
+               } else {
+                       data[i++] = 0;
+                       data[i++] = 0;
+               }
        }
 
-       ice_for_each_rxq(vsi, j) {
+       ice_for_each_alloc_rxq(vsi, j) {
                ring = READ_ONCE(vsi->rx_rings[j]);
-               data[i++] = ring->stats.pkts;
-               data[i++] = ring->stats.bytes;
+               if (ring) {
+                       data[i++] = ring->stats.pkts;
+                       data[i++] = ring->stats.bytes;
+               } else {
+                       data[i++] = 0;
+                       data[i++] = 0;
+               }
        }
 
        rcu_read_unlock();
@@ -519,7 +545,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
                goto done;
        }
 
-       for (i = 0; i < vsi->num_txq; i++) {
+       for (i = 0; i < vsi->alloc_txq; i++) {
                /* clone ring and setup updated count */
                tx_rings[i] = *vsi->tx_rings[i];
                tx_rings[i].count = new_tx_cnt;
@@ -551,7 +577,7 @@ process_rx:
                goto done;
        }
 
-       for (i = 0; i < vsi->num_rxq; i++) {
+       for (i = 0; i < vsi->alloc_rxq; i++) {
                /* clone ring and setup updated count */
                rx_rings[i] = *vsi->rx_rings[i];
                rx_rings[i].count = new_rx_cnt;
index 499904874b3ff863554c315add28a03f3a260eeb..6076fc87df9d28d81d3cc40d6b1ee7f042667b7f 100644 (file)
 #define PFINT_FW_CTL_CAUSE_ENA_S       30
 #define PFINT_FW_CTL_CAUSE_ENA_M       BIT(PFINT_FW_CTL_CAUSE_ENA_S)
 #define PFINT_OICR                     0x0016CA00
-#define PFINT_OICR_HLP_RDY_S           14
-#define PFINT_OICR_HLP_RDY_M           BIT(PFINT_OICR_HLP_RDY_S)
-#define PFINT_OICR_CPM_RDY_S           15
-#define PFINT_OICR_CPM_RDY_M           BIT(PFINT_OICR_CPM_RDY_S)
 #define PFINT_OICR_ECC_ERR_S           16
 #define PFINT_OICR_ECC_ERR_M           BIT(PFINT_OICR_ECC_ERR_S)
 #define PFINT_OICR_MAL_DETECT_S                19
 #define PFINT_OICR_GRST_M              BIT(PFINT_OICR_GRST_S)
 #define PFINT_OICR_PCI_EXCEPTION_S     21
 #define PFINT_OICR_PCI_EXCEPTION_M     BIT(PFINT_OICR_PCI_EXCEPTION_S)
-#define PFINT_OICR_GPIO_S              22
-#define PFINT_OICR_GPIO_M              BIT(PFINT_OICR_GPIO_S)
-#define PFINT_OICR_STORM_DETECT_S      24
-#define PFINT_OICR_STORM_DETECT_M      BIT(PFINT_OICR_STORM_DETECT_S)
 #define PFINT_OICR_HMC_ERR_S           26
 #define PFINT_OICR_HMC_ERR_M           BIT(PFINT_OICR_HMC_ERR_S)
 #define PFINT_OICR_PE_CRITERR_S                28
index d23a91665b463799a6a3e4445d3c681a2400fb15..068dbc740b7667ce98541921a57108503e825594 100644 (file)
@@ -265,6 +265,7 @@ enum ice_rx_flex_desc_status_error_0_bits {
 struct ice_rlan_ctx {
        u16 head;
        u16 cpuid; /* bigger than needed, see above for reason */
+#define ICE_RLAN_BASE_S 7
        u64 base;
        u16 qlen;
 #define ICE_RLAN_CTX_DBUF_S 7
index 5299caf55a7f2b44772988d9f4eeb70b27c51cc4..f1e80eed2fd6d9f94eab163acb4d178d83ba4af2 100644 (file)
@@ -901,7 +901,7 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
                case ice_aqc_opc_get_link_status:
                        if (ice_handle_link_event(pf))
                                dev_err(&pf->pdev->dev,
-                                       "Could not handle link event");
+                                       "Could not handle link event\n");
                        break;
                default:
                        dev_dbg(&pf->pdev->dev,
@@ -916,6 +916,21 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
        return pending && (i == ICE_DFLT_IRQ_WORK);
 }
 
+/**
+ * ice_ctrlq_pending - check if there is a difference between ntc and ntu
+ * @hw: pointer to hardware info
+ * @cq: control queue information
+ *
+ * returns true if there are pending messages in a queue, false if there aren't
+ */
+static bool ice_ctrlq_pending(struct ice_hw *hw, struct ice_ctl_q_info *cq)
+{
+       u16 ntu;
+
+       ntu = (u16)(rd32(hw, cq->rq.head) & cq->rq.head_mask);
+       return cq->rq.next_to_clean != ntu;
+}
+
 /**
  * ice_clean_adminq_subtask - clean the AdminQ rings
  * @pf: board private structure
@@ -923,7 +938,6 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
 static void ice_clean_adminq_subtask(struct ice_pf *pf)
 {
        struct ice_hw *hw = &pf->hw;
-       u32 val;
 
        if (!test_bit(__ICE_ADMINQ_EVENT_PENDING, pf->state))
                return;
@@ -933,9 +947,13 @@ static void ice_clean_adminq_subtask(struct ice_pf *pf)
 
        clear_bit(__ICE_ADMINQ_EVENT_PENDING, pf->state);
 
-       /* re-enable Admin queue interrupt causes */
-       val = rd32(hw, PFINT_FW_CTL);
-       wr32(hw, PFINT_FW_CTL, (val | PFINT_FW_CTL_CAUSE_ENA_M));
+       /* There might be a situation where new messages arrive to a control
+        * queue between processing the last message and clearing the
+        * EVENT_PENDING bit. So before exiting, check queue head again (using
+        * ice_ctrlq_pending) and process new messages if any.
+        */
+       if (ice_ctrlq_pending(hw, &hw->adminq))
+               __ice_clean_ctrlq(pf, ICE_CTL_Q_ADMIN);
 
        ice_flush(hw);
 }
@@ -1295,11 +1313,8 @@ static void ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt)
                qcount = numq_tc;
        }
 
-       /* find higher power-of-2 of qcount */
-       pow = ilog2(qcount);
-
-       if (!is_power_of_2(qcount))
-               pow++;
+       /* find the (rounded up) power-of-2 of qcount */
+       pow = order_base_2(qcount);
 
        for (i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) {
                if (!(vsi->tc_cfg.ena_tc & BIT(i))) {
@@ -1352,14 +1367,15 @@ static void ice_set_dflt_vsi_ctx(struct ice_vsi_ctx *ctxt)
        ctxt->info.sw_flags = ICE_AQ_VSI_SW_FLAG_SRC_PRUNE;
        /* Traffic from VSI can be sent to LAN */
        ctxt->info.sw_flags2 = ICE_AQ_VSI_SW_FLAG_LAN_ENA;
-       /* Allow all packets untagged/tagged */
-       ctxt->info.port_vlan_flags = ((ICE_AQ_VSI_PVLAN_MODE_ALL &
-                                      ICE_AQ_VSI_PVLAN_MODE_M) >>
-                                     ICE_AQ_VSI_PVLAN_MODE_S);
-       /* Show VLAN/UP from packets in Rx descriptors */
-       ctxt->info.port_vlan_flags |= ((ICE_AQ_VSI_PVLAN_EMOD_STR_BOTH &
-                                       ICE_AQ_VSI_PVLAN_EMOD_M) >>
-                                      ICE_AQ_VSI_PVLAN_EMOD_S);
+
+       /* By default bits 3 and 4 in vlan_flags are 0's which results in legacy
+        * behavior (show VLAN, DEI, and UP) in descriptor. Also, allow all
+        * packets untagged/tagged.
+        */
+       ctxt->info.vlan_flags = ((ICE_AQ_VSI_VLAN_MODE_ALL &
+                                 ICE_AQ_VSI_VLAN_MODE_M) >>
+                                ICE_AQ_VSI_VLAN_MODE_S);
+
        /* Have 1:1 UP mapping for both ingress/egress tables */
        table |= ICE_UP_TABLE_TRANSLATE(0, 0);
        table |= ICE_UP_TABLE_TRANSLATE(1, 1);
@@ -1688,15 +1704,12 @@ static void ice_ena_misc_vector(struct ice_pf *pf)
        wr32(hw, PFINT_OICR_ENA, 0);    /* disable all */
        rd32(hw, PFINT_OICR);           /* read to clear */
 
-       val = (PFINT_OICR_HLP_RDY_M |
-              PFINT_OICR_CPM_RDY_M |
-              PFINT_OICR_ECC_ERR_M |
+       val = (PFINT_OICR_ECC_ERR_M |
               PFINT_OICR_MAL_DETECT_M |
               PFINT_OICR_GRST_M |
               PFINT_OICR_PCI_EXCEPTION_M |
-              PFINT_OICR_GPIO_M |
-              PFINT_OICR_STORM_DETECT_M |
-              PFINT_OICR_HMC_ERR_M);
+              PFINT_OICR_HMC_ERR_M |
+              PFINT_OICR_PE_CRITERR_M);
 
        wr32(hw, PFINT_OICR_ENA, val);
 
@@ -2058,15 +2071,13 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
 skip_req_irq:
        ice_ena_misc_vector(pf);
 
-       val = (pf->oicr_idx & PFINT_OICR_CTL_MSIX_INDX_M) |
-             (ICE_RX_ITR & PFINT_OICR_CTL_ITR_INDX_M) |
-             PFINT_OICR_CTL_CAUSE_ENA_M;
+       val = ((pf->oicr_idx & PFINT_OICR_CTL_MSIX_INDX_M) |
+              PFINT_OICR_CTL_CAUSE_ENA_M);
        wr32(hw, PFINT_OICR_CTL, val);
 
        /* This enables Admin queue Interrupt causes */
-       val = (pf->oicr_idx & PFINT_FW_CTL_MSIX_INDX_M) |
-             (ICE_RX_ITR & PFINT_FW_CTL_ITR_INDX_M) |
-             PFINT_FW_CTL_CAUSE_ENA_M;
+       val = ((pf->oicr_idx & PFINT_FW_CTL_MSIX_INDX_M) |
+              PFINT_FW_CTL_CAUSE_ENA_M);
        wr32(hw, PFINT_FW_CTL, val);
 
        itr_gran = hw->itr_gran_200;
@@ -3246,8 +3257,10 @@ static void ice_clear_interrupt_scheme(struct ice_pf *pf)
        if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags))
                ice_dis_msix(pf);
 
-       devm_kfree(&pf->pdev->dev, pf->irq_tracker);
-       pf->irq_tracker = NULL;
+       if (pf->irq_tracker) {
+               devm_kfree(&pf->pdev->dev, pf->irq_tracker);
+               pf->irq_tracker = NULL;
+       }
 }
 
 /**
@@ -3271,7 +3284,7 @@ static int ice_probe(struct pci_dev *pdev,
 
        err = pcim_iomap_regions(pdev, BIT(ICE_BAR0), pci_name(pdev));
        if (err) {
-               dev_err(&pdev->dev, "I/O map error %d\n", err);
+               dev_err(&pdev->dev, "BAR0 I/O map error %d\n", err);
                return err;
        }
 
@@ -3720,10 +3733,10 @@ static int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi)
        enum ice_status status;
 
        /* Here we are configuring the VSI to let the driver add VLAN tags by
-        * setting port_vlan_flags to ICE_AQ_VSI_PVLAN_MODE_ALL. The actual VLAN
-        * tag insertion happens in the Tx hot path, in ice_tx_map.
+        * setting vlan_flags to ICE_AQ_VSI_VLAN_MODE_ALL. The actual VLAN tag
+        * insertion happens in the Tx hot path, in ice_tx_map.
         */
-       ctxt.info.port_vlan_flags = ICE_AQ_VSI_PVLAN_MODE_ALL;
+       ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_MODE_ALL;
 
        ctxt.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID);
        ctxt.vsi_num = vsi->vsi_num;
@@ -3735,7 +3748,7 @@ static int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi)
                return -EIO;
        }
 
-       vsi->info.port_vlan_flags = ctxt.info.port_vlan_flags;
+       vsi->info.vlan_flags = ctxt.info.vlan_flags;
        return 0;
 }
 
@@ -3757,12 +3770,15 @@ static int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena)
         */
        if (ena) {
                /* Strip VLAN tag from Rx packet and put it in the desc */
-               ctxt.info.port_vlan_flags = ICE_AQ_VSI_PVLAN_EMOD_STR_BOTH;
+               ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_STR_BOTH;
        } else {
                /* Disable stripping. Leave tag in packet */
-               ctxt.info.port_vlan_flags = ICE_AQ_VSI_PVLAN_EMOD_NOTHING;
+               ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_NOTHING;
        }
 
+       /* Allow all packets untagged/tagged */
+       ctxt.info.vlan_flags |= ICE_AQ_VSI_VLAN_MODE_ALL;
+
        ctxt.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID);
        ctxt.vsi_num = vsi->vsi_num;
 
@@ -3773,7 +3789,7 @@ static int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena)
                return -EIO;
        }
 
-       vsi->info.port_vlan_flags = ctxt.info.port_vlan_flags;
+       vsi->info.vlan_flags = ctxt.info.vlan_flags;
        return 0;
 }
 
@@ -3986,7 +4002,7 @@ static int ice_setup_rx_ctx(struct ice_ring *ring)
        /* clear the context structure first */
        memset(&rlan_ctx, 0, sizeof(rlan_ctx));
 
-       rlan_ctx.base = ring->dma >> 7;
+       rlan_ctx.base = ring->dma >> ICE_RLAN_BASE_S;
 
        rlan_ctx.qlen = ring->count;
 
@@ -4098,11 +4114,12 @@ static int ice_vsi_cfg(struct ice_vsi *vsi)
 {
        int err;
 
-       ice_set_rx_mode(vsi->netdev);
-
-       err = ice_restore_vlan(vsi);
-       if (err)
-               return err;
+       if (vsi->netdev) {
+               ice_set_rx_mode(vsi->netdev);
+               err = ice_restore_vlan(vsi);
+               if (err)
+                       return err;
+       }
 
        err = ice_vsi_cfg_txqs(vsi);
        if (!err)
@@ -4868,7 +4885,7 @@ int ice_down(struct ice_vsi *vsi)
  */
 static int ice_vsi_setup_tx_rings(struct ice_vsi *vsi)
 {
-       int i, err;
+       int i, err = 0;
 
        if (!vsi->num_txq) {
                dev_err(&vsi->back->pdev->dev, "VSI %d has 0 Tx queues\n",
@@ -4893,7 +4910,7 @@ static int ice_vsi_setup_tx_rings(struct ice_vsi *vsi)
  */
 static int ice_vsi_setup_rx_rings(struct ice_vsi *vsi)
 {
-       int i, err;
+       int i, err = 0;
 
        if (!vsi->num_rxq) {
                dev_err(&vsi->back->pdev->dev, "VSI %d has 0 Rx queues\n",
@@ -5235,7 +5252,7 @@ static int ice_change_mtu(struct net_device *netdev, int new_mtu)
        u8 count = 0;
 
        if (new_mtu == netdev->mtu) {
-               netdev_warn(netdev, "mtu is already %d\n", netdev->mtu);
+               netdev_warn(netdev, "mtu is already %u\n", netdev->mtu);
                return 0;
        }
 
index 92da0a626ce0b38395633ff90df504f8f88f40c8..295a8cd87fc16565148bf6cbb7713c02a71454f9 100644 (file)
@@ -131,9 +131,8 @@ ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data)
  *
  * This function will request NVM ownership.
  */
-static enum
-ice_status ice_acquire_nvm(struct ice_hw *hw,
-                          enum ice_aq_res_access_type access)
+static enum ice_status
+ice_acquire_nvm(struct ice_hw *hw, enum ice_aq_res_access_type access)
 {
        if (hw->nvm.blank_nvm_mode)
                return 0;
index 2e6c1d92cc8884b2bb9755483f82c421b5d9e6f1..eeae199469b6e7f17f680276bb83f77534cbe555 100644 (file)
@@ -1576,8 +1576,7 @@ ice_sched_update_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_id, u8 tc,
                        return status;
        }
 
-       if (owner == ICE_SCHED_NODE_OWNER_LAN)
-               vsi->max_lanq[tc] = new_numqs;
+       vsi->max_lanq[tc] = new_numqs;
 
        return status;
 }
index 723d15f1e90b4abbb4db585734940bfc874d4712..6b7ec2ae5ad6798818a9d5947e8071aba410ffff 100644 (file)
@@ -645,14 +645,14 @@ ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
        act |= (1 << ICE_LG_ACT_GENERIC_VALUE_S) & ICE_LG_ACT_GENERIC_VALUE_M;
        lg_act->pdata.lg_act.act[1] = cpu_to_le32(act);
 
-       act = (7 << ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_VALUE_M;
+       act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX <<
+              ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M;
 
        /* Third action Marker value */
        act |= ICE_LG_ACT_GENERIC;
        act |= (sw_marker << ICE_LG_ACT_GENERIC_VALUE_S) &
                ICE_LG_ACT_GENERIC_VALUE_M;
 
-       act |= (0 << ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_VALUE_M;
        lg_act->pdata.lg_act.act[2] = cpu_to_le32(act);
 
        /* call the fill switch rule to fill the lookup tx rx structure */
index 6f4a0d159dbfdc2bfb1fe5fbd5fa355dc5503832..9b8ec128ee31f57ea2c2498a0fa55bde139ca7b9 100644 (file)
@@ -17,7 +17,7 @@ struct ice_vsi_ctx {
        u16 vsis_unallocated;
        u16 flags;
        struct ice_aqc_vsi_props info;
-       bool alloc_from_pool;
+       u8 alloc_from_pool;
 };
 
 enum ice_sw_fwd_act_type {
@@ -94,8 +94,8 @@ struct ice_fltr_info {
        u8 qgrp_size;
 
        /* Rule creations populate these indicators basing on the switch type */
-       bool lb_en;     /* Indicate if packet can be looped back */
-       bool lan_en;    /* Indicate if packet can be forwarded to the uplink */
+       u8 lb_en;       /* Indicate if packet can be looped back */
+       u8 lan_en;      /* Indicate if packet can be forwarded to the uplink */
 };
 
 /* Bookkeeping structure to hold bitmap of VSIs corresponding to VSI list id */
index 567067b650c4129acafbea94388731f7ad315ba6..31bc998fe2006f7fa515a4b05917abdae50cb7c0 100644 (file)
@@ -143,7 +143,7 @@ struct ice_ring {
        u16 next_to_use;
        u16 next_to_clean;
 
-       bool ring_active;               /* is ring online or not */
+       u8 ring_active;                 /* is ring online or not */
 
        /* stats structs */
        struct ice_q_stats      stats;
index 99c8a9a71b5e4f433a89d575c92fcd34e59ab6ae..97c366e0ca596facaec70c7f1bb4ddc8b81e8774 100644 (file)
@@ -83,7 +83,7 @@ struct ice_link_status {
        u64 phy_type_low;
        u16 max_frame_size;
        u16 link_speed;
-       bool lse_ena;   /* Link Status Event notification */
+       u8 lse_ena;     /* Link Status Event notification */
        u8 link_info;
        u8 an_info;
        u8 ext_info;
@@ -101,7 +101,7 @@ struct ice_phy_info {
        struct ice_link_status link_info_old;
        u64 phy_type_low;
        enum ice_media_type media_type;
-       bool get_link_info;
+       u8 get_link_info;
 };
 
 /* Common HW capabilities for SW use */
@@ -167,7 +167,7 @@ struct ice_nvm_info {
        u32 oem_ver;              /* OEM version info */
        u16 sr_words;             /* Shadow RAM size in words */
        u16 ver;                  /* NVM package version */
-       bool blank_nvm_mode;      /* is NVM empty (no FW present) */
+       u8 blank_nvm_mode;        /* is NVM empty (no FW present) */
 };
 
 /* Max number of port to queue branches w.r.t topology */
@@ -181,7 +181,7 @@ struct ice_sched_node {
        struct ice_aqc_txsched_elem_data info;
        u32 agg_id;                     /* aggregator group id */
        u16 vsi_id;
-       bool in_use;                    /* suspended or in use */
+       u8 in_use;                      /* suspended or in use */
        u8 tx_sched_layer;              /* Logical Layer (1-9) */
        u8 num_children;
        u8 tc_num;
@@ -218,7 +218,7 @@ struct ice_sched_vsi_info {
 struct ice_sched_tx_policy {
        u16 max_num_vsis;
        u8 max_num_lan_qs_per_tc[ICE_MAX_TRAFFIC_CLASS];
-       bool rdma_ena;
+       u8 rdma_ena;
 };
 
 struct ice_port_info {
@@ -243,7 +243,7 @@ struct ice_port_info {
        struct list_head agg_list;      /* lists all aggregator */
        u8 lport;
 #define ICE_LPORT_MASK         0xff
-       bool is_vf;
+       u8 is_vf;
 };
 
 struct ice_switch_info {
@@ -287,7 +287,7 @@ struct ice_hw {
        u8 max_cgds;
        u8 sw_entry_point_layer;
 
-       bool evb_veb;           /* true for VEB, false for VEPA */
+       u8 evb_veb;             /* true for VEB, false for VEPA */
        struct ice_bus_info bus;
        struct ice_nvm_info nvm;
        struct ice_hw_dev_caps dev_caps;        /* device capabilities */
@@ -318,7 +318,7 @@ struct ice_hw {
        u8 itr_gran_100;
        u8 itr_gran_50;
        u8 itr_gran_25;
-       bool ucast_shared;      /* true if VSIs can share unicast addr */
+       u8 ucast_shared;        /* true if VSIs can share unicast addr */
 
 };
 
index f92f7918112de063700f12de3462a482999c8bb3..5acf3b743876a485f61002658dccba47a0ca3d59 100644 (file)
@@ -1649,7 +1649,7 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter)
        if (hw->phy.type == e1000_phy_m88)
                igb_phy_disable_receiver(adapter);
 
-       mdelay(500);
+       msleep(500);
        return 0;
 }
 
index d03c2f0d759260df50e9d71da5758912326e804f..a32c576c1e656c0102989413cad114d1d8f03771 100644 (file)
@@ -3873,7 +3873,7 @@ static int igb_sw_init(struct igb_adapter *adapter)
 
        adapter->mac_table = kcalloc(hw->mac.rar_entry_count,
                                     sizeof(struct igb_mac_addr),
-                                    GFP_ATOMIC);
+                                    GFP_KERNEL);
        if (!adapter->mac_table)
                return -ENOMEM;
 
@@ -3883,7 +3883,7 @@ static int igb_sw_init(struct igb_adapter *adapter)
 
        /* Setup and initialize a copy of the hw vlan table array */
        adapter->shadow_vfta = kcalloc(E1000_VLAN_FILTER_TBL_SIZE, sizeof(u32),
-                                      GFP_ATOMIC);
+                                      GFP_KERNEL);
        if (!adapter->shadow_vfta)
                return -ENOMEM;
 
@@ -5816,7 +5816,8 @@ static void igb_tx_csum(struct igb_ring *tx_ring, struct igb_tx_buffer *first)
 
        if (skb->ip_summed != CHECKSUM_PARTIAL) {
 csum_failed:
-               if (!(first->tx_flags & IGB_TX_FLAGS_VLAN))
+               if (!(first->tx_flags & IGB_TX_FLAGS_VLAN) &&
+                   !tx_ring->launchtime_enable)
                        return;
                goto no_csum;
        }
index 43664adf7a3c120d024889ac59f42e2da5d5b1ae..d3e72d0f66ef428b08e4bd88508e05b734bc43a4 100644 (file)
@@ -771,14 +771,13 @@ ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
        rxdr->size = rxdr->count * sizeof(struct ixgb_rx_desc);
        rxdr->size = ALIGN(rxdr->size, 4096);
 
-       rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma,
-                                       GFP_KERNEL);
+       rxdr->desc = dma_zalloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma,
+                                        GFP_KERNEL);
 
        if (!rxdr->desc) {
                vfree(rxdr->buffer_info);
                return -ENOMEM;
        }
-       memset(rxdr->desc, 0, rxdr->size);
 
        rxdr->next_to_clean = 0;
        rxdr->next_to_use = 0;
index 94b3165ff543055621326783d330da1f7b4272e7..ccd852ad62a4b109ff26ea40e7587024f8b0d198 100644 (file)
@@ -192,7 +192,7 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid,
        }
 
        /* alloc the udl from per cpu ddp pool */
-       ddp->udl = dma_pool_alloc(ddp_pool->pool, GFP_ATOMIC, &ddp->udp);
+       ddp->udl = dma_pool_alloc(ddp_pool->pool, GFP_KERNEL, &ddp->udp);
        if (!ddp->udl) {
                e_err(drv, "failed allocated ddp context\n");
                goto out_noddp_unmap;
@@ -760,7 +760,7 @@ int ixgbe_setup_fcoe_ddp_resources(struct ixgbe_adapter *adapter)
                return 0;
 
        /* Extra buffer to be shared by all DDPs for HW work around */
-       buffer = kmalloc(IXGBE_FCBUFF_MIN, GFP_ATOMIC);
+       buffer = kmalloc(IXGBE_FCBUFF_MIN, GFP_KERNEL);
        if (!buffer)
                return -ENOMEM;
 
index 447098005490926f67e5fb32f7c84b798e387eab..9a23d33a47ed52bfeb10d79d970e114ee4702d6e 100644 (file)
@@ -6201,7 +6201,7 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter,
 
        adapter->mac_table = kcalloc(hw->mac.num_rar_entries,
                                     sizeof(struct ixgbe_mac_addr),
-                                    GFP_ATOMIC);
+                                    GFP_KERNEL);
        if (!adapter->mac_table)
                return -ENOMEM;
 
@@ -6620,8 +6620,18 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
        if (adapter->xdp_prog) {
-               e_warn(probe, "MTU cannot be changed while XDP program is loaded\n");
-               return -EPERM;
+               int new_frame_size = new_mtu + ETH_HLEN + ETH_FCS_LEN +
+                                    VLAN_HLEN;
+               int i;
+
+               for (i = 0; i < adapter->num_rx_queues; i++) {
+                       struct ixgbe_ring *ring = adapter->rx_ring[i];
+
+                       if (new_frame_size > ixgbe_rx_bufsz(ring)) {
+                               e_warn(probe, "Requested MTU size is not supported with XDP\n");
+                               return -EINVAL;
+                       }
+               }
        }
 
        /*
@@ -8983,6 +8993,15 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
 
 #ifdef CONFIG_IXGBE_DCB
        if (tc) {
+               if (adapter->xdp_prog) {
+                       e_warn(probe, "DCB is not supported with XDP\n");
+
+                       ixgbe_init_interrupt_scheme(adapter);
+                       if (netif_running(dev))
+                               ixgbe_open(dev);
+                       return -EINVAL;
+               }
+
                netdev_set_num_tc(dev, tc);
                ixgbe_set_prio_tc_map(adapter);
 
@@ -9171,14 +9190,12 @@ static int parse_tc_actions(struct ixgbe_adapter *adapter,
                            struct tcf_exts *exts, u64 *action, u8 *queue)
 {
        const struct tc_action *a;
-       LIST_HEAD(actions);
+       int i;
 
        if (!tcf_exts_has_actions(exts))
                return -EINVAL;
 
-       tcf_exts_to_list(exts, &actions);
-       list_for_each_entry(a, &actions, list) {
-
+       tcf_exts_for_each_action(i, a, exts) {
                /* Drop action */
                if (is_tcf_gact_shot(a)) {
                        *action = IXGBE_FDIR_DROP_QUEUE;
@@ -9936,6 +9953,11 @@ static void *ixgbe_fwd_add(struct net_device *pdev, struct net_device *vdev)
        int tcs = adapter->hw_tcs ? : 1;
        int pool, err;
 
+       if (adapter->xdp_prog) {
+               e_warn(probe, "L2FW offload is not supported with XDP\n");
+               return ERR_PTR(-EINVAL);
+       }
+
        /* The hardware supported by ixgbe only filters on the destination MAC
         * address. In order to avoid issues we only support offloading modes
         * where the hardware can actually provide the functionality.
index 6f59933cdff7d5ff13620ced894036ddeb3052c3..3c6f01c41b788eb45730e49083f2025c7c0683f1 100644 (file)
@@ -53,6 +53,11 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
        struct ixgbe_hw *hw = &adapter->hw;
        int i;
 
+       if (adapter->xdp_prog) {
+               e_warn(probe, "SRIOV is not supported with XDP\n");
+               return -EINVAL;
+       }
+
        /* Enable VMDq flag so device will be set in VM mode */
        adapter->flags |= IXGBE_FLAG_SRIOV_ENABLED |
                          IXGBE_FLAG_VMDQ_ENABLED;
@@ -688,8 +693,13 @@ static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,
 static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
 {
        struct ixgbe_hw *hw = &adapter->hw;
+       struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ];
        struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
+       u32 q_per_pool = __ALIGN_MASK(1, ~vmdq->mask);
        u8 num_tcs = adapter->hw_tcs;
+       u32 reg_val;
+       u32 queue;
+       u32 word;
 
        /* remove VLAN filters beloning to this VF */
        ixgbe_clear_vf_vlans(adapter, vf);
@@ -726,6 +736,27 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
 
        /* reset VF api back to unknown */
        adapter->vfinfo[vf].vf_api = ixgbe_mbox_api_10;
+
+       /* Restart each queue for given VF */
+       for (queue = 0; queue < q_per_pool; queue++) {
+               unsigned int reg_idx = (vf * q_per_pool) + queue;
+
+               reg_val = IXGBE_READ_REG(hw, IXGBE_PVFTXDCTL(reg_idx));
+
+               /* Re-enabling only configured queues */
+               if (reg_val) {
+                       reg_val |= IXGBE_TXDCTL_ENABLE;
+                       IXGBE_WRITE_REG(hw, IXGBE_PVFTXDCTL(reg_idx), reg_val);
+                       reg_val &= ~IXGBE_TXDCTL_ENABLE;
+                       IXGBE_WRITE_REG(hw, IXGBE_PVFTXDCTL(reg_idx), reg_val);
+               }
+       }
+
+       /* Clear VF's mailbox memory */
+       for (word = 0; word < IXGBE_VFMAILBOX_SIZE; word++)
+               IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf), word, 0);
+
+       IXGBE_WRITE_FLUSH(hw);
 }
 
 static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
index 44cfb2021145b9be9284c3862c52abf5c5ba6f82..41bcbb337e837ff1dbeb8e6061ae92e9d050350c 100644 (file)
@@ -2518,6 +2518,7 @@ enum {
 /* Translated register #defines */
 #define IXGBE_PVFTDH(P)                (0x06010 + (0x40 * (P)))
 #define IXGBE_PVFTDT(P)                (0x06018 + (0x40 * (P)))
+#define IXGBE_PVFTXDCTL(P)     (0x06028 + (0x40 * (P)))
 #define IXGBE_PVFTDWBAL(P)     (0x06038 + (0x40 * (P)))
 #define IXGBE_PVFTDWBAH(P)     (0x0603C + (0x40 * (P)))
 
index 32d785b616e1e270f2adb47978ce3b3f172f02ac..28500417843ed3db0b7b0d53e705f7384b3341b1 100644 (file)
@@ -4803,6 +4803,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
        dev->min_mtu = ETH_MIN_MTU;
        /* 9704 == 9728 - 20 and rounding to 8 */
        dev->max_mtu = MVPP2_BM_JUMBO_PKT_SIZE;
+       dev->dev.of_node = port_node;
 
        /* Phylink isn't used w/ ACPI as of now */
        if (port_node) {
index 9131a1376e7dc540cc0238b0cf980bc54c9c19ae..9fed54017659de3b0f58a1287a7eff605c077f6c 100644 (file)
@@ -1982,14 +1982,15 @@ static bool modify_header_match_supported(struct mlx5_flow_spec *spec,
                goto out_ok;
 
        modify_ip_header = false;
-       tcf_exts_to_list(exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, exts) {
+               int k;
+
                if (!is_tcf_pedit(a))
                        continue;
 
                nkeys = tcf_pedit_nkeys(a);
-               for (i = 0; i < nkeys; i++) {
-                       htype = tcf_pedit_htype(a, i);
+               for (k = 0; k < nkeys; k++) {
+                       htype = tcf_pedit_htype(a, k);
                        if (htype == TCA_PEDIT_KEY_EX_HDR_TYPE_IP4 ||
                            htype == TCA_PEDIT_KEY_EX_HDR_TYPE_IP6) {
                                modify_ip_header = true;
@@ -2053,15 +2054,14 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
        const struct tc_action *a;
        LIST_HEAD(actions);
        u32 action = 0;
-       int err;
+       int err, i;
 
        if (!tcf_exts_has_actions(exts))
                return -EINVAL;
 
        attr->flow_tag = MLX5_FS_DEFAULT_FLOW_TAG;
 
-       tcf_exts_to_list(exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, exts) {
                if (is_tcf_gact_shot(a)) {
                        action |= MLX5_FLOW_CONTEXT_ACTION_DROP;
                        if (MLX5_CAP_FLOWTABLE(priv->mdev,
@@ -2666,7 +2666,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
        LIST_HEAD(actions);
        bool encap = false;
        u32 action = 0;
-       int err;
+       int err, i;
 
        if (!tcf_exts_has_actions(exts))
                return -EINVAL;
@@ -2674,8 +2674,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
        attr->in_rep = rpriv->rep;
        attr->in_mdev = priv->mdev;
 
-       tcf_exts_to_list(exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, exts) {
                if (is_tcf_gact_shot(a)) {
                        action |= MLX5_FLOW_CONTEXT_ACTION_DROP |
                                  MLX5_FLOW_CONTEXT_ACTION_COUNT;
index 86478a6b99c5068e13688f2556e954ee3b3f9486..c8c315eb512804033fd88723c217504007010453 100644 (file)
@@ -139,14 +139,15 @@ int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
                      struct mlx5_wq_ctrl *wq_ctrl)
 {
        u32 sq_strides_offset;
+       u32 rq_pg_remainder;
        int err;
 
        mlx5_fill_fbc(MLX5_GET(qpc, qpc, log_rq_stride) + 4,
                      MLX5_GET(qpc, qpc, log_rq_size),
                      &wq->rq.fbc);
 
-       sq_strides_offset =
-               ((wq->rq.fbc.frag_sz_m1 + 1) % PAGE_SIZE) / MLX5_SEND_WQE_BB;
+       rq_pg_remainder   = mlx5_wq_cyc_get_byte_size(&wq->rq) % PAGE_SIZE;
+       sq_strides_offset = rq_pg_remainder / MLX5_SEND_WQE_BB;
 
        mlx5_fill_fbc_offset(ilog2(MLX5_SEND_WQE_BB),
                             MLX5_GET(qpc, qpc, log_sq_size),
index 6070d1591d1e77885185fa43e261ec4a80b5ae01..930700413b1d07dd8a62ffbabf47aea995d062cf 100644 (file)
@@ -1346,8 +1346,7 @@ static int mlxsw_sp_port_add_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port,
                return -ENOMEM;
        mall_tc_entry->cookie = f->cookie;
 
-       tcf_exts_to_list(f->exts, &actions);
-       a = list_first_entry(&actions, struct tc_action, list);
+       a = tcf_exts_first_action(f->exts);
 
        if (is_tcf_mirred_egress_mirror(a) && protocol == htons(ETH_P_ALL)) {
                struct mlxsw_sp_port_mall_mirror_tc_entry *mirror;
index 3ae9301967410bca24e601e888b8b270b25c8e82..3cdb7aca90b72492f02fd4bce2c35ad6de76eaa9 100644 (file)
@@ -414,6 +414,8 @@ mlxsw_sp_netdevice_ipip_ul_event(struct mlxsw_sp *mlxsw_sp,
 void
 mlxsw_sp_port_vlan_router_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan);
 void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif);
+void mlxsw_sp_rif_destroy_by_dev(struct mlxsw_sp *mlxsw_sp,
+                                struct net_device *dev);
 
 /* spectrum_kvdl.c */
 enum mlxsw_sp_kvdl_entry_type {
index ebd1b24ebaa5dd48df775d9a0704bd81b8ed09df..8d211972c5e90fbe1a24dc32edf6f371ff018bd4 100644 (file)
@@ -21,8 +21,7 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
                                         struct netlink_ext_ack *extack)
 {
        const struct tc_action *a;
-       LIST_HEAD(actions);
-       int err;
+       int err, i;
 
        if (!tcf_exts_has_actions(exts))
                return 0;
@@ -32,8 +31,7 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
        if (err)
                return err;
 
-       tcf_exts_to_list(exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, exts) {
                if (is_tcf_gact_ok(a)) {
                        err = mlxsw_sp_acl_rulei_act_terminate(rulei);
                        if (err) {
index 3a96307f51b055e4bcf0693704118fd9d4e90995..2ab9cf25a08ae19788d28ffddaa8698ba2213152 100644 (file)
@@ -6234,6 +6234,17 @@ void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif)
        mlxsw_sp_vr_put(mlxsw_sp, vr);
 }
 
+void mlxsw_sp_rif_destroy_by_dev(struct mlxsw_sp *mlxsw_sp,
+                                struct net_device *dev)
+{
+       struct mlxsw_sp_rif *rif;
+
+       rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
+       if (!rif)
+               return;
+       mlxsw_sp_rif_destroy(rif);
+}
+
 static void
 mlxsw_sp_rif_subport_params_init(struct mlxsw_sp_rif_params *params,
                                 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
index 0d8444aaba01ae7e5eddc58ef7dbc87ee5d1cb7b..db715da7bab7746c58ed23b48048d8a4917ca10d 100644 (file)
@@ -127,6 +127,24 @@ bool mlxsw_sp_bridge_device_is_offloaded(const struct mlxsw_sp *mlxsw_sp,
        return !!mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev);
 }
 
+static int mlxsw_sp_bridge_device_upper_rif_destroy(struct net_device *dev,
+                                                   void *data)
+{
+       struct mlxsw_sp *mlxsw_sp = data;
+
+       mlxsw_sp_rif_destroy_by_dev(mlxsw_sp, dev);
+       return 0;
+}
+
+static void mlxsw_sp_bridge_device_rifs_destroy(struct mlxsw_sp *mlxsw_sp,
+                                               struct net_device *dev)
+{
+       mlxsw_sp_rif_destroy_by_dev(mlxsw_sp, dev);
+       netdev_walk_all_upper_dev_rcu(dev,
+                                     mlxsw_sp_bridge_device_upper_rif_destroy,
+                                     mlxsw_sp);
+}
+
 static struct mlxsw_sp_bridge_device *
 mlxsw_sp_bridge_device_create(struct mlxsw_sp_bridge *bridge,
                              struct net_device *br_dev)
@@ -165,6 +183,8 @@ static void
 mlxsw_sp_bridge_device_destroy(struct mlxsw_sp_bridge *bridge,
                               struct mlxsw_sp_bridge_device *bridge_device)
 {
+       mlxsw_sp_bridge_device_rifs_destroy(bridge->mlxsw_sp,
+                                           bridge_device->dev);
        list_del(&bridge_device->list);
        if (bridge_device->vlan_enabled)
                bridge->vlan_enabled_exists = false;
index 0ba0356ec4e6dcd47977436bfe228891c0114b55..9044496803e627e8a992fbcac23eb8e0201e1e76 100644 (file)
@@ -796,11 +796,10 @@ int nfp_flower_compile_action(struct nfp_app *app,
                              struct net_device *netdev,
                              struct nfp_fl_payload *nfp_flow)
 {
-       int act_len, act_cnt, err, tun_out_cnt, out_cnt;
+       int act_len, act_cnt, err, tun_out_cnt, out_cnt, i;
        enum nfp_flower_tun_type tun_type;
        const struct tc_action *a;
        u32 csum_updated = 0;
-       LIST_HEAD(actions);
 
        memset(nfp_flow->action_data, 0, NFP_FL_MAX_A_SIZ);
        nfp_flow->meta.act_len = 0;
@@ -810,8 +809,7 @@ int nfp_flower_compile_action(struct nfp_app *app,
        tun_out_cnt = 0;
        out_cnt = 0;
 
-       tcf_exts_to_list(flow->exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, flow->exts) {
                err = nfp_flower_loop_action(app, a, flow, nfp_flow, &act_len,
                                             netdev, &tun_type, &tun_out_cnt,
                                             &out_cnt, &csum_updated);
index a8b9fbab5f73391eaf20f10afb2c70f44ad44d29..253bdaef150557a7e20ded3de921021a051a9ca7 100644 (file)
@@ -229,29 +229,16 @@ done:
        spin_unlock_bh(&nn->reconfig_lock);
 }
 
-/**
- * nfp_net_reconfig() - Reconfigure the firmware
- * @nn:      NFP Net device to reconfigure
- * @update:  The value for the update field in the BAR config
- *
- * Write the update word to the BAR and ping the reconfig queue.  The
- * poll until the firmware has acknowledged the update by zeroing the
- * update word.
- *
- * Return: Negative errno on error, 0 on success
- */
-int nfp_net_reconfig(struct nfp_net *nn, u32 update)
+static void nfp_net_reconfig_sync_enter(struct nfp_net *nn)
 {
        bool cancelled_timer = false;
        u32 pre_posted_requests;
-       int ret;
 
        spin_lock_bh(&nn->reconfig_lock);
 
        nn->reconfig_sync_present = true;
 
        if (nn->reconfig_timer_active) {
-               del_timer(&nn->reconfig_timer);
                nn->reconfig_timer_active = false;
                cancelled_timer = true;
        }
@@ -260,14 +247,43 @@ int nfp_net_reconfig(struct nfp_net *nn, u32 update)
 
        spin_unlock_bh(&nn->reconfig_lock);
 
-       if (cancelled_timer)
+       if (cancelled_timer) {
+               del_timer_sync(&nn->reconfig_timer);
                nfp_net_reconfig_wait(nn, nn->reconfig_timer.expires);
+       }
 
        /* Run the posted reconfigs which were issued before we started */
        if (pre_posted_requests) {
                nfp_net_reconfig_start(nn, pre_posted_requests);
                nfp_net_reconfig_wait(nn, jiffies + HZ * NFP_NET_POLL_TIMEOUT);
        }
+}
+
+static void nfp_net_reconfig_wait_posted(struct nfp_net *nn)
+{
+       nfp_net_reconfig_sync_enter(nn);
+
+       spin_lock_bh(&nn->reconfig_lock);
+       nn->reconfig_sync_present = false;
+       spin_unlock_bh(&nn->reconfig_lock);
+}
+
+/**
+ * nfp_net_reconfig() - Reconfigure the firmware
+ * @nn:      NFP Net device to reconfigure
+ * @update:  The value for the update field in the BAR config
+ *
+ * Write the update word to the BAR and ping the reconfig queue.  The
+ * poll until the firmware has acknowledged the update by zeroing the
+ * update word.
+ *
+ * Return: Negative errno on error, 0 on success
+ */
+int nfp_net_reconfig(struct nfp_net *nn, u32 update)
+{
+       int ret;
+
+       nfp_net_reconfig_sync_enter(nn);
 
        nfp_net_reconfig_start(nn, update);
        ret = nfp_net_reconfig_wait(nn, jiffies + HZ * NFP_NET_POLL_TIMEOUT);
@@ -3633,6 +3649,7 @@ struct nfp_net *nfp_net_alloc(struct pci_dev *pdev, bool needs_netdev,
  */
 void nfp_net_free(struct nfp_net *nn)
 {
+       WARN_ON(timer_pending(&nn->reconfig_timer) || nn->reconfig_posted);
        if (nn->dp.netdev)
                free_netdev(nn->dp.netdev);
        else
@@ -3920,4 +3937,5 @@ void nfp_net_clean(struct nfp_net *nn)
                return;
 
        unregister_netdev(nn->dp.netdev);
+       nfp_net_reconfig_wait_posted(nn);
 }
index d9ab5add27a8bf06af92247b60158e6de2e316be..34193c2f169961a37617b84e675ee78df473d085 100644 (file)
@@ -407,7 +407,7 @@ static void qed_init_cmd_rd(struct qed_hwfn *p_hwfn,
 
        if (i == QED_INIT_MAX_POLL_COUNT) {
                DP_ERR(p_hwfn,
-                      "Timeout when polling reg: 0x%08x [ Waiting-for: %08x Got: %08x (comparsion %08x)]\n",
+                      "Timeout when polling reg: 0x%08x [ Waiting-for: %08x Got: %08x (comparison %08x)]\n",
                       addr, le32_to_cpu(cmd->expected_val),
                       val, le32_to_cpu(cmd->op_data));
        }
index d89a0e22f6e4307896cae0383889c7b5b8f05c22..5d37ec7e9b0b7b2bc3785ec00ce2e23314b7c955 100644 (file)
@@ -48,7 +48,7 @@
 #include "qed_reg_addr.h"
 #include "qed_sriov.h"
 
-#define CHIP_MCP_RESP_ITER_US 10
+#define QED_MCP_RESP_ITER_US   10
 
 #define QED_DRV_MB_MAX_RETRIES (500 * 1000)    /* Account for 5 sec */
 #define QED_MCP_RESET_RETRIES  (50 * 1000)     /* Account for 500 msec */
@@ -183,18 +183,57 @@ int qed_mcp_free(struct qed_hwfn *p_hwfn)
        return 0;
 }
 
+/* Maximum of 1 sec to wait for the SHMEM ready indication */
+#define QED_MCP_SHMEM_RDY_MAX_RETRIES  20
+#define QED_MCP_SHMEM_RDY_ITER_MS      50
+
 static int qed_load_mcp_offsets(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 {
        struct qed_mcp_info *p_info = p_hwfn->mcp_info;
+       u8 cnt = QED_MCP_SHMEM_RDY_MAX_RETRIES;
+       u8 msec = QED_MCP_SHMEM_RDY_ITER_MS;
        u32 drv_mb_offsize, mfw_mb_offsize;
        u32 mcp_pf_id = MCP_PF_ID(p_hwfn);
 
        p_info->public_base = qed_rd(p_hwfn, p_ptt, MISC_REG_SHARED_MEM_ADDR);
-       if (!p_info->public_base)
-               return 0;
+       if (!p_info->public_base) {
+               DP_NOTICE(p_hwfn,
+                         "The address of the MCP scratch-pad is not configured\n");
+               return -EINVAL;
+       }
 
        p_info->public_base |= GRCBASE_MCP;
 
+       /* Get the MFW MB address and number of supported messages */
+       mfw_mb_offsize = qed_rd(p_hwfn, p_ptt,
+                               SECTION_OFFSIZE_ADDR(p_info->public_base,
+                                                    PUBLIC_MFW_MB));
+       p_info->mfw_mb_addr = SECTION_ADDR(mfw_mb_offsize, mcp_pf_id);
+       p_info->mfw_mb_length = (u16)qed_rd(p_hwfn, p_ptt,
+                                           p_info->mfw_mb_addr +
+                                           offsetof(struct public_mfw_mb,
+                                                    sup_msgs));
+
+       /* The driver can notify that there was an MCP reset, and might read the
+        * SHMEM values before the MFW has completed initializing them.
+        * To avoid this, the "sup_msgs" field in the MFW mailbox is used as a
+        * data ready indication.
+        */
+       while (!p_info->mfw_mb_length && --cnt) {
+               msleep(msec);
+               p_info->mfw_mb_length =
+                       (u16)qed_rd(p_hwfn, p_ptt,
+                                   p_info->mfw_mb_addr +
+                                   offsetof(struct public_mfw_mb, sup_msgs));
+       }
+
+       if (!cnt) {
+               DP_NOTICE(p_hwfn,
+                         "Failed to get the SHMEM ready notification after %d msec\n",
+                         QED_MCP_SHMEM_RDY_MAX_RETRIES * msec);
+               return -EBUSY;
+       }
+
        /* Calculate the driver and MFW mailbox address */
        drv_mb_offsize = qed_rd(p_hwfn, p_ptt,
                                SECTION_OFFSIZE_ADDR(p_info->public_base,
@@ -204,13 +243,6 @@ static int qed_load_mcp_offsets(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
                   "drv_mb_offsiz = 0x%x, drv_mb_addr = 0x%x mcp_pf_id = 0x%x\n",
                   drv_mb_offsize, p_info->drv_mb_addr, mcp_pf_id);
 
-       /* Set the MFW MB address */
-       mfw_mb_offsize = qed_rd(p_hwfn, p_ptt,
-                               SECTION_OFFSIZE_ADDR(p_info->public_base,
-                                                    PUBLIC_MFW_MB));
-       p_info->mfw_mb_addr = SECTION_ADDR(mfw_mb_offsize, mcp_pf_id);
-       p_info->mfw_mb_length = (u16)qed_rd(p_hwfn, p_ptt, p_info->mfw_mb_addr);
-
        /* Get the current driver mailbox sequence before sending
         * the first command
         */
@@ -285,9 +317,15 @@ static void qed_mcp_reread_offsets(struct qed_hwfn *p_hwfn,
 
 int qed_mcp_reset(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 {
-       u32 org_mcp_reset_seq, seq, delay = CHIP_MCP_RESP_ITER_US, cnt = 0;
+       u32 org_mcp_reset_seq, seq, delay = QED_MCP_RESP_ITER_US, cnt = 0;
        int rc = 0;
 
+       if (p_hwfn->mcp_info->b_block_cmd) {
+               DP_NOTICE(p_hwfn,
+                         "The MFW is not responsive. Avoid sending MCP_RESET mailbox command.\n");
+               return -EBUSY;
+       }
+
        /* Ensure that only a single thread is accessing the mailbox */
        spin_lock_bh(&p_hwfn->mcp_info->cmd_lock);
 
@@ -413,14 +451,41 @@ static void __qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
                   (p_mb_params->cmd | seq_num), p_mb_params->param);
 }
 
+static void qed_mcp_cmd_set_blocking(struct qed_hwfn *p_hwfn, bool block_cmd)
+{
+       p_hwfn->mcp_info->b_block_cmd = block_cmd;
+
+       DP_INFO(p_hwfn, "%s sending of mailbox commands to the MFW\n",
+               block_cmd ? "Block" : "Unblock");
+}
+
+static void qed_mcp_print_cpu_info(struct qed_hwfn *p_hwfn,
+                                  struct qed_ptt *p_ptt)
+{
+       u32 cpu_mode, cpu_state, cpu_pc_0, cpu_pc_1, cpu_pc_2;
+       u32 delay = QED_MCP_RESP_ITER_US;
+
+       cpu_mode = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_MODE);
+       cpu_state = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_STATE);
+       cpu_pc_0 = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_PROGRAM_COUNTER);
+       udelay(delay);
+       cpu_pc_1 = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_PROGRAM_COUNTER);
+       udelay(delay);
+       cpu_pc_2 = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_PROGRAM_COUNTER);
+
+       DP_NOTICE(p_hwfn,
+                 "MCP CPU info: mode 0x%08x, state 0x%08x, pc {0x%08x, 0x%08x, 0x%08x}\n",
+                 cpu_mode, cpu_state, cpu_pc_0, cpu_pc_1, cpu_pc_2);
+}
+
 static int
 _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
                       struct qed_ptt *p_ptt,
                       struct qed_mcp_mb_params *p_mb_params,
-                      u32 max_retries, u32 delay)
+                      u32 max_retries, u32 usecs)
 {
+       u32 cnt = 0, msecs = DIV_ROUND_UP(usecs, 1000);
        struct qed_mcp_cmd_elem *p_cmd_elem;
-       u32 cnt = 0;
        u16 seq_num;
        int rc = 0;
 
@@ -443,7 +508,11 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
                        goto err;
 
                spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock);
-               udelay(delay);
+
+               if (QED_MB_FLAGS_IS_SET(p_mb_params, CAN_SLEEP))
+                       msleep(msecs);
+               else
+                       udelay(usecs);
        } while (++cnt < max_retries);
 
        if (cnt >= max_retries) {
@@ -472,7 +541,11 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
                 * The spinlock stays locked until the list element is removed.
                 */
 
-               udelay(delay);
+               if (QED_MB_FLAGS_IS_SET(p_mb_params, CAN_SLEEP))
+                       msleep(msecs);
+               else
+                       udelay(usecs);
+
                spin_lock_bh(&p_hwfn->mcp_info->cmd_lock);
 
                if (p_cmd_elem->b_is_completed)
@@ -491,11 +564,15 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
                DP_NOTICE(p_hwfn,
                          "The MFW failed to respond to command 0x%08x [param 0x%08x].\n",
                          p_mb_params->cmd, p_mb_params->param);
+               qed_mcp_print_cpu_info(p_hwfn, p_ptt);
 
                spin_lock_bh(&p_hwfn->mcp_info->cmd_lock);
                qed_mcp_cmd_del_elem(p_hwfn, p_cmd_elem);
                spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock);
 
+               if (!QED_MB_FLAGS_IS_SET(p_mb_params, AVOID_BLOCK))
+                       qed_mcp_cmd_set_blocking(p_hwfn, true);
+
                return -EAGAIN;
        }
 
@@ -507,7 +584,7 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
                   "MFW mailbox: response 0x%08x param 0x%08x [after %d.%03d ms]\n",
                   p_mb_params->mcp_resp,
                   p_mb_params->mcp_param,
-                  (cnt * delay) / 1000, (cnt * delay) % 1000);
+                  (cnt * usecs) / 1000, (cnt * usecs) % 1000);
 
        /* Clear the sequence number from the MFW response */
        p_mb_params->mcp_resp &= FW_MSG_CODE_MASK;
@@ -525,7 +602,7 @@ static int qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
 {
        size_t union_data_size = sizeof(union drv_union_data);
        u32 max_retries = QED_DRV_MB_MAX_RETRIES;
-       u32 delay = CHIP_MCP_RESP_ITER_US;
+       u32 usecs = QED_MCP_RESP_ITER_US;
 
        /* MCP not initialized */
        if (!qed_mcp_is_init(p_hwfn)) {
@@ -533,6 +610,13 @@ static int qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
                return -EBUSY;
        }
 
+       if (p_hwfn->mcp_info->b_block_cmd) {
+               DP_NOTICE(p_hwfn,
+                         "The MFW is not responsive. Avoid sending mailbox command 0x%08x [param 0x%08x].\n",
+                         p_mb_params->cmd, p_mb_params->param);
+               return -EBUSY;
+       }
+
        if (p_mb_params->data_src_size > union_data_size ||
            p_mb_params->data_dst_size > union_data_size) {
                DP_ERR(p_hwfn,
@@ -542,8 +626,13 @@ static int qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn,
                return -EINVAL;
        }
 
+       if (QED_MB_FLAGS_IS_SET(p_mb_params, CAN_SLEEP)) {
+               max_retries = DIV_ROUND_UP(max_retries, 1000);
+               usecs *= 1000;
+       }
+
        return _qed_mcp_cmd_and_union(p_hwfn, p_ptt, p_mb_params, max_retries,
-                                     delay);
+                                     usecs);
 }
 
 int qed_mcp_cmd(struct qed_hwfn *p_hwfn,
@@ -761,6 +850,7 @@ __qed_mcp_load_req(struct qed_hwfn *p_hwfn,
        mb_params.data_src_size = sizeof(load_req);
        mb_params.p_data_dst = &load_rsp;
        mb_params.data_dst_size = sizeof(load_rsp);
+       mb_params.flags = QED_MB_FLAG_CAN_SLEEP | QED_MB_FLAG_AVOID_BLOCK;
 
        DP_VERBOSE(p_hwfn, QED_MSG_SP,
                   "Load Request: param 0x%08x [init_hw %d, drv_type %d, hsi_ver %d, pda 0x%04x]\n",
@@ -982,7 +1072,8 @@ int qed_mcp_load_req(struct qed_hwfn *p_hwfn,
 
 int qed_mcp_unload_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 {
-       u32 wol_param, mcp_resp, mcp_param;
+       struct qed_mcp_mb_params mb_params;
+       u32 wol_param;
 
        switch (p_hwfn->cdev->wol_config) {
        case QED_OV_WOL_DISABLED:
@@ -1000,8 +1091,12 @@ int qed_mcp_unload_req(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
                wol_param = DRV_MB_PARAM_UNLOAD_WOL_MCP;
        }
 
-       return qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_UNLOAD_REQ, wol_param,
-                          &mcp_resp, &mcp_param);
+       memset(&mb_params, 0, sizeof(mb_params));
+       mb_params.cmd = DRV_MSG_CODE_UNLOAD_REQ;
+       mb_params.param = wol_param;
+       mb_params.flags = QED_MB_FLAG_CAN_SLEEP | QED_MB_FLAG_AVOID_BLOCK;
+
+       return qed_mcp_cmd_and_union(p_hwfn, p_ptt, &mb_params);
 }
 
 int qed_mcp_unload_done(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
@@ -2077,31 +2172,65 @@ qed_mcp_send_drv_version(struct qed_hwfn *p_hwfn,
        return rc;
 }
 
+/* A maximal 100 msec waiting time for the MCP to halt */
+#define QED_MCP_HALT_SLEEP_MS          10
+#define QED_MCP_HALT_MAX_RETRIES       10
+
 int qed_mcp_halt(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 {
-       u32 resp = 0, param = 0;
+       u32 resp = 0, param = 0, cpu_state, cnt = 0;
        int rc;
 
        rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_MCP_HALT, 0, &resp,
                         &param);
-       if (rc)
+       if (rc) {
                DP_ERR(p_hwfn, "MCP response failure, aborting\n");
+               return rc;
+       }
 
-       return rc;
+       do {
+               msleep(QED_MCP_HALT_SLEEP_MS);
+               cpu_state = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_STATE);
+               if (cpu_state & MCP_REG_CPU_STATE_SOFT_HALTED)
+                       break;
+       } while (++cnt < QED_MCP_HALT_MAX_RETRIES);
+
+       if (cnt == QED_MCP_HALT_MAX_RETRIES) {
+               DP_NOTICE(p_hwfn,
+                         "Failed to halt the MCP [CPU_MODE = 0x%08x, CPU_STATE = 0x%08x]\n",
+                         qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_MODE), cpu_state);
+               return -EBUSY;
+       }
+
+       qed_mcp_cmd_set_blocking(p_hwfn, true);
+
+       return 0;
 }
 
+#define QED_MCP_RESUME_SLEEP_MS        10
+
 int qed_mcp_resume(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 {
-       u32 value, cpu_mode;
+       u32 cpu_mode, cpu_state;
 
        qed_wr(p_hwfn, p_ptt, MCP_REG_CPU_STATE, 0xffffffff);
 
-       value = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_MODE);
-       value &= ~MCP_REG_CPU_MODE_SOFT_HALT;
-       qed_wr(p_hwfn, p_ptt, MCP_REG_CPU_MODE, value);
        cpu_mode = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_MODE);
+       cpu_mode &= ~MCP_REG_CPU_MODE_SOFT_HALT;
+       qed_wr(p_hwfn, p_ptt, MCP_REG_CPU_MODE, cpu_mode);
+       msleep(QED_MCP_RESUME_SLEEP_MS);
+       cpu_state = qed_rd(p_hwfn, p_ptt, MCP_REG_CPU_STATE);
 
-       return (cpu_mode & MCP_REG_CPU_MODE_SOFT_HALT) ? -EAGAIN : 0;
+       if (cpu_state & MCP_REG_CPU_STATE_SOFT_HALTED) {
+               DP_NOTICE(p_hwfn,
+                         "Failed to resume the MCP [CPU_MODE = 0x%08x, CPU_STATE = 0x%08x]\n",
+                         cpu_mode, cpu_state);
+               return -EBUSY;
+       }
+
+       qed_mcp_cmd_set_blocking(p_hwfn, false);
+
+       return 0;
 }
 
 int qed_mcp_ov_update_current_config(struct qed_hwfn *p_hwfn,
index 047976d5c6e962e19323bd5fb6ce99abbd92aa2e..85e6b3989e7a913c7157f27ff27469e6cbf1f3aa 100644 (file)
@@ -635,11 +635,14 @@ struct qed_mcp_info {
         */
        spinlock_t                              cmd_lock;
 
+       /* Flag to indicate whether sending a MFW mailbox command is blocked */
+       bool                                    b_block_cmd;
+
        /* Spinlock used for syncing SW link-changes and link-changes
         * originating from attention context.
         */
        spinlock_t                              link_lock;
-       bool                                    block_mb_sending;
+
        u32                                     public_base;
        u32                                     drv_mb_addr;
        u32                                     mfw_mb_addr;
@@ -660,14 +663,20 @@ struct qed_mcp_info {
 };
 
 struct qed_mcp_mb_params {
-       u32                     cmd;
-       u32                     param;
-       void                    *p_data_src;
-       u8                      data_src_size;
-       void                    *p_data_dst;
-       u8                      data_dst_size;
-       u32                     mcp_resp;
-       u32                     mcp_param;
+       u32 cmd;
+       u32 param;
+       void *p_data_src;
+       void *p_data_dst;
+       u8 data_src_size;
+       u8 data_dst_size;
+       u32 mcp_resp;
+       u32 mcp_param;
+       u32 flags;
+#define QED_MB_FLAG_CAN_SLEEP  (0x1 << 0)
+#define QED_MB_FLAG_AVOID_BLOCK        (0x1 << 1)
+#define QED_MB_FLAGS_IS_SET(params, flag) \
+       ({ typeof(params) __params = (params); \
+          (__params && (__params->flags & QED_MB_FLAG_ ## flag)); })
 };
 
 struct qed_drv_tlv_hdr {
index d8ad2dcad8d5ef589252eb797556359ebe89fbcb..f736f70956fd3763f3f94bffa0e009dec28b9516 100644 (file)
        0
 #define MCP_REG_CPU_STATE \
        0xe05004UL
+#define MCP_REG_CPU_STATE_SOFT_HALTED  (0x1UL << 10)
 #define MCP_REG_CPU_EVENT_MASK \
        0xe05008UL
+#define MCP_REG_CPU_PROGRAM_COUNTER    0xe0501cUL
 #define PGLUE_B_REG_PF_BAR0_SIZE \
        0x2aae60UL
 #define PGLUE_B_REG_PF_BAR1_SIZE \
index 9673d19308e65c37a7ad42e5752ac9f8238b7d4f..b16ce7d93caff5802e41b79ecb8e8b8e5fc78ed5 100644 (file)
@@ -2006,18 +2006,16 @@ unlock:
 static int qede_parse_actions(struct qede_dev *edev,
                              struct tcf_exts *exts)
 {
-       int rc = -EINVAL, num_act = 0;
+       int rc = -EINVAL, num_act = 0, i;
        const struct tc_action *a;
        bool is_drop = false;
-       LIST_HEAD(actions);
 
        if (!tcf_exts_has_actions(exts)) {
                DP_NOTICE(edev, "No tc actions received\n");
                return rc;
        }
 
-       tcf_exts_to_list(exts, &actions);
-       list_for_each_entry(a, &actions, list) {
+       tcf_exts_for_each_action(i, a, exts) {
                num_act++;
 
                if (is_tcf_gact_shot(a))
index 353f1c129af1e247e1a8ddaa6d316edfc285682d..059ba9429e51a3193f3af73c16a20ce94ef42844 100644 (file)
@@ -2384,26 +2384,20 @@ static int qlge_update_hw_vlan_features(struct net_device *ndev,
        return status;
 }
 
-static netdev_features_t qlge_fix_features(struct net_device *ndev,
-       netdev_features_t features)
-{
-       int err;
-
-       /* Update the behavior of vlan accel in the adapter */
-       err = qlge_update_hw_vlan_features(ndev, features);
-       if (err)
-               return err;
-
-       return features;
-}
-
 static int qlge_set_features(struct net_device *ndev,
        netdev_features_t features)
 {
        netdev_features_t changed = ndev->features ^ features;
+       int err;
+
+       if (changed & NETIF_F_HW_VLAN_CTAG_RX) {
+               /* Update the behavior of vlan accel in the adapter */
+               err = qlge_update_hw_vlan_features(ndev, features);
+               if (err)
+                       return err;
 
-       if (changed & NETIF_F_HW_VLAN_CTAG_RX)
                qlge_vlan_mode(ndev, features);
+       }
 
        return 0;
 }
@@ -4719,7 +4713,6 @@ static const struct net_device_ops qlge_netdev_ops = {
        .ndo_set_mac_address    = qlge_set_mac_address,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_tx_timeout         = qlge_tx_timeout,
-       .ndo_fix_features       = qlge_fix_features,
        .ndo_set_features       = qlge_set_features,
        .ndo_vlan_rx_add_vid    = qlge_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = qlge_vlan_rx_kill_vid,
index 0efa977c422dd5a32a8a241a5c32b6fc2cd71664..b08d51bf7a20482cece8df7c95e6e861cfbffe4f 100644 (file)
@@ -218,6 +218,7 @@ static const struct pci_device_id rtl8169_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK,     0x8161), 0, 0, RTL_CFG_1 },
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK,     0x8167), 0, 0, RTL_CFG_0 },
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK,     0x8168), 0, 0, RTL_CFG_1 },
+       { PCI_DEVICE(PCI_VENDOR_ID_NCUBE,       0x8168), 0, 0, RTL_CFG_1 },
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK,     0x8169), 0, 0, RTL_CFG_0 },
        { PCI_VENDOR_ID_DLINK,                  0x4300,
                PCI_VENDOR_ID_DLINK, 0x4b10,             0, 0, RTL_CFG_1 },
@@ -4522,7 +4523,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
        rtl_hw_reset(tp);
 }
 
-static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp)
+static void rtl_set_tx_config_registers(struct rtl8169_private *tp)
 {
        /* Set DMA burst size and Interframe Gap Time */
        RTL_W32(tp, TxConfig, (TX_DMA_BURST << TxDMAShift) |
@@ -4633,12 +4634,14 @@ static void rtl_hw_start(struct  rtl8169_private *tp)
 
        rtl_set_rx_max_size(tp);
        rtl_set_rx_tx_desc_registers(tp);
-       rtl_set_rx_tx_config_registers(tp);
+       rtl_set_tx_config_registers(tp);
        RTL_W8(tp, Cfg9346, Cfg9346_Lock);
 
        /* Initially a 10 us delay. Turned it into a PCI commit. - FR */
        RTL_R8(tp, IntrMask);
        RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb);
+       rtl_init_rxcfg(tp);
+
        rtl_set_rx_mode(tp->dev);
        /* no early-rx interrupts */
        RTL_W16(tp, MultiIntr, RTL_R16(tp, MultiIntr) & 0xf000);
index b81f4faf7b10114df1f17a0c0d80881e8ea9c5ea..1470fc12282b255181838457ff6a07a362e3e321 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /* Renesas Ethernet AVB device driver
  *
  * Copyright (C) 2014-2015 Renesas Electronics Corporation
@@ -5,10 +6,6 @@
  * Copyright (C) 2015-2016 Cogent Embedded, Inc. <source@cogentembedded.com>
  *
  * Based on the SuperH Ethernet driver
- *
- * 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.
  */
 
 #ifndef __RAVB_H__
index c06f2df895c2c3e432fc8341f15cc77b0550db11..aff5516b781e27067efc9c1cca19f11bea19dd19 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /* Renesas Ethernet AVB device driver
  *
  * Copyright (C) 2014-2015 Renesas Electronics Corporation
@@ -5,10 +6,6 @@
  * Copyright (C) 2015-2016 Cogent Embedded, Inc. <source@cogentembedded.com>
  *
  * Based on the SuperH Ethernet driver
- *
- * 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.
  */
 
 #include <linux/cache.h>
index 5573199c4536c283164351ca17d4377ad5a6c6a2..f27a0dc8c56331db3f7063c251333b04716f0365 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*  SuperH Ethernet device driver
  *
  *  Copyright (C) 2014 Renesas Electronics Corporation
@@ -5,18 +6,6 @@
  *  Copyright (C) 2008-2014 Renesas Solutions Corp.
  *  Copyright (C) 2013-2017 Cogent Embedded, Inc.
  *  Copyright (C) 2014 Codethink Limited
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms and conditions of the GNU General Public License,
- *  version 2, as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- *  more details.
- *
- *  The full GNU General Public License is included in this distribution in
- *  the file called "COPYING".
  */
 
 #include <linux/module.h>
@@ -809,6 +798,41 @@ static struct sh_eth_cpu_data r8a77980_data = {
        .magic          = 1,
        .cexcr          = 1,
 };
+
+/* R7S9210 */
+static struct sh_eth_cpu_data r7s9210_data = {
+       .soft_reset     = sh_eth_soft_reset,
+
+       .set_duplex     = sh_eth_set_duplex,
+       .set_rate       = sh_eth_set_rate_rcar,
+
+       .register_type  = SH_ETH_REG_FAST_SH4,
+
+       .edtrr_trns     = EDTRR_TRNS_ETHER,
+       .ecsr_value     = ECSR_ICD,
+       .ecsipr_value   = ECSIPR_ICDIP,
+       .eesipr_value   = EESIPR_TWBIP | EESIPR_TABTIP | EESIPR_RABTIP |
+                         EESIPR_RFCOFIP | EESIPR_ECIIP | EESIPR_FTCIP |
+                         EESIPR_TDEIP | EESIPR_TFUFIP | EESIPR_FRIP |
+                         EESIPR_RDEIP | EESIPR_RFOFIP | EESIPR_CNDIP |
+                         EESIPR_DLCIP | EESIPR_CDIP | EESIPR_TROIP |
+                         EESIPR_RMAFIP | EESIPR_RRFIP | EESIPR_RTLFIP |
+                         EESIPR_RTSFIP | EESIPR_PREIP | EESIPR_CERFIP,
+
+       .tx_check       = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_TRO,
+       .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
+                         EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE,
+
+       .fdr_value      = 0x0000070f,
+
+       .apr            = 1,
+       .mpr            = 1,
+       .tpauser        = 1,
+       .hw_swap        = 1,
+       .rpadir         = 1,
+       .no_ade         = 1,
+       .xdfar_rw       = 1,
+};
 #endif /* CONFIG_OF */
 
 static void sh_eth_set_rate_sh7724(struct net_device *ndev)
@@ -3132,6 +3156,7 @@ static const struct of_device_id sh_eth_match_table[] = {
        { .compatible = "renesas,ether-r8a7794", .data = &rcar_gen2_data },
        { .compatible = "renesas,gether-r8a77980", .data = &r8a77980_data },
        { .compatible = "renesas,ether-r7s72100", .data = &r7s72100_data },
+       { .compatible = "renesas,ether-r7s9210", .data = &r7s9210_data },
        { .compatible = "renesas,rcar-gen1-ether", .data = &rcar_gen1_data },
        { .compatible = "renesas,rcar-gen2-ether", .data = &rcar_gen2_data },
        { }
index f94be99cf4002190347014d7643387883556981a..0c18650bbfe69f7c22a78a87b1c263bd4f2e15e5 100644 (file)
@@ -1,19 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*  SuperH Ethernet device driver
  *
  *  Copyright (C) 2006-2012 Nobuhiro Iwamatsu
  *  Copyright (C) 2008-2012 Renesas Solutions Corp.
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms and conditions of the GNU General Public License,
- *  version 2, as published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- *  more details.
- *
- *  The full GNU General Public License is included in this distribution in
- *  the file called "COPYING".
  */
 
 #ifndef __SH_ETH_H__
index 05157442a9807f41c3ac45ba6fc7f74e37bba95a..b1b53f6c452f5267f8af304bf42bf68b0238703a 100644 (file)
@@ -74,7 +74,6 @@ static const char version[] =
 #include <linux/skbuff.h>
 
 #include <linux/dmaengine.h>
-#include <linux/dma/pxa-dma.h>
 
 #include <asm/io.h>
 
@@ -1795,7 +1794,6 @@ static int smc911x_probe(struct net_device *dev)
 #ifdef SMC_USE_DMA
        struct dma_slave_config config;
        dma_cap_mask_t mask;
-       struct pxad_param param;
 #endif
 
        DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
@@ -1971,15 +1969,8 @@ static int smc911x_probe(struct net_device *dev)
 
        dma_cap_zero(mask);
        dma_cap_set(DMA_SLAVE, mask);
-       param.prio = PXAD_PRIO_LOWEST;
-       param.drcmr = -1UL;
-
-       lp->rxdma =
-               dma_request_slave_channel_compat(mask, pxad_filter_fn,
-                                                &param, &dev->dev, "rx");
-       lp->txdma =
-               dma_request_slave_channel_compat(mask, pxad_filter_fn,
-                                                &param, &dev->dev, "tx");
+       lp->rxdma = dma_request_channel(mask, NULL, NULL);
+       lp->txdma = dma_request_channel(mask, NULL, NULL);
        lp->rxdma_active = 0;
        lp->txdma_active = 0;
 
index 0804287628584ec24faa12a827f179a346cae0cb..b944828f9ea3ddfba9849ba0b1c6e66243cd8b78 100644 (file)
@@ -2019,17 +2019,10 @@ static int smc_probe(struct net_device *dev, void __iomem *ioaddr,
 #  endif
        if (lp->cfg.flags & SMC91X_USE_DMA) {
                dma_cap_mask_t mask;
-               struct pxad_param param;
 
                dma_cap_zero(mask);
                dma_cap_set(DMA_SLAVE, mask);
-               param.prio = PXAD_PRIO_LOWEST;
-               param.drcmr = -1UL;
-
-               lp->dma_chan =
-                       dma_request_slave_channel_compat(mask, pxad_filter_fn,
-                                                        &param, &dev->dev,
-                                                        "data");
+               lp->dma_chan = dma_request_channel(mask, NULL, NULL);
        }
 #endif
 
index b337ee97e0c0c7eaa0a51e9a067b13420b789aa4..a27352229fc216cd75b44d932943ad1befa1cfe0 100644 (file)
@@ -301,7 +301,6 @@ struct smc_local {
  * as RX which can overrun memory and lose packets.
  */
 #include <linux/dma-mapping.h>
-#include <linux/dma/pxa-dma.h>
 
 #ifdef SMC_insl
 #undef SMC_insl
index edf20361ea5f15c7ddee617f899e31b92d7e261e..324049eebb9b140a1ca9a2c65de1eaf82048d263 100644 (file)
@@ -33,7 +33,7 @@ config DWMAC_DWC_QOS_ETH
        select PHYLIB
        select CRC32
        select MII
-       depends on OF && COMMON_CLK && HAS_DMA
+       depends on OF && HAS_DMA
        help
          Support for chips using the snps,dwc-qos-ethernet.txt DT binding.
 
@@ -57,7 +57,7 @@ config DWMAC_ANARION
 config DWMAC_IPQ806X
        tristate "QCA IPQ806x DWMAC support"
        default ARCH_QCOM
-       depends on OF && COMMON_CLK && (ARCH_QCOM || COMPILE_TEST)
+       depends on OF && (ARCH_QCOM || COMPILE_TEST)
        select MFD_SYSCON
        help
          Support for QCA IPQ806X DWMAC Ethernet.
@@ -100,7 +100,7 @@ config DWMAC_OXNAS
 config DWMAC_ROCKCHIP
        tristate "Rockchip dwmac support"
        default ARCH_ROCKCHIP
-       depends on OF && COMMON_CLK && (ARCH_ROCKCHIP || COMPILE_TEST)
+       depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
        select MFD_SYSCON
        help
          Support for Ethernet controller on Rockchip RK3288 SoC.
@@ -110,7 +110,7 @@ config DWMAC_ROCKCHIP
 
 config DWMAC_SOCFPGA
        tristate "SOCFPGA dwmac support"
-       default ARCH_SOCFPGA
+       default (ARCH_SOCFPGA || ARCH_STRATIX10)
        depends on OF && (ARCH_SOCFPGA || ARCH_STRATIX10 || COMPILE_TEST)
        select MFD_SYSCON
        help
@@ -123,7 +123,7 @@ config DWMAC_SOCFPGA
 config DWMAC_STI
        tristate "STi GMAC support"
        default ARCH_STI
-       depends on OF && COMMON_CLK && (ARCH_STI || COMPILE_TEST)
+       depends on OF && (ARCH_STI || COMPILE_TEST)
        select MFD_SYSCON
        ---help---
          Support for ethernet controller on STi SOCs.
@@ -147,7 +147,7 @@ config DWMAC_STM32
 config DWMAC_SUNXI
        tristate "Allwinner GMAC support"
        default ARCH_SUNXI
-       depends on OF && COMMON_CLK && (ARCH_SUNXI || COMPILE_TEST)
+       depends on OF && (ARCH_SUNXI || COMPILE_TEST)
        ---help---
          Support for Allwinner A20/A31 GMAC ethernet controllers.
 
index 76649adf8fb0639e66094cb29f83ed58f124bf2c..c0a855b7ab3b4304a0ba734117ee63d903701df8 100644 (file)
@@ -112,7 +112,6 @@ struct stmmac_priv {
        u32 tx_count_frames;
        u32 tx_coal_frames;
        u32 tx_coal_timer;
-       bool tx_timer_armed;
 
        int tx_coalesce;
        int hwts_tx_en;
index ff1ffb46198a7614bb282e992c8e0a3f58052893..9f458bb16f2a6edb6ab8cca33c00176b1cce1d67 100644 (file)
@@ -3147,16 +3147,13 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
         * element in case of no SG.
         */
        priv->tx_count_frames += nfrags + 1;
-       if (likely(priv->tx_coal_frames > priv->tx_count_frames) &&
-           !priv->tx_timer_armed) {
+       if (likely(priv->tx_coal_frames > priv->tx_count_frames)) {
                mod_timer(&priv->txtimer,
                          STMMAC_COAL_TIMER(priv->tx_coal_timer));
-               priv->tx_timer_armed = true;
        } else {
                priv->tx_count_frames = 0;
                stmmac_set_tx_ic(priv, desc);
                priv->xstats.tx_set_ic_bit++;
-               priv->tx_timer_armed = false;
        }
 
        skb_tx_timestamp(skb);
index 1a96dd9c1091e6c515753132c4a3fd0128f41bdf..531294f4978bc42bbb0e3cb0177b1312a33bef61 100644 (file)
@@ -61,7 +61,7 @@ static int tc_fill_actions(struct stmmac_tc_entry *entry,
        struct stmmac_tc_entry *action_entry = entry;
        const struct tc_action *act;
        struct tcf_exts *exts;
-       LIST_HEAD(actions);
+       int i;
 
        exts = cls->knode.exts;
        if (!tcf_exts_has_actions(exts))
@@ -69,8 +69,7 @@ static int tc_fill_actions(struct stmmac_tc_entry *entry,
        if (frag)
                action_entry = frag;
 
-       tcf_exts_to_list(exts, &actions);
-       list_for_each_entry(act, &actions, list) {
+       tcf_exts_for_each_action(i, act, exts) {
                /* Accept */
                if (is_tcf_gact_ok(act)) {
                        action_entry->val.af = 1;
index 0c1adad7415da7d9b858925d0ec5715e9ca7dfec..396e1cd1066796b815cedf4ab172215aaf238f33 100644 (file)
@@ -170,10 +170,13 @@ void cpsw_phy_sel(struct device *dev, phy_interface_t phy_mode, int slave)
        struct device_node *node;
        struct cpsw_phy_sel_priv *priv;
 
-       node = of_get_child_by_name(dev->of_node, "cpsw-phy-sel");
+       node = of_parse_phandle(dev->of_node, "cpsw-phy-sel", 0);
        if (!node) {
-               dev_err(dev, "Phy mode driver DT not found\n");
-               return;
+               node = of_get_child_by_name(dev->of_node, "cpsw-phy-sel");
+               if (!node) {
+                       dev_err(dev, "Phy mode driver DT not found\n");
+                       return;
+               }
        }
 
        dev = bus_find_device(&platform_bus_type, NULL, node, match);
index 507f68190cb1b4cbf88b8a441a040f8aacafd1d4..70921bbe0e28b448256d18cd8897eba9ae731c31 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/netdevice.h>
 #include <linux/inetdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/pci.h>
 #include <linux/skbuff.h>
 #include <linux/if_vlan.h>
 #include <linux/in.h>
@@ -2039,12 +2040,16 @@ static int netvsc_register_vf(struct net_device *vf_netdev)
 {
        struct net_device *ndev;
        struct net_device_context *net_device_ctx;
+       struct device *pdev = vf_netdev->dev.parent;
        struct netvsc_device *netvsc_dev;
        int ret;
 
        if (vf_netdev->addr_len != ETH_ALEN)
                return NOTIFY_DONE;
 
+       if (!pdev || !dev_is_pci(pdev) || dev_is_pf(pdev))
+               return NOTIFY_DONE;
+
        /*
         * We will use the MAC address to locate the synthetic interface to
         * associate with the VF interface. If we don't find a matching
@@ -2201,6 +2206,16 @@ static int netvsc_probe(struct hv_device *dev,
 
        memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN);
 
+       /* We must get rtnl lock before scheduling nvdev->subchan_work,
+        * otherwise netvsc_subchan_work() can get rtnl lock first and wait
+        * all subchannels to show up, but that may not happen because
+        * netvsc_probe() can't get rtnl lock and as a result vmbus_onoffer()
+        * -> ... -> device_add() -> ... -> __device_attach() can't get
+        * the device lock, so all the subchannels can't be processed --
+        * finally netvsc_subchan_work() hangs for ever.
+        */
+       rtnl_lock();
+
        if (nvdev->num_chn > 1)
                schedule_work(&nvdev->subchan_work);
 
@@ -2219,7 +2234,6 @@ static int netvsc_probe(struct hv_device *dev,
        else
                net->max_mtu = ETH_DATA_LEN;
 
-       rtnl_lock();
        ret = register_netdevice(net);
        if (ret != 0) {
                pr_err("Unable to register netdev.\n");
index 4637d980310e1503fc314004d18906ee2c1ac50f..52fffb98fde9ac3fd05c7f6fd8e5dc123ecae341 100644 (file)
@@ -398,7 +398,6 @@ static umode_t sfp_hwmon_is_visible(const void *data,
        switch (type) {
        case hwmon_temp:
                switch (attr) {
-               case hwmon_temp_input:
                case hwmon_temp_min_alarm:
                case hwmon_temp_max_alarm:
                case hwmon_temp_lcrit_alarm:
@@ -407,13 +406,16 @@ static umode_t sfp_hwmon_is_visible(const void *data,
                case hwmon_temp_max:
                case hwmon_temp_lcrit:
                case hwmon_temp_crit:
+                       if (!(sfp->id.ext.enhopts & SFP_ENHOPTS_ALARMWARN))
+                               return 0;
+                       /* fall through */
+               case hwmon_temp_input:
                        return 0444;
                default:
                        return 0;
                }
        case hwmon_in:
                switch (attr) {
-               case hwmon_in_input:
                case hwmon_in_min_alarm:
                case hwmon_in_max_alarm:
                case hwmon_in_lcrit_alarm:
@@ -422,13 +424,16 @@ static umode_t sfp_hwmon_is_visible(const void *data,
                case hwmon_in_max:
                case hwmon_in_lcrit:
                case hwmon_in_crit:
+                       if (!(sfp->id.ext.enhopts & SFP_ENHOPTS_ALARMWARN))
+                               return 0;
+                       /* fall through */
+               case hwmon_in_input:
                        return 0444;
                default:
                        return 0;
                }
        case hwmon_curr:
                switch (attr) {
-               case hwmon_curr_input:
                case hwmon_curr_min_alarm:
                case hwmon_curr_max_alarm:
                case hwmon_curr_lcrit_alarm:
@@ -437,6 +442,10 @@ static umode_t sfp_hwmon_is_visible(const void *data,
                case hwmon_curr_max:
                case hwmon_curr_lcrit:
                case hwmon_curr_crit:
+                       if (!(sfp->id.ext.enhopts & SFP_ENHOPTS_ALARMWARN))
+                               return 0;
+                       /* fall through */
+               case hwmon_curr_input:
                        return 0444;
                default:
                        return 0;
@@ -452,7 +461,6 @@ static umode_t sfp_hwmon_is_visible(const void *data,
                    channel == 1)
                        return 0;
                switch (attr) {
-               case hwmon_power_input:
                case hwmon_power_min_alarm:
                case hwmon_power_max_alarm:
                case hwmon_power_lcrit_alarm:
@@ -461,6 +469,10 @@ static umode_t sfp_hwmon_is_visible(const void *data,
                case hwmon_power_max:
                case hwmon_power_lcrit:
                case hwmon_power_crit:
+                       if (!(sfp->id.ext.enhopts & SFP_ENHOPTS_ALARMWARN))
+                               return 0;
+                       /* fall through */
+               case hwmon_power_input:
                        return 0444;
                default:
                        return 0;
index 2bbefe828670135d85ae8b4cdb9e537e27301be8..ebd07ad82431ec78c3801999fdc986188216655a 100644 (file)
@@ -3217,7 +3217,7 @@ static int tun_chr_fasync(int fd, struct file *file, int on)
                goto out;
 
        if (on) {
-               __f_setown(file, task_pid(current), PIDTYPE_PID, 0);
+               __f_setown(file, task_pid(current), PIDTYPE_TGID, 0);
                tfile->flags |= TUN_FASYNC;
        } else
                tfile->flags &= ~TUN_FASYNC;
index 97742708460bc8a415713537ff90060c07b07d27..2cd71bdb6484c774659598fff1e99cd49181337b 100644 (file)
@@ -5217,8 +5217,8 @@ static int rtl8152_probe(struct usb_interface *intf,
                netdev->hw_features &= ~NETIF_F_RXCSUM;
        }
 
-       if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x3011 &&
-           udev->serial && !strcmp(udev->serial, "000001000000")) {
+       if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x3011 && udev->serial &&
+           (!strcmp(udev->serial, "000001000000") || !strcmp(udev->serial, "000002000000"))) {
                dev_info(&udev->dev, "Dell TB16 Dock, disable RX aggregation");
                set_bit(DELL_TB_RX_AGG_BUG, &tp->flags);
        }
index b4c3a957c102d2463fde9d4987dcdf3764e2a694..73969dbeb5c5ff390709dea24cbd61da794d9a3a 100644 (file)
@@ -985,15 +985,12 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
        const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ?
                             iwl_ext_nvm_channels : iwl_nvm_channels;
        struct ieee80211_regdomain *regd, *copy_rd;
-       int size_of_regd, regd_to_copy, wmms_to_copy;
-       int size_of_wmms = 0;
+       int size_of_regd, regd_to_copy;
        struct ieee80211_reg_rule *rule;
-       struct ieee80211_wmm_rule *wmm_rule, *d_wmm, *s_wmm;
        struct regdb_ptrs *regdb_ptrs;
        enum nl80211_band band;
        int center_freq, prev_center_freq = 0;
-       int valid_rules = 0, n_wmms = 0;
-       int i;
+       int valid_rules = 0;
        bool new_rule;
        int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ?
                         IWL_NVM_NUM_CHANNELS_EXT : IWL_NVM_NUM_CHANNELS;
@@ -1012,11 +1009,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
                sizeof(struct ieee80211_regdomain) +
                num_of_ch * sizeof(struct ieee80211_reg_rule);
 
-       if (geo_info & GEO_WMM_ETSI_5GHZ_INFO)
-               size_of_wmms =
-                       num_of_ch * sizeof(struct ieee80211_wmm_rule);
-
-       regd = kzalloc(size_of_regd + size_of_wmms, GFP_KERNEL);
+       regd = kzalloc(size_of_regd, GFP_KERNEL);
        if (!regd)
                return ERR_PTR(-ENOMEM);
 
@@ -1030,8 +1023,6 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
        regd->alpha2[0] = fw_mcc >> 8;
        regd->alpha2[1] = fw_mcc & 0xff;
 
-       wmm_rule = (struct ieee80211_wmm_rule *)((u8 *)regd + size_of_regd);
-
        for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
                ch_flags = (u16)__le32_to_cpup(channels + ch_idx);
                band = (ch_idx < NUM_2GHZ_CHANNELS) ?
@@ -1085,26 +1076,10 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
                    band == NL80211_BAND_2GHZ)
                        continue;
 
-               if (!reg_query_regdb_wmm(regd->alpha2, center_freq,
-                                        &regdb_ptrs[n_wmms].token, wmm_rule)) {
-                       /* Add only new rules */
-                       for (i = 0; i < n_wmms; i++) {
-                               if (regdb_ptrs[i].token ==
-                                   regdb_ptrs[n_wmms].token) {
-                                       rule->wmm_rule = regdb_ptrs[i].rule;
-                                       break;
-                               }
-                       }
-                       if (i == n_wmms) {
-                               rule->wmm_rule = wmm_rule;
-                               regdb_ptrs[n_wmms++].rule = wmm_rule;
-                               wmm_rule++;
-                       }
-               }
+               reg_query_regdb_wmm(regd->alpha2, center_freq, rule);
        }
 
        regd->n_reg_rules = valid_rules;
-       regd->n_wmm_rules = n_wmms;
 
        /*
         * Narrow down regdom for unused regulatory rules to prevent hole
@@ -1113,28 +1088,13 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
        regd_to_copy = sizeof(struct ieee80211_regdomain) +
                valid_rules * sizeof(struct ieee80211_reg_rule);
 
-       wmms_to_copy = sizeof(struct ieee80211_wmm_rule) * n_wmms;
-
-       copy_rd = kzalloc(regd_to_copy + wmms_to_copy, GFP_KERNEL);
+       copy_rd = kzalloc(regd_to_copy, GFP_KERNEL);
        if (!copy_rd) {
                copy_rd = ERR_PTR(-ENOMEM);
                goto out;
        }
 
        memcpy(copy_rd, regd, regd_to_copy);
-       memcpy((u8 *)copy_rd + regd_to_copy, (u8 *)regd + size_of_regd,
-              wmms_to_copy);
-
-       d_wmm = (struct ieee80211_wmm_rule *)((u8 *)copy_rd + regd_to_copy);
-       s_wmm = (struct ieee80211_wmm_rule *)((u8 *)regd + size_of_regd);
-
-       for (i = 0; i < regd->n_reg_rules; i++) {
-               if (!regd->reg_rules[i].wmm_rule)
-                       continue;
-
-               copy_rd->reg_rules[i].wmm_rule = d_wmm +
-                       (regd->reg_rules[i].wmm_rule - s_wmm);
-       }
 
 out:
        kfree(regdb_ptrs);
index 998dfac0fcff359d3727fb5df313e257484378b6..1068757ec42e4784942e69c00161ae4e1ee16548 100644 (file)
@@ -34,6 +34,7 @@
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 #include <linux/rhashtable.h>
+#include <linux/nospec.h>
 #include "mac80211_hwsim.h"
 
 #define WARN_QUEUE 100
@@ -2820,9 +2821,6 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
                                IEEE80211_VHT_CAP_SHORT_GI_80 |
                                IEEE80211_VHT_CAP_SHORT_GI_160 |
                                IEEE80211_VHT_CAP_TXSTBC |
-                               IEEE80211_VHT_CAP_RXSTBC_1 |
-                               IEEE80211_VHT_CAP_RXSTBC_2 |
-                               IEEE80211_VHT_CAP_RXSTBC_3 |
                                IEEE80211_VHT_CAP_RXSTBC_4 |
                                IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
                        sband->vht_cap.vht_mcs.rx_mcs_map =
@@ -3317,6 +3315,11 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
        if (info->attrs[HWSIM_ATTR_CHANNELS])
                param.channels = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]);
 
+       if (param.channels < 1) {
+               GENL_SET_ERR_MSG(info, "must have at least one channel");
+               return -EINVAL;
+       }
+
        if (param.channels > CFG80211_MAX_NUM_DIFFERENT_CHANNELS) {
                GENL_SET_ERR_MSG(info, "too many channels specified");
                return -EINVAL;
@@ -3350,6 +3353,9 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
                        kfree(hwname);
                        return -EINVAL;
                }
+
+               idx = array_index_nospec(idx,
+                                        ARRAY_SIZE(hwsim_world_regdom_custom));
                param.regd = hwsim_world_regdom_custom[idx];
        }
 
index 27902a8799b1e022049078efc2ce14269dbea672..8aae6dcc839fed90a76e31eaf35a5f47ac04957d 100644 (file)
@@ -812,9 +812,9 @@ u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd,
                 * overshoots the remainder by 4 bytes, assume it was
                 * including 'status'.
                 */
-               if (out_field[1] - 8 == remainder)
+               if (out_field[1] - 4 == remainder)
                        return remainder;
-               return out_field[1] - 4;
+               return out_field[1] - 8;
        } else if (cmd == ND_CMD_CALL) {
                struct nd_cmd_pkg *pkg = (struct nd_cmd_pkg *) in_field;
 
index 233907889f96a36d6a3b87fc79cf82cabf602def..6c8fb7590838668c537aa09cfb289ed82f7fa563 100644 (file)
@@ -34,6 +34,9 @@ static int nvdimm_probe(struct device *dev)
                return rc;
        }
 
+       /* reset locked, to be validated below... */
+       nvdimm_clear_locked(dev);
+
        ndd = kzalloc(sizeof(*ndd), GFP_KERNEL);
        if (!ndd)
                return -ENOMEM;
@@ -48,12 +51,30 @@ static int nvdimm_probe(struct device *dev)
        get_device(dev);
        kref_init(&ndd->kref);
 
+       /*
+        * EACCES failures reading the namespace label-area-properties
+        * are interpreted as the DIMM capacity being locked but the
+        * namespace labels themselves being accessible.
+        */
        rc = nvdimm_init_nsarea(ndd);
-       if (rc == -EACCES)
+       if (rc == -EACCES) {
+               /*
+                * See nvdimm_namespace_common_probe() where we fail to
+                * allow namespaces to probe while the DIMM is locked,
+                * but we do allow for namespace enumeration.
+                */
                nvdimm_set_locked(dev);
+               rc = 0;
+       }
        if (rc)
                goto err;
 
+       /*
+        * EACCES failures reading the namespace label-data are
+        * interpreted as the label area being locked in addition to the
+        * DIMM capacity. We fail the dimm probe to prevent regions from
+        * attempting to parse the label area.
+        */
        rc = nvdimm_init_config_data(ndd);
        if (rc == -EACCES)
                nvdimm_set_locked(dev);
@@ -72,7 +93,6 @@ static int nvdimm_probe(struct device *dev)
                if (rc == 0)
                        nvdimm_set_aliasing(dev);
        }
-       nvdimm_clear_locked(dev);
        nvdimm_bus_unlock(dev);
 
        if (rc)
index 8d348b22ba453a58938d9fa921dd890109a4c7de..863cabc352159c54e3beb6659519418aadc3c0bc 100644 (file)
@@ -536,6 +536,37 @@ resource_size_t nd_blk_available_dpa(struct nd_region *nd_region)
        return info.available;
 }
 
+/**
+ * nd_pmem_max_contiguous_dpa - For the given dimm+region, return the max
+ *                        contiguous unallocated dpa range.
+ * @nd_region: constrain available space check to this reference region
+ * @nd_mapping: container of dpa-resource-root + labels
+ */
+resource_size_t nd_pmem_max_contiguous_dpa(struct nd_region *nd_region,
+                                          struct nd_mapping *nd_mapping)
+{
+       struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
+       struct nvdimm_bus *nvdimm_bus;
+       resource_size_t max = 0;
+       struct resource *res;
+
+       /* if a dimm is disabled the available capacity is zero */
+       if (!ndd)
+               return 0;
+
+       nvdimm_bus = walk_to_nvdimm_bus(ndd->dev);
+       if (__reserve_free_pmem(&nd_region->dev, nd_mapping->nvdimm))
+               return 0;
+       for_each_dpa_resource(ndd, res) {
+               if (strcmp(res->name, "pmem-reserve") != 0)
+                       continue;
+               if (resource_size(res) > max)
+                       max = resource_size(res);
+       }
+       release_free_pmem(nvdimm_bus, nd_mapping);
+       return max;
+}
+
 /**
  * nd_pmem_available_dpa - for the given dimm+region account unallocated dpa
  * @nd_mapping: container of dpa-resource-root + labels
index 28afdd668905019472d802be06695bfc06897b48..4a4266250c28cfde56b08a2aa7ce04a27d6e6527 100644 (file)
@@ -799,7 +799,7 @@ static int merge_dpa(struct nd_region *nd_region,
        return 0;
 }
 
-static int __reserve_free_pmem(struct device *dev, void *data)
+int __reserve_free_pmem(struct device *dev, void *data)
 {
        struct nvdimm *nvdimm = data;
        struct nd_region *nd_region;
@@ -836,7 +836,7 @@ static int __reserve_free_pmem(struct device *dev, void *data)
        return 0;
 }
 
-static void release_free_pmem(struct nvdimm_bus *nvdimm_bus,
+void release_free_pmem(struct nvdimm_bus *nvdimm_bus,
                struct nd_mapping *nd_mapping)
 {
        struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
@@ -1032,7 +1032,7 @@ static ssize_t __size_store(struct device *dev, unsigned long long val)
 
                allocated += nvdimm_allocated_dpa(ndd, &label_id);
        }
-       available = nd_region_available_dpa(nd_region);
+       available = nd_region_allocatable_dpa(nd_region);
 
        if (val > available + allocated)
                return -ENOSPC;
@@ -1144,6 +1144,26 @@ resource_size_t nvdimm_namespace_capacity(struct nd_namespace_common *ndns)
 }
 EXPORT_SYMBOL(nvdimm_namespace_capacity);
 
+bool nvdimm_namespace_locked(struct nd_namespace_common *ndns)
+{
+       int i;
+       bool locked = false;
+       struct device *dev = &ndns->dev;
+       struct nd_region *nd_region = to_nd_region(dev->parent);
+
+       for (i = 0; i < nd_region->ndr_mappings; i++) {
+               struct nd_mapping *nd_mapping = &nd_region->mapping[i];
+               struct nvdimm *nvdimm = nd_mapping->nvdimm;
+
+               if (test_bit(NDD_LOCKED, &nvdimm->flags)) {
+                       dev_dbg(dev, "%s locked\n", nvdimm_name(nvdimm));
+                       locked = true;
+               }
+       }
+       return locked;
+}
+EXPORT_SYMBOL(nvdimm_namespace_locked);
+
 static ssize_t size_show(struct device *dev,
                struct device_attribute *attr, char *buf)
 {
@@ -1695,6 +1715,9 @@ struct nd_namespace_common *nvdimm_namespace_common_probe(struct device *dev)
                }
        }
 
+       if (nvdimm_namespace_locked(ndns))
+               return ERR_PTR(-EACCES);
+
        size = nvdimm_namespace_capacity(ndns);
        if (size < ND_MIN_NAMESPACE_SIZE) {
                dev_dbg(&ndns->dev, "%pa, too small must be at least %#x\n",
index 79274ead54fb0cbe3f7034f095a7b1d3b925756a..ac68072fb8cd683c8917c9f061f127315cabb2ef 100644 (file)
@@ -100,6 +100,14 @@ struct nd_region;
 struct nvdimm_drvdata;
 struct nd_mapping;
 void nd_mapping_free_labels(struct nd_mapping *nd_mapping);
+
+int __reserve_free_pmem(struct device *dev, void *data);
+void release_free_pmem(struct nvdimm_bus *nvdimm_bus,
+                      struct nd_mapping *nd_mapping);
+
+resource_size_t nd_pmem_max_contiguous_dpa(struct nd_region *nd_region,
+                                          struct nd_mapping *nd_mapping);
+resource_size_t nd_region_allocatable_dpa(struct nd_region *nd_region);
 resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region,
                struct nd_mapping *nd_mapping, resource_size_t *overlap);
 resource_size_t nd_blk_available_dpa(struct nd_region *nd_region);
index 6ee7fd7e4bbdc6e37ccdfa4cd3616339e8791ba2..98317e7ce5b54dbd2e2172a40d114e2734650391 100644 (file)
@@ -357,6 +357,7 @@ struct resource *nvdimm_allocate_dpa(struct nvdimm_drvdata *ndd,
                struct nd_label_id *label_id, resource_size_t start,
                resource_size_t n);
 resource_size_t nvdimm_namespace_capacity(struct nd_namespace_common *ndns);
+bool nvdimm_namespace_locked(struct nd_namespace_common *ndns);
 struct nd_namespace_common *nvdimm_namespace_common_probe(struct device *dev);
 int nvdimm_namespace_attach_btt(struct nd_namespace_common *ndns);
 int nvdimm_namespace_detach_btt(struct nd_btt *nd_btt);
index dd17acd8fe6810e5d1a04c05bd8f23241ceec409..6071e2942053c903564d6f08f278d3735a619308 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/hdreg.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/set_memory.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/badblocks.h>
@@ -51,6 +52,30 @@ static struct nd_region *to_region(struct pmem_device *pmem)
        return to_nd_region(to_dev(pmem)->parent);
 }
 
+static void hwpoison_clear(struct pmem_device *pmem,
+               phys_addr_t phys, unsigned int len)
+{
+       unsigned long pfn_start, pfn_end, pfn;
+
+       /* only pmem in the linear map supports HWPoison */
+       if (is_vmalloc_addr(pmem->virt_addr))
+               return;
+
+       pfn_start = PHYS_PFN(phys);
+       pfn_end = pfn_start + PHYS_PFN(len);
+       for (pfn = pfn_start; pfn < pfn_end; pfn++) {
+               struct page *page = pfn_to_page(pfn);
+
+               /*
+                * Note, no need to hold a get_dev_pagemap() reference
+                * here since we're in the driver I/O path and
+                * outstanding I/O requests pin the dev_pagemap.
+                */
+               if (test_and_clear_pmem_poison(page))
+                       clear_mce_nospec(pfn);
+       }
+}
+
 static blk_status_t pmem_clear_poison(struct pmem_device *pmem,
                phys_addr_t offset, unsigned int len)
 {
@@ -65,6 +90,7 @@ static blk_status_t pmem_clear_poison(struct pmem_device *pmem,
        if (cleared < len)
                rc = BLK_STS_IOERR;
        if (cleared > 0 && cleared / 512) {
+               hwpoison_clear(pmem, pmem->phys_addr + offset, cleared);
                cleared /= 512;
                dev_dbg(dev, "%#llx clear %ld sector%s\n",
                                (unsigned long long) sector, cleared,
@@ -226,8 +252,11 @@ __weak long __pmem_direct_access(struct pmem_device *pmem, pgoff_t pgoff,
        if (unlikely(is_bad_pmem(&pmem->bb, PFN_PHYS(pgoff) / 512,
                                        PFN_PHYS(nr_pages))))
                return -EIO;
-       *kaddr = pmem->virt_addr + offset;
-       *pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags);
+
+       if (kaddr)
+               *kaddr = pmem->virt_addr + offset;
+       if (pfn)
+               *pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags);
 
        /*
         * If badblocks are present, limit known good range to the
index a64ebc78b5dffbac4072fc722d9961650e681f88..59cfe13ea8a85c3bcccf9211409ae237196626d5 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #ifndef __NVDIMM_PMEM_H__
 #define __NVDIMM_PMEM_H__
+#include <linux/page-flags.h>
 #include <linux/badblocks.h>
 #include <linux/types.h>
 #include <linux/pfn_t.h>
@@ -27,4 +28,16 @@ struct pmem_device {
 
 long __pmem_direct_access(struct pmem_device *pmem, pgoff_t pgoff,
                long nr_pages, void **kaddr, pfn_t *pfn);
+
+#ifdef CONFIG_MEMORY_FAILURE
+static inline bool test_and_clear_pmem_poison(struct page *page)
+{
+       return TestClearPageHWPoison(page);
+}
+#else
+static inline bool test_and_clear_pmem_poison(struct page *page)
+{
+       return false;
+}
+#endif
 #endif /* __NVDIMM_PMEM_H__ */
index ec3543b83330f25e040894599c44b3898d6bd66b..fa37afcd43ff8ceb8ac4e8b18a8a7f23218d3e90 100644 (file)
@@ -389,6 +389,30 @@ resource_size_t nd_region_available_dpa(struct nd_region *nd_region)
        return available;
 }
 
+resource_size_t nd_region_allocatable_dpa(struct nd_region *nd_region)
+{
+       resource_size_t available = 0;
+       int i;
+
+       if (is_memory(&nd_region->dev))
+               available = PHYS_ADDR_MAX;
+
+       WARN_ON(!is_nvdimm_bus_locked(&nd_region->dev));
+       for (i = 0; i < nd_region->ndr_mappings; i++) {
+               struct nd_mapping *nd_mapping = &nd_region->mapping[i];
+
+               if (is_memory(&nd_region->dev))
+                       available = min(available,
+                                       nd_pmem_max_contiguous_dpa(nd_region,
+                                                                  nd_mapping));
+               else if (is_nd_blk(&nd_region->dev))
+                       available += nd_blk_available_dpa(nd_region);
+       }
+       if (is_memory(&nd_region->dev))
+               return available * nd_region->ndr_mappings;
+       return available;
+}
+
 static ssize_t available_size_show(struct device *dev,
                struct device_attribute *attr, char *buf)
 {
@@ -410,6 +434,21 @@ static ssize_t available_size_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(available_size);
 
+static ssize_t max_available_extent_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct nd_region *nd_region = to_nd_region(dev);
+       unsigned long long available = 0;
+
+       nvdimm_bus_lock(dev);
+       wait_nvdimm_bus_probe_idle(dev);
+       available = nd_region_allocatable_dpa(nd_region);
+       nvdimm_bus_unlock(dev);
+
+       return sprintf(buf, "%llu\n", available);
+}
+static DEVICE_ATTR_RO(max_available_extent);
+
 static ssize_t init_namespaces_show(struct device *dev,
                struct device_attribute *attr, char *buf)
 {
@@ -561,6 +600,7 @@ static struct attribute *nd_region_attributes[] = {
        &dev_attr_read_only.attr,
        &dev_attr_set_cookie.attr,
        &dev_attr_available_size.attr,
+       &dev_attr_max_available_extent.attr,
        &dev_attr_namespace_seed.attr,
        &dev_attr_init_namespaces.attr,
        &dev_attr_badblocks.attr,
index 1b9951d2067e631de9115b1845dcc2e050069c0e..d668682f91dfdb3428e02a44df2c8ade9ccf0042 100644 (file)
@@ -316,6 +316,14 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
                old_value = *dbbuf_db;
                *dbbuf_db = value;
 
+               /*
+                * Ensure that the doorbell is updated before reading the event
+                * index from memory.  The controller needs to provide similar
+                * ordering to ensure the envent index is updated before reading
+                * the doorbell.
+                */
+               mb();
+
                if (!nvme_dbbuf_need_event(*dbbuf_ei, value, old_value))
                        return false;
        }
index ebf3e7a6c49ee27003c1e667501eb9d5441791d0..b5ec96abd04870209ed7ea97452180cf6cb63038 100644 (file)
@@ -1210,7 +1210,7 @@ static int __init nvmet_init(void)
 
        error = nvmet_init_discovery();
        if (error)
-               goto out;
+               goto out_free_work_queue;
 
        error = nvmet_init_configfs();
        if (error)
@@ -1219,6 +1219,8 @@ static int __init nvmet_init(void)
 
 out_exit_discovery:
        nvmet_exit_discovery();
+out_free_work_queue:
+       destroy_workqueue(buffered_io_wq);
 out:
        return error;
 }
index 34712def81b15a566bb16a7e320ec7012796cf27..5251689a1d9ac2e5a5852c724f7f54d2ec80801c 100644 (file)
@@ -311,7 +311,7 @@ fcloop_tgt_lsrqst_done_work(struct work_struct *work)
        struct fcloop_tport *tport = tls_req->tport;
        struct nvmefc_ls_req *lsreq = tls_req->lsreq;
 
-       if (tport->remoteport)
+       if (!tport || tport->remoteport)
                lsreq->done(lsreq, tls_req->status);
 }
 
@@ -329,6 +329,7 @@ fcloop_ls_req(struct nvme_fc_local_port *localport,
 
        if (!rport->targetport) {
                tls_req->status = -ECONNREFUSED;
+               tls_req->tport = NULL;
                schedule_work(&tls_req->work);
                return ret;
        }
index 466e3c8582f0fd62628b90872b2046971e064776..9095b8290150c5bd2b8da3916d9f6c9243f24c56 100644 (file)
@@ -54,6 +54,28 @@ DEFINE_MUTEX(of_mutex);
  */
 DEFINE_RAW_SPINLOCK(devtree_lock);
 
+bool of_node_name_eq(const struct device_node *np, const char *name)
+{
+       const char *node_name;
+       size_t len;
+
+       if (!np)
+               return false;
+
+       node_name = kbasename(np->full_name);
+       len = strchrnul(node_name, '@') - node_name;
+
+       return (strlen(name) == len) && (strncmp(node_name, name, len) == 0);
+}
+
+bool of_node_name_prefix(const struct device_node *np, const char *prefix)
+{
+       if (!np)
+               return false;
+
+       return strncmp(kbasename(np->full_name), prefix, strlen(prefix)) == 0;
+}
+
 int of_n_addr_cells(struct device_node *np)
 {
        u32 cells;
@@ -719,6 +741,31 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
 }
 EXPORT_SYMBOL(of_get_next_available_child);
 
+/**
+ * of_get_compatible_child - Find compatible child node
+ * @parent:    parent node
+ * @compatible:        compatible string
+ *
+ * Lookup child node whose compatible property contains the given compatible
+ * string.
+ *
+ * Returns a node pointer with refcount incremented, use of_node_put() on it
+ * when done; or NULL if not found.
+ */
+struct device_node *of_get_compatible_child(const struct device_node *parent,
+                               const char *compatible)
+{
+       struct device_node *child;
+
+       for_each_child_of_node(parent, child) {
+               if (of_device_is_compatible(child, compatible))
+                       break;
+       }
+
+       return child;
+}
+EXPORT_SYMBOL(of_get_compatible_child);
+
 /**
  *     of_get_child_by_name - Find the child node by name for a given parent
  *     @node:  parent node
index 7ba90c290a428186322cc0128ae4a7afbae87748..6c59673933e90817dea1023f3e200c486f82fdde 100644 (file)
@@ -241,6 +241,10 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
        if (!dev)
                goto err_clear_flag;
 
+       /* AMBA devices only support a single DMA mask */
+       dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+       dev->dev.dma_mask = &dev->dev.coherent_dma_mask;
+
        /* setup generic device info */
        dev->dev.of_node = of_node_get(node);
        dev->dev.fwnode = &node->fwnode;
index 738e3546abb166914b42c08e1ed57ce4b7c4a0f3..c2ab577050434bb602fd8c4c8252547b90a9ff4f 100644 (file)
@@ -615,13 +615,11 @@ static bool acpi_pci_need_resume(struct pci_dev *dev)
        /*
         * In some cases (eg. Samsung 305V4A) leaving a bridge in suspend over
         * system-wide suspend/resume confuses the platform firmware, so avoid
-        * doing that, unless the bridge has a driver that should take care of
-        * the PM handling.  According to Section 16.1.6 of ACPI 6.2, endpoint
+        * doing that.  According to Section 16.1.6 of ACPI 6.2, endpoint
         * devices are expected to be in D3 before invoking the S3 entry path
         * from the firmware, so they should not be affected by this issue.
         */
-       if (pci_is_bridge(dev) && !dev->driver &&
-           acpi_target_system_state() != ACPI_STATE_S0)
+       if (pci_is_bridge(dev) && acpi_target_system_state() != ACPI_STATE_S0)
                return true;
 
        if (!adev || !acpi_device_power_manageable(adev))
index 46f58a9771d7399dbfa7c9ea5fd25819f325ed91..ef7143a274e00c9431a26c14702443dbd7853aa1 100644 (file)
@@ -66,9 +66,15 @@ static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
                     f->vendor == (u16) PCI_ANY_ID) &&
                    (f->device == dev->device ||
                     f->device == (u16) PCI_ANY_ID)) {
-                       calltime = fixup_debug_start(dev, f->hook);
-                       f->hook(dev);
-                       fixup_debug_report(dev, calltime, f->hook);
+                       void (*hook)(struct pci_dev *dev);
+#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
+                       hook = offset_to_ptr(&f->hook_offset);
+#else
+                       hook = f->hook;
+#endif
+                       calltime = fixup_debug_start(dev, hook);
+                       hook(dev);
+                       fixup_debug_report(dev, calltime, hook);
                }
 }
 
index b935df6a9694c93b0af5144e19e89be4d8ac15c9..1e81f8144c0d6f2e36027863df7e3dab2ec0d2f6 100644 (file)
@@ -1,8 +1,16 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: GPL-2.0
 // Driver to detect Tablet Mode for ChromeOS convertible.
 //
 // Copyright (C) 2017 Google, Inc.
 // Author: Gwendal Grignou <gwendal@chromium.org>
+//
+// On Chromebook using ACPI, this device listens for notification
+// from GOOG0006 and issue method TBMC to retrieve the status.
+//
+// GOOG0006 issues the notification when it receives EC_HOST_EVENT_MODE_CHANGE
+// from the EC.
+// Method TBMC reads EC_ACPI_MEM_DEVICE_ORIENTATION byte from the shared
+// memory region.
 
 #include <linux/acpi.h>
 #include <linux/input.h>
index 591bccdeaff920600f3c4fcfcd4b5cafc5661e2e..cd8a908460633c315813e9363fe7bd0b67fa49fa 100644 (file)
@@ -23,4 +23,15 @@ config MLXREG_HOTPLUG
          This driver handles hot-plug events for the power suppliers, power
          cables and fans on the wide range Mellanox IB and Ethernet systems.
 
+config MLXREG_IO
+       tristate "Mellanox platform register access driver support"
+       depends on REGMAP
+       depends on HWMON
+       help
+         This driver allows access to Mellanox programmable device register
+         space through sysfs interface. The sets of registers for sysfs access
+         are defined per system type bases and include the registers related
+         to system resets operation, system reset causes monitoring and some
+         kinds of mux selection.
+
 endif # MELLANOX_PLATFORM
index 7c8385e497a833f5959e225384a39f4f7032d677..57074d9c722c7ada0c06378a1c0dcc5cb19cef38 100644 (file)
@@ -4,3 +4,4 @@
 # Mellanox Platform-Specific Drivers
 #
 obj-$(CONFIG_MLXREG_HOTPLUG)   += mlxreg-hotplug.o
+obj-$(CONFIG_MLXREG_IO) += mlxreg-io.o
index ac97aa020db326dfc32ce821943ff37e2d77749c..b6d44550d98cf3fbe95a021b79b23dd1ad54bea2 100644 (file)
@@ -50,9 +50,8 @@
 #define MLXREG_HOTPLUG_MASK_OFF                2
 #define MLXREG_HOTPLUG_AGGR_MASK_OFF   1
 
-/* ASIC health parameters. */
-#define MLXREG_HOTPLUG_HEALTH_MASK     0x02
-#define MLXREG_HOTPLUG_RST_CNTR                3
+/* ASIC good health mask. */
+#define MLXREG_HOTPLUG_GOOD_HEALTH_MASK        0x02
 
 #define MLXREG_HOTPLUG_ATTRS_MAX       24
 #define MLXREG_HOTPLUG_NOT_ASSERT      3
@@ -103,6 +102,9 @@ static int mlxreg_hotplug_device_create(struct mlxreg_hotplug_priv_data *priv,
 {
        struct mlxreg_core_hotplug_platform_data *pdata;
 
+       /* Notify user by sending hwmon uevent. */
+       kobject_uevent(&priv->hwmon->kobj, KOBJ_CHANGE);
+
        /*
         * Return if adapter number is negative. It could be in case hotplug
         * event is not associated with hotplug device.
@@ -134,8 +136,13 @@ static int mlxreg_hotplug_device_create(struct mlxreg_hotplug_priv_data *priv,
        return 0;
 }
 
-static void mlxreg_hotplug_device_destroy(struct mlxreg_core_data *data)
+static void
+mlxreg_hotplug_device_destroy(struct mlxreg_hotplug_priv_data *priv,
+                             struct mlxreg_core_data *data)
 {
+       /* Notify user by sending hwmon uevent. */
+       kobject_uevent(&priv->hwmon->kobj, KOBJ_CHANGE);
+
        if (data->hpdev.client) {
                i2c_unregister_device(data->hpdev.client);
                data->hpdev.client = NULL;
@@ -278,14 +285,14 @@ mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv,
                data = item->data + bit;
                if (regval & BIT(bit)) {
                        if (item->inversed)
-                               mlxreg_hotplug_device_destroy(data);
+                               mlxreg_hotplug_device_destroy(priv, data);
                        else
                                mlxreg_hotplug_device_create(priv, data);
                } else {
                        if (item->inversed)
                                mlxreg_hotplug_device_create(priv, data);
                        else
-                               mlxreg_hotplug_device_destroy(data);
+                               mlxreg_hotplug_device_destroy(priv, data);
                }
        }
 
@@ -325,21 +332,40 @@ mlxreg_hotplug_health_work_helper(struct mlxreg_hotplug_priv_data *priv,
                        goto out;
 
                regval &= data->mask;
-               item->cache = regval;
-               if (regval == MLXREG_HOTPLUG_HEALTH_MASK) {
-                       if ((data->health_cntr++ == MLXREG_HOTPLUG_RST_CNTR) ||
-                           !priv->after_probe) {
+
+               if (item->cache == regval)
+                       goto ack_event;
+
+               /*
+                * ASIC health indication is provided through two bits. Bits
+                * value 0x2 indicates that ASIC reached the good health, value
+                * 0x0 indicates ASIC the bad health or dormant state and value
+                * 0x3 indicates the booting state. During ASIC reset it should
+                * pass the following states: dormant -> booting -> good.
+                */
+               if (regval == MLXREG_HOTPLUG_GOOD_HEALTH_MASK) {
+                       if (!data->attached) {
+                               /*
+                                * ASIC is in steady state. Connect associated
+                                * device, if configured.
+                                */
                                mlxreg_hotplug_device_create(priv, data);
                                data->attached = true;
                        }
                } else {
                        if (data->attached) {
-                               mlxreg_hotplug_device_destroy(data);
+                               /*
+                                * ASIC health is failed after ASIC has been
+                                * in steady state. Disconnect associated
+                                * device, if it has been connected.
+                                */
+                               mlxreg_hotplug_device_destroy(priv, data);
                                data->attached = false;
                                data->health_cntr = 0;
                        }
                }
-
+               item->cache = regval;
+ack_event:
                /* Acknowledge event. */
                ret = regmap_write(priv->regmap, data->reg +
                                   MLXREG_HOTPLUG_EVENT_OFF, 0);
@@ -551,7 +577,7 @@ static void mlxreg_hotplug_unset_irq(struct mlxreg_hotplug_priv_data *priv)
                /* Remove all the attached devices in group. */
                count = item->count;
                for (j = 0; j < count; j++, data++)
-                       mlxreg_hotplug_device_destroy(data);
+                       mlxreg_hotplug_device_destroy(priv, data);
        }
 }
 
@@ -616,10 +642,6 @@ static int mlxreg_hotplug_probe(struct platform_device *pdev)
        disable_irq(priv->irq);
        spin_lock_init(&priv->lock);
        INIT_DELAYED_WORK(&priv->dwork_irq, mlxreg_hotplug_work_handler);
-       /* Perform initial interrupts setup. */
-       mlxreg_hotplug_set_irq(priv);
-
-       priv->after_probe = true;
        dev_set_drvdata(&pdev->dev, priv);
 
        err = mlxreg_hotplug_attr_init(priv);
@@ -637,6 +659,10 @@ static int mlxreg_hotplug_probe(struct platform_device *pdev)
                return PTR_ERR(priv->hwmon);
        }
 
+       /* Perform initial interrupts setup. */
+       mlxreg_hotplug_set_irq(priv);
+       priv->after_probe = true;
+
        return 0;
 }
 
diff --git a/drivers/platform/mellanox/mlxreg-io.c b/drivers/platform/mellanox/mlxreg-io.c
new file mode 100644 (file)
index 0000000..acfaf64
--- /dev/null
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Mellanox register access driver
+ *
+ * Copyright (C) 2018 Mellanox Technologies
+ * Copyright (C) 2018 Vadim Pasternak <vadimp@mellanox.com>
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_data/mlxreg.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+/* Attribute parameters. */
+#define MLXREG_IO_ATT_SIZE     10
+#define MLXREG_IO_ATT_NUM      48
+
+/**
+ * struct mlxreg_io_priv_data - driver's private data:
+ *
+ * @pdev: platform device;
+ * @pdata: platform data;
+ * @hwmon: hwmon device;
+ * @mlxreg_io_attr: sysfs attributes array;
+ * @mlxreg_io_dev_attr: sysfs sensor device attribute array;
+ * @group: sysfs attribute group;
+ * @groups: list of sysfs attribute group for hwmon registration;
+ */
+struct mlxreg_io_priv_data {
+       struct platform_device *pdev;
+       struct mlxreg_core_platform_data *pdata;
+       struct device *hwmon;
+       struct attribute *mlxreg_io_attr[MLXREG_IO_ATT_NUM + 1];
+       struct sensor_device_attribute mlxreg_io_dev_attr[MLXREG_IO_ATT_NUM];
+       struct attribute_group group;
+       const struct attribute_group *groups[2];
+};
+
+static int
+mlxreg_io_get_reg(void *regmap, struct mlxreg_core_data *data, u32 in_val,
+                 bool rw_flag, u32 *regval)
+{
+       int ret;
+
+       ret = regmap_read(regmap, data->reg, regval);
+       if (ret)
+               goto access_error;
+
+       /*
+        * There are three kinds of attributes: single bit, full register's
+        * bits and bit sequence. For the first kind field mask indicates which
+        * bits are not related and field bit is set zero. For the second kind
+        * field mask is set to zero and field bit is set with all bits one.
+        * No special handling for such kind of attributes - pass value as is.
+        * For the third kind, field mask indicates which bits are related and
+        * field bit is set to the first bit number (from 1 to 32) is the bit
+        * sequence.
+        */
+       if (!data->bit) {
+               /* Single bit. */
+               if (rw_flag) {
+                       /* For show: expose effective bit value as 0 or 1. */
+                       *regval = !!(*regval & ~data->mask);
+               } else {
+                       /* For store: set effective bit value. */
+                       *regval &= data->mask;
+                       if (in_val)
+                               *regval |= ~data->mask;
+               }
+       } else if (data->mask) {
+               /* Bit sequence. */
+               if (rw_flag) {
+                       /* For show: mask and shift right. */
+                       *regval = ror32(*regval & data->mask, (data->bit - 1));
+               } else {
+                       /* For store: shift to the position and mask. */
+                       in_val = rol32(in_val, data->bit - 1) & data->mask;
+                       /* Clear relevant bits and set them to new value. */
+                       *regval = (*regval & ~data->mask) | in_val;
+               }
+       }
+
+access_error:
+       return ret;
+}
+
+static ssize_t
+mlxreg_io_attr_show(struct device *dev, struct device_attribute *attr,
+                   char *buf)
+{
+       struct mlxreg_io_priv_data *priv = dev_get_drvdata(dev);
+       int index = to_sensor_dev_attr(attr)->index;
+       struct mlxreg_core_data *data = priv->pdata->data + index;
+       u32 regval = 0;
+       int ret;
+
+       ret = mlxreg_io_get_reg(priv->pdata->regmap, data, 0, true, &regval);
+       if (ret)
+               goto access_error;
+
+       return sprintf(buf, "%u\n", regval);
+
+access_error:
+       return ret;
+}
+
+static ssize_t
+mlxreg_io_attr_store(struct device *dev, struct device_attribute *attr,
+                    const char *buf, size_t len)
+{
+       struct mlxreg_io_priv_data *priv = dev_get_drvdata(dev);
+       int index = to_sensor_dev_attr(attr)->index;
+       struct mlxreg_core_data *data = priv->pdata->data + index;
+       u32 input_val, regval;
+       int ret;
+
+       if (len > MLXREG_IO_ATT_SIZE)
+               return -EINVAL;
+
+       /* Convert buffer to input value. */
+       ret = kstrtou32(buf, len, &input_val);
+       if (ret)
+               return ret;
+
+       ret = mlxreg_io_get_reg(priv->pdata->regmap, data, input_val, false,
+                               &regval);
+       if (ret)
+               goto access_error;
+
+       ret = regmap_write(priv->pdata->regmap, data->reg, regval);
+       if (ret)
+               goto access_error;
+
+       return len;
+
+access_error:
+       dev_err(&priv->pdev->dev, "Bus access error\n");
+       return ret;
+}
+
+static struct device_attribute mlxreg_io_devattr_rw = {
+       .show   = mlxreg_io_attr_show,
+       .store  = mlxreg_io_attr_store,
+};
+
+static int mlxreg_io_attr_init(struct mlxreg_io_priv_data *priv)
+{
+       int i;
+
+       priv->group.attrs = devm_kcalloc(&priv->pdev->dev,
+                                        priv->pdata->counter,
+                                        sizeof(struct attribute *),
+                                        GFP_KERNEL);
+       if (!priv->group.attrs)
+               return -ENOMEM;
+
+       for (i = 0; i < priv->pdata->counter; i++) {
+               priv->mlxreg_io_attr[i] =
+                               &priv->mlxreg_io_dev_attr[i].dev_attr.attr;
+               memcpy(&priv->mlxreg_io_dev_attr[i].dev_attr,
+                      &mlxreg_io_devattr_rw, sizeof(struct device_attribute));
+
+               /* Set attribute name as a label. */
+               priv->mlxreg_io_attr[i]->name =
+                               devm_kasprintf(&priv->pdev->dev, GFP_KERNEL,
+                                              priv->pdata->data[i].label);
+
+               if (!priv->mlxreg_io_attr[i]->name) {
+                       dev_err(&priv->pdev->dev, "Memory allocation failed for sysfs attribute %d.\n",
+                               i + 1);
+                       return -ENOMEM;
+               }
+
+               priv->mlxreg_io_dev_attr[i].dev_attr.attr.mode =
+                                               priv->pdata->data[i].mode;
+               priv->mlxreg_io_dev_attr[i].dev_attr.attr.name =
+                                       priv->mlxreg_io_attr[i]->name;
+               priv->mlxreg_io_dev_attr[i].index = i;
+               sysfs_attr_init(&priv->mlxreg_io_dev_attr[i].dev_attr.attr);
+       }
+
+       priv->group.attrs = priv->mlxreg_io_attr;
+       priv->groups[0] = &priv->group;
+       priv->groups[1] = NULL;
+
+       return 0;
+}
+
+static int mlxreg_io_probe(struct platform_device *pdev)
+{
+       struct mlxreg_io_priv_data *priv;
+       int err;
+
+       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->pdata = dev_get_platdata(&pdev->dev);
+       if (!priv->pdata) {
+               dev_err(&pdev->dev, "Failed to get platform data.\n");
+               return -EINVAL;
+       }
+
+       priv->pdev = pdev;
+
+       err = mlxreg_io_attr_init(priv);
+       if (err) {
+               dev_err(&priv->pdev->dev, "Failed to allocate attributes: %d\n",
+                       err);
+               return err;
+       }
+
+       priv->hwmon = devm_hwmon_device_register_with_groups(&pdev->dev,
+                                                            "mlxreg_io",
+                                                             priv,
+                                                             priv->groups);
+       if (IS_ERR(priv->hwmon)) {
+               dev_err(&pdev->dev, "Failed to register hwmon device %ld\n",
+                       PTR_ERR(priv->hwmon));
+               return PTR_ERR(priv->hwmon);
+       }
+
+       dev_set_drvdata(&pdev->dev, priv);
+
+       return 0;
+}
+
+static struct platform_driver mlxreg_io_driver = {
+       .driver = {
+           .name = "mlxreg-io",
+       },
+       .probe = mlxreg_io_probe,
+};
+
+module_platform_driver(mlxreg_io_driver);
+
+MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
+MODULE_DESCRIPTION("Mellanox regmap I/O access driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mlxreg-io");
index 107d336453b2c3d15d804ba75ad843dc765a2e93..0c1aa6c314f50a94c55aada1ae314a9edf24ea80 100644 (file)
@@ -1196,16 +1196,16 @@ config INTEL_TURBO_MAX_3
          This driver is only required when the system is not using Hardware
          P-States (HWP). In HWP mode, priority can be read from ACPI tables.
 
-config SILEAD_DMI
-       bool "Tablets with Silead touchscreens"
+config TOUCHSCREEN_DMI
+       bool "DMI based touchscreen configuration info"
        depends on ACPI && DMI && I2C=y && TOUCHSCREEN_SILEAD
        ---help---
-         Certain ACPI based tablets with Silead touchscreens do not have
-         enough data in ACPI tables for the touchscreen driver to handle
-         the touchscreen properly, as OEMs expected the data to be baked
-         into the tablet model specific version of the driver shipped
-         with the OS-image for the device. This option supplies the missing
-         information. Enable this for x86 tablets with Silead touchscreens.
+         Certain ACPI based tablets with e.g. Silead or Chipone touchscreens
+         do not have enough data in ACPI tables for the touchscreen driver to
+         handle the touchscreen properly, as OEMs expect the data to be baked
+         into the tablet model specific version of the driver shipped with the
+         the OS-image for the device. This option supplies the missing info.
+         Enable this for x86 tablets with Silead or Chipone touchscreens.
 
 config INTEL_CHTDC_TI_PWRBTN
        tristate "Intel Cherry Trail Dollar Cove TI power button driver"
index 50dc8f2809144cf23491b1ee473e874b7decc00f..e6d1becf81ce8c6bd526e196b8c167576d0f5c6f 100644 (file)
@@ -78,7 +78,7 @@ obj-$(CONFIG_INTEL_SMARTCONNECT)      += intel-smartconnect.o
 obj-$(CONFIG_PVPANIC)           += pvpanic.o
 obj-$(CONFIG_ALIENWARE_WMI)    += alienware-wmi.o
 obj-$(CONFIG_INTEL_PMC_IPC)    += intel_pmc_ipc.o
-obj-$(CONFIG_SILEAD_DMI)       += silead_dmi.o
+obj-$(CONFIG_TOUCHSCREEN_DMI)  += touchscreen_dmi.o
 obj-$(CONFIG_SURFACE_PRO3_BUTTON)      += surfacepro3_button.o
 obj-$(CONFIG_SURFACE_3_BUTTON) += surface3_button.o
 obj-$(CONFIG_INTEL_PUNIT_IPC)  += intel_punit_ipc.o
index 8952173dd380b6e650c6d54dd6498660286f0a27..fcfeadd1301f427a1f0ba3381ac7ed3fe311966a 100644 (file)
@@ -672,10 +672,7 @@ static void __init find_quirks(void)
 
 static bool has_cap(u32 cap)
 {
-       if ((interface->capability & cap) != 0)
-               return 1;
-
-       return 0;
+       return interface->capability & cap;
 }
 
 /*
@@ -2216,7 +2213,7 @@ static int __init acer_wmi_init(void)
        if (wmi_has_guid(AMW0_GUID1) &&
            !dmi_check_system(amw0_whitelist) &&
            quirks == &quirk_unknown) {
-               pr_err("Unsupported machine has AMW0_GUID1, unable to load\n");
+               pr_debug("Unsupported machine has AMW0_GUID1, unable to load\n");
                return -ENODEV;
        }
 
index 136ff2b4cce5e200cc04ce049d98f7199cf6e8a7..db2af09067dbcb4d57da168ebffed7ede9c5fa94 100644 (file)
@@ -496,6 +496,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = {
        { KE_KEY, 0xC4, { KEY_KBDILLUMUP } },
        { KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } },
        { KE_IGNORE, 0xC6, },  /* Ambient Light Sensor notification */
+       { KE_KEY, 0xFA, { KEY_PROG2 } },           /* Lid flip action */
        { KE_END, 0},
 };
 
index 6afd011de9e514ef05e13c6a5912ff2e78c2be00..7458f7602d5e73be5fcd9b341a54b8ba0290c3b9 100644 (file)
@@ -52,13 +52,12 @@ static const struct acpi_device_id device_ids[] = {
 };
 MODULE_DEVICE_TABLE(acpi, device_ids);
 
-static u64 asus_wireless_method(acpi_handle handle, const char *method,
-                               int param)
+static acpi_status asus_wireless_method(acpi_handle handle, const char *method,
+                                       int param, u64 *ret)
 {
        struct acpi_object_list p;
        union acpi_object obj;
        acpi_status s;
-       u64 ret;
 
        acpi_handle_debug(handle, "Evaluating method %s, parameter %#x\n",
                          method, param);
@@ -67,24 +66,27 @@ static u64 asus_wireless_method(acpi_handle handle, const char *method,
        p.count = 1;
        p.pointer = &obj;
 
-       s = acpi_evaluate_integer(handle, (acpi_string) method, &p, &ret);
+       s = acpi_evaluate_integer(handle, (acpi_string) method, &p, ret);
        if (ACPI_FAILURE(s))
                acpi_handle_err(handle,
                                "Failed to eval method %s, param %#x (%d)\n",
                                method, param, s);
-       acpi_handle_debug(handle, "%s returned %#llx\n", method, ret);
-       return ret;
+       else
+               acpi_handle_debug(handle, "%s returned %#llx\n", method, *ret);
+
+       return s;
 }
 
 static enum led_brightness led_state_get(struct led_classdev *led)
 {
        struct asus_wireless_data *data;
-       int s;
+       acpi_status s;
+       u64 ret;
 
        data = container_of(led, struct asus_wireless_data, led);
        s = asus_wireless_method(acpi_device_handle(data->adev), "HSWC",
-                                data->hswc_params->status);
-       if (s == data->hswc_params->on)
+                                data->hswc_params->status, &ret);
+       if (ACPI_SUCCESS(s) && ret == data->hswc_params->on)
                return LED_FULL;
        return LED_OFF;
 }
@@ -92,10 +94,11 @@ static enum led_brightness led_state_get(struct led_classdev *led)
 static void led_state_update(struct work_struct *work)
 {
        struct asus_wireless_data *data;
+       u64 ret;
 
        data = container_of(work, struct asus_wireless_data, led_work);
        asus_wireless_method(acpi_device_handle(data->adev), "HSWC",
-                            data->led_state);
+                            data->led_state, &ret);
 }
 
 static void led_state_set(struct led_classdev *led, enum led_brightness value)
@@ -167,6 +170,7 @@ static int asus_wireless_add(struct acpi_device *adev)
        data->led.brightness_get = led_state_get;
        data->led.flags = LED_CORE_SUSPENDRESUME;
        data->led.max_brightness = 1;
+       data->led.default_trigger = "rfkill-none";
        err = devm_led_classdev_register(&adev->dev, &data->led);
        if (err)
                destroy_workqueue(data->wq);
index d67f32a29bb4b374b1ef22ef6db7ef417b4fb562..2d6e272315a82eae024c0fe3f242f097c2787f02 100644 (file)
@@ -67,6 +67,7 @@ MODULE_LICENSE("GPL");
 #define NOTIFY_BRNDOWN_MAX             0x2e
 #define NOTIFY_KBD_BRTUP               0xc4
 #define NOTIFY_KBD_BRTDWN              0xc5
+#define NOTIFY_KBD_BRTTOGGLE           0xc7
 
 /* WMI Methods */
 #define ASUS_WMI_METHODID_SPEC         0x43455053 /* BIOS SPECification */
@@ -470,6 +471,7 @@ static void kbd_led_update(struct work_struct *work)
                ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F);
 
        asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL);
+       led_classdev_notify_brightness_hw_changed(&asus->kbd_led, asus->kbd_led_wk);
 }
 
 static int kbd_led_read(struct asus_wmi *asus, int *level, int *env)
@@ -500,15 +502,16 @@ static int kbd_led_read(struct asus_wmi *asus, int *level, int *env)
        return retval;
 }
 
-static void kbd_led_set(struct led_classdev *led_cdev,
-                       enum led_brightness value)
+static void do_kbd_led_set(struct led_classdev *led_cdev, int value)
 {
        struct asus_wmi *asus;
+       int max_level;
 
        asus = container_of(led_cdev, struct asus_wmi, kbd_led);
+       max_level = asus->kbd_led.max_brightness;
 
-       if (value > asus->kbd_led.max_brightness)
-               value = asus->kbd_led.max_brightness;
+       if (value > max_level)
+               value = max_level;
        else if (value < 0)
                value = 0;
 
@@ -516,6 +519,12 @@ static void kbd_led_set(struct led_classdev *led_cdev,
        queue_work(asus->led_workqueue, &asus->kbd_led_work);
 }
 
+static void kbd_led_set(struct led_classdev *led_cdev,
+                       enum led_brightness value)
+{
+       do_kbd_led_set(led_cdev, value);
+}
+
 static enum led_brightness kbd_led_get(struct led_classdev *led_cdev)
 {
        struct asus_wmi *asus;
@@ -666,6 +675,7 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
 
                asus->kbd_led_wk = led_val;
                asus->kbd_led.name = "asus::kbd_backlight";
+               asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
                asus->kbd_led.brightness_set = kbd_led_set;
                asus->kbd_led.brightness_get = kbd_led_get;
                asus->kbd_led.max_brightness = 3;
@@ -1754,6 +1764,22 @@ static void asus_wmi_notify(u32 value, void *context)
                }
        }
 
+       if (code == NOTIFY_KBD_BRTUP) {
+               do_kbd_led_set(&asus->kbd_led, asus->kbd_led_wk + 1);
+               goto exit;
+       }
+       if (code == NOTIFY_KBD_BRTDWN) {
+               do_kbd_led_set(&asus->kbd_led, asus->kbd_led_wk - 1);
+               goto exit;
+       }
+       if (code == NOTIFY_KBD_BRTTOGGLE) {
+               if (asus->kbd_led_wk == asus->kbd_led.max_brightness)
+                       do_kbd_led_set(&asus->kbd_led, 0);
+               else
+                       do_kbd_led_set(&asus->kbd_led, asus->kbd_led_wk + 1);
+               goto exit;
+       }
+
        if (is_display_toggle(code) &&
            asus->driver->quirks->no_display_toggle)
                goto exit;
index 9dc282ed5a9e1db7d926348ea30bd7905893a27c..0537d44d45a6e335ec2f9db02bfa6a2bbad172ed 100644 (file)
@@ -212,6 +212,12 @@ int dell_smbios_call_filter(struct device *d,
        if ((buffer->cmd_class == CLASS_TOKEN_READ ||
             buffer->cmd_class == CLASS_TOKEN_WRITE) &&
             buffer->cmd_select < 3) {
+               /* tokens enabled ? */
+               if (!da_tokens) {
+                       dev_dbg(d, "no token support on this system\n");
+                       return -EINVAL;
+               }
+
                /* find the matching token ID */
                for (i = 0; i < da_num_tokens; i++) {
                        if (da_tokens[i].location != buffer->input[0])
@@ -315,6 +321,9 @@ struct calling_interface_token *dell_smbios_find_token(int tokenid)
 {
        int i;
 
+       if (!da_tokens)
+               return NULL;
+
        for (i = 0; i < da_num_tokens; i++) {
                if (da_tokens[i].tokenID == tokenid)
                        return &da_tokens[i];
@@ -565,11 +574,6 @@ static int __init dell_smbios_init(void)
 
        dmi_walk(find_tokens, NULL);
 
-       if (!da_tokens)  {
-               pr_info("Unable to find dmi tokens\n");
-               return -ENODEV;
-       }
-
        ret = platform_driver_register(&platform_driver);
        if (ret)
                goto fail_platform_driver;
@@ -583,13 +587,6 @@ static int __init dell_smbios_init(void)
        if (ret)
                goto fail_platform_device_add;
 
-       /* duplicate tokens will cause problems building sysfs files */
-       zero_duplicates(&platform_device->dev);
-
-       ret = build_tokens_sysfs(platform_device);
-       if (ret)
-               goto fail_create_group;
-
        /* register backends */
        wmi = init_dell_smbios_wmi();
        if (wmi)
@@ -600,7 +597,16 @@ static int __init dell_smbios_init(void)
        if (wmi && smm) {
                pr_err("No SMBIOS backends available (wmi: %d, smm: %d)\n",
                        wmi, smm);
-               goto fail_sysfs;
+               goto fail_create_group;
+       }
+
+       if (da_tokens)  {
+               /* duplicate tokens will cause problems building sysfs files */
+               zero_duplicates(&platform_device->dev);
+
+               ret = build_tokens_sysfs(platform_device);
+               if (ret)
+                       goto fail_sysfs;
        }
 
        return 0;
@@ -628,7 +634,8 @@ static void __exit dell_smbios_exit(void)
        exit_dell_smbios_smm();
        mutex_lock(&smbios_mutex);
        if (platform_device) {
-               free_group(platform_device);
+               if (da_tokens)
+                       free_group(platform_device);
                platform_device_unregister(platform_device);
                platform_driver_unregister(&platform_driver);
        }
index e9e9da556318703275ac6cb9eef59ae7426d4776..97a90bebc36079f5ff716b8d739bd27928aa442a 100644 (file)
@@ -24,7 +24,7 @@
 static int da_command_address;
 static int da_command_code;
 static struct calling_interface_buffer *buffer;
-struct platform_device *platform_device;
+static struct platform_device *platform_device;
 static DEFINE_MUTEX(smm_mutex);
 
 static const struct dmi_system_id dell_device_table[] __initconst = {
@@ -82,7 +82,7 @@ static void find_cmd_address(const struct dmi_header *dm, void *dummy)
        }
 }
 
-int dell_smbios_smm_call(struct calling_interface_buffer *input)
+static int dell_smbios_smm_call(struct calling_interface_buffer *input)
 {
        struct smi_cmd command;
        size_t size;
index fbefedb1c17237c5a926446bb9162ef2a8fcb993..88afe5651d24aec8e1d30b748cd67f295d1558d5 100644 (file)
@@ -82,7 +82,7 @@ static int run_smbios_call(struct wmi_device *wdev)
        return 0;
 }
 
-int dell_smbios_wmi_call(struct calling_interface_buffer *buffer)
+static int dell_smbios_wmi_call(struct calling_interface_buffer *buffer)
 {
        struct wmi_smbios_priv *priv;
        size_t difference;
index 45b7cb01f4101ee8526ac5f4f7f86a626959f220..d4f1259ff5a233bc22bb0700ddb354ace4b40e58 100644 (file)
@@ -1133,10 +1133,17 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
                },
        },
        {
-               .ident = "Lenovo Legion Y520-15IKBN",
+               .ident = "Lenovo Legion Y520-15IKB",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Y520-15IKBN"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Y520-15IKB"),
+               },
+       },
+       {
+               .ident = "Lenovo Y520-15IKBM",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Y520-15IKBM"),
                },
        },
        {
@@ -1153,6 +1160,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
                        DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Y720-15IKBN"),
                },
        },
+       {
+               .ident = "Lenovo Y720-15IKBM",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Y720-15IKBM"),
+               },
+       },
        {
                .ident = "Lenovo Yoga 2 11 / 13 / Pro",
                .matches = {
index b5adba2277832262883ef7034460898138de32ff..6cf9b7fa5bf0486fcf7e9d0b3ed805cfe07ca19d 100644 (file)
@@ -96,13 +96,140 @@ struct intel_hid_priv {
        bool wakeup_mode;
 };
 
-static int intel_hid_set_enable(struct device *device, bool enable)
+#define HID_EVENT_FILTER_UUID  "eeec56b3-4442-408f-a792-4edd4d758054"
+
+enum intel_hid_dsm_fn_codes {
+       INTEL_HID_DSM_FN_INVALID,
+       INTEL_HID_DSM_BTNL_FN,
+       INTEL_HID_DSM_HDMM_FN,
+       INTEL_HID_DSM_HDSM_FN,
+       INTEL_HID_DSM_HDEM_FN,
+       INTEL_HID_DSM_BTNS_FN,
+       INTEL_HID_DSM_BTNE_FN,
+       INTEL_HID_DSM_HEBC_V1_FN,
+       INTEL_HID_DSM_VGBS_FN,
+       INTEL_HID_DSM_HEBC_V2_FN,
+       INTEL_HID_DSM_FN_MAX
+};
+
+static const char *intel_hid_dsm_fn_to_method[INTEL_HID_DSM_FN_MAX] = {
+       NULL,
+       "BTNL",
+       "HDMM",
+       "HDSM",
+       "HDEM",
+       "BTNS",
+       "BTNE",
+       "HEBC",
+       "VGBS",
+       "HEBC"
+};
+
+static unsigned long long intel_hid_dsm_fn_mask;
+static guid_t intel_dsm_guid;
+
+static bool intel_hid_execute_method(acpi_handle handle,
+                                    enum intel_hid_dsm_fn_codes fn_index,
+                                    unsigned long long arg)
 {
+       union acpi_object *obj, argv4, req;
        acpi_status status;
+       char *method_name;
 
-       status = acpi_execute_simple_method(ACPI_HANDLE(device), "HDSM",
-                                           enable);
-       if (ACPI_FAILURE(status)) {
+       if (fn_index <= INTEL_HID_DSM_FN_INVALID ||
+           fn_index >= INTEL_HID_DSM_FN_MAX)
+               return false;
+
+       method_name = (char *)intel_hid_dsm_fn_to_method[fn_index];
+
+       if (!(intel_hid_dsm_fn_mask & fn_index))
+               goto skip_dsm_exec;
+
+       /* All methods expects a package with one integer element */
+       req.type = ACPI_TYPE_INTEGER;
+       req.integer.value = arg;
+
+       argv4.type = ACPI_TYPE_PACKAGE;
+       argv4.package.count = 1;
+       argv4.package.elements = &req;
+
+       obj = acpi_evaluate_dsm(handle, &intel_dsm_guid, 1, fn_index, &argv4);
+       if (obj) {
+               acpi_handle_debug(handle, "Exec DSM Fn code: %d[%s] success\n",
+                                 fn_index, method_name);
+               ACPI_FREE(obj);
+               return true;
+       }
+
+skip_dsm_exec:
+       status = acpi_execute_simple_method(handle, method_name, arg);
+       if (ACPI_SUCCESS(status))
+               return true;
+
+       return false;
+}
+
+static bool intel_hid_evaluate_method(acpi_handle handle,
+                                     enum intel_hid_dsm_fn_codes fn_index,
+                                     unsigned long long *result)
+{
+       union acpi_object *obj;
+       acpi_status status;
+       char *method_name;
+
+       if (fn_index <= INTEL_HID_DSM_FN_INVALID ||
+           fn_index >= INTEL_HID_DSM_FN_MAX)
+               return false;
+
+       method_name = (char *)intel_hid_dsm_fn_to_method[fn_index];
+
+       if (!(intel_hid_dsm_fn_mask & fn_index))
+               goto skip_dsm_eval;
+
+       obj = acpi_evaluate_dsm_typed(handle, &intel_dsm_guid,
+                                     1, fn_index,
+                                     NULL,  ACPI_TYPE_INTEGER);
+       if (obj) {
+               *result = obj->integer.value;
+               acpi_handle_debug(handle,
+                                 "Eval DSM Fn code: %d[%s] results: 0x%llx\n",
+                                 fn_index, method_name, *result);
+               ACPI_FREE(obj);
+               return true;
+       }
+
+skip_dsm_eval:
+       status = acpi_evaluate_integer(handle, method_name, NULL, result);
+       if (ACPI_SUCCESS(status))
+               return true;
+
+       return false;
+}
+
+static void intel_hid_init_dsm(acpi_handle handle)
+{
+       union acpi_object *obj;
+
+       guid_parse(HID_EVENT_FILTER_UUID, &intel_dsm_guid);
+
+       obj = acpi_evaluate_dsm_typed(handle, &intel_dsm_guid, 1, 0, NULL,
+                                     ACPI_TYPE_BUFFER);
+       if (obj) {
+               intel_hid_dsm_fn_mask = *obj->buffer.pointer;
+               ACPI_FREE(obj);
+       }
+
+       acpi_handle_debug(handle, "intel_hid_dsm_fn_mask = %llx\n",
+                         intel_hid_dsm_fn_mask);
+}
+
+static int intel_hid_set_enable(struct device *device, bool enable)
+{
+       acpi_handle handle = ACPI_HANDLE(device);
+
+       /* Enable|disable features - power button is always enabled */
+       if (!intel_hid_execute_method(handle, INTEL_HID_DSM_HDSM_FN,
+                                     enable)) {
                dev_warn(device, "failed to %sable hotkeys\n",
                         enable ? "en" : "dis");
                return -EIO;
@@ -129,9 +256,8 @@ static void intel_button_array_enable(struct device *device, bool enable)
        }
 
        /* Enable|disable features - power button is always enabled */
-       status = acpi_execute_simple_method(handle, "BTNE",
-                                           enable ? button_cap : 1);
-       if (ACPI_FAILURE(status))
+       if (!intel_hid_execute_method(handle, INTEL_HID_DSM_BTNE_FN,
+                                     enable ? button_cap : 1))
                dev_warn(device, "failed to set button capability\n");
 }
 
@@ -217,7 +343,6 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
        struct platform_device *device = context;
        struct intel_hid_priv *priv = dev_get_drvdata(&device->dev);
        unsigned long long ev_index;
-       acpi_status status;
 
        if (priv->wakeup_mode) {
                /*
@@ -269,8 +394,8 @@ wakeup:
                return;
        }
 
-       status = acpi_evaluate_integer(handle, "HDEM", NULL, &ev_index);
-       if (ACPI_FAILURE(status)) {
+       if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_HDEM_FN,
+                                      &ev_index)) {
                dev_warn(&device->dev, "failed to get event index\n");
                return;
        }
@@ -284,17 +409,24 @@ static bool button_array_present(struct platform_device *device)
 {
        acpi_handle handle = ACPI_HANDLE(&device->dev);
        unsigned long long event_cap;
-       acpi_status status;
-       bool supported = false;
 
-       status = acpi_evaluate_integer(handle, "HEBC", NULL, &event_cap);
-       if (ACPI_SUCCESS(status) && (event_cap & 0x20000))
-               supported = true;
+       if (intel_hid_evaluate_method(handle, INTEL_HID_DSM_HEBC_V2_FN,
+                                     &event_cap)) {
+               /* Check presence of 5 button array or v2 power button */
+               if (event_cap & 0x60000)
+                       return true;
+       }
+
+       if (intel_hid_evaluate_method(handle, INTEL_HID_DSM_HEBC_V1_FN,
+                                     &event_cap)) {
+               if (event_cap & 0x20000)
+                       return true;
+       }
 
        if (dmi_check_system(button_array_table))
-               supported = true;
+               return true;
 
-       return supported;
+       return false;
 }
 
 static int intel_hid_probe(struct platform_device *device)
@@ -305,8 +437,9 @@ static int intel_hid_probe(struct platform_device *device)
        acpi_status status;
        int err;
 
-       status = acpi_evaluate_integer(handle, "HDMM", NULL, &mode);
-       if (ACPI_FAILURE(status)) {
+       intel_hid_init_dsm(handle);
+
+       if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_HDMM_FN, &mode)) {
                dev_warn(&device->dev, "failed to read mode\n");
                return -ENODEV;
        }
@@ -352,13 +485,16 @@ static int intel_hid_probe(struct platform_device *device)
                goto err_remove_notify;
 
        if (priv->array) {
+               unsigned long long dummy;
+
                intel_button_array_enable(&device->dev, true);
 
                /* Call button load method to enable HID power button */
-               status = acpi_evaluate_object(handle, "BTNL", NULL, NULL);
-               if (ACPI_FAILURE(status))
+               if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN,
+                                              &dummy)) {
                        dev_warn(&device->dev,
                                 "failed to enable HID power button\n");
+               }
        }
 
        device_init_wakeup(&device->dev, true);
index c13780b8dabbe089c24a2b5c323f1510f589153e..06cd7e818ed5dd8b9c28c5f67289d8dc90b07644 100644 (file)
@@ -17,6 +17,7 @@
 
 /* When NOT in tablet mode, VGBS returns with the flag 0x40 */
 #define TABLET_MODE_FLAG 0x40
+#define DOCK_MODE_FLAG   0x80
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("AceLan Kao");
@@ -38,6 +39,8 @@ static const struct key_entry intel_vbtn_keymap[] = {
        { KE_IGNORE, 0xC7, { KEY_VOLUMEDOWN } },        /* volume-down key release */
        { KE_KEY,    0xC8, { KEY_ROTATE_LOCK_TOGGLE } },        /* rotate-lock key press */
        { KE_KEY,    0xC9, { KEY_ROTATE_LOCK_TOGGLE } },        /* rotate-lock key release */
+       { KE_SW,     0xCA, { .sw = { SW_DOCK, 1 } } },          /* Docked */
+       { KE_SW,     0xCB, { .sw = { SW_DOCK, 0 } } },          /* Undocked */
        { KE_SW,     0xCC, { .sw = { SW_TABLET_MODE, 1 } } },   /* Tablet */
        { KE_SW,     0xCD, { .sw = { SW_TABLET_MODE, 0 } } },   /* Laptop */
        { KE_END },
@@ -121,6 +124,8 @@ static void detect_tablet_mode(struct platform_device *device)
 
        m = !(obj->integer.value & TABLET_MODE_FLAG);
        input_report_switch(priv->input_dev, SW_TABLET_MODE, m);
+       m = (obj->integer.value & DOCK_MODE_FLAG) ? 1 : 0;
+       input_report_switch(priv->input_dev, SW_DOCK, m);
 out:
        kfree(vgbs_output.pointer);
 }
index 014fc1634a3d856300e4c439c6b5c0c20a699b58..c5ece7ef08c6df36b2d1ccff788f99c3cb408abe 100644 (file)
@@ -858,10 +858,7 @@ static u16 read_mgtv(struct ips_driver *ips)
 
 static u16 read_ptv(struct ips_driver *ips)
 {
-       u16 val, slope, offset;
-
-       slope = (ips->pta_val & PTA_SLOPE_MASK) >> PTA_SLOPE_SHIFT;
-       offset = ips->pta_val & PTA_OFFSET_MASK;
+       u16 val;
 
        val = thm_readw(THM_PTV) & PTV_MASK;
 
index 43bbe74743d9e85efa43584346adddc1bca1992d..2d272a3e017621365de7d38dfbfa68bef7d73ab2 100644 (file)
@@ -196,9 +196,67 @@ static const struct pmc_bit_map cnp_pfear_map[] = {
        {}
 };
 
+static const struct pmc_bit_map cnp_slps0_dbg0_map[] = {
+       {"AUDIO_D3",            BIT(0)},
+       {"OTG_D3",              BIT(1)},
+       {"XHCI_D3",             BIT(2)},
+       {"LPIO_D3",             BIT(3)},
+       {"SDX_D3",              BIT(4)},
+       {"SATA_D3",             BIT(5)},
+       {"UFS0_D3",             BIT(6)},
+       {"UFS1_D3",             BIT(7)},
+       {"EMMC_D3",             BIT(8)},
+       {}
+};
+
+static const struct pmc_bit_map cnp_slps0_dbg1_map[] = {
+       {"SDIO_PLL_OFF",        BIT(0)},
+       {"USB2_PLL_OFF",        BIT(1)},
+       {"AUDIO_PLL_OFF",       BIT(2)},
+       {"OC_PLL_OFF",          BIT(3)},
+       {"MAIN_PLL_OFF",        BIT(4)},
+       {"XOSC_OFF",            BIT(5)},
+       {"LPC_CLKS_GATED",      BIT(6)},
+       {"PCIE_CLKREQS_IDLE",   BIT(7)},
+       {"AUDIO_ROSC_OFF",      BIT(8)},
+       {"HPET_XOSC_CLK_REQ",   BIT(9)},
+       {"PMC_ROSC_SLOW_CLK",   BIT(10)},
+       {"AON2_ROSC_GATED",     BIT(11)},
+       {"CLKACKS_DEASSERTED",  BIT(12)},
+       {}
+};
+
+static const struct pmc_bit_map cnp_slps0_dbg2_map[] = {
+       {"MPHY_CORE_GATED",     BIT(0)},
+       {"CSME_GATED",          BIT(1)},
+       {"USB2_SUS_GATED",      BIT(2)},
+       {"DYN_FLEX_IO_IDLE",    BIT(3)},
+       {"GBE_NO_LINK",         BIT(4)},
+       {"THERM_SEN_DISABLED",  BIT(5)},
+       {"PCIE_LOW_POWER",      BIT(6)},
+       {"ISH_VNNAON_REQ_ACT",  BIT(7)},
+       {"ISH_VNN_REQ_ACT",     BIT(8)},
+       {"CNV_VNNAON_REQ_ACT",  BIT(9)},
+       {"CNV_VNN_REQ_ACT",     BIT(10)},
+       {"NPK_VNNON_REQ_ACT",   BIT(11)},
+       {"PMSYNC_STATE_IDLE",   BIT(12)},
+       {"ALST_GT_THRES",       BIT(13)},
+       {"PMC_ARC_PG_READY",    BIT(14)},
+       {}
+};
+
+static const struct pmc_bit_map *cnp_slps0_dbg_maps[] = {
+       cnp_slps0_dbg0_map,
+       cnp_slps0_dbg1_map,
+       cnp_slps0_dbg2_map,
+       NULL,
+};
+
 static const struct pmc_reg_map cnp_reg_map = {
        .pfear_sts = cnp_pfear_map,
        .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
+       .slps0_dbg_maps = cnp_slps0_dbg_maps,
+       .slps0_dbg_offset = CNP_PMC_SLPS0_DBG_OFFSET,
        .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
        .regmap_length = CNP_PMC_MMIO_REG_LEN,
        .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
@@ -252,6 +310,8 @@ static int pmc_core_check_read_lock_bit(void)
 }
 
 #if IS_ENABLED(CONFIG_DEBUG_FS)
+static bool slps0_dbg_latch;
+
 static void pmc_core_display_map(struct seq_file *s, int index,
                                 u8 pf_reg, const struct pmc_bit_map *pf_map)
 {
@@ -481,6 +541,57 @@ static const struct file_operations pmc_core_ltr_ignore_ops = {
        .release        = single_release,
 };
 
+static void pmc_core_slps0_dbg_latch(struct pmc_dev *pmcdev, bool reset)
+{
+       const struct pmc_reg_map *map = pmcdev->map;
+       u32 fd;
+
+       mutex_lock(&pmcdev->lock);
+
+       if (!reset && !slps0_dbg_latch)
+               goto out_unlock;
+
+       fd = pmc_core_reg_read(pmcdev, map->slps0_dbg_offset);
+       if (reset)
+               fd &= ~CNP_PMC_LATCH_SLPS0_EVENTS;
+       else
+               fd |= CNP_PMC_LATCH_SLPS0_EVENTS;
+       pmc_core_reg_write(pmcdev, map->slps0_dbg_offset, fd);
+
+       slps0_dbg_latch = 0;
+
+out_unlock:
+       mutex_unlock(&pmcdev->lock);
+}
+
+static int pmc_core_slps0_dbg_show(struct seq_file *s, void *unused)
+{
+       struct pmc_dev *pmcdev = s->private;
+       const struct pmc_bit_map **maps = pmcdev->map->slps0_dbg_maps;
+       const struct pmc_bit_map *map;
+       int offset;
+       u32 data;
+
+       pmc_core_slps0_dbg_latch(pmcdev, false);
+       offset = pmcdev->map->slps0_dbg_offset;
+       while (*maps) {
+               map = *maps;
+               data = pmc_core_reg_read(pmcdev, offset);
+               offset += 4;
+               while (map->name) {
+                       seq_printf(s, "SLP_S0_DBG: %-32s\tState: %s\n",
+                                  map->name,
+                                  data & map->bit_mask ?
+                                  "Yes" : "No");
+                       ++map;
+               }
+               ++maps;
+       }
+       pmc_core_slps0_dbg_latch(pmcdev, true);
+       return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(pmc_core_slps0_dbg);
+
 static void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev)
 {
        debugfs_remove_recursive(pmcdev->dbgfs_dir);
@@ -514,6 +625,15 @@ static int pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
                                    0444, dir, pmcdev,
                                    &pmc_core_mphy_pg_ops);
 
+       if (pmcdev->map->slps0_dbg_maps) {
+               debugfs_create_file("slp_s0_debug_status", 0444,
+                                   dir, pmcdev,
+                                   &pmc_core_slps0_dbg_fops);
+
+               debugfs_create_bool("slp_s0_dbg_latch", 0644,
+                                   dir, &slps0_dbg_latch);
+       }
+
        return 0;
 }
 #else
index 5fa5f97870aafe4890ff77ec591bb94e7fba68f5..93a7e99e1f8b8a0a8d241416c1540cc66c779f20 100644 (file)
@@ -127,12 +127,14 @@ enum ppfear_regs {
 #define CNP_PMC_SLP_S0_RES_COUNTER_OFFSET      0x193C
 #define CNP_PMC_LTR_IGNORE_OFFSET              0x1B0C
 #define CNP_PMC_PM_CFG_OFFSET                  0x1818
+#define CNP_PMC_SLPS0_DBG_OFFSET               0x10B4
 /* Cannonlake: PGD PFET Enable Ack Status Register(s) start */
 #define CNP_PMC_HOST_PPFEAR0A                  0x1D90
 
 #define CNP_PMC_MMIO_REG_LEN                   0x2000
 #define CNP_PPFEAR_NUM_ENTRIES                 8
 #define CNP_PMC_READ_DISABLE_BIT               22
+#define CNP_PMC_LATCH_SLPS0_EVENTS             BIT(31)
 
 struct pmc_bit_map {
        const char *name;
@@ -145,6 +147,7 @@ struct pmc_bit_map {
  * @pfear_sts:         Maps name of IP block to PPFEAR* bit
  * @mphy_sts:          Maps name of MPHY lane to MPHY status lane status bit
  * @pll_sts:           Maps name of PLL to corresponding bit status
+ * @slps0_dbg_maps:    Array of SLP_S0_DBG* registers containing debug info
  * @slp_s0_offset:     PWRMBASE offset to read SLP_S0 residency
  * @ltr_ignore_offset: PWRMBASE offset to read/write LTR ignore bit
  * @regmap_length:     Length of memory to map from PWRMBASE address to access
@@ -153,6 +156,7 @@ struct pmc_bit_map {
  *                     PPFEAR
  * @pm_cfg_offset:     PWRMBASE offset to PM_CFG register
  * @pm_read_disable_bit: Bit index to read PMC_READ_DISABLE
+ * @slps0_dbg_offset:  PWRMBASE offset to SLP_S0_DEBUG_REG*
  *
  * Each PCH has unique set of register offsets and bit indexes. This structure
  * captures them to have a common implementation.
@@ -161,6 +165,7 @@ struct pmc_reg_map {
        const struct pmc_bit_map *pfear_sts;
        const struct pmc_bit_map *mphy_sts;
        const struct pmc_bit_map *pll_sts;
+       const struct pmc_bit_map **slps0_dbg_maps;
        const u32 slp_s0_offset;
        const u32 ltr_ignore_offset;
        const int regmap_length;
@@ -168,6 +173,7 @@ struct pmc_reg_map {
        const int ppfear_buckets;
        const u32 pm_cfg_offset;
        const int pm_read_disable_bit;
+       const u32 slps0_dbg_offset;
 };
 
 /**
index f1afc0ebbc68939f4ff2dc62df5248d583e038ce..2efeab650345c044371aa7c56624e4d650ea7c93 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/platform_device.h>
 #include <asm/intel_punit_ipc.h>
 
index a0fd9aa6d93258f7305dae2dd60506f9f1464689..d89936c93ba0fe069900d739e6f8d8ac1e02f902 100644 (file)
 /* LPC bus IO offsets */
 #define MLXPLAT_CPLD_LPC_I2C_BASE_ADRR         0x2000
 #define MLXPLAT_CPLD_LPC_REG_BASE_ADRR         0x2500
+#define MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET  0x00
+#define MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET  0x01
+#define MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET        0x1d
 #define MLXPLAT_CPLD_LPC_REG_LED1_OFFSET       0x20
 #define MLXPLAT_CPLD_LPC_REG_LED2_OFFSET       0x21
 #define MLXPLAT_CPLD_LPC_REG_LED3_OFFSET       0x22
 #define MLXPLAT_CPLD_LPC_REG_LED4_OFFSET       0x23
 #define MLXPLAT_CPLD_LPC_REG_LED5_OFFSET       0x24
+#define MLXPLAT_CPLD_LPC_REG_GP1_OFFSET                0x30
+#define MLXPLAT_CPLD_LPC_REG_WP1_OFFSET                0x31
+#define MLXPLAT_CPLD_LPC_REG_GP2_OFFSET                0x32
+#define MLXPLAT_CPLD_LPC_REG_WP2_OFFSET                0x33
+#define MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET        0x37
 #define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET       0x3a
 #define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET  0x3b
 #define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET     0x40
 #define MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET        0x41
+#define MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET 0x50
+#define MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET 0x51
+#define MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET  0x52
 #define MLXPLAT_CPLD_LPC_REG_PSU_OFFSET                0x58
 #define MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET  0x59
 #define MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET   0x5a
 #define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET                0x88
 #define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET  0x89
 #define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET   0x8a
+#define MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET       0xe3
+#define MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET     0xe4
+#define MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET     0xe5
+#define MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET     0xe6
+#define MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET     0xe7
+#define MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET     0xe8
+#define MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET     0xe9
+#define MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET     0xea
+#define MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET     0xeb
+#define MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET     0xec
+#define MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET    0xed
+#define MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET    0xee
+#define MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET    0xef
 #define MLXPLAT_CPLD_LPC_IO_RANGE              0x100
 #define MLXPLAT_CPLD_LPC_I2C_CH1_OFF           0xdb
 #define MLXPLAT_CPLD_LPC_I2C_CH2_OFF           0xda
+
 #define MLXPLAT_CPLD_LPC_PIO_OFFSET            0x10000UL
 #define MLXPLAT_CPLD_LPC_REG1  ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
                                  MLXPLAT_CPLD_LPC_I2C_CH1_OFF) | \
                                  MLXPLAT_CPLD_LPC_PIO_OFFSET)
 
 /* Masks for aggregation, psu, pwr and fan event in CPLD related registers. */
+#define MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF        0x04
 #define MLXPLAT_CPLD_AGGR_PSU_MASK_DEF 0x08
 #define MLXPLAT_CPLD_AGGR_PWR_MASK_DEF 0x08
 #define MLXPLAT_CPLD_AGGR_FAN_MASK_DEF 0x40
-#define MLXPLAT_CPLD_AGGR_MASK_DEF     (MLXPLAT_CPLD_AGGR_PSU_MASK_DEF | \
+#define MLXPLAT_CPLD_AGGR_MASK_DEF     (MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF | \
+                                        MLXPLAT_CPLD_AGGR_PSU_MASK_DEF | \
                                         MLXPLAT_CPLD_AGGR_FAN_MASK_DEF)
+#define MLXPLAT_CPLD_AGGR_ASIC_MASK_NG 0x01
 #define MLXPLAT_CPLD_AGGR_MASK_NG_DEF  0x04
-#define MLXPLAT_CPLD_LOW_AGGR_MASK_LOW 0xc0
-#define MLXPLAT_CPLD_AGGR_MASK_MSN21XX 0x04
+#define MLXPLAT_CPLD_LOW_AGGR_MASK_LOW 0xc1
 #define MLXPLAT_CPLD_PSU_MASK          GENMASK(1, 0)
 #define MLXPLAT_CPLD_PWR_MASK          GENMASK(1, 0)
 #define MLXPLAT_CPLD_FAN_MASK          GENMASK(3, 0)
+#define MLXPLAT_CPLD_ASIC_MASK         GENMASK(1, 0)
 #define MLXPLAT_CPLD_FAN_NG_MASK       GENMASK(5, 0)
 #define MLXPLAT_CPLD_LED_LO_NIBBLE_MASK        GENMASK(7, 4)
 #define MLXPLAT_CPLD_LED_HI_NIBBLE_MASK        GENMASK(3, 0)
  * @pdev_mux - array of mux platform devices
  * @pdev_hotplug - hotplug platform devices
  * @pdev_led - led platform devices
+ * @pdev_io_regs - register access platform devices
+ * @pdev_fan - FAN platform devices
  */
 struct mlxplat_priv {
        struct platform_device *pdev_i2c;
        struct platform_device *pdev_mux[MLXPLAT_CPLD_LPC_MUX_DEVS];
        struct platform_device *pdev_hotplug;
        struct platform_device *pdev_led;
+       struct platform_device *pdev_io_regs;
+       struct platform_device *pdev_fan;
 };
 
 /* Regions for LPC I2C controller and LPC base register space */
@@ -288,6 +320,15 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_items_data[] = {
        },
 };
 
+static struct mlxreg_core_data mlxplat_mlxcpld_default_asic_items_data[] = {
+       {
+               .label = "asic1",
+               .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
+               .mask = MLXPLAT_CPLD_ASIC_MASK,
+               .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
+       },
+};
+
 static struct mlxreg_core_item mlxplat_mlxcpld_default_items[] = {
        {
                .data = mlxplat_mlxcpld_default_psu_items_data,
@@ -316,6 +357,15 @@ static struct mlxreg_core_item mlxplat_mlxcpld_default_items[] = {
                .inversed = 1,
                .health = false,
        },
+       {
+               .data = mlxplat_mlxcpld_default_asic_items_data,
+               .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
+               .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
+               .mask = MLXPLAT_CPLD_ASIC_MASK,
+               .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
+               .inversed = 0,
+               .health = true,
+       },
 };
 
 static
@@ -324,6 +374,8 @@ struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_data = {
        .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_items),
        .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
        .mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
+       .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
+       .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
 };
 
 static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_pwr_items_data[] = {
@@ -352,6 +404,15 @@ static struct mlxreg_core_item mlxplat_mlxcpld_msn21xx_items[] = {
                .inversed = 0,
                .health = false,
        },
+       {
+               .data = mlxplat_mlxcpld_default_asic_items_data,
+               .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
+               .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
+               .mask = MLXPLAT_CPLD_ASIC_MASK,
+               .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
+               .inversed = 0,
+               .health = true,
+       },
 };
 
 static
@@ -454,6 +515,15 @@ static struct mlxreg_core_item mlxplat_mlxcpld_msn274x_items[] = {
                .inversed = 1,
                .health = false,
        },
+       {
+               .data = mlxplat_mlxcpld_default_asic_items_data,
+               .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
+               .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
+               .mask = MLXPLAT_CPLD_ASIC_MASK,
+               .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
+               .inversed = 0,
+               .health = true,
+       },
 };
 
 static
@@ -492,6 +562,15 @@ static struct mlxreg_core_item mlxplat_mlxcpld_msn201x_items[] = {
                .inversed = 0,
                .health = false,
        },
+       {
+               .data = mlxplat_mlxcpld_default_asic_items_data,
+               .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
+               .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
+               .mask = MLXPLAT_CPLD_ASIC_MASK,
+               .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
+               .inversed = 0,
+               .health = true,
+       },
 };
 
 static
@@ -589,6 +668,15 @@ static struct mlxreg_core_item mlxplat_mlxcpld_default_ng_items[] = {
                .inversed = 1,
                .health = false,
        },
+       {
+               .data = mlxplat_mlxcpld_default_asic_items_data,
+               .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
+               .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
+               .mask = MLXPLAT_CPLD_ASIC_MASK,
+               .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
+               .inversed = 0,
+               .health = true,
+       },
 };
 
 static
@@ -813,6 +901,278 @@ static struct mlxreg_core_platform_data mlxplat_default_ng_led_data = {
                .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_led_data),
 };
 
+/* Platform register access default */
+static struct mlxreg_core_data mlxplat_mlxcpld_default_regs_io_data[] = {
+       {
+               .label = "cpld1_version",
+               .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
+               .bit = GENMASK(7, 0),
+               .mode = 0444,
+       },
+       {
+               .label = "cpld2_version",
+               .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
+               .bit = GENMASK(7, 0),
+               .mode = 0444,
+       },
+       {
+               .label = "reset_long_pb",
+               .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(0),
+               .mode = 0444,
+       },
+       {
+               .label = "reset_short_pb",
+               .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(1),
+               .mode = 0444,
+       },
+       {
+               .label = "reset_aux_pwr_or_ref",
+               .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(2),
+               .mode = 0444,
+       },
+       {
+               .label = "reset_main_pwr_fail",
+               .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(3),
+               .mode = 0444,
+       },
+       {
+               .label = "reset_sw_reset",
+               .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(4),
+               .mode = 0444,
+       },
+       {
+               .label = "reset_fw_reset",
+               .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(5),
+               .mode = 0444,
+       },
+       {
+               .label = "reset_hotswap_or_wd",
+               .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(6),
+               .mode = 0444,
+       },
+       {
+               .label = "reset_asic_thermal",
+               .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(7),
+               .mode = 0444,
+       },
+       {
+               .label = "psu1_on",
+               .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(0),
+               .mode = 0200,
+       },
+       {
+               .label = "psu2_on",
+               .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(1),
+               .mode = 0200,
+       },
+       {
+               .label = "pwr_cycle",
+               .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(2),
+               .mode = 0200,
+       },
+       {
+               .label = "pwr_down",
+               .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(3),
+               .mode = 0200,
+       },
+       {
+               .label = "select_iio",
+               .reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(6),
+               .mode = 0644,
+       },
+       {
+               .label = "asic_health",
+               .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
+               .mask = MLXPLAT_CPLD_ASIC_MASK,
+               .bit = 1,
+               .mode = 0444,
+       },
+};
+
+static struct mlxreg_core_platform_data mlxplat_default_regs_io_data = {
+               .data = mlxplat_mlxcpld_default_regs_io_data,
+               .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_regs_io_data),
+};
+
+/* Platform register access MSN21xx, MSN201x, MSN274x systems families data */
+static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_regs_io_data[] = {
+       {
+               .label = "cpld1_version",
+               .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
+               .bit = GENMASK(7, 0),
+               .mode = 0444,
+       },
+       {
+               .label = "cpld2_version",
+               .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
+               .bit = GENMASK(7, 0),
+               .mode = 0444,
+       },
+       {
+               .label = "reset_long_pb",
+               .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(0),
+               .mode = 0444,
+       },
+       {
+               .label = "reset_short_pb",
+               .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(1),
+               .mode = 0444,
+       },
+       {
+               .label = "reset_aux_pwr_or_ref",
+               .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(2),
+               .mode = 0444,
+       },
+       {
+               .label = "reset_sw_reset",
+               .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(3),
+               .mode = 0444,
+       },
+       {
+               .label = "reset_main_pwr_fail",
+               .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(4),
+               .mode = 0444,
+       },
+       {
+               .label = "reset_asic_thermal",
+               .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(5),
+               .mode = 0444,
+       },
+       {
+               .label = "reset_hotswap_or_halt",
+               .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(6),
+               .mode = 0444,
+       },
+       {
+               .label = "psu1_on",
+               .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(0),
+               .mode = 0200,
+       },
+       {
+               .label = "psu2_on",
+               .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(1),
+               .mode = 0200,
+       },
+       {
+               .label = "pwr_cycle",
+               .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(2),
+               .mode = 0200,
+       },
+       {
+               .label = "pwr_down",
+               .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
+               .mask = GENMASK(7, 0) & ~BIT(3),
+               .mode = 0200,
+       },
+       {
+               .label = "asic_health",
+               .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
+               .mask = MLXPLAT_CPLD_ASIC_MASK,
+               .bit = 1,
+               .mode = 0444,
+       },
+};
+
+static struct mlxreg_core_platform_data mlxplat_msn21xx_regs_io_data = {
+               .data = mlxplat_mlxcpld_msn21xx_regs_io_data,
+               .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_regs_io_data),
+};
+
+/* Platform FAN default */
+static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_data[] = {
+       {
+               .label = "pwm1",
+               .reg = MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET,
+       },
+       {
+               .label = "tacho1",
+               .reg = MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET,
+               .mask = GENMASK(7, 0),
+       },
+       {
+               .label = "tacho2",
+               .reg = MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET,
+               .mask = GENMASK(7, 0),
+       },
+       {
+               .label = "tacho3",
+               .reg = MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET,
+               .mask = GENMASK(7, 0),
+       },
+       {
+               .label = "tacho4",
+               .reg = MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET,
+               .mask = GENMASK(7, 0),
+       },
+       {
+               .label = "tacho5",
+               .reg = MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET,
+               .mask = GENMASK(7, 0),
+       },
+       {
+               .label = "tacho6",
+               .reg = MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET,
+               .mask = GENMASK(7, 0),
+       },
+       {
+               .label = "tacho7",
+               .reg = MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET,
+               .mask = GENMASK(7, 0),
+       },
+       {
+               .label = "tacho8",
+               .reg = MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET,
+               .mask = GENMASK(7, 0),
+       },
+       {
+               .label = "tacho9",
+               .reg = MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET,
+               .mask = GENMASK(7, 0),
+       },
+       {
+               .label = "tacho10",
+               .reg = MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET,
+               .mask = GENMASK(7, 0),
+       },
+       {
+               .label = "tacho11",
+               .reg = MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET,
+               .mask = GENMASK(7, 0),
+       },
+       {
+               .label = "tacho12",
+               .reg = MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET,
+               .mask = GENMASK(7, 0),
+       },
+};
+
+static struct mlxreg_core_platform_data mlxplat_default_fan_data = {
+               .data = mlxplat_mlxcpld_default_fan_data,
+               .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_fan_data),
+};
 
 static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
 {
@@ -822,14 +1182,22 @@ static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
        case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
                return true;
        }
        return false;
@@ -838,15 +1206,25 @@ static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
 static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
 {
        switch (reg) {
+       case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
@@ -856,6 +1234,20 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
        case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
                return true;
        }
        return false;
@@ -864,15 +1256,23 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
 static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
 {
        switch (reg) {
+       case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
@@ -882,11 +1282,31 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
        case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
        case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
+       case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
                return true;
        }
        return false;
 }
 
+static const struct reg_default mlxplat_mlxcpld_regmap_default[] = {
+       { MLXPLAT_CPLD_LPC_REG_WP1_OFFSET, 0x00 },
+       { MLXPLAT_CPLD_LPC_REG_WP2_OFFSET, 0x00 },
+       { MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
+};
+
 struct mlxplat_mlxcpld_regmap_context {
        void __iomem *base;
 };
@@ -919,6 +1339,8 @@ static const struct regmap_config mlxplat_mlxcpld_regmap_config = {
        .writeable_reg = mlxplat_mlxcpld_writeable_reg,
        .readable_reg = mlxplat_mlxcpld_readable_reg,
        .volatile_reg = mlxplat_mlxcpld_volatile_reg,
+       .reg_defaults = mlxplat_mlxcpld_regmap_default,
+       .num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_default),
        .reg_read = mlxplat_mlxcpld_reg_read,
        .reg_write = mlxplat_mlxcpld_reg_write,
 };
@@ -930,6 +1352,8 @@ static struct resource mlxplat_mlxcpld_resources[] = {
 static struct platform_device *mlxplat_dev;
 static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug;
 static struct mlxreg_core_platform_data *mlxplat_led;
+static struct mlxreg_core_platform_data *mlxplat_regs_io;
+static struct mlxreg_core_platform_data *mlxplat_fan;
 
 static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
 {
@@ -944,6 +1368,7 @@ static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
        mlxplat_hotplug->deferred_nr =
                mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
        mlxplat_led = &mlxplat_default_led_data;
+       mlxplat_regs_io = &mlxplat_default_regs_io_data;
 
        return 1;
 };
@@ -961,6 +1386,7 @@ static int __init mlxplat_dmi_msn21xx_matched(const struct dmi_system_id *dmi)
        mlxplat_hotplug->deferred_nr =
                mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
        mlxplat_led = &mlxplat_msn21xx_led_data;
+       mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
 
        return 1;
 };
@@ -978,6 +1404,7 @@ static int __init mlxplat_dmi_msn274x_matched(const struct dmi_system_id *dmi)
        mlxplat_hotplug->deferred_nr =
                mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
        mlxplat_led = &mlxplat_default_led_data;
+       mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
 
        return 1;
 };
@@ -995,6 +1422,7 @@ static int __init mlxplat_dmi_msn201x_matched(const struct dmi_system_id *dmi)
        mlxplat_hotplug->deferred_nr =
                mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
        mlxplat_led = &mlxplat_default_ng_led_data;
+       mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
 
        return 1;
 };
@@ -1012,6 +1440,7 @@ static int __init mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id *dmi)
        mlxplat_hotplug->deferred_nr =
                mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
        mlxplat_led = &mlxplat_msn21xx_led_data;
+       mlxplat_fan = &mlxplat_default_fan_data;
 
        return 1;
 };
@@ -1163,7 +1592,7 @@ static int mlxplat_mlxcpld_verify_bus_topology(int *nr)
 static int __init mlxplat_init(void)
 {
        struct mlxplat_priv *priv;
-       int i, nr, err;
+       int i, j, nr, err;
 
        if (!dmi_check_system(mlxplat_dmi_table))
                return -ENODEV;
@@ -1233,6 +1662,15 @@ static int __init mlxplat_init(void)
                goto fail_platform_mux_register;
        }
 
+       /* Set default registers. */
+       for (j = 0; j <  mlxplat_mlxcpld_regmap_config.num_reg_defaults; j++) {
+               err = regmap_write(mlxplat_hotplug->regmap,
+                                  mlxplat_mlxcpld_regmap_default[j].reg,
+                                  mlxplat_mlxcpld_regmap_default[j].def);
+               if (err)
+                       goto fail_platform_mux_register;
+       }
+
        /* Add LED driver. */
        mlxplat_led->regmap = mlxplat_hotplug->regmap;
        priv->pdev_led = platform_device_register_resndata(
@@ -1244,14 +1682,48 @@ static int __init mlxplat_init(void)
                goto fail_platform_hotplug_register;
        }
 
+       /* Add registers io access driver. */
+       if (mlxplat_regs_io) {
+               mlxplat_regs_io->regmap = mlxplat_hotplug->regmap;
+               priv->pdev_io_regs = platform_device_register_resndata(
+                                       &mlxplat_dev->dev, "mlxreg-io",
+                                       PLATFORM_DEVID_NONE, NULL, 0,
+                                       mlxplat_regs_io,
+                                       sizeof(*mlxplat_regs_io));
+               if (IS_ERR(priv->pdev_io_regs)) {
+                       err = PTR_ERR(priv->pdev_io_regs);
+                       goto fail_platform_led_register;
+               }
+       }
+
+       /* Add FAN driver. */
+       if (mlxplat_fan) {
+               mlxplat_fan->regmap = mlxplat_hotplug->regmap;
+               priv->pdev_fan = platform_device_register_resndata(
+                                       &mlxplat_dev->dev, "mlxreg-fan",
+                                       PLATFORM_DEVID_NONE, NULL, 0,
+                                       mlxplat_fan,
+                                       sizeof(*mlxplat_fan));
+               if (IS_ERR(priv->pdev_fan)) {
+                       err = PTR_ERR(priv->pdev_fan);
+                       goto fail_platform_io_regs_register;
+               }
+       }
+
        /* Sync registers with hardware. */
        regcache_mark_dirty(mlxplat_hotplug->regmap);
        err = regcache_sync(mlxplat_hotplug->regmap);
        if (err)
-               goto fail_platform_led_register;
+               goto fail_platform_fan_register;
 
        return 0;
 
+fail_platform_fan_register:
+       if (mlxplat_fan)
+               platform_device_unregister(priv->pdev_fan);
+fail_platform_io_regs_register:
+       if (mlxplat_regs_io)
+               platform_device_unregister(priv->pdev_io_regs);
 fail_platform_led_register:
        platform_device_unregister(priv->pdev_led);
 fail_platform_hotplug_register:
@@ -1272,6 +1744,10 @@ static void __exit mlxplat_exit(void)
        struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev);
        int i;
 
+       if (priv->pdev_fan)
+               platform_device_unregister(priv->pdev_fan);
+       if (priv->pdev_io_regs)
+               platform_device_unregister(priv->pdev_io_regs);
        platform_device_unregister(priv->pdev_led);
        platform_device_unregister(priv->pdev_hotplug);
 
diff --git a/drivers/platform/x86/silead_dmi.c b/drivers/platform/x86/silead_dmi.c
deleted file mode 100644 (file)
index 853a7ce..0000000
+++ /dev/null
@@ -1,623 +0,0 @@
-/*
- * Silead touchscreen driver DMI based configuration code
- *
- * Copyright (c) 2017 Red Hat 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.
- *
- * Red Hat authors:
- * Hans de Goede <hdegoede@redhat.com>
- */
-
-#include <linux/acpi.h>
-#include <linux/device.h>
-#include <linux/dmi.h>
-#include <linux/i2c.h>
-#include <linux/notifier.h>
-#include <linux/property.h>
-#include <linux/string.h>
-
-struct silead_ts_dmi_data {
-       const char *acpi_name;
-       const struct property_entry *properties;
-};
-
-static const struct property_entry cube_iwork8_air_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1660),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 900),
-       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
-       PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-cube-iwork8-air.fw"),
-       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
-       { }
-};
-
-static const struct silead_ts_dmi_data cube_iwork8_air_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = cube_iwork8_air_props,
-};
-
-static const struct property_entry jumper_ezpad_mini3_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1700),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 1150),
-       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
-       PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-jumper-ezpad-mini3.fw"),
-       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
-       { }
-};
-
-static const struct silead_ts_dmi_data jumper_ezpad_mini3_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = jumper_ezpad_mini3_props,
-};
-
-static const struct property_entry jumper_ezpad_6_pro_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
-       PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-jumper-ezpad-6-pro.fw"),
-       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
-       PROPERTY_ENTRY_BOOL("silead,home-button"),
-       { }
-};
-
-static const struct silead_ts_dmi_data jumper_ezpad_6_pro_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = jumper_ezpad_6_pro_props,
-};
-
-static const struct property_entry dexp_ursus_7w_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 890),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 630),
-       PROPERTY_ENTRY_STRING("firmware-name", "gsl1686-dexp-ursus-7w.fw"),
-       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
-       PROPERTY_ENTRY_BOOL("silead,home-button"),
-       { }
-};
-
-static const struct silead_ts_dmi_data dexp_ursus_7w_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = dexp_ursus_7w_props,
-};
-
-static const struct property_entry surftab_twin_10_1_st10432_8_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1900),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
-       PROPERTY_ENTRY_U32("touchscreen-inverted-y", 1),
-       PROPERTY_ENTRY_STRING("firmware-name",
-                             "gsl3670-surftab-twin-10-1-st10432-8.fw"),
-       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
-       { }
-};
-
-static const struct silead_ts_dmi_data surftab_twin_10_1_st10432_8_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = surftab_twin_10_1_st10432_8_props,
-};
-
-static const struct property_entry surftab_wintron70_st70416_6_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 884),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 632),
-       PROPERTY_ENTRY_STRING("firmware-name",
-                             "gsl1686-surftab-wintron70-st70416-6.fw"),
-       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
-       PROPERTY_ENTRY_BOOL("silead,home-button"),
-       { }
-};
-
-static const struct silead_ts_dmi_data surftab_wintron70_st70416_6_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = surftab_wintron70_st70416_6_props,
-};
-
-static const struct property_entry gp_electronic_t701_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 960),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 640),
-       PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
-       PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
-       PROPERTY_ENTRY_STRING("firmware-name",
-                             "gsl1680-gp-electronic-t701.fw"),
-       { }
-};
-
-static const struct silead_ts_dmi_data gp_electronic_t701_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = gp_electronic_t701_props,
-};
-
-static const struct property_entry pipo_w2s_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1660),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 880),
-       PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
-       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
-       PROPERTY_ENTRY_STRING("firmware-name",
-                             "gsl1680-pipo-w2s.fw"),
-       { }
-};
-
-static const struct silead_ts_dmi_data pipo_w2s_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = pipo_w2s_props,
-};
-
-static const struct property_entry pov_mobii_wintab_p800w_v20_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-min-x", 32),
-       PROPERTY_ENTRY_U32("touchscreen-min-y", 16),
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1692),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 1146),
-       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
-       PROPERTY_ENTRY_STRING("firmware-name",
-                             "gsl3680-pov-mobii-wintab-p800w-v20.fw"),
-       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
-       PROPERTY_ENTRY_BOOL("silead,home-button"),
-       { }
-};
-
-static const struct silead_ts_dmi_data pov_mobii_wintab_p800w_v20_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = pov_mobii_wintab_p800w_v20_props,
-};
-
-static const struct property_entry pov_mobii_wintab_p800w_v21_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1800),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 1150),
-       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
-       PROPERTY_ENTRY_STRING("firmware-name",
-                             "gsl3692-pov-mobii-wintab-p800w.fw"),
-       PROPERTY_ENTRY_BOOL("silead,home-button"),
-       { }
-};
-
-static const struct silead_ts_dmi_data pov_mobii_wintab_p800w_v21_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = pov_mobii_wintab_p800w_v21_props,
-};
-
-static const struct property_entry itworks_tw891_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1600),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 890),
-       PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
-       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
-       PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-itworks-tw891.fw"),
-       { }
-};
-
-static const struct silead_ts_dmi_data itworks_tw891_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = itworks_tw891_props,
-};
-
-static const struct property_entry chuwi_hi8_pro_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
-       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
-       PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-chuwi-hi8-pro.fw"),
-       PROPERTY_ENTRY_BOOL("silead,home-button"),
-       { }
-};
-
-static const struct silead_ts_dmi_data chuwi_hi8_pro_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = chuwi_hi8_pro_props,
-};
-
-static const struct property_entry digma_citi_e200_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
-       PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
-       PROPERTY_ENTRY_STRING("firmware-name",
-                             "gsl1686-digma_citi_e200.fw"),
-       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
-       PROPERTY_ENTRY_BOOL("silead,home-button"),
-       { }
-};
-
-static const struct silead_ts_dmi_data digma_citi_e200_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = digma_citi_e200_props,
-};
-
-static const struct property_entry onda_obook_20_plus_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
-       PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
-       PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
-       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
-       PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-onda-obook-20-plus.fw"),
-       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
-       PROPERTY_ENTRY_BOOL("silead,home-button"),
-       { }
-};
-
-static const struct silead_ts_dmi_data onda_obook_20_plus_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = onda_obook_20_plus_props,
-};
-
-static const struct property_entry chuwi_hi8_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1665),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
-       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
-       PROPERTY_ENTRY_BOOL("silead,home-button"),
-       PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi8.fw"),
-       { }
-};
-
-static const struct silead_ts_dmi_data chuwi_hi8_data = {
-       .acpi_name      = "MSSL0001:00",
-       .properties     = chuwi_hi8_props,
-};
-
-static const struct property_entry chuwi_vi8_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1724),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
-       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
-       PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-chuwi-vi8.fw"),
-       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
-       PROPERTY_ENTRY_BOOL("silead,home-button"),
-       { }
-};
-
-static const struct silead_ts_dmi_data chuwi_vi8_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = chuwi_vi8_props,
-};
-
-static const struct property_entry trekstor_primebook_c13_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 2624),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
-       PROPERTY_ENTRY_STRING("firmware-name",
-                             "gsl1680-trekstor-primebook-c13.fw"),
-       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
-       PROPERTY_ENTRY_BOOL("silead,home-button"),
-       { }
-};
-
-static const struct silead_ts_dmi_data trekstor_primebook_c13_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = trekstor_primebook_c13_props,
-};
-
-static const struct property_entry teclast_x98plus2_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 2048),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
-       PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
-       PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
-       PROPERTY_ENTRY_STRING("firmware-name",
-                             "gsl1686-teclast_x98plus2.fw"),
-       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
-       { }
-};
-
-static const struct silead_ts_dmi_data teclast_x98plus2_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = teclast_x98plus2_props,
-};
-
-static const struct property_entry teclast_x3_plus_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
-       PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-teclast-x3-plus.fw"),
-       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
-       PROPERTY_ENTRY_BOOL("silead,home-button"),
-       { }
-};
-
-static const struct silead_ts_dmi_data teclast_x3_plus_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = teclast_x3_plus_props,
-};
-
-static const struct property_entry onda_v891w_v1_props[] = {
-       PROPERTY_ENTRY_U32("touchscreen-min-x", 46),
-       PROPERTY_ENTRY_U32("touchscreen-min-y",  8),
-       PROPERTY_ENTRY_U32("touchscreen-size-x", 1676),
-       PROPERTY_ENTRY_U32("touchscreen-size-y", 1130),
-       PROPERTY_ENTRY_STRING("firmware-name",
-                             "gsl3680-onda-v891w-v1.fw"),
-       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
-       PROPERTY_ENTRY_BOOL("silead,home-button"),
-       { }
-};
-
-static const struct silead_ts_dmi_data onda_v891w_v1_data = {
-       .acpi_name      = "MSSL1680:00",
-       .properties     = onda_v891w_v1_props,
-};
-
-static const struct dmi_system_id silead_ts_dmi_table[] = {
-       {
-               /* CUBE iwork8 Air */
-               .driver_data = (void *)&cube_iwork8_air_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "cube"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "i1-TF"),
-                       DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
-               },
-       },
-       {
-               /* Jumper EZpad mini3 */
-               .driver_data = (void *)&jumper_ezpad_mini3_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
-                       /* jumperx.T87.KFBNEEA02 with the version-nr dropped */
-                       DMI_MATCH(DMI_BIOS_VERSION, "jumperx.T87.KFBNEEA"),
-               },
-       },
-       {
-               /* Jumper EZpad 6 Pro */
-               .driver_data = (void *)&jumper_ezpad_6_pro_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Jumper"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "EZpad"),
-                       DMI_MATCH(DMI_BIOS_VERSION, "5.12"),
-                       /* Above matches are too generic, add bios-date match */
-                       DMI_MATCH(DMI_BIOS_DATE, "08/18/2017"),
-               },
-       },
-       {
-               /* DEXP Ursus 7W */
-               .driver_data = (void *)&dexp_ursus_7w_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "7W"),
-               },
-       },
-       {
-               /* TrekStor SurfTab twin 10.1 ST10432-8 */
-               .driver_data = (void *)&surftab_twin_10_1_st10432_8_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "TrekStor"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "SurfTab twin 10.1"),
-               },
-       },
-       {
-               /* Trekstor Surftab Wintron 7.0 ST70416-6 */
-               .driver_data = (void *)&surftab_wintron70_st70416_6_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "ST70416-6"),
-                       /* Exact match, different versions need different fw */
-                       DMI_MATCH(DMI_BIOS_VERSION, "TREK.G.WI71C.JGBMRBA04"),
-               },
-       },
-       {
-               /* Trekstor Surftab Wintron 7.0 ST70416-6, newer BIOS */
-               .driver_data = (void *)&surftab_wintron70_st70416_6_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "TrekStor"),
-                       DMI_MATCH(DMI_PRODUCT_NAME,
-                                            "SurfTab wintron 7.0 ST70416-6"),
-                       /* Exact match, different versions need different fw */
-                       DMI_MATCH(DMI_BIOS_VERSION, "TREK.G.WI71C.JGBMRBA05"),
-               },
-       },
-       {
-               /* Ployer Momo7w (same hardware as the Trekstor ST70416-6) */
-               .driver_data = (void *)&surftab_wintron70_st70416_6_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Shenzhen PLOYER"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "MOMO7W"),
-                       /* Exact match, different versions need different fw */
-                       DMI_MATCH(DMI_BIOS_VERSION, "MOMO.G.WI71C.MABMRBA02"),
-               },
-       },
-       {
-               /* GP-electronic T701 */
-               .driver_data = (void *)&gp_electronic_t701_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "T701"),
-                       DMI_MATCH(DMI_BIOS_VERSION, "BYT70A.YNCHENG.WIN.007"),
-               },
-       },
-       {
-               /* Pipo W2S */
-               .driver_data = (void *)&pipo_w2s_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "PIPO"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "W2S"),
-               },
-       },
-       {
-               /* Point of View mobii wintab p800w (v2.0) */
-               .driver_data = (void *)&pov_mobii_wintab_p800w_v20_data,
-               .matches = {
-                       DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
-                       DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
-                       DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1014"),
-                       /* Above matches are too generic, add bios-date match */
-                       DMI_MATCH(DMI_BIOS_DATE, "10/24/2014"),
-               },
-       },
-       {
-               /* Point of View mobii wintab p800w (v2.1) */
-               .driver_data = (void *)&pov_mobii_wintab_p800w_v21_data,
-               .matches = {
-                       DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
-                       DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
-                       DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
-                       /* Above matches are too generic, add bios-date match */
-                       DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"),
-               },
-       },
-       {
-               /* I.T.Works TW891 */
-               .driver_data = (void *)&itworks_tw891_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "TW891"),
-               },
-       },
-       {
-               /* Chuwi Hi8 Pro */
-               .driver_data = (void *)&chuwi_hi8_pro_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Hampoo"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "X1D3_C806N"),
-               },
-       },
-       {
-               /* Digma Citi E200 */
-               .driver_data = (void *)&digma_citi_e200_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Digma"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "CITI E200"),
-                       DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
-               },
-       },
-       {
-               /* Onda oBook 20 Plus */
-               .driver_data = (void *)&onda_obook_20_plus_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ONDA"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "OBOOK 20 PLUS"),
-               },
-       },
-       {
-               /* Chuwi Hi8 */
-               .driver_data = (void *)&chuwi_hi8_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "S806"),
-               },
-       },
-       {
-               /* Chuwi Hi8 (H1D_S806_206) */
-               .driver_data = (void *)&chuwi_hi8_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "BayTrail"),
-                       DMI_MATCH(DMI_BIOS_VERSION, "H1D_S806_206"),
-               },
-       },
-       {
-               /* Chuwi Vi8 (CWI506) */
-               .driver_data = (void *)&chuwi_vi8_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "i86"),
-                       DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.D86JLBNR"),
-               },
-       },
-       {
-               /* Trekstor Primebook C13 */
-               .driver_data = (void *)&trekstor_primebook_c13_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Primebook C13"),
-               },
-       },
-       {
-               /* Teclast X98 Plus II */
-               .driver_data = (void *)&teclast_x98plus2_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "X98 Plus II"),
-               },
-       },
-       {
-               /* Teclast X3 Plus */
-               .driver_data = (void *)&teclast_x3_plus_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "X3 Plus"),
-                       DMI_MATCH(DMI_BOARD_NAME, "X3 Plus"),
-               },
-       },
-       {
-               /* I.T.Works TW701 */
-               .driver_data = (void *)&surftab_wintron70_st70416_6_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "i71c"),
-                       DMI_MATCH(DMI_BIOS_VERSION, "itWORKS.G.WI71C.JGBMRB"),
-               },
-       },
-       {
-               /* Yours Y8W81, same case and touchscreen as Chuwi Vi8 */
-               .driver_data = (void *)&chuwi_vi8_data,
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "YOURS"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Y8W81"),
-               },
-       },
-       {
-               /* ONDA V891w revision P891WBEBV1B00 aka v1 */
-               .driver_data = (void *)&onda_v891w_v1_data,
-               .matches = {
-                       DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "ONDA"),
-                       DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONDA Tablet"),
-                       DMI_EXACT_MATCH(DMI_BOARD_VERSION, "V001"),
-                       /* Exact match, different versions need different fw */
-                       DMI_EXACT_MATCH(DMI_BIOS_VERSION, "ONDA.W89EBBN08"),
-               },
-       },
-       { },
-};
-
-static const struct silead_ts_dmi_data *silead_ts_data;
-
-static void silead_ts_dmi_add_props(struct i2c_client *client)
-{
-       struct device *dev = &client->dev;
-       int error;
-
-       if (has_acpi_companion(dev) &&
-           !strncmp(silead_ts_data->acpi_name, client->name, I2C_NAME_SIZE)) {
-               error = device_add_properties(dev, silead_ts_data->properties);
-               if (error)
-                       dev_err(dev, "failed to add properties: %d\n", error);
-       }
-}
-
-static int silead_ts_dmi_notifier_call(struct notifier_block *nb,
-                                      unsigned long action, void *data)
-{
-       struct device *dev = data;
-       struct i2c_client *client;
-
-       switch (action) {
-       case BUS_NOTIFY_ADD_DEVICE:
-               client = i2c_verify_client(dev);
-               if (client)
-                       silead_ts_dmi_add_props(client);
-               break;
-
-       default:
-               break;
-       }
-
-       return 0;
-}
-
-static struct notifier_block silead_ts_dmi_notifier = {
-       .notifier_call = silead_ts_dmi_notifier_call,
-};
-
-static int __init silead_ts_dmi_init(void)
-{
-       const struct dmi_system_id *dmi_id;
-       int error;
-
-       dmi_id = dmi_first_match(silead_ts_dmi_table);
-       if (!dmi_id)
-               return 0; /* Not an error */
-
-       silead_ts_data = dmi_id->driver_data;
-
-       error = bus_register_notifier(&i2c_bus_type, &silead_ts_dmi_notifier);
-       if (error)
-               pr_err("%s: failed to register i2c bus notifier: %d\n",
-                       __func__, error);
-
-       return error;
-}
-
-/*
- * We are registering out notifier after i2c core is initialized and i2c bus
- * itself is ready (which happens at postcore initcall level), but before
- * ACPI starts enumerating devices (at subsys initcall level).
- */
-arch_initcall(silead_ts_dmi_init);
index cae9b059569229d7c937e2f7101040969d9c7d5f..fde08a997557fed3aeef16b3729ef1b8c85efe75 100644 (file)
@@ -57,6 +57,7 @@
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/sched.h>
+#include <linux/sched/signal.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/delay.h>
@@ -335,6 +336,7 @@ static struct {
        u32 second_fan:1;
        u32 beep_needs_two_args:1;
        u32 mixer_no_level_control:1;
+       u32 battery_force_primary:1;
        u32 input_device_registered:1;
        u32 platform_drv_registered:1;
        u32 platform_drv_attrs_registered:1;
@@ -343,7 +345,6 @@ static struct {
        u32 sensors_pdev_attrs_registered:1;
        u32 hotkey_poll_active:1;
        u32 has_adaptive_kbd:1;
-       u32 battery:1;
 } tp_features;
 
 static struct {
@@ -358,9 +359,9 @@ struct thinkpad_id_data {
        char *bios_version_str; /* Something like 1ZET51WW (1.03z) */
        char *ec_version_str;   /* Something like 1ZHT51WW-1.04a */
 
-       u16 bios_model;         /* 1Y = 0x5931, 0 = unknown */
-       u16 ec_model;
-       u16 bios_release;       /* 1ZETK1WW = 0x314b, 0 = unknown */
+       u32 bios_model;         /* 1Y = 0x3159, 0 = unknown */
+       u32 ec_model;
+       u16 bios_release;       /* 1ZETK1WW = 0x4b31, 0 = unknown */
        u16 ec_release;
 
        char *model_str;        /* ThinkPad T43 */
@@ -444,17 +445,20 @@ do {                                                                      \
 /*
  * Quirk handling helpers
  *
- * ThinkPad IDs and versions seen in the field so far
- * are two-characters from the set [0-9A-Z], i.e. base 36.
+ * ThinkPad IDs and versions seen in the field so far are
+ * two or three characters from the set [0-9A-Z], i.e. base 36.
  *
  * We use values well outside that range as specials.
  */
 
-#define TPACPI_MATCH_ANY               0xffffU
+#define TPACPI_MATCH_ANY               0xffffffffU
+#define TPACPI_MATCH_ANY_VERSION       0xffffU
 #define TPACPI_MATCH_UNKNOWN           0U
 
-/* TPID('1', 'Y') == 0x5931 */
-#define TPID(__c1, __c2) (((__c2) << 8) | (__c1))
+/* TPID('1', 'Y') == 0x3159 */
+#define TPID(__c1, __c2)       (((__c1) << 8) | (__c2))
+#define TPID3(__c1, __c2, __c3)        (((__c1) << 16) | ((__c2) << 8) | (__c3))
+#define TPVER TPID
 
 #define TPACPI_Q_IBM(__id1, __id2, __quirk)    \
        { .vendor = PCI_VENDOR_ID_IBM,          \
@@ -468,6 +472,12 @@ do {                                                                       \
          .ec = TPACPI_MATCH_ANY,               \
          .quirks = (__quirk) }
 
+#define TPACPI_Q_LNV3(__id1, __id2, __id3, __quirk) \
+       { .vendor = PCI_VENDOR_ID_LENOVO,       \
+         .bios = TPID3(__id1, __id2, __id3),   \
+         .ec = TPACPI_MATCH_ANY,               \
+         .quirks = (__quirk) }
+
 #define TPACPI_QEC_LNV(__id1, __id2, __quirk)  \
        { .vendor = PCI_VENDOR_ID_LENOVO,       \
          .bios = TPACPI_MATCH_ANY,             \
@@ -476,8 +486,8 @@ do {                                                                        \
 
 struct tpacpi_quirk {
        unsigned int vendor;
-       u16 bios;
-       u16 ec;
+       u32 bios;
+       u32 ec;
        unsigned long quirks;
 };
 
@@ -1647,16 +1657,16 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv)
        { .vendor       = (__v),                        \
          .bios         = TPID(__id1, __id2),           \
          .ec           = TPACPI_MATCH_ANY,             \
-         .quirks       = TPACPI_MATCH_ANY << 16        \
-                         | (__bv1) << 8 | (__bv2) }
+         .quirks       = TPACPI_MATCH_ANY_VERSION << 16 \
+                         | TPVER(__bv1, __bv2) }
 
 #define TPV_Q_X(__v, __bid1, __bid2, __bv1, __bv2,     \
                __eid, __ev1, __ev2)                    \
        { .vendor       = (__v),                        \
          .bios         = TPID(__bid1, __bid2),         \
          .ec           = __eid,                        \
-         .quirks       = (__ev1) << 24 | (__ev2) << 16 \
-                         | (__bv1) << 8 | (__bv2) }
+         .quirks       = TPVER(__ev1, __ev2) << 16     \
+                         | TPVER(__bv1, __bv2) }
 
 #define TPV_QI0(__id1, __id2, __bv1, __bv2) \
        TPV_Q(PCI_VENDOR_ID_IBM, __id1, __id2, __bv1, __bv2)
@@ -1798,7 +1808,7 @@ static void __init tpacpi_check_outdated_fw(void)
        /* note that unknown versions are set to 0x0000 and we use that */
        if ((bios_version > thinkpad_id.bios_release) ||
            (ec_version > thinkpad_id.ec_release &&
-                               ec_version != TPACPI_MATCH_ANY)) {
+                               ec_version != TPACPI_MATCH_ANY_VERSION)) {
                /*
                 * The changelogs would let us track down the exact
                 * reason, but it is just too much of a pain to track
@@ -1928,7 +1938,7 @@ enum {    /* hot key scan codes (derived from ACPI DSDT) */
        /* first new observed key (star, favorites) is 0x1311 */
        TP_ACPI_HOTKEYSCAN_STAR = 69,
        TP_ACPI_HOTKEYSCAN_CLIPPING_TOOL2,
-       TP_ACPI_HOTKEYSCAN_UNK25,
+       TP_ACPI_HOTKEYSCAN_CALCULATOR,
        TP_ACPI_HOTKEYSCAN_BLUETOOTH,
        TP_ACPI_HOTKEYSCAN_KEYBOARD,
 
@@ -3449,7 +3459,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
 
                KEY_FAVORITES,       /* Favorite app, 0x311 */
                KEY_RESERVED,        /* Clipping tool */
-               KEY_RESERVED,
+               KEY_CALC,            /* Calculator (above numpad, P52) */
                KEY_BLUETOOTH,       /* Bluetooth */
                KEY_KEYBOARD         /* Keyboard, 0x315 */
                },
@@ -9365,7 +9375,9 @@ static int tpacpi_battery_probe(int battery)
 {
        int ret = 0;
 
-       memset(&battery_info, 0, sizeof(struct tpacpi_battery_driver_data));
+       memset(&battery_info.batteries[battery], 0,
+               sizeof(battery_info.batteries[battery]));
+
        /*
         * 1) Get the current start threshold
         * 2) Check for support
@@ -9420,7 +9432,8 @@ static int tpacpi_battery_probe(int battery)
 static int tpacpi_battery_get_id(const char *battery_name)
 {
 
-       if (strcmp(battery_name, "BAT0") == 0)
+       if (strcmp(battery_name, "BAT0") == 0 ||
+           tp_features.battery_force_primary)
                return BAT_PRIMARY;
        if (strcmp(battery_name, "BAT1") == 0)
                return BAT_SECONDARY;
@@ -9596,8 +9609,26 @@ static struct acpi_battery_hook battery_hook = {
 
 /* Subdriver init/exit */
 
+static const struct tpacpi_quirk battery_quirk_table[] __initconst = {
+       /*
+        * Individual addressing is broken on models that expose the
+        * primary battery as BAT1.
+        */
+       TPACPI_Q_LNV('J', '7', true),       /* B5400 */
+       TPACPI_Q_LNV('J', 'I', true),       /* Thinkpad 11e */
+       TPACPI_Q_LNV3('R', '0', 'B', true), /* Thinkpad 11e gen 3 */
+       TPACPI_Q_LNV3('R', '0', 'C', true), /* Thinkpad 13 */
+       TPACPI_Q_LNV3('R', '0', 'J', true), /* Thinkpad 13 gen 2 */
+};
+
 static int __init tpacpi_battery_init(struct ibm_init_struct *ibm)
 {
+       memset(&battery_info, 0, sizeof(battery_info));
+
+       tp_features.battery_force_primary = tpacpi_check_quirks(
+                                       battery_quirk_table,
+                                       ARRAY_SIZE(battery_quirk_table));
+
        battery_hook_register(&battery_hook);
        return 0;
 }
@@ -9808,36 +9839,37 @@ err_out:
 
 /* Probing */
 
-static bool __pure __init tpacpi_is_fw_digit(const char c)
+static char __init tpacpi_parse_fw_id(const char * const s,
+                                     u32 *model, u16 *release)
 {
-       return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z');
-}
+       int i;
+
+       if (!s || strlen(s) < 8)
+               goto invalid;
+
+       for (i = 0; i < 8; i++)
+               if (!((s[i] >= '0' && s[i] <= '9') ||
+                     (s[i] >= 'A' && s[i] <= 'Z')))
+                       goto invalid;
 
-static bool __pure __init tpacpi_is_valid_fw_id(const char * const s,
-                                               const char t)
-{
        /*
         * Most models: xxyTkkWW (#.##c)
         * Ancient 570/600 and -SL lacks (#.##c)
         */
-       if (s && strlen(s) >= 8 &&
-               tpacpi_is_fw_digit(s[0]) &&
-               tpacpi_is_fw_digit(s[1]) &&
-               s[2] == t &&
-               (s[3] == 'T' || s[3] == 'N') &&
-               tpacpi_is_fw_digit(s[4]) &&
-               tpacpi_is_fw_digit(s[5]))
-               return true;
+       if (s[3] == 'T' || s[3] == 'N') {
+               *model = TPID(s[0], s[1]);
+               *release = TPVER(s[4], s[5]);
+               return s[2];
 
        /* New models: xxxyTkkW (#.##c); T550 and some others */
-       return s && strlen(s) >= 8 &&
-               tpacpi_is_fw_digit(s[0]) &&
-               tpacpi_is_fw_digit(s[1]) &&
-               tpacpi_is_fw_digit(s[2]) &&
-               s[3] == t &&
-               (s[4] == 'T' || s[4] == 'N') &&
-               tpacpi_is_fw_digit(s[5]) &&
-               tpacpi_is_fw_digit(s[6]);
+       } else if (s[4] == 'T' || s[4] == 'N') {
+               *model = TPID3(s[0], s[1], s[2]);
+               *release = TPVER(s[5], s[6]);
+               return s[3];
+       }
+
+invalid:
+       return '\0';
 }
 
 /* returns 0 - probe ok, or < 0 - probe error.
@@ -9849,6 +9881,7 @@ static int __must_check __init get_thinkpad_model_data(
        const struct dmi_device *dev = NULL;
        char ec_fw_string[18];
        char const *s;
+       char t;
 
        if (!tp)
                return -EINVAL;
@@ -9868,15 +9901,11 @@ static int __must_check __init get_thinkpad_model_data(
                return -ENOMEM;
 
        /* Really ancient ThinkPad 240X will fail this, which is fine */
-       if (!(tpacpi_is_valid_fw_id(tp->bios_version_str, 'E') ||
-             tpacpi_is_valid_fw_id(tp->bios_version_str, 'C')))
+       t = tpacpi_parse_fw_id(tp->bios_version_str,
+                              &tp->bios_model, &tp->bios_release);
+       if (t != 'E' && t != 'C')
                return 0;
 
-       tp->bios_model = tp->bios_version_str[0]
-                        | (tp->bios_version_str[1] << 8);
-       tp->bios_release = (tp->bios_version_str[4] << 8)
-                        | tp->bios_version_str[5];
-
        /*
         * ThinkPad T23 or newer, A31 or newer, R50e or newer,
         * X32 or newer, all Z series;  Some models must have an
@@ -9895,12 +9924,9 @@ static int __must_check __init get_thinkpad_model_data(
                        if (!tp->ec_version_str)
                                return -ENOMEM;
 
-                       if (tpacpi_is_valid_fw_id(ec_fw_string, 'H')) {
-                               tp->ec_model = ec_fw_string[0]
-                                               | (ec_fw_string[1] << 8);
-                               tp->ec_release = (ec_fw_string[4] << 8)
-                                               | ec_fw_string[5];
-                       } else {
+                       t = tpacpi_parse_fw_id(ec_fw_string,
+                                              &tp->ec_model, &tp->ec_release);
+                       if (t != 'H') {
                                pr_notice("ThinkPad firmware release %s doesn't match the known patterns\n",
                                          ec_fw_string);
                                pr_notice("please report this to %s\n",
index eef76bfa5d737c44c4675ca9ea7580d3d92fcc79..e366977bda418fa1c8de5a3879549927ba64883d 100644 (file)
@@ -34,6 +34,7 @@
 #define TOSHIBA_ACPI_VERSION   "0.24"
 #define PROC_INTERFACE_VERSION 1
 
+#include <linux/compiler.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -1682,7 +1683,7 @@ static const struct file_operations keys_proc_fops = {
        .write          = keys_proc_write,
 };
 
-static int version_proc_show(struct seq_file *m, void *v)
+static int __maybe_unused version_proc_show(struct seq_file *m, void *v)
 {
        seq_printf(m, "driver:                  %s\n", TOSHIBA_ACPI_VERSION);
        seq_printf(m, "proc_interface:          %d\n", PROC_INTERFACE_VERSION);
@@ -1836,6 +1837,7 @@ static ssize_t kbd_backlight_mode_store(struct device *dev,
                        return ret;
 
                toshiba->kbd_mode = mode;
+               toshiba_acpi->kbd_mode = mode;
 
                /*
                 * Some laptop models with the second generation backlit
@@ -1852,7 +1854,7 @@ static ssize_t kbd_backlight_mode_store(struct device *dev,
                 * event via genetlink.
                 */
                if (toshiba->kbd_type == 2 &&
-                   !toshiba_acpi->kbd_event_generated)
+                   !toshiba->kbd_event_generated)
                        schedule_work(&kbd_bl_work);
        }
 
@@ -2413,16 +2415,21 @@ static const struct attribute_group toshiba_attr_group = {
 
 static void toshiba_acpi_kbd_bl_work(struct work_struct *work)
 {
-       struct acpi_device *acpi_dev = toshiba_acpi->acpi_dev;
-
        /* Update the sysfs entries */
-       if (sysfs_update_group(&acpi_dev->dev.kobj,
+       if (sysfs_update_group(&toshiba_acpi->acpi_dev->dev.kobj,
                               &toshiba_attr_group))
                pr_err("Unable to update sysfs entries\n");
 
+       /* Notify LED subsystem about keyboard backlight change */
+       if (toshiba_acpi->kbd_type == 2 &&
+           toshiba_acpi->kbd_mode != SCI_KBD_MODE_AUTO)
+               led_classdev_notify_brightness_hw_changed(&toshiba_acpi->kbd_led,
+                               (toshiba_acpi->kbd_mode == SCI_KBD_MODE_ON) ?
+                               LED_FULL : LED_OFF);
+
        /* Emulate the keyboard backlight event */
-       acpi_bus_generate_netlink_event(acpi_dev->pnp.device_class,
-                                       dev_name(&acpi_dev->dev),
+       acpi_bus_generate_netlink_event(toshiba_acpi->acpi_dev->pnp.device_class,
+                                       dev_name(&toshiba_acpi->acpi_dev->dev),
                                        0x92, 0);
 }
 
@@ -3119,9 +3126,12 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev)
        /*
         * Only register the LED if KBD illumination is supported
         * and the keyboard backlight operation mode is set to FN-Z
+        * or we detect a second gen keyboard backlight
         */
-       if (dev->kbd_illum_supported && dev->kbd_mode == SCI_KBD_MODE_FNZ) {
+       if (dev->kbd_illum_supported &&
+           (dev->kbd_mode == SCI_KBD_MODE_FNZ || dev->kbd_type == 2)) {
                dev->kbd_led.name = "toshiba::kbd_backlight";
+               dev->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
                dev->kbd_led.max_brightness = 1;
                dev->kbd_led.brightness_set = toshiba_kbd_backlight_set;
                dev->kbd_led.brightness_get = toshiba_kbd_backlight_get;
@@ -3237,11 +3247,16 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event)
                pr_info("SATA power event received %x\n", event);
                break;
        case 0x92: /* Keyboard backlight mode changed */
-               toshiba_acpi->kbd_event_generated = true;
+               dev->kbd_event_generated = true;
                /* Update sysfs entries */
                if (sysfs_update_group(&acpi_dev->dev.kobj,
                                       &toshiba_attr_group))
                        pr_err("Unable to update sysfs entries\n");
+               /* Notify LED subsystem about keyboard backlight change */
+               if (dev->kbd_type == 2 && dev->kbd_mode != SCI_KBD_MODE_AUTO)
+                       led_classdev_notify_brightness_hw_changed(&dev->kbd_led,
+                                       (dev->kbd_mode == SCI_KBD_MODE_ON) ?
+                                       LED_FULL : LED_OFF);
                break;
        case 0x85: /* Unknown */
        case 0x8d: /* Unknown */
diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c
new file mode 100644 (file)
index 0000000..cb204f9
--- /dev/null
@@ -0,0 +1,754 @@
+/*
+ * Touchscreen driver DMI based configuration code
+ *
+ * Copyright (c) 2017 Red Hat 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.
+ *
+ * Red Hat authors:
+ * Hans de Goede <hdegoede@redhat.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/dmi.h>
+#include <linux/i2c.h>
+#include <linux/notifier.h>
+#include <linux/property.h>
+#include <linux/string.h>
+
+struct ts_dmi_data {
+       const char *acpi_name;
+       const struct property_entry *properties;
+};
+
+/* NOTE: Please keep all entries sorted alphabetically */
+
+static const struct property_entry chuwi_hi8_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1665),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
+       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi8.fw"),
+       { }
+};
+
+static const struct ts_dmi_data chuwi_hi8_data = {
+       .acpi_name      = "MSSL0001:00",
+       .properties     = chuwi_hi8_props,
+};
+
+static const struct property_entry chuwi_hi8_pro_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
+       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+       PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-chuwi-hi8-pro.fw"),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data chuwi_hi8_pro_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = chuwi_hi8_pro_props,
+};
+
+static const struct property_entry chuwi_vi8_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1724),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
+       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+       PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-chuwi-vi8.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data chuwi_vi8_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = chuwi_vi8_props,
+};
+
+static const struct property_entry chuwi_vi10_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-min-x", 0),
+       PROPERTY_ENTRY_U32("touchscreen-min-y", 4),
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1858),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
+       PROPERTY_ENTRY_STRING("firmware-name", "gsl3680-chuwi-vi10.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data chuwi_vi10_data = {
+       .acpi_name      = "MSSL0002:00",
+       .properties     = chuwi_vi10_props,
+};
+
+static const struct property_entry connect_tablet9_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-min-x", 9),
+       PROPERTY_ENTRY_U32("touchscreen-min-y", 8),
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1664),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 878),
+       PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
+       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+       PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-connect-tablet9.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       { }
+};
+
+static const struct ts_dmi_data connect_tablet9_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = connect_tablet9_props,
+};
+
+static const struct property_entry cube_iwork8_air_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1660),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 900),
+       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+       PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-cube-iwork8-air.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       { }
+};
+
+static const struct ts_dmi_data cube_iwork8_air_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = cube_iwork8_air_props,
+};
+
+static const struct property_entry cube_knote_i1101_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-min-x", 20),
+       PROPERTY_ENTRY_U32("touchscreen-min-y",  22),
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1961),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1513),
+       PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-cube-knote-i1101.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data cube_knote_i1101_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = cube_knote_i1101_props,
+};
+
+static const struct property_entry dexp_ursus_7w_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 890),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 630),
+       PROPERTY_ENTRY_STRING("firmware-name", "gsl1686-dexp-ursus-7w.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data dexp_ursus_7w_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = dexp_ursus_7w_props,
+};
+
+static const struct property_entry digma_citi_e200_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
+       PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl1686-digma_citi_e200.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data digma_citi_e200_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = digma_citi_e200_props,
+};
+
+static const struct property_entry gp_electronic_t701_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 960),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 640),
+       PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
+       PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl1680-gp-electronic-t701.fw"),
+       { }
+};
+
+static const struct ts_dmi_data gp_electronic_t701_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = gp_electronic_t701_props,
+};
+
+static const struct property_entry itworks_tw891_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1600),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 890),
+       PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
+       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+       PROPERTY_ENTRY_STRING("firmware-name", "gsl3670-itworks-tw891.fw"),
+       { }
+};
+
+static const struct ts_dmi_data itworks_tw891_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = itworks_tw891_props,
+};
+
+static const struct property_entry jumper_ezpad_6_pro_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
+       PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-jumper-ezpad-6-pro.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data jumper_ezpad_6_pro_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = jumper_ezpad_6_pro_props,
+};
+
+static const struct property_entry jumper_ezpad_mini3_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1700),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1150),
+       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+       PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-jumper-ezpad-mini3.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       { }
+};
+
+static const struct ts_dmi_data jumper_ezpad_mini3_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = jumper_ezpad_mini3_props,
+};
+
+static const struct property_entry onda_obook_20_plus_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
+       PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
+       PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
+       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+       PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-onda-obook-20-plus.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data onda_obook_20_plus_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = onda_obook_20_plus_props,
+};
+
+static const struct property_entry onda_v820w_32g_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1665),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
+       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl1680-onda-v820w-32g.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data onda_v820w_32g_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = onda_v820w_32g_props,
+};
+
+static const struct property_entry onda_v891w_v1_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-min-x", 46),
+       PROPERTY_ENTRY_U32("touchscreen-min-y",  8),
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1676),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1130),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl3680-onda-v891w-v1.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data onda_v891w_v1_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = onda_v891w_v1_props,
+};
+
+static const struct property_entry onda_v891w_v3_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-min-x", 35),
+       PROPERTY_ENTRY_U32("touchscreen-min-y", 15),
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1625),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1135),
+       PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl3676-onda-v891w-v3.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data onda_v891w_v3_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = onda_v891w_v3_props,
+};
+
+static const struct property_entry pipo_w2s_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1660),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 880),
+       PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
+       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl1680-pipo-w2s.fw"),
+       { }
+};
+
+static const struct ts_dmi_data pipo_w2s_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = pipo_w2s_props,
+};
+
+static const struct property_entry pov_mobii_wintab_p800w_v20_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-min-x", 32),
+       PROPERTY_ENTRY_U32("touchscreen-min-y", 16),
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1692),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1146),
+       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl3680-pov-mobii-wintab-p800w-v20.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data pov_mobii_wintab_p800w_v20_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = pov_mobii_wintab_p800w_v20_props,
+};
+
+static const struct property_entry pov_mobii_wintab_p800w_v21_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1800),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1150),
+       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl3692-pov-mobii-wintab-p800w.fw"),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data pov_mobii_wintab_p800w_v21_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = pov_mobii_wintab_p800w_v21_props,
+};
+
+static const struct property_entry teclast_x3_plus_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
+       PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-teclast-x3-plus.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data teclast_x3_plus_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = teclast_x3_plus_props,
+};
+
+static const struct property_entry teclast_x98plus2_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 2048),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
+       PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
+       PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl1686-teclast_x98plus2.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       { }
+};
+
+static const struct ts_dmi_data teclast_x98plus2_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = teclast_x98plus2_props,
+};
+
+static const struct property_entry trekstor_primebook_c13_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 2624),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl1680-trekstor-primebook-c13.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data trekstor_primebook_c13_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = trekstor_primebook_c13_props,
+};
+
+static const struct property_entry trekstor_surftab_twin_10_1_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 1900),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
+       PROPERTY_ENTRY_U32("touchscreen-inverted-y", 1),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl3670-surftab-twin-10-1-st10432-8.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       { }
+};
+
+static const struct ts_dmi_data trekstor_surftab_twin_10_1_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = trekstor_surftab_twin_10_1_props,
+};
+
+static const struct property_entry trekstor_surftab_wintron70_props[] = {
+       PROPERTY_ENTRY_U32("touchscreen-size-x", 884),
+       PROPERTY_ENTRY_U32("touchscreen-size-y", 632),
+       PROPERTY_ENTRY_STRING("firmware-name",
+                             "gsl1686-surftab-wintron70-st70416-6.fw"),
+       PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+       PROPERTY_ENTRY_BOOL("silead,home-button"),
+       { }
+};
+
+static const struct ts_dmi_data trekstor_surftab_wintron70_data = {
+       .acpi_name      = "MSSL1680:00",
+       .properties     = trekstor_surftab_wintron70_props,
+};
+
+/* NOTE: Please keep this table sorted alphabetically */
+static const struct dmi_system_id touchscreen_dmi_table[] = {
+       {
+               /* Chuwi Hi8 */
+               .driver_data = (void *)&chuwi_hi8_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "S806"),
+               },
+       },
+       {
+               /* Chuwi Hi8 (H1D_S806_206) */
+               .driver_data = (void *)&chuwi_hi8_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "BayTrail"),
+                       DMI_MATCH(DMI_BIOS_VERSION, "H1D_S806_206"),
+               },
+       },
+       {
+               /* Chuwi Hi8 Pro (CWI513) */
+               .driver_data = (void *)&chuwi_hi8_pro_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hampoo"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "X1D3_C806N"),
+               },
+       },
+       {
+               /* Chuwi Vi8 (CWI506) */
+               .driver_data = (void *)&chuwi_vi8_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "i86"),
+                       DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.D86JLBNR"),
+               },
+       },
+       {
+               /* Chuwi Vi10 (CWI505) */
+               .driver_data = (void *)&chuwi_vi10_data,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
+                       DMI_MATCH(DMI_BOARD_NAME, "BYT-PF02"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "S165"),
+               },
+       },
+       {
+               /* Connect Tablet 9 */
+               .driver_data = (void *)&connect_tablet9_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Connect"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Tablet 9"),
+               },
+       },
+       {
+               /* CUBE iwork8 Air */
+               .driver_data = (void *)&cube_iwork8_air_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "cube"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "i1-TF"),
+                       DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
+               },
+       },
+       {
+               /* Cube KNote i1101 */
+               .driver_data = (void *)&cube_knote_i1101_data,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
+                       DMI_MATCH(DMI_BOARD_NAME, "L1W6_I1101"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "ALLDOCUBE"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "i1101"),
+               },
+       },
+       {
+               /* DEXP Ursus 7W */
+               .driver_data = (void *)&dexp_ursus_7w_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "7W"),
+               },
+       },
+       {
+               /* Digma Citi E200 */
+               .driver_data = (void *)&digma_citi_e200_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Digma"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "CITI E200"),
+                       DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
+               },
+       },
+       {
+               /* GP-electronic T701 */
+               .driver_data = (void *)&gp_electronic_t701_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "T701"),
+                       DMI_MATCH(DMI_BIOS_VERSION, "BYT70A.YNCHENG.WIN.007"),
+               },
+       },
+       {
+               /* I.T.Works TW701 (same hardware as the Trekstor ST70416-6) */
+               .driver_data = (void *)&trekstor_surftab_wintron70_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "i71c"),
+                       DMI_MATCH(DMI_BIOS_VERSION, "itWORKS.G.WI71C.JGBMRB"),
+               },
+       },
+       {
+               /* I.T.Works TW891 */
+               .driver_data = (void *)&itworks_tw891_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "TW891"),
+               },
+       },
+       {
+               /* Jumper EZpad 6 Pro */
+               .driver_data = (void *)&jumper_ezpad_6_pro_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Jumper"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "EZpad"),
+                       DMI_MATCH(DMI_BIOS_VERSION, "5.12"),
+                       /* Above matches are too generic, add bios-date match */
+                       DMI_MATCH(DMI_BIOS_DATE, "08/18/2017"),
+               },
+       },
+       {
+               /* Jumper EZpad mini3 */
+               .driver_data = (void *)&jumper_ezpad_mini3_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+                       /* jumperx.T87.KFBNEEA02 with the version-nr dropped */
+                       DMI_MATCH(DMI_BIOS_VERSION, "jumperx.T87.KFBNEEA"),
+               },
+       },
+       {
+               /* Onda oBook 20 Plus */
+               .driver_data = (void *)&onda_obook_20_plus_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ONDA"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "OBOOK 20 PLUS"),
+               },
+       },
+       {
+               /* ONDA V820w DualOS */
+               .driver_data = (void *)&onda_v820w_32g_data,
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "ONDA"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "V820w DualOS")
+               },
+       },
+       {
+               /* ONDA V891w revision P891WBEBV1B00 aka v1 */
+               .driver_data = (void *)&onda_v891w_v1_data,
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "ONDA"),
+                       DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONDA Tablet"),
+                       DMI_EXACT_MATCH(DMI_BOARD_VERSION, "V001"),
+                       /* Exact match, different versions need different fw */
+                       DMI_EXACT_MATCH(DMI_BIOS_VERSION, "ONDA.W89EBBN08"),
+               },
+       },
+       {
+               /* ONDA V891w Dual OS P891DCF2V1A01274 64GB */
+               .driver_data = (void *)&onda_v891w_v3_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ONDA Tablet"),
+                       DMI_MATCH(DMI_BIOS_VERSION, "ONDA.D890HBBNR0A"),
+               },
+       },
+       {
+               /* Pipo W2S */
+               .driver_data = (void *)&pipo_w2s_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "PIPO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "W2S"),
+               },
+       },
+       {
+               /* Ployer Momo7w (same hardware as the Trekstor ST70416-6) */
+               .driver_data = (void *)&trekstor_surftab_wintron70_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Shenzhen PLOYER"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MOMO7W"),
+                       /* Exact match, different versions need different fw */
+                       DMI_MATCH(DMI_BIOS_VERSION, "MOMO.G.WI71C.MABMRBA02"),
+               },
+       },
+       {
+               /* Point of View mobii wintab p800w (v2.0) */
+               .driver_data = (void *)&pov_mobii_wintab_p800w_v20_data,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+                       DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
+                       DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1014"),
+                       /* Above matches are too generic, add bios-date match */
+                       DMI_MATCH(DMI_BIOS_DATE, "10/24/2014"),
+               },
+       },
+       {
+               /* Point of View mobii wintab p800w (v2.1) */
+               .driver_data = (void *)&pov_mobii_wintab_p800w_v21_data,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+                       DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
+                       DMI_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
+                       /* Above matches are too generic, add bios-date match */
+                       DMI_MATCH(DMI_BIOS_DATE, "08/22/2014"),
+               },
+       },
+       {
+               /* Teclast X3 Plus */
+               .driver_data = (void *)&teclast_x3_plus_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "X3 Plus"),
+                       DMI_MATCH(DMI_BOARD_NAME, "X3 Plus"),
+               },
+       },
+       {
+               /* Teclast X98 Plus II */
+               .driver_data = (void *)&teclast_x98plus2_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "X98 Plus II"),
+               },
+       },
+       {
+               /* Trekstor Primebook C13 */
+               .driver_data = (void *)&trekstor_primebook_c13_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Primebook C13"),
+               },
+       },
+       {
+               /* TrekStor SurfTab twin 10.1 ST10432-8 */
+               .driver_data = (void *)&trekstor_surftab_twin_10_1_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "TrekStor"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "SurfTab twin 10.1"),
+               },
+       },
+       {
+               /* Trekstor Surftab Wintron 7.0 ST70416-6 */
+               .driver_data = (void *)&trekstor_surftab_wintron70_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ST70416-6"),
+                       /* Exact match, different versions need different fw */
+                       DMI_MATCH(DMI_BIOS_VERSION, "TREK.G.WI71C.JGBMRBA04"),
+               },
+       },
+       {
+               /* Trekstor Surftab Wintron 7.0 ST70416-6, newer BIOS */
+               .driver_data = (void *)&trekstor_surftab_wintron70_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "TrekStor"),
+                       DMI_MATCH(DMI_PRODUCT_NAME,
+                                            "SurfTab wintron 7.0 ST70416-6"),
+                       /* Exact match, different versions need different fw */
+                       DMI_MATCH(DMI_BIOS_VERSION, "TREK.G.WI71C.JGBMRBA05"),
+               },
+       },
+       {
+               /* Yours Y8W81, same case and touchscreen as Chuwi Vi8 */
+               .driver_data = (void *)&chuwi_vi8_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "YOURS"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Y8W81"),
+               },
+       },
+       { },
+};
+
+static const struct ts_dmi_data *ts_data;
+
+static void ts_dmi_add_props(struct i2c_client *client)
+{
+       struct device *dev = &client->dev;
+       int error;
+
+       if (has_acpi_companion(dev) &&
+           !strncmp(ts_data->acpi_name, client->name, I2C_NAME_SIZE)) {
+               error = device_add_properties(dev, ts_data->properties);
+               if (error)
+                       dev_err(dev, "failed to add properties: %d\n", error);
+       }
+}
+
+static int ts_dmi_notifier_call(struct notifier_block *nb,
+                                      unsigned long action, void *data)
+{
+       struct device *dev = data;
+       struct i2c_client *client;
+
+       switch (action) {
+       case BUS_NOTIFY_ADD_DEVICE:
+               client = i2c_verify_client(dev);
+               if (client)
+                       ts_dmi_add_props(client);
+               break;
+
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+static struct notifier_block ts_dmi_notifier = {
+       .notifier_call = ts_dmi_notifier_call,
+};
+
+static int __init ts_dmi_init(void)
+{
+       const struct dmi_system_id *dmi_id;
+       int error;
+
+       dmi_id = dmi_first_match(touchscreen_dmi_table);
+       if (!dmi_id)
+               return 0; /* Not an error */
+
+       ts_data = dmi_id->driver_data;
+
+       error = bus_register_notifier(&i2c_bus_type, &ts_dmi_notifier);
+       if (error)
+               pr_err("%s: failed to register i2c bus notifier: %d\n",
+                       __func__, error);
+
+       return error;
+}
+
+/*
+ * We are registering out notifier after i2c core is initialized and i2c bus
+ * itself is ready (which happens at postcore initcall level), but before
+ * ACPI starts enumerating devices (at subsys initcall level).
+ */
+arch_initcall(ts_dmi_init);
index 8e3d0146ff8c30332184d7aa35f4cae748a0b4bf..04791ea5d97b69f9ed9fc30fb7de46cf2370acbe 100644 (file)
@@ -895,7 +895,6 @@ static int wmi_dev_probe(struct device *dev)
        struct wmi_driver *wdriver =
                container_of(dev->driver, struct wmi_driver, driver);
        int ret = 0;
-       int count;
        char *buf;
 
        if (ACPI_FAILURE(wmi_method_enable(wblock, 1)))
@@ -917,9 +916,8 @@ static int wmi_dev_probe(struct device *dev)
                        goto probe_failure;
                }
 
-               count = get_order(wblock->req_buf_size);
-               wblock->handler_data = (void *)__get_free_pages(GFP_KERNEL,
-                                                               count);
+               wblock->handler_data = kmalloc(wblock->req_buf_size,
+                                              GFP_KERNEL);
                if (!wblock->handler_data) {
                        ret = -ENOMEM;
                        goto probe_failure;
@@ -964,8 +962,7 @@ static int wmi_dev_remove(struct device *dev)
        if (wdriver->filter_callback) {
                misc_deregister(&wblock->char_dev);
                kfree(wblock->char_dev.name);
-               free_pages((unsigned long)wblock->handler_data,
-                          get_order(wblock->req_buf_size));
+               kfree(wblock->handler_data);
        }
 
        if (wdriver->remove)
index df58fc878b3e5278394a9b9e2fdc135f3353817e..6533aa560aa1fb6a87eeb15399c9e37e86945fbe 100644 (file)
@@ -104,6 +104,17 @@ config POWER_RESET_MSM
        help
          Power off and restart support for Qualcomm boards.
 
+config POWER_RESET_QCOM_PON
+       tristate "Qualcomm power-on driver"
+       depends on ARCH_QCOM
+       depends on MFD_SPMI_PMIC
+       select REBOOT_MODE
+       help
+         Power On support for Qualcomm boards.
+         If you have a Qualcomm platform and need support for
+         power-on and reboot reason, Say Y.
+         If unsure, Say N.
+
 config POWER_RESET_OCELOT_RESET
        bool "Microsemi Ocelot reset driver"
        depends on MSCC_OCELOT || COMPILE_TEST
index 7778c7485cf19b44b1ccd84fa5e6b738d5866faf..0aebee954ac1bfb6f1775a341a564a470125ed5e 100644 (file)
@@ -11,6 +11,7 @@ obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
 obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
 obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
 obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
+obj-$(CONFIG_POWER_RESET_QCOM_PON) += qcom-pon.o
 obj-$(CONFIG_POWER_RESET_OCELOT_RESET) += ocelot-reset.o
 obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o
 obj-$(CONFIG_POWER_RESET_LTC2952) += ltc2952-poweroff.o
index 2ac291af1265b3feb6770af7d8d337d044df48af..90e35c07240aee158c3478a4f6a248c15b138552 100644 (file)
@@ -130,7 +130,17 @@ static int gemini_poweroff_probe(struct platform_device *pdev)
        val |= GEMINI_CTRL_ENABLE;
        writel(val, gpw->base + GEMINI_PWC_CTRLREG);
 
-       /* Now that the state machine is active, clear the IRQ */
+       /* Clear the IRQ */
+       val = readl(gpw->base + GEMINI_PWC_CTRLREG);
+       val |= GEMINI_CTRL_IRQ_CLR;
+       writel(val, gpw->base + GEMINI_PWC_CTRLREG);
+
+       /* Wait for this to clear */
+       val = readl(gpw->base + GEMINI_PWC_STATREG);
+       while (val & 0x70U)
+               val = readl(gpw->base + GEMINI_PWC_STATREG);
+
+       /* Clear the IRQ again */
        val = readl(gpw->base + GEMINI_PWC_CTRLREG);
        val |= GEMINI_CTRL_IRQ_CLR;
        writel(val, gpw->base + GEMINI_PWC_CTRLREG);
index 6b911b6b10a6b413e60cb33ab8d107cecb1a8774..c484584745bc9f5cf13969714d8dc6cfdc92c976 100644 (file)
@@ -2,7 +2,7 @@
  * LTC2952 (PowerPath) driver
  *
  * Copyright (C) 2014, Xsens Technologies BV <info@xsens.com>
- * Maintainer: René Moll <linux@r-moll.nl>
+ * Maintainer: René Moll <linux@r-moll.nl>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -319,6 +319,6 @@ static struct platform_driver ltc2952_poweroff_driver = {
 
 module_platform_driver(ltc2952_poweroff_driver);
 
-MODULE_AUTHOR("René Moll <rene.moll@xsens.com>");
+MODULE_AUTHOR("René Moll <rene.moll@xsens.com>");
 MODULE_DESCRIPTION("LTC PowerPath power-off driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/power/reset/qcom-pon.c b/drivers/power/reset/qcom-pon.c
new file mode 100644 (file)
index 0000000..0c4caaa
--- /dev/null
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017-18 Linaro Limited
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/reboot-mode.h>
+#include <linux/regmap.h>
+
+#define PON_SOFT_RB_SPARE              0x8f
+
+struct pm8916_pon {
+       struct device *dev;
+       struct regmap *regmap;
+       u32 baseaddr;
+       struct reboot_mode_driver reboot_mode;
+};
+
+static int pm8916_reboot_mode_write(struct reboot_mode_driver *reboot,
+                                   unsigned int magic)
+{
+       struct pm8916_pon *pon = container_of
+                       (reboot, struct pm8916_pon, reboot_mode);
+       int ret;
+
+       ret = regmap_update_bits(pon->regmap,
+                                pon->baseaddr + PON_SOFT_RB_SPARE,
+                                0xfc, magic << 2);
+       if (ret < 0)
+               dev_err(pon->dev, "update reboot mode bits failed\n");
+
+       return ret;
+}
+
+static int pm8916_pon_probe(struct platform_device *pdev)
+{
+       struct pm8916_pon *pon;
+       int error;
+
+       pon = devm_kzalloc(&pdev->dev, sizeof(*pon), GFP_KERNEL);
+       if (!pon)
+               return -ENOMEM;
+
+       pon->dev = &pdev->dev;
+
+       pon->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+       if (!pon->regmap) {
+               dev_err(&pdev->dev, "failed to locate regmap\n");
+               return -ENODEV;
+       }
+
+       error = of_property_read_u32(pdev->dev.of_node, "reg",
+                                    &pon->baseaddr);
+       if (error)
+               return error;
+
+       pon->reboot_mode.dev = &pdev->dev;
+       pon->reboot_mode.write = pm8916_reboot_mode_write;
+       error = devm_reboot_mode_register(&pdev->dev, &pon->reboot_mode);
+       if (error) {
+               dev_err(&pdev->dev, "can't register reboot mode\n");
+               return error;
+       }
+
+       platform_set_drvdata(pdev, pon);
+
+       return devm_of_platform_populate(&pdev->dev);
+}
+
+static const struct of_device_id pm8916_pon_id_table[] = {
+       { .compatible = "qcom,pm8916-pon" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, pm8916_pon_id_table);
+
+static struct platform_driver pm8916_pon_driver = {
+       .probe = pm8916_pon_probe,
+       .driver = {
+               .name = "pm8916-pon",
+               .of_match_table = of_match_ptr(pm8916_pon_id_table),
+       },
+};
+module_platform_driver(pm8916_pon_driver);
+
+MODULE_DESCRIPTION("pm8916 Power On driver");
+MODULE_LICENSE("GPL v2");
index 102f95a094603ff4c0b54245c6d79c50e764cab0..e9e749f87517d871cf2d4113568a44fb9c0b5d09 100644 (file)
@@ -35,6 +35,7 @@ static void vexpress_reset_do(struct device *dev, const char *what)
 }
 
 static struct device *vexpress_power_off_device;
+static atomic_t vexpress_restart_nb_refcnt = ATOMIC_INIT(0);
 
 static void vexpress_power_off(void)
 {
@@ -99,10 +100,13 @@ static int _vexpress_register_restart_handler(struct device *dev)
        int err;
 
        vexpress_restart_device = dev;
-       err = register_restart_handler(&vexpress_restart_nb);
-       if (err) {
-               dev_err(dev, "cannot register restart handler (err=%d)\n", err);
-               return err;
+       if (atomic_inc_return(&vexpress_restart_nb_refcnt) == 1) {
+               err = register_restart_handler(&vexpress_restart_nb);
+               if (err) {
+                       dev_err(dev, "cannot register restart handler (err=%d)\n", err);
+                       atomic_dec(&vexpress_restart_nb_refcnt);
+                       return err;
+               }
        }
        device_create_file(dev, &dev_attr_active);
 
index c03e96e6a041fb261b3b9720e2462d6a59c5a856..186901c96c01769ee5b6f87dc17d57e0df44517d 100644 (file)
@@ -51,6 +51,7 @@ static int zx_reboot_probe(struct platform_device *pdev)
 
        np = of_find_compatible_node(NULL, NULL, "zte,zx296702-pcu");
        pcu_base = of_iomap(np, 0);
+       of_node_put(np);
        if (!pcu_base) {
                iounmap(base);
                WARN(1, "failed to map pcu_base address");
index 428b426842f4bbc574bb100215bd989f9ded602b..ff6dab0bf0ddc2e784b357e0038135761bf2a708 100644 (file)
@@ -75,6 +75,17 @@ config BATTERY_88PM860X
        help
          Say Y here to enable battery monitor for Marvell 88PM860x chip.
 
+config CHARGER_ADP5061
+       tristate "ADP5061 battery charger driver"
+       depends on I2C
+       select REGMAP_I2C
+       help
+         Say Y here to enable support for the ADP5061 standalone battery
+         charger.
+
+         This driver can be built as a module. If so, the module will be
+         called adp5061.
+
 config BATTERY_ACT8945A
        tristate "Active-semi ACT8945A charger driver"
        depends on MFD_ACT8945A || COMPILE_TEST
@@ -92,7 +103,7 @@ config BATTERY_CPCAP
 
 config BATTERY_DS2760
        tristate "DS2760 battery driver (HP iPAQ & others)"
-       depends on W1 && W1_SLAVE_DS2760
+       depends on W1
        help
          Say Y here to enable support for batteries with ds2760 chip.
 
@@ -624,4 +635,14 @@ config CHARGER_RT9455
        help
          Say Y to enable support for Richtek RT9455 battery charger.
 
+config CHARGER_CROS_USBPD
+       tristate "ChromeOS EC based USBPD charger"
+       depends on MFD_CROS_EC
+       default n
+       help
+         Say Y here to enable ChromeOS EC based USBPD charger
+         driver. This driver gets various bits of information about
+         what is connected to USB PD ports from the EC and converts
+         that into power_supply properties.
+
 endif # POWER_SUPPLY
index e83aa843bcc6023f1d3af3f11848cc65ee8a8f36..a26b402c45d91b2c76af8b00dd74424ed980f2b2 100644 (file)
@@ -18,6 +18,7 @@ obj-$(CONFIG_WM8350_POWER)    += wm8350_power.o
 obj-$(CONFIG_TEST_POWER)       += test_power.o
 
 obj-$(CONFIG_BATTERY_88PM860X) += 88pm860x_battery.o
+obj-$(CONFIG_CHARGER_ADP5061)  += adp5061.o
 obj-$(CONFIG_BATTERY_ACT8945A) += act8945a_charger.o
 obj-$(CONFIG_BATTERY_AXP20X)   += axp20x_battery.o
 obj-$(CONFIG_CHARGER_AXP20X)   += axp20x_ac_power.o
@@ -83,3 +84,4 @@ obj-$(CONFIG_CHARGER_TPS65090)        += tps65090-charger.o
 obj-$(CONFIG_CHARGER_TPS65217) += tps65217_charger.o
 obj-$(CONFIG_AXP288_FUEL_GAUGE) += axp288_fuel_gauge.o
 obj-$(CONFIG_AXP288_CHARGER)   += axp288_charger.o
+obj-$(CONFIG_CHARGER_CROS_USBPD)       += cros_usbpd-charger.o
index d9c6c7bedd85968355b4fda5216649657e314266..02356f9b5f22a4e89ef74160a8a54e88b117e733 100644 (file)
@@ -379,15 +379,13 @@ static int ab8500_fg_is_low_curr(struct ab8500_fg *di, int curr)
  */
 static int ab8500_fg_add_cap_sample(struct ab8500_fg *di, int sample)
 {
-       struct timespec64 ts64;
+       time64_t now = ktime_get_boottime_seconds();
        struct ab8500_fg_avg_cap *avg = &di->avg_cap;
 
-       getnstimeofday64(&ts64);
-
        do {
                avg->sum += sample - avg->samples[avg->pos];
                avg->samples[avg->pos] = sample;
-               avg->time_stamps[avg->pos] = ts64.tv_sec;
+               avg->time_stamps[avg->pos] = now;
                avg->pos++;
 
                if (avg->pos == NBR_AVG_SAMPLES)
@@ -400,7 +398,7 @@ static int ab8500_fg_add_cap_sample(struct ab8500_fg *di, int sample)
                 * Check the time stamp for each sample. If too old,
                 * replace with latest sample
                 */
-       } while (ts64.tv_sec - VALID_CAPACITY_SEC > avg->time_stamps[avg->pos]);
+       } while (now - VALID_CAPACITY_SEC > avg->time_stamps[avg->pos]);
 
        avg->avg = avg->sum / avg->nbr_samples;
 
@@ -439,14 +437,14 @@ static void ab8500_fg_clear_cap_samples(struct ab8500_fg *di)
 static void ab8500_fg_fill_cap_sample(struct ab8500_fg *di, int sample)
 {
        int i;
-       struct timespec64 ts64;
+       time64_t now;
        struct ab8500_fg_avg_cap *avg = &di->avg_cap;
 
-       getnstimeofday64(&ts64);
+       now = ktime_get_boottime_seconds();
 
        for (i = 0; i < NBR_AVG_SAMPLES; i++) {
                avg->samples[i] = sample;
-               avg->time_stamps[i] = ts64.tv_sec;
+               avg->time_stamps[i] = now;
        }
 
        avg->pos = 0;
diff --git a/drivers/power/supply/adp5061.c b/drivers/power/supply/adp5061.c
new file mode 100644 (file)
index 0000000..939fd3d
--- /dev/null
@@ -0,0 +1,745 @@
+/*
+ * ADP5061 I2C Programmable Linear Battery Charger
+ *
+ * Copyright 2018 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/mod_devicetable.h>
+#include <linux/power_supply.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+/* ADP5061 registers definition */
+#define ADP5061_ID                     0x00
+#define ADP5061_REV                    0x01
+#define ADP5061_VINX_SET               0x02
+#define ADP5061_TERM_SET               0x03
+#define ADP5061_CHG_CURR               0x04
+#define ADP5061_VOLTAGE_TH             0x05
+#define ADP5061_TIMER_SET              0x06
+#define ADP5061_FUNC_SET_1             0x07
+#define ADP5061_FUNC_SET_2             0x08
+#define ADP5061_INT_EN                 0x09
+#define ADP5061_INT_ACT                        0x0A
+#define ADP5061_CHG_STATUS_1           0x0B
+#define ADP5061_CHG_STATUS_2           0x0C
+#define ADP5061_FAULT                  0x0D
+#define ADP5061_BATTERY_SHORT          0x10
+#define ADP5061_IEND                   0x11
+
+/* ADP5061_VINX_SET */
+#define ADP5061_VINX_SET_ILIM_MSK              GENMASK(3, 0)
+#define ADP5061_VINX_SET_ILIM_MODE(x)          (((x) & 0x0F) << 0)
+
+/* ADP5061_TERM_SET */
+#define ADP5061_TERM_SET_VTRM_MSK              GENMASK(7, 2)
+#define ADP5061_TERM_SET_VTRM_MODE(x)          (((x) & 0x3F) << 2)
+#define ADP5061_TERM_SET_CHG_VLIM_MSK          GENMASK(1, 0)
+#define ADP5061_TERM_SET_CHG_VLIM_MODE(x)      (((x) & 0x03) << 0)
+
+/* ADP5061_CHG_CURR */
+#define ADP5061_CHG_CURR_ICHG_MSK              GENMASK(6, 2)
+#define ADP5061_CHG_CURR_ICHG_MODE(x)          (((x) & 0x1F) << 2)
+#define ADP5061_CHG_CURR_ITRK_DEAD_MSK         GENMASK(1, 0)
+#define ADP5061_CHG_CURR_ITRK_DEAD_MODE(x)     (((x) & 0x03) << 0)
+
+/* ADP5061_VOLTAGE_TH */
+#define ADP5061_VOLTAGE_TH_DIS_RCH_MSK         BIT(7)
+#define ADP5061_VOLTAGE_TH_DIS_RCH_MODE(x)     (((x) & 0x01) << 7)
+#define ADP5061_VOLTAGE_TH_VRCH_MSK            GENMASK(6, 5)
+#define ADP5061_VOLTAGE_TH_VRCH_MODE(x)                (((x) & 0x03) << 5)
+#define ADP5061_VOLTAGE_TH_VTRK_DEAD_MSK       GENMASK(4, 3)
+#define ADP5061_VOLTAGE_TH_VTRK_DEAD_MODE(x)   (((x) & 0x03) << 3)
+#define ADP5061_VOLTAGE_TH_VWEAK_MSK           GENMASK(2, 0)
+#define ADP5061_VOLTAGE_TH_VWEAK_MODE(x)       (((x) & 0x07) << 0)
+
+/* ADP5061_CHG_STATUS_1 */
+#define ADP5061_CHG_STATUS_1_VIN_OV(x)         (((x) >> 7) & 0x1)
+#define ADP5061_CHG_STATUS_1_VIN_OK(x)         (((x) >> 6) & 0x1)
+#define ADP5061_CHG_STATUS_1_VIN_ILIM(x)       (((x) >> 5) & 0x1)
+#define ADP5061_CHG_STATUS_1_THERM_LIM(x)      (((x) >> 4) & 0x1)
+#define ADP5061_CHG_STATUS_1_CHDONE(x)         (((x) >> 3) & 0x1)
+#define ADP5061_CHG_STATUS_1_CHG_STATUS(x)     (((x) >> 0) & 0x7)
+
+/* ADP5061_CHG_STATUS_2 */
+#define ADP5061_CHG_STATUS_2_THR_STATUS(x)     (((x) >> 5) & 0x7)
+#define ADP5061_CHG_STATUS_2_RCH_LIM_INFO(x)   (((x) >> 3) & 0x1)
+#define ADP5061_CHG_STATUS_2_BAT_STATUS(x)     (((x) >> 0) & 0x7)
+
+/* ADP5061_IEND */
+#define ADP5061_IEND_IEND_MSK                  GENMASK(7, 5)
+#define ADP5061_IEND_IEND_MODE(x)              (((x) & 0x07) << 5)
+
+#define ADP5061_NO_BATTERY     0x01
+#define ADP5061_ICHG_MAX       1300 // mA
+
+enum adp5061_chg_status {
+       ADP5061_CHG_OFF,
+       ADP5061_CHG_TRICKLE,
+       ADP5061_CHG_FAST_CC,
+       ADP5061_CHG_FAST_CV,
+       ADP5061_CHG_COMPLETE,
+       ADP5061_CHG_LDO_MODE,
+       ADP5061_CHG_TIMER_EXP,
+       ADP5061_CHG_BAT_DET,
+};
+
+static const int adp5061_chg_type[4] = {
+       [ADP5061_CHG_OFF] = POWER_SUPPLY_CHARGE_TYPE_NONE,
+       [ADP5061_CHG_TRICKLE] = POWER_SUPPLY_CHARGE_TYPE_TRICKLE,
+       [ADP5061_CHG_FAST_CC] = POWER_SUPPLY_CHARGE_TYPE_FAST,
+       [ADP5061_CHG_FAST_CV] = POWER_SUPPLY_CHARGE_TYPE_FAST,
+};
+
+static const int adp5061_vweak_th[8] = {
+       2700, 2800, 2900, 3000, 3100, 3200, 3300, 3400,
+};
+
+static const int adp5061_prechg_current[4] = {
+       5, 10, 20, 80,
+};
+
+static const int adp5061_vmin[4] = {
+       2000, 2500, 2600, 2900,
+};
+
+static const int adp5061_const_chg_vmax[4] = {
+       3200, 3400, 3700, 3800,
+};
+
+static const int adp5061_const_ichg[24] = {
+       50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650,
+       700, 750, 800, 850, 900, 950, 1000, 1050, 1100, 1200, 1300,
+};
+
+static const int adp5061_vmax[36] = {
+       3800, 3820, 3840, 3860, 3880, 3900, 3920, 3940, 3960, 3980,
+       4000, 4020, 4040, 4060, 4080, 4100, 4120, 4140, 4160, 4180,
+       4200, 4220, 4240, 4260, 4280, 4300, 4320, 4340, 4360, 4380,
+       4400, 4420, 4440, 4460, 4480, 4500,
+};
+
+static const int adp5061_in_current_lim[16] = {
+       100, 150, 200, 250, 300, 400, 500, 600, 700,
+       800, 900, 1000, 1200, 1500, 1800, 2100,
+};
+
+static const int adp5061_iend[8] = {
+       12500, 32500, 52500, 72500, 92500, 117500, 142500, 170000,
+};
+
+struct adp5061_state {
+       struct i2c_client               *client;
+       struct regmap                   *regmap;
+       struct power_supply             *psy;
+};
+
+static int adp5061_get_array_index(const int *array, u8 size, int val)
+{
+       int i;
+
+       for (i = 1; i < size; i++) {
+               if (val < array[i])
+                       break;
+       }
+
+       return i-1;
+}
+
+static int adp5061_get_status(struct adp5061_state *st,
+                             u8 *status1, u8 *status2)
+{
+       u8 buf[2];
+       int ret;
+
+       /* CHG_STATUS1 and CHG_STATUS2 are adjacent regs */
+       ret = regmap_bulk_read(st->regmap, ADP5061_CHG_STATUS_1,
+                              &buf[0], 2);
+       if (ret < 0)
+               return ret;
+
+       *status1 = buf[0];
+       *status2 = buf[1];
+
+       return ret;
+}
+
+static int adp5061_get_input_current_limit(struct adp5061_state *st,
+               union power_supply_propval *val)
+{
+       unsigned int regval;
+       int mode, ret;
+
+       ret = regmap_read(st->regmap, ADP5061_VINX_SET, &regval);
+       if (ret < 0)
+               return ret;
+
+       mode = ADP5061_VINX_SET_ILIM_MODE(regval);
+       val->intval = adp5061_in_current_lim[mode] * 1000;
+
+       return ret;
+}
+
+static int adp5061_set_input_current_limit(struct adp5061_state *st, int val)
+{
+       int index;
+
+       /* Convert from uA to mA */
+       val /= 1000;
+       index = adp5061_get_array_index(adp5061_in_current_lim,
+                                       ARRAY_SIZE(adp5061_in_current_lim),
+                                       val);
+       if (index < 0)
+               return index;
+
+       return regmap_update_bits(st->regmap, ADP5061_VINX_SET,
+                                 ADP5061_VINX_SET_ILIM_MSK,
+                                 ADP5061_VINX_SET_ILIM_MODE(index));
+}
+
+static int adp5061_set_min_voltage(struct adp5061_state *st, int val)
+{
+       int index;
+
+       /* Convert from uV to mV */
+       val /= 1000;
+       index = adp5061_get_array_index(adp5061_vmin,
+                                       ARRAY_SIZE(adp5061_vmin),
+                                       val);
+       if (index < 0)
+               return index;
+
+       return regmap_update_bits(st->regmap, ADP5061_VOLTAGE_TH,
+                                 ADP5061_VOLTAGE_TH_VTRK_DEAD_MSK,
+                                 ADP5061_VOLTAGE_TH_VTRK_DEAD_MODE(index));
+}
+
+static int adp5061_get_min_voltage(struct adp5061_state *st,
+                                  union power_supply_propval *val)
+{
+       unsigned int regval;
+       int ret;
+
+       ret = regmap_read(st->regmap, ADP5061_VOLTAGE_TH, &regval);
+       if (ret < 0)
+               return ret;
+
+       regval = ((regval & ADP5061_VOLTAGE_TH_VTRK_DEAD_MSK) >> 3);
+       val->intval = adp5061_vmin[regval] * 1000;
+
+       return ret;
+}
+
+static int adp5061_get_chg_volt_lim(struct adp5061_state *st,
+                                   union power_supply_propval *val)
+{
+       unsigned int regval;
+       int mode, ret;
+
+       ret = regmap_read(st->regmap, ADP5061_TERM_SET, &regval);
+       if (ret < 0)
+               return ret;
+
+       mode = ADP5061_TERM_SET_CHG_VLIM_MODE(regval);
+       val->intval = adp5061_const_chg_vmax[mode] * 1000;
+
+       return ret;
+}
+
+static int adp5061_get_max_voltage(struct adp5061_state *st,
+                                  union power_supply_propval *val)
+{
+       unsigned int regval;
+       int ret;
+
+       ret = regmap_read(st->regmap, ADP5061_TERM_SET, &regval);
+       if (ret < 0)
+               return ret;
+
+       regval = ((regval & ADP5061_TERM_SET_VTRM_MSK) >> 2) - 0x0F;
+       if (regval >= ARRAY_SIZE(adp5061_vmax))
+               regval = ARRAY_SIZE(adp5061_vmax) - 1;
+
+       val->intval = adp5061_vmax[regval] * 1000;
+
+       return ret;
+}
+
+static int adp5061_set_max_voltage(struct adp5061_state *st, int val)
+{
+       int vmax_index;
+
+       /* Convert from uV to mV */
+       val /= 1000;
+       if (val > 4500)
+               val = 4500;
+
+       vmax_index = adp5061_get_array_index(adp5061_vmax,
+                                            ARRAY_SIZE(adp5061_vmax), val);
+       if (vmax_index < 0)
+               return vmax_index;
+
+       vmax_index += 0x0F;
+
+       return regmap_update_bits(st->regmap, ADP5061_TERM_SET,
+                                 ADP5061_TERM_SET_VTRM_MSK,
+                                 ADP5061_TERM_SET_VTRM_MODE(vmax_index));
+}
+
+static int adp5061_set_const_chg_vmax(struct adp5061_state *st, int val)
+{
+       int index;
+
+       /* Convert from uV to mV */
+       val /= 1000;
+       index = adp5061_get_array_index(adp5061_const_chg_vmax,
+                                       ARRAY_SIZE(adp5061_const_chg_vmax),
+                                       val);
+       if (index < 0)
+               return index;
+
+       return regmap_update_bits(st->regmap, ADP5061_TERM_SET,
+                                 ADP5061_TERM_SET_CHG_VLIM_MSK,
+                                 ADP5061_TERM_SET_CHG_VLIM_MODE(index));
+}
+
+static int adp5061_set_const_chg_current(struct adp5061_state *st, int val)
+{
+
+       int index;
+
+       /* Convert from uA to mA */
+       val /= 1000;
+       if (val > ADP5061_ICHG_MAX)
+               val = ADP5061_ICHG_MAX;
+
+       index = adp5061_get_array_index(adp5061_const_ichg,
+                                       ARRAY_SIZE(adp5061_const_ichg),
+                                       val);
+       if (index < 0)
+               return index;
+
+       return regmap_update_bits(st->regmap, ADP5061_CHG_CURR,
+                                 ADP5061_CHG_CURR_ICHG_MSK,
+                                 ADP5061_CHG_CURR_ICHG_MODE(index));
+}
+
+static int adp5061_get_const_chg_current(struct adp5061_state *st,
+               union power_supply_propval *val)
+{
+       unsigned int regval;
+       int ret;
+
+       ret = regmap_read(st->regmap, ADP5061_CHG_CURR, &regval);
+       if (ret < 0)
+               return ret;
+
+       regval = ((regval & ADP5061_CHG_CURR_ICHG_MSK) >> 2);
+       if (regval >= ARRAY_SIZE(adp5061_const_ichg))
+               regval = ARRAY_SIZE(adp5061_const_ichg) - 1;
+
+       val->intval = adp5061_const_ichg[regval] * 1000;
+
+       return ret;
+}
+
+static int adp5061_get_prechg_current(struct adp5061_state *st,
+                                     union power_supply_propval *val)
+{
+       unsigned int regval;
+       int ret;
+
+       ret = regmap_read(st->regmap, ADP5061_CHG_CURR, &regval);
+       if (ret < 0)
+               return ret;
+
+       regval &= ADP5061_CHG_CURR_ITRK_DEAD_MSK;
+       val->intval = adp5061_prechg_current[regval] * 1000;
+
+       return ret;
+}
+
+static int adp5061_set_prechg_current(struct adp5061_state *st, int val)
+{
+       int index;
+
+       /* Convert from uA to mA */
+       val /= 1000;
+       index = adp5061_get_array_index(adp5061_prechg_current,
+                                       ARRAY_SIZE(adp5061_prechg_current),
+                                       val);
+       if (index < 0)
+               return index;
+
+       return regmap_update_bits(st->regmap, ADP5061_CHG_CURR,
+                                 ADP5061_CHG_CURR_ITRK_DEAD_MSK,
+                                 ADP5061_CHG_CURR_ITRK_DEAD_MODE(index));
+}
+
+static int adp5061_get_vweak_th(struct adp5061_state *st,
+                               union power_supply_propval *val)
+{
+       unsigned int regval;
+       int ret;
+
+       ret = regmap_read(st->regmap, ADP5061_VOLTAGE_TH, &regval);
+       if (ret < 0)
+               return ret;
+
+       regval &= ADP5061_VOLTAGE_TH_VWEAK_MSK;
+       val->intval = adp5061_vweak_th[regval] * 1000;
+
+       return ret;
+}
+
+static int adp5061_set_vweak_th(struct adp5061_state *st, int val)
+{
+       int index;
+
+       /* Convert from uV to mV */
+       val /= 1000;
+       index = adp5061_get_array_index(adp5061_vweak_th,
+                                       ARRAY_SIZE(adp5061_vweak_th),
+                                       val);
+       if (index < 0)
+               return index;
+
+       return regmap_update_bits(st->regmap, ADP5061_VOLTAGE_TH,
+                                 ADP5061_VOLTAGE_TH_VWEAK_MSK,
+                                 ADP5061_VOLTAGE_TH_VWEAK_MODE(index));
+}
+
+static int adp5061_get_chg_type(struct adp5061_state *st,
+                               union power_supply_propval *val)
+{
+       u8 status1, status2;
+       int chg_type, ret;
+
+       ret = adp5061_get_status(st, &status1, &status2);
+       if (ret < 0)
+               return ret;
+
+       chg_type = adp5061_chg_type[ADP5061_CHG_STATUS_1_CHG_STATUS(status1)];
+       if (chg_type > ADP5061_CHG_FAST_CV)
+               val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+       else
+               val->intval = chg_type;
+
+       return ret;
+}
+
+static int adp5061_get_charger_status(struct adp5061_state *st,
+                                     union power_supply_propval *val)
+{
+       u8 status1, status2;
+       int ret;
+
+       ret = adp5061_get_status(st, &status1, &status2);
+       if (ret < 0)
+               return ret;
+
+       switch (ADP5061_CHG_STATUS_1_CHG_STATUS(status1)) {
+       case ADP5061_CHG_OFF:
+               val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+               break;
+       case ADP5061_CHG_TRICKLE:
+       case ADP5061_CHG_FAST_CC:
+       case ADP5061_CHG_FAST_CV:
+               val->intval = POWER_SUPPLY_STATUS_CHARGING;
+               break;
+       case ADP5061_CHG_COMPLETE:
+               val->intval = POWER_SUPPLY_STATUS_FULL;
+               break;
+       case ADP5061_CHG_TIMER_EXP:
+               /* The battery must be discharging if there is a charge fault */
+               val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+               break;
+       default:
+               val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+       }
+
+       return ret;
+}
+
+static int adp5061_get_battery_status(struct adp5061_state *st,
+                                     union power_supply_propval *val)
+{
+       u8 status1, status2;
+       int ret;
+
+       ret = adp5061_get_status(st, &status1, &status2);
+       if (ret < 0)
+               return ret;
+
+       switch (ADP5061_CHG_STATUS_2_BAT_STATUS(status2)) {
+       case 0x0: /* Battery monitor off */
+       case 0x1: /* No battery */
+               val->intval = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
+               break;
+       case 0x2: /* VBAT < VTRK */
+               val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
+               break;
+       case 0x3: /* VTRK < VBAT_SNS < VWEAK */
+               val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
+               break;
+       case 0x4: /* VBAT_SNS > VWEAK */
+               val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
+               break;
+       }
+
+       return ret;
+}
+
+static int adp5061_get_termination_current(struct adp5061_state *st,
+                                          union power_supply_propval *val)
+{
+       unsigned int regval;
+       int ret;
+
+       ret = regmap_read(st->regmap, ADP5061_IEND, &regval);
+       if (ret < 0)
+               return ret;
+
+       regval = (regval & ADP5061_IEND_IEND_MSK) >> 5;
+       val->intval = adp5061_iend[regval];
+
+       return ret;
+}
+
+static int adp5061_set_termination_current(struct adp5061_state *st, int val)
+{
+       int index;
+
+       index = adp5061_get_array_index(adp5061_iend,
+                                       ARRAY_SIZE(adp5061_iend),
+                                       val);
+       if (index < 0)
+               return index;
+
+       return regmap_update_bits(st->regmap, ADP5061_IEND,
+                                 ADP5061_IEND_IEND_MSK,
+                                 ADP5061_IEND_IEND_MODE(index));
+}
+
+static int adp5061_get_property(struct power_supply *psy,
+                               enum power_supply_property psp,
+                               union power_supply_propval *val)
+{
+       struct adp5061_state *st = power_supply_get_drvdata(psy);
+       u8 status1, status2;
+       int mode, ret;
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_PRESENT:
+               ret = adp5061_get_status(st, &status1, &status2);
+               if (ret < 0)
+                       return ret;
+
+               mode = ADP5061_CHG_STATUS_2_BAT_STATUS(status2);
+               if (mode == ADP5061_NO_BATTERY)
+                       val->intval = 0;
+               else
+                       val->intval = 1;
+               break;
+       case POWER_SUPPLY_PROP_CHARGE_TYPE:
+               return adp5061_get_chg_type(st, val);
+       case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
+               /* This property is used to indicate the input current
+                * limit into VINx (ILIM)
+                */
+               return adp5061_get_input_current_limit(st, val);
+       case POWER_SUPPLY_PROP_VOLTAGE_MAX:
+               /* This property is used to indicate the termination
+                * voltage (VTRM)
+                */
+               return adp5061_get_max_voltage(st, val);
+       case POWER_SUPPLY_PROP_VOLTAGE_MIN:
+               /*
+                * This property is used to indicate the trickle to fast
+                * charge threshold (VTRK_DEAD)
+                */
+               return adp5061_get_min_voltage(st, val);
+       case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
+               /* This property is used to indicate the charging
+                * voltage limit (CHG_VLIM)
+                */
+               return adp5061_get_chg_volt_lim(st, val);
+       case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
+               /*
+                * This property is used to indicate the value of the constant
+                * current charge (ICHG)
+                */
+               return adp5061_get_const_chg_current(st, val);
+       case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
+               /*
+                * This property is used to indicate the value of the trickle
+                * and weak charge currents (ITRK_DEAD)
+                */
+               return adp5061_get_prechg_current(st, val);
+       case POWER_SUPPLY_PROP_VOLTAGE_AVG:
+               /*
+                * This property is used to set the VWEAK threshold
+                * bellow this value, weak charge mode is entered
+                * above this value, fast chargerge mode is entered
+                */
+               return adp5061_get_vweak_th(st, val);
+       case POWER_SUPPLY_PROP_STATUS:
+               /*
+                * Indicate the charger status in relation to power
+                * supply status property
+                */
+               return adp5061_get_charger_status(st, val);
+       case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
+               /*
+                * Indicate the battery status in relation to power
+                * supply capacity level property
+                */
+               return adp5061_get_battery_status(st, val);
+       case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
+               /* Indicate the values of the termination current */
+               return adp5061_get_termination_current(st, val);
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int adp5061_set_property(struct power_supply *psy,
+                               enum power_supply_property psp,
+                               const union power_supply_propval *val)
+{
+       struct adp5061_state *st = power_supply_get_drvdata(psy);
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
+               return adp5061_set_input_current_limit(st, val->intval);
+       case POWER_SUPPLY_PROP_VOLTAGE_MAX:
+               return adp5061_set_max_voltage(st, val->intval);
+       case POWER_SUPPLY_PROP_VOLTAGE_MIN:
+               return adp5061_set_min_voltage(st, val->intval);
+       case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
+               return adp5061_set_const_chg_vmax(st, val->intval);
+       case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
+               return adp5061_set_const_chg_current(st, val->intval);
+       case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
+               return adp5061_set_prechg_current(st, val->intval);
+       case POWER_SUPPLY_PROP_VOLTAGE_AVG:
+               return adp5061_set_vweak_th(st, val->intval);
+       case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
+               return adp5061_set_termination_current(st, val->intval);
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int adp5061_prop_writeable(struct power_supply *psy,
+                                 enum power_supply_property psp)
+{
+       switch (psp) {
+       case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
+       case POWER_SUPPLY_PROP_VOLTAGE_MAX:
+       case POWER_SUPPLY_PROP_VOLTAGE_MIN:
+       case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
+       case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
+       case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
+       case POWER_SUPPLY_PROP_VOLTAGE_AVG:
+       case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static enum power_supply_property adp5061_props[] = {
+       POWER_SUPPLY_PROP_PRESENT,
+       POWER_SUPPLY_PROP_CHARGE_TYPE,
+       POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
+       POWER_SUPPLY_PROP_VOLTAGE_MAX,
+       POWER_SUPPLY_PROP_VOLTAGE_MIN,
+       POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
+       POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
+       POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
+       POWER_SUPPLY_PROP_VOLTAGE_AVG,
+       POWER_SUPPLY_PROP_STATUS,
+       POWER_SUPPLY_PROP_CAPACITY_LEVEL,
+       POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
+};
+
+static const struct regmap_config adp5061_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+};
+
+static const struct power_supply_desc adp5061_desc = {
+       .name                   = "adp5061",
+       .type                   = POWER_SUPPLY_TYPE_USB,
+       .get_property           = adp5061_get_property,
+       .set_property           = adp5061_set_property,
+       .property_is_writeable  = adp5061_prop_writeable,
+       .properties             = adp5061_props,
+       .num_properties         = ARRAY_SIZE(adp5061_props),
+};
+
+static int adp5061_probe(struct i2c_client *client,
+                        const struct i2c_device_id *id)
+{
+       struct power_supply_config psy_cfg = {};
+       struct adp5061_state *st;
+
+       st = devm_kzalloc(&client->dev, sizeof(*st), GFP_KERNEL);
+       if (!st)
+               return -ENOMEM;
+
+       st->client = client;
+       st->regmap = devm_regmap_init_i2c(client,
+                                         &adp5061_regmap_config);
+       if (IS_ERR(st->regmap)) {
+               dev_err(&client->dev, "Failed to initialize register map\n");
+               return -EINVAL;
+       }
+
+       i2c_set_clientdata(client, st);
+       psy_cfg.drv_data = st;
+
+       st->psy = devm_power_supply_register(&client->dev,
+                                            &adp5061_desc,
+                                            &psy_cfg);
+
+       if (IS_ERR(st->psy)) {
+               dev_err(&client->dev, "Failed to register power supply\n");
+               return PTR_ERR(st->psy);
+       }
+
+       return 0;
+}
+
+static const struct i2c_device_id adp5061_id[] = {
+       { "adp5061", 0},
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, adp5061_id);
+
+static struct i2c_driver adp5061_driver = {
+       .driver = {
+               .name = KBUILD_MODNAME,
+       },
+       .probe = adp5061_probe,
+       .id_table = adp5061_id,
+};
+module_i2c_driver(adp5061_driver);
+
+MODULE_DESCRIPTION("Analog Devices adp5061 battery charger driver");
+MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
+MODULE_LICENSE("GPL v2");
index 44f70dcea61e3c7ac51086bb148ce894243ed933..42001df4bd13f147b1825e66791150ab4525dc98 100644 (file)
@@ -222,6 +222,7 @@ static int axp20x_usb_power_set_current_max(struct axp20x_usb_power *power,
        case 100000:
                if (power->axp20x_id == AXP221_ID)
                        return -EINVAL;
+               /* fall through */
        case 500000:
        case 900000:
                val = (900000 - intval) / 400000;
index 6e1bc14c33049c9a7322c28890bff35948462294..735658ee1c60f3fd42adb6b11d66ba5f238861f9 100644 (file)
@@ -718,7 +718,7 @@ static int charger_init_hw_regs(struct axp288_chrg_info *info)
        }
 
        /* Determine charge current limit */
-       cc = (ret & CHRG_CCCV_CC_MASK) >> CHRG_CCCV_CC_BIT_POS;
+       cc = (val & CHRG_CCCV_CC_MASK) >> CHRG_CCCV_CC_BIT_POS;
        cc = (cc * CHRG_CCCV_CC_LSB_RES) + CHRG_CCCV_CC_OFFSET;
        info->cc = cc;
 
index d44ed8e17c477f711818c5e2724439c3b647f534..f022e1b550dfe6f736b8b226516047c1786e1cea 100644 (file)
@@ -26,7 +26,6 @@
  * http://www.ti.com/product/bq27510-g1
  * http://www.ti.com/product/bq27510-g2
  * http://www.ti.com/product/bq27510-g3
- * http://www.ti.com/product/bq27520-g4
  * http://www.ti.com/product/bq27520-g1
  * http://www.ti.com/product/bq27520-g2
  * http://www.ti.com/product/bq27520-g3
@@ -40,7 +39,9 @@
  * http://www.ti.com/product/bq27545-g1
  * http://www.ti.com/product/bq27421-g1
  * http://www.ti.com/product/bq27425-g1
+ * http://www.ti.com/product/bq27426
  * http://www.ti.com/product/bq27411-g1
+ * http://www.ti.com/product/bq27441-g1
  * http://www.ti.com/product/bq27621-g1
  */
 
diff --git a/drivers/power/supply/cros_usbpd-charger.c b/drivers/power/supply/cros_usbpd-charger.c
new file mode 100644 (file)
index 0000000..688a16b
--- /dev/null
@@ -0,0 +1,545 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Power supply driver for ChromeOS EC based USB PD Charger.
+ *
+ * Copyright (c) 2014 - 2018 Google, Inc
+ */
+
+#include <linux/module.h>
+#include <linux/mfd/cros_ec.h>
+#include <linux/mfd/cros_ec_commands.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/slab.h>
+
+#define CHARGER_DIR_NAME                       "CROS_USBPD_CHARGER%d"
+#define CHARGER_DIR_NAME_LENGTH                        sizeof(CHARGER_DIR_NAME)
+#define CHARGER_CACHE_UPDATE_DELAY             msecs_to_jiffies(500)
+#define CHARGER_MANUFACTURER_MODEL_LENGTH      32
+
+#define DRV_NAME "cros-usbpd-charger"
+
+struct port_data {
+       int port_number;
+       char name[CHARGER_DIR_NAME_LENGTH];
+       char manufacturer[CHARGER_MANUFACTURER_MODEL_LENGTH];
+       char model_name[CHARGER_MANUFACTURER_MODEL_LENGTH];
+       struct power_supply *psy;
+       struct power_supply_desc psy_desc;
+       int psy_usb_type;
+       int psy_online;
+       int psy_status;
+       int psy_current_max;
+       int psy_voltage_max_design;
+       int psy_voltage_now;
+       int psy_power_max;
+       struct charger_data *charger;
+       unsigned long last_update;
+};
+
+struct charger_data {
+       struct device *dev;
+       struct cros_ec_dev *ec_dev;
+       struct cros_ec_device *ec_device;
+       int num_charger_ports;
+       int num_registered_psy;
+       struct port_data *ports[EC_USB_PD_MAX_PORTS];
+       struct notifier_block notifier;
+};
+
+static enum power_supply_property cros_usbpd_charger_props[] = {
+       POWER_SUPPLY_PROP_ONLINE,
+       POWER_SUPPLY_PROP_STATUS,
+       POWER_SUPPLY_PROP_CURRENT_MAX,
+       POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+       POWER_SUPPLY_PROP_VOLTAGE_NOW,
+       POWER_SUPPLY_PROP_MODEL_NAME,
+       POWER_SUPPLY_PROP_MANUFACTURER,
+       POWER_SUPPLY_PROP_USB_TYPE
+};
+
+static enum power_supply_usb_type cros_usbpd_charger_usb_types[] = {
+       POWER_SUPPLY_USB_TYPE_UNKNOWN,
+       POWER_SUPPLY_USB_TYPE_SDP,
+       POWER_SUPPLY_USB_TYPE_DCP,
+       POWER_SUPPLY_USB_TYPE_CDP,
+       POWER_SUPPLY_USB_TYPE_C,
+       POWER_SUPPLY_USB_TYPE_PD,
+       POWER_SUPPLY_USB_TYPE_PD_DRP,
+       POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID
+};
+
+static int cros_usbpd_charger_ec_command(struct charger_data *charger,
+                                        unsigned int version,
+                                        unsigned int command,
+                                        void *outdata,
+                                        unsigned int outsize,
+                                        void *indata,
+                                        unsigned int insize)
+{
+       struct cros_ec_dev *ec_dev = charger->ec_dev;
+       struct cros_ec_command *msg;
+       int ret;
+
+       msg = kzalloc(sizeof(*msg) + max(outsize, insize), GFP_KERNEL);
+       if (!msg)
+               return -ENOMEM;
+
+       msg->version = version;
+       msg->command = ec_dev->cmd_offset + command;
+       msg->outsize = outsize;
+       msg->insize = insize;
+
+       if (outsize)
+               memcpy(msg->data, outdata, outsize);
+
+       ret = cros_ec_cmd_xfer_status(charger->ec_device, msg);
+       if (ret >= 0 && insize)
+               memcpy(indata, msg->data, insize);
+
+       kfree(msg);
+       return ret;
+}
+
+static int cros_usbpd_charger_get_num_ports(struct charger_data *charger)
+{
+       struct ec_response_usb_pd_ports resp;
+       int ret;
+
+       ret = cros_usbpd_charger_ec_command(charger, 0, EC_CMD_USB_PD_PORTS,
+                                           NULL, 0, &resp, sizeof(resp));
+       if (ret < 0) {
+               dev_err(charger->dev,
+                       "Unable to get the number or ports (err:0x%x)\n", ret);
+               return ret;
+       }
+
+       return resp.num_ports;
+}
+
+static int cros_usbpd_charger_get_discovery_info(struct port_data *port)
+{
+       struct charger_data *charger = port->charger;
+       struct ec_params_usb_pd_discovery_entry resp;
+       struct ec_params_usb_pd_info_request req;
+       int ret;
+
+       req.port = port->port_number;
+
+       ret = cros_usbpd_charger_ec_command(charger, 0,
+                                           EC_CMD_USB_PD_DISCOVERY,
+                                           &req, sizeof(req),
+                                           &resp, sizeof(resp));
+       if (ret < 0) {
+               dev_err(charger->dev,
+                       "Unable to query discovery info (err:0x%x)\n", ret);
+               return ret;
+       }
+
+       dev_dbg(charger->dev, "Port %d: VID = 0x%x, PID=0x%x, PTYPE=0x%x\n",
+               port->port_number, resp.vid, resp.pid, resp.ptype);
+
+       snprintf(port->manufacturer, sizeof(port->manufacturer), "%x",
+                resp.vid);
+       snprintf(port->model_name, sizeof(port->model_name), "%x", resp.pid);
+
+       return 0;
+}
+
+static int cros_usbpd_charger_get_power_info(struct port_data *port)
+{
+       struct charger_data *charger = port->charger;
+       struct ec_response_usb_pd_power_info resp;
+       struct ec_params_usb_pd_power_info req;
+       int last_psy_status, last_psy_usb_type;
+       struct device *dev = charger->dev;
+       int ret;
+
+       req.port = port->port_number;
+       ret = cros_usbpd_charger_ec_command(charger, 0,
+                                           EC_CMD_USB_PD_POWER_INFO,
+                                           &req, sizeof(req),
+                                           &resp, sizeof(resp));
+       if (ret < 0) {
+               dev_err(dev, "Unable to query PD power info (err:0x%x)\n", ret);
+               return ret;
+       }
+
+       last_psy_status = port->psy_status;
+       last_psy_usb_type = port->psy_usb_type;
+
+       switch (resp.role) {
+       case USB_PD_PORT_POWER_DISCONNECTED:
+               port->psy_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+               port->psy_online = 0;
+               break;
+       case USB_PD_PORT_POWER_SOURCE:
+               port->psy_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+               port->psy_online = 0;
+               break;
+       case USB_PD_PORT_POWER_SINK:
+               port->psy_status = POWER_SUPPLY_STATUS_CHARGING;
+               port->psy_online = 1;
+               break;
+       case USB_PD_PORT_POWER_SINK_NOT_CHARGING:
+               port->psy_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+               port->psy_online = 1;
+               break;
+       default:
+               dev_err(dev, "Unknown role %d\n", resp.role);
+               break;
+       }
+
+       port->psy_voltage_max_design = resp.meas.voltage_max;
+       port->psy_voltage_now = resp.meas.voltage_now;
+       port->psy_current_max = resp.meas.current_max;
+       port->psy_power_max = resp.max_power;
+
+       switch (resp.type) {
+       case USB_CHG_TYPE_BC12_SDP:
+       case USB_CHG_TYPE_VBUS:
+               port->psy_usb_type = POWER_SUPPLY_USB_TYPE_SDP;
+               break;
+       case USB_CHG_TYPE_NONE:
+               /*
+                * For dual-role devices when we are a source, the firmware
+                * reports the type as NONE. Report such chargers as type
+                * USB_PD_DRP.
+                */
+               if (resp.role == USB_PD_PORT_POWER_SOURCE && resp.dualrole)
+                       port->psy_usb_type = POWER_SUPPLY_USB_TYPE_PD_DRP;
+               else
+                       port->psy_usb_type = POWER_SUPPLY_USB_TYPE_SDP;
+               break;
+       case USB_CHG_TYPE_OTHER:
+       case USB_CHG_TYPE_PROPRIETARY:
+               port->psy_usb_type = POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID;
+               break;
+       case USB_CHG_TYPE_C:
+               port->psy_usb_type = POWER_SUPPLY_USB_TYPE_C;
+               break;
+       case USB_CHG_TYPE_BC12_DCP:
+               port->psy_usb_type = POWER_SUPPLY_USB_TYPE_DCP;
+               break;
+       case USB_CHG_TYPE_BC12_CDP:
+               port->psy_usb_type = POWER_SUPPLY_USB_TYPE_CDP;
+               break;
+       case USB_CHG_TYPE_PD:
+               if (resp.dualrole)
+                       port->psy_usb_type = POWER_SUPPLY_USB_TYPE_PD_DRP;
+               else
+                       port->psy_usb_type = POWER_SUPPLY_USB_TYPE_PD;
+               break;
+       case USB_CHG_TYPE_UNKNOWN:
+               /*
+                * While the EC is trying to determine the type of charger that
+                * has been plugged in, it will report the charger type as
+                * unknown. Additionally since the power capabilities are
+                * unknown, report the max current and voltage as zero.
+                */
+               port->psy_usb_type = POWER_SUPPLY_USB_TYPE_UNKNOWN;
+               port->psy_voltage_max_design = 0;
+               port->psy_current_max = 0;
+               break;
+       default:
+               dev_err(dev, "Port %d: default case!\n", port->port_number);
+               port->psy_usb_type = POWER_SUPPLY_USB_TYPE_SDP;
+       }
+
+       port->psy_desc.type = POWER_SUPPLY_TYPE_USB;
+
+       dev_dbg(dev,
+               "Port %d: type=%d vmax=%d vnow=%d cmax=%d clim=%d pmax=%d\n",
+               port->port_number, resp.type, resp.meas.voltage_max,
+               resp.meas.voltage_now, resp.meas.current_max,
+               resp.meas.current_lim, resp.max_power);
+
+       /*
+        * If power supply type or status changed, explicitly call
+        * power_supply_changed. This results in udev event getting generated
+        * and allows user mode apps to react quicker instead of waiting for
+        * their next poll of power supply status.
+        */
+       if (last_psy_usb_type != port->psy_usb_type ||
+           last_psy_status != port->psy_status)
+               power_supply_changed(port->psy);
+
+       return 0;
+}
+
+static int cros_usbpd_charger_get_port_status(struct port_data *port,
+                                             bool ratelimit)
+{
+       int ret;
+
+       if (ratelimit &&
+           time_is_after_jiffies(port->last_update +
+                                 CHARGER_CACHE_UPDATE_DELAY))
+               return 0;
+
+       ret = cros_usbpd_charger_get_power_info(port);
+       if (ret < 0)
+               return ret;
+
+       ret = cros_usbpd_charger_get_discovery_info(port);
+       port->last_update = jiffies;
+
+       return ret;
+}
+
+static void cros_usbpd_charger_power_changed(struct power_supply *psy)
+{
+       struct port_data *port = power_supply_get_drvdata(psy);
+       struct charger_data *charger = port->charger;
+       int i;
+
+       for (i = 0; i < charger->num_registered_psy; i++)
+               cros_usbpd_charger_get_port_status(charger->ports[i], false);
+}
+
+static int cros_usbpd_charger_get_prop(struct power_supply *psy,
+                                      enum power_supply_property psp,
+                                      union power_supply_propval *val)
+{
+       struct port_data *port = power_supply_get_drvdata(psy);
+       struct charger_data *charger = port->charger;
+       struct cros_ec_device *ec_device = charger->ec_device;
+       struct device *dev = charger->dev;
+       int ret;
+
+       /* Only refresh ec_port_status for dynamic properties */
+       switch (psp) {
+       case POWER_SUPPLY_PROP_ONLINE:
+               /*
+                * If mkbp_event_supported, then we can be assured that
+                * the driver's state for the online property is consistent
+                * with the hardware. However, if we aren't event driven,
+                * the optimization before to skip an ec_port_status get
+                * and only returned cached values of the online property will
+                * cause a delay in detecting a cable attach until one of the
+                * other properties are read.
+                *
+                * Allow an ec_port_status refresh for online property check
+                * if we're not already online to check for plug events if
+                * not mkbp_event_supported.
+                */
+               if (ec_device->mkbp_event_supported || port->psy_online)
+                       break;
+               /* fall through */
+       case POWER_SUPPLY_PROP_CURRENT_MAX:
+       case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+       case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+               ret = cros_usbpd_charger_get_port_status(port, true);
+               if (ret < 0) {
+                       dev_err(dev, "Failed to get port status (err:0x%x)\n",
+                               ret);
+                       return -EINVAL;
+               }
+               break;
+       default:
+               break;
+       }
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_ONLINE:
+               val->intval = port->psy_online;
+               break;
+       case POWER_SUPPLY_PROP_STATUS:
+               val->intval = port->psy_status;
+               break;
+       case POWER_SUPPLY_PROP_CURRENT_MAX:
+               val->intval = port->psy_current_max * 1000;
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+               val->intval = port->psy_voltage_max_design * 1000;
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+               val->intval = port->psy_voltage_now * 1000;
+               break;
+       case POWER_SUPPLY_PROP_USB_TYPE:
+               val->intval = port->psy_usb_type;
+               break;
+       case POWER_SUPPLY_PROP_MODEL_NAME:
+               val->strval = port->model_name;
+               break;
+       case POWER_SUPPLY_PROP_MANUFACTURER:
+               val->strval = port->manufacturer;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int cros_usbpd_charger_ec_event(struct notifier_block *nb,
+                                      unsigned long queued_during_suspend,
+                                      void *_notify)
+{
+       struct cros_ec_device *ec_device;
+       struct charger_data *charger;
+       struct device *dev;
+       u32 host_event;
+
+       charger = container_of(nb, struct charger_data, notifier);
+       ec_device = charger->ec_device;
+       dev = charger->dev;
+
+       host_event = cros_ec_get_host_event(ec_device);
+       if (host_event & EC_HOST_EVENT_MASK(EC_HOST_EVENT_PD_MCU)) {
+               cros_usbpd_charger_power_changed(charger->ports[0]->psy);
+               return NOTIFY_OK;
+       } else {
+               return NOTIFY_DONE;
+       }
+}
+
+static void cros_usbpd_charger_unregister_notifier(void *data)
+{
+       struct charger_data *charger = data;
+       struct cros_ec_device *ec_device = charger->ec_device;
+
+       blocking_notifier_chain_unregister(&ec_device->event_notifier,
+                                          &charger->notifier);
+}
+
+static int cros_usbpd_charger_probe(struct platform_device *pd)
+{
+       struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent);
+       struct cros_ec_device *ec_device = ec_dev->ec_dev;
+       struct power_supply_desc *psy_desc;
+       struct device *dev = &pd->dev;
+       struct charger_data *charger;
+       struct power_supply *psy;
+       struct port_data *port;
+       int ret = -EINVAL;
+       int i;
+
+       charger = devm_kzalloc(dev, sizeof(struct charger_data),
+                              GFP_KERNEL);
+       if (!charger)
+               return -ENOMEM;
+
+       charger->dev = dev;
+       charger->ec_dev = ec_dev;
+       charger->ec_device = ec_device;
+
+       platform_set_drvdata(pd, charger);
+
+       charger->num_charger_ports = cros_usbpd_charger_get_num_ports(charger);
+       if (charger->num_charger_ports <= 0) {
+               /*
+                * This can happen on a system that doesn't support USB PD.
+                * Log a message, but no need to warn.
+                */
+               dev_info(dev, "No charging ports found\n");
+               ret = -ENODEV;
+               goto fail_nowarn;
+       }
+
+       for (i = 0; i < charger->num_charger_ports; i++) {
+               struct power_supply_config psy_cfg = {};
+
+               port = devm_kzalloc(dev, sizeof(struct port_data), GFP_KERNEL);
+               if (!port) {
+                       ret = -ENOMEM;
+                       goto fail;
+               }
+
+               port->charger = charger;
+               port->port_number = i;
+               sprintf(port->name, CHARGER_DIR_NAME, i);
+
+               psy_desc = &port->psy_desc;
+               psy_desc->name = port->name;
+               psy_desc->type = POWER_SUPPLY_TYPE_USB;
+               psy_desc->get_property = cros_usbpd_charger_get_prop;
+               psy_desc->external_power_changed =
+                                       cros_usbpd_charger_power_changed;
+               psy_desc->properties = cros_usbpd_charger_props;
+               psy_desc->num_properties =
+                                       ARRAY_SIZE(cros_usbpd_charger_props);
+               psy_desc->usb_types = cros_usbpd_charger_usb_types;
+               psy_desc->num_usb_types =
+                               ARRAY_SIZE(cros_usbpd_charger_usb_types);
+               psy_cfg.drv_data = port;
+
+               psy = devm_power_supply_register_no_ws(dev, psy_desc,
+                                                      &psy_cfg);
+               if (IS_ERR(psy)) {
+                       dev_err(dev, "Failed to register power supply\n");
+                       continue;
+               }
+               port->psy = psy;
+
+               charger->ports[charger->num_registered_psy++] = port;
+       }
+
+       if (!charger->num_registered_psy) {
+               ret = -ENODEV;
+               dev_err(dev, "No power supplies registered\n");
+               goto fail;
+       }
+
+       if (ec_device->mkbp_event_supported) {
+               /* Get PD events from the EC */
+               charger->notifier.notifier_call = cros_usbpd_charger_ec_event;
+               ret = blocking_notifier_chain_register(
+                                               &ec_device->event_notifier,
+                                               &charger->notifier);
+               if (ret < 0) {
+                       dev_warn(dev, "failed to register notifier\n");
+               } else {
+                       ret = devm_add_action_or_reset(dev,
+                                       cros_usbpd_charger_unregister_notifier,
+                                       charger);
+                       if (ret < 0)
+                               goto fail;
+               }
+       }
+
+       return 0;
+
+fail:
+       WARN(1, "%s: Failing probe (err:0x%x)\n", dev_name(dev), ret);
+
+fail_nowarn:
+       dev_info(dev, "Failing probe (err:0x%x)\n", ret);
+       return ret;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int cros_usbpd_charger_resume(struct device *dev)
+{
+       struct charger_data *charger = dev_get_drvdata(dev);
+       int i;
+
+       if (!charger)
+               return 0;
+
+       for (i = 0; i < charger->num_registered_psy; i++) {
+               power_supply_changed(charger->ports[i]->psy);
+               charger->ports[i]->last_update =
+                               jiffies - CHARGER_CACHE_UPDATE_DELAY;
+       }
+
+       return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(cros_usbpd_charger_pm_ops, NULL,
+                        cros_usbpd_charger_resume);
+
+static struct platform_driver cros_usbpd_charger_driver = {
+       .driver = {
+               .name = DRV_NAME,
+               .pm = &cros_usbpd_charger_pm_ops,
+       },
+       .probe = cros_usbpd_charger_probe
+};
+
+module_platform_driver(cros_usbpd_charger_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ChromeOS EC USBPD charger");
+MODULE_ALIAS("platform:" DRV_NAME);
index ae180dc929c9360e1b6efb8b0677b802b3c91e83..11bed88a89facfaa76a7b17cd9586f3483597a3b 100644 (file)
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
-
+#include <linux/suspend.h>
 #include <linux/w1.h>
-#include "../../w1/slaves/w1_ds2760.h"
+#include <linux/of.h>
+
+static unsigned int cache_time = 1000;
+module_param(cache_time, uint, 0644);
+MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
+
+static bool pmod_enabled;
+module_param(pmod_enabled, bool, 0644);
+MODULE_PARM_DESC(pmod_enabled, "PMOD enable bit");
+
+static unsigned int rated_capacity;
+module_param(rated_capacity, uint, 0644);
+MODULE_PARM_DESC(rated_capacity, "rated battery capacity, 10*mAh or index");
+
+static unsigned int current_accum;
+module_param(current_accum, uint, 0644);
+MODULE_PARM_DESC(current_accum, "current accumulator value");
+
+#define W1_FAMILY_DS2760               0x30
+
+/* Known commands to the DS2760 chip */
+#define W1_DS2760_SWAP                 0xAA
+#define W1_DS2760_READ_DATA            0x69
+#define W1_DS2760_WRITE_DATA           0x6C
+#define W1_DS2760_COPY_DATA            0x48
+#define W1_DS2760_RECALL_DATA          0xB8
+#define W1_DS2760_LOCK                 0x6A
+
+/* Number of valid register addresses */
+#define DS2760_DATA_SIZE               0x40
+
+#define DS2760_PROTECTION_REG          0x00
+
+#define DS2760_STATUS_REG              0x01
+#define DS2760_STATUS_IE               (1 << 2)
+#define DS2760_STATUS_SWEN             (1 << 3)
+#define DS2760_STATUS_RNAOP            (1 << 4)
+#define DS2760_STATUS_PMOD             (1 << 5)
+
+#define DS2760_EEPROM_REG              0x07
+#define DS2760_SPECIAL_FEATURE_REG     0x08
+#define DS2760_VOLTAGE_MSB             0x0c
+#define DS2760_VOLTAGE_LSB             0x0d
+#define DS2760_CURRENT_MSB             0x0e
+#define DS2760_CURRENT_LSB             0x0f
+#define DS2760_CURRENT_ACCUM_MSB       0x10
+#define DS2760_CURRENT_ACCUM_LSB       0x11
+#define DS2760_TEMP_MSB                        0x18
+#define DS2760_TEMP_LSB                        0x19
+#define DS2760_EEPROM_BLOCK0           0x20
+#define DS2760_ACTIVE_FULL             0x20
+#define DS2760_EEPROM_BLOCK1           0x30
+#define DS2760_STATUS_WRITE_REG                0x31
+#define DS2760_RATED_CAPACITY          0x32
+#define DS2760_CURRENT_OFFSET_BIAS     0x33
+#define DS2760_ACTIVE_EMPTY            0x3b
 
 struct ds2760_device_info {
        struct device *dev;
@@ -55,28 +110,113 @@ struct ds2760_device_info {
        int full_counter;
        struct power_supply *bat;
        struct power_supply_desc bat_desc;
-       struct device *w1_dev;
        struct workqueue_struct *monitor_wqueue;
        struct delayed_work monitor_work;
        struct delayed_work set_charged_work;
+       struct notifier_block pm_notifier;
 };
 
-static unsigned int cache_time = 1000;
-module_param(cache_time, uint, 0644);
-MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
+static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count,
+                       int io)
+{
+       struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
 
-static bool pmod_enabled;
-module_param(pmod_enabled, bool, 0644);
-MODULE_PARM_DESC(pmod_enabled, "PMOD enable bit");
+       if (!dev)
+               return 0;
 
-static unsigned int rated_capacity;
-module_param(rated_capacity, uint, 0644);
-MODULE_PARM_DESC(rated_capacity, "rated battery capacity, 10*mAh or index");
+       mutex_lock(&sl->master->bus_mutex);
 
-static unsigned int current_accum;
-module_param(current_accum, uint, 0644);
-MODULE_PARM_DESC(current_accum, "current accumulator value");
+       if (addr > DS2760_DATA_SIZE || addr < 0) {
+               count = 0;
+               goto out;
+       }
+       if (addr + count > DS2760_DATA_SIZE)
+               count = DS2760_DATA_SIZE - addr;
+
+       if (!w1_reset_select_slave(sl)) {
+               if (!io) {
+                       w1_write_8(sl->master, W1_DS2760_READ_DATA);
+                       w1_write_8(sl->master, addr);
+                       count = w1_read_block(sl->master, buf, count);
+               } else {
+                       w1_write_8(sl->master, W1_DS2760_WRITE_DATA);
+                       w1_write_8(sl->master, addr);
+                       w1_write_block(sl->master, buf, count);
+                       /* XXX w1_write_block returns void, not n_written */
+               }
+       }
+
+out:
+       mutex_unlock(&sl->master->bus_mutex);
+
+       return count;
+}
+
+static int w1_ds2760_read(struct device *dev,
+                         char *buf, int addr,
+                         size_t count)
+{
+       return w1_ds2760_io(dev, buf, addr, count, 0);
+}
+
+static int w1_ds2760_write(struct device *dev,
+                          char *buf,
+                          int addr, size_t count)
+{
+       return w1_ds2760_io(dev, buf, addr, count, 1);
+}
+
+static int w1_ds2760_eeprom_cmd(struct device *dev, int addr, int cmd)
+{
+       struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
+
+       if (!dev)
+               return -EINVAL;
+
+       mutex_lock(&sl->master->bus_mutex);
+
+       if (w1_reset_select_slave(sl) == 0) {
+               w1_write_8(sl->master, cmd);
+               w1_write_8(sl->master, addr);
+       }
+
+       mutex_unlock(&sl->master->bus_mutex);
+       return 0;
+}
+
+static int w1_ds2760_store_eeprom(struct device *dev, int addr)
+{
+       return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_COPY_DATA);
+}
+
+static int w1_ds2760_recall_eeprom(struct device *dev, int addr)
+{
+       return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_RECALL_DATA);
+}
+
+static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj,
+                            struct bin_attribute *bin_attr, char *buf,
+                            loff_t off, size_t count)
+{
+       struct device *dev = container_of(kobj, struct device, kobj);
+       return w1_ds2760_read(dev, buf, off, count);
+}
+
+static BIN_ATTR_RO(w1_slave, DS2760_DATA_SIZE);
+
+static struct bin_attribute *w1_ds2760_bin_attrs[] = {
+       &bin_attr_w1_slave,
+       NULL,
+};
+
+static const struct attribute_group w1_ds2760_group = {
+       .bin_attrs = w1_ds2760_bin_attrs,
+};
 
+static const struct attribute_group *w1_ds2760_groups[] = {
+       &w1_ds2760_group,
+       NULL,
+};
 /* Some batteries have their rated capacity stored a N * 10 mAh, while
  * others use an index into this table. */
 static int rated_capacities[] = {
@@ -138,10 +278,10 @@ static int ds2760_battery_read_status(struct ds2760_device_info *di)
                count = DS2760_TEMP_LSB - start + 1;
        }
 
-       ret = w1_ds2760_read(di->w1_dev, di->raw + start, start, count);
+       ret = w1_ds2760_read(di->dev, di->raw + start, start, count);
        if (ret != count) {
                dev_warn(di->dev, "call to w1_ds2760_read failed (0x%p)\n",
-                        di->w1_dev);
+                        di->dev);
                return 1;
        }
 
@@ -242,7 +382,7 @@ static void ds2760_battery_set_current_accum(struct ds2760_device_info *di,
        acr[0] = acr_val >> 8;
        acr[1] = acr_val & 0xff;
 
-       if (w1_ds2760_write(di->w1_dev, acr, DS2760_CURRENT_ACCUM_MSB, 2) < 2)
+       if (w1_ds2760_write(di->dev, acr, DS2760_CURRENT_ACCUM_MSB, 2) < 2)
                dev_warn(di->dev, "ACR write failed\n");
 }
 
@@ -297,9 +437,9 @@ static void ds2760_battery_write_status(struct ds2760_device_info *di,
        if (status == di->raw[DS2760_STATUS_REG])
                return;
 
-       w1_ds2760_write(di->w1_dev, &status, DS2760_STATUS_WRITE_REG, 1);
-       w1_ds2760_store_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1);
-       w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1);
+       w1_ds2760_write(di->dev, &status, DS2760_STATUS_WRITE_REG, 1);
+       w1_ds2760_store_eeprom(di->dev, DS2760_EEPROM_BLOCK1);
+       w1_ds2760_recall_eeprom(di->dev, DS2760_EEPROM_BLOCK1);
 }
 
 static void ds2760_battery_write_rated_capacity(struct ds2760_device_info *di,
@@ -308,9 +448,9 @@ static void ds2760_battery_write_rated_capacity(struct ds2760_device_info *di,
        if (rated_capacity == di->raw[DS2760_RATED_CAPACITY])
                return;
 
-       w1_ds2760_write(di->w1_dev, &rated_capacity, DS2760_RATED_CAPACITY, 1);
-       w1_ds2760_store_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1);
-       w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1);
+       w1_ds2760_write(di->dev, &rated_capacity, DS2760_RATED_CAPACITY, 1);
+       w1_ds2760_store_eeprom(di->dev, DS2760_EEPROM_BLOCK1);
+       w1_ds2760_recall_eeprom(di->dev, DS2760_EEPROM_BLOCK1);
 }
 
 static void ds2760_battery_write_active_full(struct ds2760_device_info *di,
@@ -325,9 +465,9 @@ static void ds2760_battery_write_active_full(struct ds2760_device_info *di,
            tmp[1] == di->raw[DS2760_ACTIVE_FULL + 1])
                return;
 
-       w1_ds2760_write(di->w1_dev, tmp, DS2760_ACTIVE_FULL, sizeof(tmp));
-       w1_ds2760_store_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK0);
-       w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK0);
+       w1_ds2760_write(di->dev, tmp, DS2760_ACTIVE_FULL, sizeof(tmp));
+       w1_ds2760_store_eeprom(di->dev, DS2760_EEPROM_BLOCK0);
+       w1_ds2760_recall_eeprom(di->dev, DS2760_EEPROM_BLOCK0);
 
        /* Write to the di->raw[] buffer directly - the DS2760_ACTIVE_FULL
         * values won't be read back by ds2760_battery_read_status() */
@@ -383,9 +523,9 @@ static void ds2760_battery_set_charged_work(struct work_struct *work)
 
        dev_dbg(di->dev, "%s: bias = %d\n", __func__, bias);
 
-       w1_ds2760_write(di->w1_dev, &bias, DS2760_CURRENT_OFFSET_BIAS, 1);
-       w1_ds2760_store_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1);
-       w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1);
+       w1_ds2760_write(di->dev, &bias, DS2760_CURRENT_OFFSET_BIAS, 1);
+       w1_ds2760_store_eeprom(di->dev, DS2760_EEPROM_BLOCK1);
+       w1_ds2760_recall_eeprom(di->dev, DS2760_EEPROM_BLOCK1);
 
        /* Write to the di->raw[] buffer directly - the CURRENT_OFFSET_BIAS
         * value won't be read back by ds2760_battery_read_status() */
@@ -504,24 +644,55 @@ static enum power_supply_property ds2760_battery_props[] = {
        POWER_SUPPLY_PROP_CAPACITY,
 };
 
-static int ds2760_battery_probe(struct platform_device *pdev)
+static int ds2760_pm_notifier(struct notifier_block *notifier,
+                             unsigned long pm_event,
+                             void *unused)
+{
+       struct ds2760_device_info *di =
+               container_of(notifier, struct ds2760_device_info, pm_notifier);
+
+       switch (pm_event) {
+       case PM_HIBERNATION_PREPARE:
+       case PM_SUSPEND_PREPARE:
+               di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
+               break;
+
+       case PM_POST_RESTORE:
+       case PM_POST_HIBERNATION:
+       case PM_POST_SUSPEND:
+               di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
+               power_supply_changed(di->bat);
+               mod_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ);
+
+               break;
+
+       case PM_RESTORE_PREPARE:
+       default:
+               break;
+       }
+
+       return NOTIFY_DONE;
+}
+
+static int w1_ds2760_add_slave(struct w1_slave *sl)
 {
        struct power_supply_config psy_cfg = {};
-       char status;
-       int retval = 0;
        struct ds2760_device_info *di;
+       struct device *dev = &sl->dev;
+       int retval = 0;
+       char name[32];
+       char status;
 
-       di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
+       di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL);
        if (!di) {
                retval = -ENOMEM;
                goto di_alloc_failed;
        }
 
-       platform_set_drvdata(pdev, di);
+       snprintf(name, sizeof(name), "ds2760-battery.%d", dev->id);
 
-       di->dev                         = &pdev->dev;
-       di->w1_dev                      = pdev->dev.parent;
-       di->bat_desc.name               = dev_name(&pdev->dev);
+       di->dev                         = dev;
+       di->bat_desc.name               = name;
        di->bat_desc.type               = POWER_SUPPLY_TYPE_BATTERY;
        di->bat_desc.properties         = ds2760_battery_props;
        di->bat_desc.num_properties     = ARRAY_SIZE(ds2760_battery_props);
@@ -533,10 +704,30 @@ static int ds2760_battery_probe(struct platform_device *pdev)
        di->bat_desc.external_power_changed =
                                  ds2760_battery_external_power_changed;
 
-       psy_cfg.drv_data                = di;
+       psy_cfg.drv_data = di;
+
+       if (dev->of_node) {
+               u32 tmp;
+
+               psy_cfg.of_node = dev->of_node;
+
+               if (!of_property_read_bool(dev->of_node, "maxim,pmod-enabled"))
+                       pmod_enabled = true;
+
+               if (!of_property_read_u32(dev->of_node,
+                                         "maxim,cache-time-ms", &tmp))
+                       cache_time = tmp;
+
+               if (!of_property_read_u32(dev->of_node,
+                                         "rated-capacity-microamp-hours",
+                                         &tmp))
+                       rated_capacity = tmp / 10; /* property is in mAh */
+       }
 
        di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
 
+       sl->family_data = di;
+
        /* enable sleep mode feature */
        ds2760_battery_read_status(di);
        status = di->raw[DS2760_STATUS_REG];
@@ -547,7 +738,7 @@ static int ds2760_battery_probe(struct platform_device *pdev)
 
        ds2760_battery_write_status(di, status);
 
-       /* set rated capacity from module param */
+       /* set rated capacity from module param or device tree */
        if (rated_capacity)
                ds2760_battery_write_rated_capacity(di, rated_capacity);
 
@@ -556,7 +747,7 @@ static int ds2760_battery_probe(struct platform_device *pdev)
        if (current_accum)
                ds2760_battery_set_current_accum(di, current_accum);
 
-       di->bat = power_supply_register(&pdev->dev, &di->bat_desc, &psy_cfg);
+       di->bat = power_supply_register(dev, &di->bat_desc, &psy_cfg);
        if (IS_ERR(di->bat)) {
                dev_err(di->dev, "failed to register battery\n");
                retval = PTR_ERR(di->bat);
@@ -566,14 +757,16 @@ static int ds2760_battery_probe(struct platform_device *pdev)
        INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work);
        INIT_DELAYED_WORK(&di->set_charged_work,
                          ds2760_battery_set_charged_work);
-       di->monitor_wqueue = alloc_ordered_workqueue(dev_name(&pdev->dev),
-                                                    WQ_MEM_RECLAIM);
+       di->monitor_wqueue = alloc_ordered_workqueue(name, WQ_MEM_RECLAIM);
        if (!di->monitor_wqueue) {
                retval = -ESRCH;
                goto workqueue_failed;
        }
        queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ * 1);
 
+       di->pm_notifier.notifier_call = ds2760_pm_notifier;
+       register_pm_notifier(&di->pm_notifier);
+
        goto success;
 
 workqueue_failed:
@@ -584,65 +777,40 @@ success:
        return retval;
 }
 
-static int ds2760_battery_remove(struct platform_device *pdev)
+static void w1_ds2760_remove_slave(struct w1_slave *sl)
 {
-       struct ds2760_device_info *di = platform_get_drvdata(pdev);
+       struct ds2760_device_info *di = sl->family_data;
 
+       unregister_pm_notifier(&di->pm_notifier);
        cancel_delayed_work_sync(&di->monitor_work);
        cancel_delayed_work_sync(&di->set_charged_work);
        destroy_workqueue(di->monitor_wqueue);
        power_supply_unregister(di->bat);
-
-       return 0;
-}
-
-#ifdef CONFIG_PM
-
-static int ds2760_battery_suspend(struct platform_device *pdev,
-                                 pm_message_t state)
-{
-       struct ds2760_device_info *di = platform_get_drvdata(pdev);
-
-       di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
-
-       return 0;
-}
-
-static int ds2760_battery_resume(struct platform_device *pdev)
-{
-       struct ds2760_device_info *di = platform_get_drvdata(pdev);
-
-       di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
-       power_supply_changed(di->bat);
-
-       mod_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ);
-
-       return 0;
 }
 
-#else
-
-#define ds2760_battery_suspend NULL
-#define ds2760_battery_resume NULL
-
-#endif /* CONFIG_PM */
-
-MODULE_ALIAS("platform:ds2760-battery");
+#ifdef CONFIG_OF
+static const struct of_device_id w1_ds2760_of_ids[] = {
+       { .compatible = "maxim,ds2760" },
+       {}
+};
+#endif
 
-static struct platform_driver ds2760_battery_driver = {
-       .driver = {
-               .name = "ds2760-battery",
-       },
-       .probe    = ds2760_battery_probe,
-       .remove   = ds2760_battery_remove,
-       .suspend  = ds2760_battery_suspend,
-       .resume   = ds2760_battery_resume,
+static struct w1_family_ops w1_ds2760_fops = {
+       .add_slave      = w1_ds2760_add_slave,
+       .remove_slave   = w1_ds2760_remove_slave,
+       .groups         = w1_ds2760_groups,
 };
 
-module_platform_driver(ds2760_battery_driver);
+static struct w1_family w1_ds2760_family = {
+       .fid            = W1_FAMILY_DS2760,
+       .fops           = &w1_ds2760_fops,
+       .of_match_table = of_match_ptr(w1_ds2760_of_ids),
+};
+module_w1_family(w1_ds2760_family);
 
-MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, "
              "Matt Reimer <mreimer@vpop.net>, "
              "Anton Vorontsov <cbou@mail.ru>");
-MODULE_DESCRIPTION("ds2760 battery driver");
+MODULE_DESCRIPTION("1-wire Driver Dallas 2760 battery monitor chip");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2760));
index 28dc056eaafade5bbf11850d3237d4f19530a44e..bc462d1ec9630de42080e4e5be428252e36b2e8d 100644 (file)
@@ -241,10 +241,10 @@ static int gab_probe(struct platform_device *pdev)
        struct power_supply_desc *psy_desc;
        struct power_supply_config psy_cfg = {};
        struct gab_platform_data *pdata = pdev->dev.platform_data;
-       enum power_supply_property *properties;
        int ret = 0;
        int chan;
-       int index = 0;
+       int index = ARRAY_SIZE(gab_props);
+       bool any = false;
 
        adc_bat = devm_kzalloc(&pdev->dev, sizeof(*adc_bat), GFP_KERNEL);
        if (!adc_bat) {
@@ -278,8 +278,6 @@ static int gab_probe(struct platform_device *pdev)
        }
 
        memcpy(psy_desc->properties, gab_props, sizeof(gab_props));
-       properties = (enum power_supply_property *)
-                       ((char *)psy_desc->properties + sizeof(gab_props));
 
        /*
         * getting channel from iio and copying the battery properties
@@ -293,15 +291,22 @@ static int gab_probe(struct platform_device *pdev)
                        adc_bat->channel[chan] = NULL;
                } else {
                        /* copying properties for supported channels only */
-                       memcpy(properties + sizeof(*(psy_desc->properties)) * index,
-                                       &gab_dyn_props[chan],
-                                       sizeof(gab_dyn_props[chan]));
-                       index++;
+                       int index2;
+
+                       for (index2 = 0; index2 < index; index2++) {
+                               if (psy_desc->properties[index2] ==
+                                   gab_dyn_props[chan])
+                                       break;  /* already known */
+                       }
+                       if (index2 == index)    /* really new */
+                               psy_desc->properties[index++] =
+                                       gab_dyn_props[chan];
+                       any = true;
                }
        }
 
        /* none of the channels are supported so let's bail out */
-       if (index == 0) {
+       if (!any) {
                ret = -ENODEV;
                goto second_mem_fail;
        }
@@ -312,7 +317,7 @@ static int gab_probe(struct platform_device *pdev)
         * as come channels may be not be supported by the device.So
         * we need to take care of that.
         */
-       psy_desc->num_properties = ARRAY_SIZE(gab_props) + index;
+       psy_desc->num_properties = index;
 
        adc_bat->psy = power_supply_register(&pdev->dev, psy_desc, &psy_cfg);
        if (IS_ERR(adc_bat->psy)) {
index 7b993d669f7f76277b560b87e04fd933902fd133..1ae3710909b78ccfc2870b2c0200a173c69ffca8 100644 (file)
@@ -39,7 +39,7 @@ static int lego_ev3_battery_get_property(struct power_supply *psy,
                                         union power_supply_propval *val)
 {
        struct lego_ev3_battery *batt = power_supply_get_drvdata(psy);
-       int val2;
+       int ret, val2;
 
        switch (psp) {
        case POWER_SUPPLY_PROP_TECHNOLOGY:
@@ -47,11 +47,18 @@ static int lego_ev3_battery_get_property(struct power_supply *psy,
                break;
        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
                /* battery voltage is iio channel * 2 + Vce of transistor */
-               iio_read_channel_processed(batt->iio_v, &val->intval);
+               ret = iio_read_channel_processed(batt->iio_v, &val->intval);
+               if (ret)
+                       return ret;
+
                val->intval *= 2000;
-               val->intval += 200000;
+               val->intval += 50000;
+
                /* plus adjust for shunt resistor drop */
-               iio_read_channel_processed(batt->iio_i, &val2);
+               ret = iio_read_channel_processed(batt->iio_i, &val2);
+               if (ret)
+                       return ret;
+
                val2 *= 1000;
                val2 /= 15;
                val->intval += val2;
@@ -64,7 +71,10 @@ static int lego_ev3_battery_get_property(struct power_supply *psy,
                break;
        case POWER_SUPPLY_PROP_CURRENT_NOW:
                /* battery current is iio channel / 15 / 0.05 ohms */
-               iio_read_channel_processed(batt->iio_i, &val->intval);
+               ret = iio_read_channel_processed(batt->iio_i, &val->intval);
+               if (ret)
+                       return ret;
+
                val->intval *= 20000;
                val->intval /= 15;
                break;
index 9ee601a03d9b7edfe20a9cddb98287293d5b6ba1..9ca895b0dabb558d084953d65aa00e2802bab37e 100644 (file)
@@ -372,7 +372,7 @@ static int devm_w1_max1721x_add_device(struct w1_slave *sl)
        }
 
        if (!info->rsense) {
-               dev_warn(info->w1_dev, "RSenese not calibrated, set 10 mOhms!\n");
+               dev_warn(info->w1_dev, "RSense not calibrated, set 10 mOhms!\n");
                info->rsense = 1000; /* in regs in 10^-5 */
        }
        dev_info(info->w1_dev, "RSense: %d mOhms.\n", info->rsense / 100);
index 6c78884bad5e3789501233b8f4991ffac0ab863b..749c7926e3c904fa197f756b57a1168a0f7566f2 100644 (file)
@@ -567,6 +567,7 @@ static int max77693_set_charge_input_threshold_volt(struct max77693_charger *chg
        case 4800000:
        case 4900000:
                data = (uvolt - 4700000) / 100000;
+               break;
        default:
                dev_err(chg->dev, "Wrong value for charge input voltage regulation threshold\n");
                return -EINVAL;
index d21f478741c17e786d534476a0288cf544c19b2e..e85361878450c52f70c280af1fcce5ba738d60ae 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/notifier.h>
 #include <linux/err.h>
@@ -140,8 +141,13 @@ static void power_supply_deferred_register_work(struct work_struct *work)
        struct power_supply *psy = container_of(work, struct power_supply,
                                                deferred_register_work.work);
 
-       if (psy->dev.parent)
-               mutex_lock(&psy->dev.parent->mutex);
+       if (psy->dev.parent) {
+               while (!mutex_trylock(&psy->dev.parent->mutex)) {
+                       if (psy->removing)
+                               return;
+                       msleep(10);
+               }
+       }
 
        power_supply_changed(psy);
 
@@ -1082,6 +1088,7 @@ EXPORT_SYMBOL_GPL(devm_power_supply_register_no_ws);
 void power_supply_unregister(struct power_supply *psy)
 {
        WARN_ON(atomic_dec_return(&psy->use_cnt));
+       psy->removing = true;
        cancel_work_sync(&psy->changed_work);
        cancel_delayed_work_sync(&psy->deferred_register_work);
        sysfs_remove_link(&psy->dev.kobj, "powers");
index 83d7b4115857e38fcb310dbbdadc373e6104dfc0..8ba6abf584de2b6ca5a66573dd8cf2b873f023f7 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/power/sbs-battery.h>
 #include <linux/power_supply.h>
 #include <linux/slab.h>
@@ -156,6 +157,9 @@ static enum power_supply_property sbs_properties[] = {
        POWER_SUPPLY_PROP_MODEL_NAME
 };
 
+/* Supports special manufacturer commands from TI BQ20Z75 IC. */
+#define SBS_FLAGS_TI_BQ20Z75           BIT(0)
+
 struct sbs_info {
        struct i2c_client               *client;
        struct power_supply             *power_supply;
@@ -168,6 +172,7 @@ struct sbs_info {
        u32                             poll_retry_count;
        struct delayed_work             work;
        struct mutex                    mode_lock;
+       u32                             flags;
 };
 
 static char model_name[I2C_SMBUS_BLOCK_MAX + 1];
@@ -315,17 +320,41 @@ static int sbs_status_correct(struct i2c_client *client, int *intval)
 static int sbs_get_battery_presence_and_health(
        struct i2c_client *client, enum power_supply_property psp,
        union power_supply_propval *val)
+{
+       int ret;
+
+       if (psp == POWER_SUPPLY_PROP_PRESENT) {
+               /* Dummy command; if it succeeds, battery is present. */
+               ret = sbs_read_word_data(client, sbs_data[REG_STATUS].addr);
+               if (ret < 0)
+                       val->intval = 0; /* battery disconnected */
+               else
+                       val->intval = 1; /* battery present */
+       } else { /* POWER_SUPPLY_PROP_HEALTH */
+               /* SBS spec doesn't have a general health command. */
+               val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
+       }
+
+       return 0;
+}
+
+static int sbs_get_ti_battery_presence_and_health(
+       struct i2c_client *client, enum power_supply_property psp,
+       union power_supply_propval *val)
 {
        s32 ret;
 
        /*
         * Write to ManufacturerAccess with ManufacturerAccess command
-        * and then read the status. Do not check for error on the write
-        * since not all batteries implement write access to this command,
-        * while others mandate it.
+        * and then read the status.
         */
-       sbs_write_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr,
-                           MANUFACTURER_ACCESS_STATUS);
+       ret = sbs_write_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr,
+                                 MANUFACTURER_ACCESS_STATUS);
+       if (ret < 0) {
+               if (psp == POWER_SUPPLY_PROP_PRESENT)
+                       val->intval = 0; /* battery removed */
+               return ret;
+       }
 
        ret = sbs_read_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr);
        if (ret < 0) {
@@ -600,7 +629,12 @@ static int sbs_get_property(struct power_supply *psy,
        switch (psp) {
        case POWER_SUPPLY_PROP_PRESENT:
        case POWER_SUPPLY_PROP_HEALTH:
-               ret = sbs_get_battery_presence_and_health(client, psp, val);
+               if (client->flags & SBS_FLAGS_TI_BQ20Z75)
+                       ret = sbs_get_ti_battery_presence_and_health(client,
+                                                                    psp, val);
+               else
+                       ret = sbs_get_battery_presence_and_health(client, psp,
+                                                                 val);
                if (psp == POWER_SUPPLY_PROP_PRESENT)
                        return 0;
                break;
@@ -806,6 +840,7 @@ static int sbs_probe(struct i2c_client *client,
        if (!chip)
                return -ENOMEM;
 
+       chip->flags = (u32)(uintptr_t)of_device_get_match_data(&client->dev);
        chip->client = client;
        chip->enable_detection = false;
        psy_cfg.of_node = client->dev.of_node;
@@ -911,16 +946,19 @@ static int sbs_suspend(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct sbs_info *chip = i2c_get_clientdata(client);
+       int ret;
 
        if (chip->poll_time > 0)
                cancel_delayed_work_sync(&chip->work);
 
-       /*
-        * Write to manufacturer access with sleep command.
-        * Support is manufacturer dependend, so ignore errors.
-        */
-       sbs_write_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr,
-               MANUFACTURER_ACCESS_SLEEP);
+       if (chip->flags & SBS_FLAGS_TI_BQ20Z75) {
+               /* Write to manufacturer access with sleep command. */
+               ret = sbs_write_word_data(client,
+                                         sbs_data[REG_MANUFACTURER_DATA].addr,
+                                         MANUFACTURER_ACCESS_SLEEP);
+               if (chip->is_present && ret < 0)
+                       return ret;
+       }
 
        return 0;
 }
@@ -941,7 +979,10 @@ MODULE_DEVICE_TABLE(i2c, sbs_id);
 
 static const struct of_device_id sbs_dt_ids[] = {
        { .compatible = "sbs,sbs-battery" },
-       { .compatible = "ti,bq20z75" },
+       {
+               .compatible = "ti,bq20z75",
+               .data = (void *)SBS_FLAGS_TI_BQ20Z75,
+       },
        { }
 };
 MODULE_DEVICE_TABLE(of, sbs_dt_ids);
index 1f5234098aaf3f9dc27a7cbdef98d42fcce34324..814c2b81fdfecad0cba9c27153de0d81ced8311e 100644 (file)
@@ -1,20 +1,8 @@
-/*
- * Battery charger driver for TI's tps65217
- *
- * Copyright (c) 2015, Collabora Ltd.
-
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
-
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
+// SPDX-License-Identifier: GPL-2.0
+// Battery charger driver for TI's tps65217
+//
+// Copyright (C) 2015 Collabora Ltd.
+// Author: Enric Balletbo i Serra <enric.balletbo@collabora.com>
 
 /*
  * Battery charger driver for TI's tps65217
index a2740cf57ad3e0de776e779c3ff179c68d5375d8..15c0ca15e2aa9d857625061682bfea47bb489fe4 100644 (file)
@@ -230,7 +230,8 @@ static irqreturn_t wm8350_charger_handler(int irq, void *data)
        case WM8350_IRQ_EXT_USB_FB:
        case WM8350_IRQ_EXT_WALL_FB:
                wm8350_charger_config(wm8350, policy);
-       case WM8350_IRQ_EXT_BAT_FB:   /* Fall through */
+               /* Fall through */
+       case WM8350_IRQ_EXT_BAT_FB:
                power_supply_changed(power->battery);
                power_supply_changed(power->usb);
                power_supply_changed(power->ac);
index a4d262db9945ff10a1d0f67409cb0b03c76026b8..504d252716f2e10db4914c8de651dff05106b82c 100644 (file)
@@ -286,7 +286,7 @@ config PWM_MTK_DISP
 
 config PWM_MEDIATEK
        tristate "MediaTek PWM support"
-       depends on ARCH_MEDIATEK || COMPILE_TEST
+       depends on ARCH_MEDIATEK || RALINK || COMPILE_TEST
        help
          Generic PWM framework driver for Mediatek ARM SoC.
 
index 771859aca4be2b104e53f57f1271e8a2c7a9677d..7c8d6a168ceb254c69420ab293f08e3b43fcdd18 100644 (file)
 #define BERLIN_PWM_EN                  0x0
 #define  BERLIN_PWM_ENABLE             BIT(0)
 #define BERLIN_PWM_CONTROL             0x4
-#define  BERLIN_PWM_PRESCALE_MASK      0x7
-#define  BERLIN_PWM_PRESCALE_MAX       4096
+/*
+ * The prescaler claims to support 8 different moduli, configured using the
+ * low three bits of PWM_CONTROL. (Sequentially, they are 1, 4, 8, 16, 64,
+ * 256, 1024, and 4096.)  However, the moduli from 4 to 1024 appear to be
+ * implemented by internally shifting TCNT left without adding additional
+ * bits. So, the max TCNT that actually works for a modulus of 4 is 0x3fff;
+ * for 8, 0x1fff; and so on. This means that those moduli are entirely
+ * useless, as we could just do the shift ourselves. The 4096 modulus is
+ * implemented with a real prescaler, so we do use that, but we treat it
+ * as a flag instead of pretending the modulus is actually configurable.
+ */
+#define  BERLIN_PWM_PRESCALE_4096      0x7
 #define  BERLIN_PWM_INVERT_POLARITY    BIT(3)
 #define BERLIN_PWM_DUTY                        0x8
 #define BERLIN_PWM_TCNT                        0xc
@@ -46,10 +56,6 @@ static inline struct berlin_pwm_chip *to_berlin_pwm_chip(struct pwm_chip *chip)
        return container_of(chip, struct berlin_pwm_chip, chip);
 }
 
-static const u32 prescaler_table[] = {
-       1, 4, 8, 16, 64, 256, 1024, 4096
-};
-
 static inline u32 berlin_pwm_readl(struct berlin_pwm_chip *chip,
                                   unsigned int channel, unsigned long offset)
 {
@@ -86,33 +92,32 @@ static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm_dev,
                             int duty_ns, int period_ns)
 {
        struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
-       unsigned int prescale;
+       bool prescale_4096 = false;
        u32 value, duty, period;
-       u64 cycles, tmp;
+       u64 cycles;
 
        cycles = clk_get_rate(pwm->clk);
        cycles *= period_ns;
        do_div(cycles, NSEC_PER_SEC);
 
-       for (prescale = 0; prescale < ARRAY_SIZE(prescaler_table); prescale++) {
-               tmp = cycles;
-               do_div(tmp, prescaler_table[prescale]);
+       if (cycles > BERLIN_PWM_MAX_TCNT) {
+               prescale_4096 = true;
+               cycles >>= 12; // Prescaled by 4096
 
-               if (tmp <= BERLIN_PWM_MAX_TCNT)
-                       break;
+               if (cycles > BERLIN_PWM_MAX_TCNT)
+                       return -ERANGE;
        }
 
-       if (tmp > BERLIN_PWM_MAX_TCNT)
-               return -ERANGE;
-
-       period = tmp;
-       cycles = tmp * duty_ns;
+       period = cycles;
+       cycles *= duty_ns;
        do_div(cycles, period_ns);
        duty = cycles;
 
        value = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
-       value &= ~BERLIN_PWM_PRESCALE_MASK;
-       value |= prescale;
+       if (prescale_4096)
+               value |= BERLIN_PWM_PRESCALE_4096;
+       else
+               value &= ~BERLIN_PWM_PRESCALE_4096;
        berlin_pwm_writel(pwm, pwm_dev->hwpwm, value, BERLIN_PWM_CONTROL);
 
        berlin_pwm_writel(pwm, pwm_dev->hwpwm, duty, BERLIN_PWM_DUTY);
index 9c13694eaa2480cdffba20b65049005a2d46ae24..98f6ac6cf6ab4f9fcda159ae51e5017c519ed042 100644 (file)
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (C) 2016 Google, Inc
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2, as published by
- * the Free Software Foundation.
- *
  * Expose a PWM controlled by the ChromeOS EC to the host processor.
+ *
+ * Copyright (C) 2016 Google, Inc.
  */
 
 #include <linux/module.h>
index 557b4ea16796bff9f18e7919bf6a07bc0dfcc3c2..883378d055c64e5887371b077d7c62f70d6a8920 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/of_address.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/pwm.h>
@@ -75,6 +76,10 @@ enum fsl_pwm_clk {
        FSL_PWM_CLK_MAX
 };
 
+struct fsl_ftm_soc {
+       bool has_enable_bits;
+};
+
 struct fsl_pwm_chip {
        struct pwm_chip chip;
 
@@ -87,7 +92,10 @@ struct fsl_pwm_chip {
 
        int period_ns;
 
+       struct clk *ipg_clk;
        struct clk *clk[FSL_PWM_CLK_MAX];
+
+       const struct fsl_ftm_soc *soc;
 };
 
 static inline struct fsl_pwm_chip *to_fsl_chip(struct pwm_chip *chip)
@@ -97,16 +105,32 @@ static inline struct fsl_pwm_chip *to_fsl_chip(struct pwm_chip *chip)
 
 static int fsl_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
 {
+       int ret;
        struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
 
-       return clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+       ret = clk_prepare_enable(fpc->ipg_clk);
+       if (!ret && fpc->soc->has_enable_bits) {
+               mutex_lock(&fpc->lock);
+               regmap_update_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16),
+                                  BIT(pwm->hwpwm + 16));
+               mutex_unlock(&fpc->lock);
+       }
+
+       return ret;
 }
 
 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]);
+       if (fpc->soc->has_enable_bits) {
+               mutex_lock(&fpc->lock);
+               regmap_update_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16),
+                                  0);
+               mutex_unlock(&fpc->lock);
+       }
+
+       clk_disable_unprepare(fpc->ipg_clk);
 }
 
 static int fsl_pwm_calculate_default_ps(struct fsl_pwm_chip *fpc,
@@ -363,7 +387,7 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
 {
        int ret;
 
-       ret = clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+       ret = clk_prepare_enable(fpc->ipg_clk);
        if (ret)
                return ret;
 
@@ -371,7 +395,7 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
        regmap_write(fpc->regmap, FTM_OUTINIT, 0x00);
        regmap_write(fpc->regmap, FTM_OUTMASK, 0xFF);
 
-       clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+       clk_disable_unprepare(fpc->ipg_clk);
 
        return 0;
 }
@@ -408,6 +432,7 @@ static int fsl_pwm_probe(struct platform_device *pdev)
 
        mutex_init(&fpc->lock);
 
+       fpc->soc = of_device_get_match_data(&pdev->dev);
        fpc->chip.dev = &pdev->dev;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -441,6 +466,15 @@ static int fsl_pwm_probe(struct platform_device *pdev)
        if (IS_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]))
                return PTR_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]);
 
+       /*
+        * ipg_clk is the interface clock for the IP. If not provided, use the
+        * ftm_sys clock as the default.
+        */
+       fpc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
+       if (IS_ERR(fpc->ipg_clk))
+               fpc->ipg_clk = fpc->clk[FSL_PWM_CLK_SYS];
+
+
        fpc->chip.ops = &fsl_pwm_ops;
        fpc->chip.of_xlate = of_pwm_xlate_with_flags;
        fpc->chip.of_pwm_n_cells = 3;
@@ -480,7 +514,7 @@ static int fsl_pwm_suspend(struct device *dev)
                if (!test_bit(PWMF_REQUESTED, &pwm->flags))
                        continue;
 
-               clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
+               clk_disable_unprepare(fpc->ipg_clk);
 
                if (!pwm_is_enabled(pwm))
                        continue;
@@ -503,7 +537,7 @@ static int fsl_pwm_resume(struct device *dev)
                if (!test_bit(PWMF_REQUESTED, &pwm->flags))
                        continue;
 
-               clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
+               clk_prepare_enable(fpc->ipg_clk);
 
                if (!pwm_is_enabled(pwm))
                        continue;
@@ -524,8 +558,17 @@ static const struct dev_pm_ops fsl_pwm_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(fsl_pwm_suspend, fsl_pwm_resume)
 };
 
+static const struct fsl_ftm_soc vf610_ftm_pwm = {
+       .has_enable_bits = false,
+};
+
+static const struct fsl_ftm_soc imx8qm_ftm_pwm = {
+       .has_enable_bits = true,
+};
+
 static const struct of_device_id fsl_pwm_dt_ids[] = {
-       { .compatible = "fsl,vf610-ftm-pwm", },
+       { .compatible = "fsl,vf610-ftm-pwm", .data = &vf610_ftm_pwm },
+       { .compatible = "fsl,imx8qm-ftm-pwm", .data = &imx8qm_ftm_pwm },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, fsl_pwm_dt_ids);
index 08cbe8120588f89c31952b256689a230abf97845..1d5242c9cde084a29a393154158ef9629cdd7499 100644 (file)
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * simple driver for PWM (Pulse Width Modulator) controller
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
  * Derived from pxa PWM driver by eric miao <eric.miao@marvell.com>
  */
 
index 328c124773b23e6501a70f8320d02f4900e6d71a..eb6674ce995ff1bda4da866cd06edb553f78a59a 100644 (file)
@@ -57,6 +57,7 @@ static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
 struct mtk_pwm_platform_data {
        unsigned int num_pwms;
        bool pwm45_fixup;
+       bool has_clks;
 };
 
 /**
@@ -86,6 +87,9 @@ static int mtk_pwm_clk_enable(struct pwm_chip *chip, struct pwm_device *pwm)
        struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
        int ret;
 
+       if (!pc->soc->has_clks)
+               return 0;
+
        ret = clk_prepare_enable(pc->clks[MTK_CLK_TOP]);
        if (ret < 0)
                return ret;
@@ -112,6 +116,9 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
        struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
 
+       if (!pc->soc->has_clks)
+               return;
+
        clk_disable_unprepare(pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]);
        clk_disable_unprepare(pc->clks[MTK_CLK_MAIN]);
        clk_disable_unprepare(pc->clks[MTK_CLK_TOP]);
@@ -239,7 +246,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
        if (IS_ERR(pc->regs))
                return PTR_ERR(pc->regs);
 
-       for (i = 0; i < data->num_pwms + 2; i++) {
+       for (i = 0; i < data->num_pwms + 2 && pc->soc->has_clks; i++) {
                pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
                if (IS_ERR(pc->clks[i])) {
                        dev_err(&pdev->dev, "clock: %s fail: %ld\n",
@@ -274,22 +281,32 @@ static int mtk_pwm_remove(struct platform_device *pdev)
 static const struct mtk_pwm_platform_data mt2712_pwm_data = {
        .num_pwms = 8,
        .pwm45_fixup = false,
+       .has_clks = true,
 };
 
 static const struct mtk_pwm_platform_data mt7622_pwm_data = {
        .num_pwms = 6,
        .pwm45_fixup = false,
+       .has_clks = true,
 };
 
 static const struct mtk_pwm_platform_data mt7623_pwm_data = {
        .num_pwms = 5,
        .pwm45_fixup = true,
+       .has_clks = true,
+};
+
+static const struct mtk_pwm_platform_data mt7628_pwm_data = {
+       .num_pwms = 4,
+       .pwm45_fixup = true,
+       .has_clks = false,
 };
 
 static const struct of_device_id mtk_pwm_of_match[] = {
        { .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
        { .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
        { .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
+       { .compatible = "mediatek,mt7628-pwm", .data = &mt7628_pwm_data },
        { },
 };
 MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
index 822860b4801a6823008d51346e82d0f279c6c053..c1ed641b3e26622041c0fead2931a13bface7454 100644 (file)
@@ -458,7 +458,6 @@ static int meson_pwm_init_channels(struct meson_pwm *meson,
                                   struct meson_pwm_channel *channels)
 {
        struct device *dev = meson->chip.dev;
-       struct device_node *np = dev->of_node;
        struct clk_init_data init;
        unsigned int i;
        char name[255];
@@ -467,7 +466,7 @@ static int meson_pwm_init_channels(struct meson_pwm *meson,
        for (i = 0; i < meson->chip.npwm; i++) {
                struct meson_pwm_channel *channel = &channels[i];
 
-               snprintf(name, sizeof(name), "%pOF#mux%u", np, i);
+               snprintf(name, sizeof(name), "%s#mux%u", dev_name(dev), i);
 
                init.name = name;
                init.ops = &clk_mux_ops;
index a6017ad9926c60a2cc0df8edfd36e2acef8c54cf..04c0f6b95c1a6c669dcc191777d01b5e9c698942 100644 (file)
@@ -1,12 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright 2012 Freescale Semiconductor, Inc.
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
  */
 
 #include <linux/clk.h>
index 665da3c8fbcebab087db37cbedc21897b0cb04e8..f45798679e3c046add4f646ecd5c86e02a7b9b9c 100644 (file)
@@ -264,8 +264,9 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 
        timer_pdata = dev_get_platdata(&timer_pdev->dev);
        if (!timer_pdata) {
-               dev_err(&pdev->dev, "dmtimer pdata structure NULL\n");
-               ret = -EINVAL;
+               dev_dbg(&pdev->dev,
+                        "dmtimer pdata structure NULL, deferring probe\n");
+               ret = -EPROBE_DEFER;
                goto put;
        }
 
index 7c13e2505080e1495997b369800bcd05379ff018..0059b24cfdc3c39579b9e70b11b9f0271399db1a 100644 (file)
@@ -217,10 +217,8 @@ static int stm32_pwm_lp_probe(struct platform_device *pdev)
 static int stm32_pwm_lp_remove(struct platform_device *pdev)
 {
        struct stm32_pwm_lp *priv = platform_get_drvdata(pdev);
-       unsigned int i;
 
-       for (i = 0; i < priv->chip.npwm; i++)
-               pwm_disable(&priv->chip.pwms[i]);
+       pwm_disable(&priv->chip.pwms[0]);
 
        return pwmchip_remove(&priv->chip);
 }
index 4c22cb39504094eb32db6ad94e7718eadb38917b..f7b8a86fa5c5e9570a616ccbcdb61e7d427b8ae3 100644 (file)
 #define TBCTL                  0x00
 #define TBPRD                  0x0A
 
-#define TBCTL_RUN_MASK         (BIT(15) | BIT(14))
-#define TBCTL_STOP_NEXT                0
-#define TBCTL_STOP_ON_CYCLE    BIT(14)
-#define TBCTL_FREE_RUN         (BIT(15) | BIT(14))
 #define TBCTL_PRDLD_MASK       BIT(3)
 #define TBCTL_PRDLD_SHDW       0
 #define TBCTL_PRDLD_IMDT       BIT(3)
@@ -360,7 +356,7 @@ static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
        /* Channels polarity can be configured from action qualifier module */
        configure_polarity(pc, pwm->hwpwm);
 
-       /* Enable TBCLK before enabling PWM device */
+       /* Enable TBCLK */
        ret = clk_enable(pc->tbclk);
        if (ret) {
                dev_err(chip->dev, "Failed to enable TBCLK for %s: %d\n",
@@ -368,9 +364,6 @@ static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
                return ret;
        }
 
-       /* Enable time counter for free_run */
-       ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_FREE_RUN);
-
        return 0;
 }
 
@@ -388,6 +381,8 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
                aqcsfrc_mask = AQCSFRC_CSFA_MASK;
        }
 
+       /* Update shadow register first before modifying active register */
+       ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val);
        /*
         * Changes to immediate action on Action Qualifier. This puts
         * Action Qualifier control on PWM output from next TBCLK
@@ -400,9 +395,6 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
        /* Disabling TBCLK on PWM disable */
        clk_disable(pc->tbclk);
 
-       /* Stop Time base counter */
-       ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_STOP_NEXT);
-
        /* Disable clock on PWM disable */
        pm_runtime_put_sync(chip->dev);
 }
index a8cb8d2f2abbbff0ce6405b14d4fc73172d1391b..cbe467ff1aba9d8ca72588f51856f2239dd4d0d9 100644 (file)
@@ -1006,7 +1006,6 @@ out_free:
 static int rio_mport_wait_for_async_dma(struct file *filp, void __user *arg)
 {
        struct mport_cdev_priv *priv;
-       struct mport_dev *md;
        struct rio_async_tx_wait w_param;
        struct mport_dma_req *req;
        dma_cookie_t cookie;
@@ -1016,7 +1015,6 @@ static int rio_mport_wait_for_async_dma(struct file *filp, void __user *arg)
        int ret;
 
        priv = (struct mport_cdev_priv *)filp->private_data;
-       md = priv->md;
 
        if (unlikely(copy_from_user(&w_param, arg, sizeof(w_param))))
                return -EFAULT;
index c0b292be1b72f1eb4d31b142636699d0736722f3..13d28fdbdbb535cdf665b39c8b52ad5127d0b9b9 100644 (file)
@@ -73,6 +73,13 @@ config RESET_MESON
        help
          This enables the reset driver for Amlogic Meson SoCs.
 
+config RESET_MESON_AUDIO_ARB
+       tristate "Meson Audio Memory Arbiter Reset Driver"
+       depends on ARCH_MESON || COMPILE_TEST
+       help
+         This enables the reset driver for Audio Memory Arbiter of
+         Amlogic's A113 based SoCs
+
 config RESET_OXNAS
        bool
 
@@ -82,6 +89,15 @@ config RESET_PISTACHIO
        help
          This enables the reset driver for ImgTec Pistachio SoCs.
 
+config RESET_QCOM_AOSS
+       bool "Qcom AOSS Reset Driver"
+       depends on ARCH_QCOM || COMPILE_TEST
+       help
+         This enables the AOSS (always on subsystem) reset driver
+         for Qualcomm SDM845 SoCs. Say Y if you want to control
+         reset signals provided by AOSS for Modem, Venus, ADSP,
+         GPU, Camera, Wireless, Display subsystem. Otherwise, say N.
+
 config RESET_SIMPLE
        bool "Simple Reset Controller Driver" if COMPILE_TEST
        default ARCH_SOCFPGA || ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARCH_ASPEED
@@ -138,6 +154,16 @@ config RESET_UNIPHIER
          Say Y if you want to control reset signals provided by System Control
          block, Media I/O block, Peripheral Block.
 
+config RESET_UNIPHIER_USB3
+       tristate "USB3 reset driver for UniPhier SoCs"
+       depends on (ARCH_UNIPHIER || COMPILE_TEST) && OF
+       default ARCH_UNIPHIER
+       select RESET_SIMPLE
+       help
+         Support for the USB3 core reset on UniPhier SoCs.
+         Say Y if you want to control reset signals provided by
+         USB3 glue layer.
+
 config RESET_ZYNQ
        bool "ZYNQ Reset Driver" if COMPILE_TEST
        default ARCH_ZYNQ
index c1261dcfe9ad29e9b1640d47da804f2d2d40ed44..4243c38228e284478048c42cfbf0f900b7d7aed4 100644 (file)
@@ -12,13 +12,16 @@ obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
 obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o
 obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
 obj-$(CONFIG_RESET_MESON) += reset-meson.o
+obj-$(CONFIG_RESET_MESON_AUDIO_ARB) += reset-meson-audio-arb.o
 obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o
 obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o
+obj-$(CONFIG_RESET_QCOM_AOSS) += reset-qcom-aoss.o
 obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
 obj-$(CONFIG_RESET_STM32MP157) += reset-stm32mp1.o
 obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
 obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
 obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o
 obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
+obj-$(CONFIG_RESET_UNIPHIER_USB3) += reset-uniphier-usb3.o
 obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o
 
index 14bc78d287074330d0c7b531fcd8c1f1417e21f2..97d9f08271c5b3756386d398f009d2c90ec6a6d8 100644 (file)
@@ -81,7 +81,7 @@ static int imx7_reset_set(struct reset_controller_dev *rcdev,
 {
        struct imx7_src *imx7src = to_imx7_src(rcdev);
        const struct imx7_src_signal *signal = &imx7_src_signals[id];
-       unsigned int value = 0;
+       unsigned int value = assert ? signal->bit : 0;
 
        switch (id) {
        case IMX7_RESET_PCIEPHY:
diff --git a/drivers/reset/reset-meson-audio-arb.c b/drivers/reset/reset-meson-audio-arb.c
new file mode 100644 (file)
index 0000000..9175161
--- /dev/null
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+// Copyright (c) 2018 BayLibre, SAS.
+// Author: Jerome Brunet <jbrunet@baylibre.com>
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/reset-controller.h>
+#include <linux/spinlock.h>
+
+#include <dt-bindings/reset/amlogic,meson-axg-audio-arb.h>
+
+struct meson_audio_arb_data {
+       struct reset_controller_dev rstc;
+       void __iomem *regs;
+       struct clk *clk;
+       const unsigned int *reset_bits;
+       spinlock_t lock;
+};
+
+#define ARB_GENERAL_BIT        31
+
+static const unsigned int axg_audio_arb_reset_bits[] = {
+       [AXG_ARB_TODDR_A]       = 0,
+       [AXG_ARB_TODDR_B]       = 1,
+       [AXG_ARB_TODDR_C]       = 2,
+       [AXG_ARB_FRDDR_A]       = 4,
+       [AXG_ARB_FRDDR_B]       = 5,
+       [AXG_ARB_FRDDR_C]       = 6,
+};
+
+static int meson_audio_arb_update(struct reset_controller_dev *rcdev,
+                                 unsigned long id, bool assert)
+{
+       u32 val;
+       struct meson_audio_arb_data *arb =
+               container_of(rcdev, struct meson_audio_arb_data, rstc);
+
+       spin_lock(&arb->lock);
+       val = readl(arb->regs);
+
+       if (assert)
+               val &= ~BIT(arb->reset_bits[id]);
+       else
+               val |= BIT(arb->reset_bits[id]);
+
+       writel(val, arb->regs);
+       spin_unlock(&arb->lock);
+
+       return 0;
+}
+
+static int meson_audio_arb_status(struct reset_controller_dev *rcdev,
+                                 unsigned long id)
+{
+       u32 val;
+       struct meson_audio_arb_data *arb =
+               container_of(rcdev, struct meson_audio_arb_data, rstc);
+
+       val = readl(arb->regs);
+
+       return !(val & BIT(arb->reset_bits[id]));
+}
+
+static int meson_audio_arb_assert(struct reset_controller_dev *rcdev,
+                                 unsigned long id)
+{
+       return meson_audio_arb_update(rcdev, id, true);
+}
+
+static int meson_audio_arb_deassert(struct reset_controller_dev *rcdev,
+                                   unsigned long id)
+{
+       return meson_audio_arb_update(rcdev, id, false);
+}
+
+static const struct reset_control_ops meson_audio_arb_rstc_ops = {
+       .assert = meson_audio_arb_assert,
+       .deassert = meson_audio_arb_deassert,
+       .status = meson_audio_arb_status,
+};
+
+static const struct of_device_id meson_audio_arb_of_match[] = {
+       { .compatible = "amlogic,meson-axg-audio-arb", },
+       {}
+};
+MODULE_DEVICE_TABLE(of, meson_audio_arb_of_match);
+
+static int meson_audio_arb_remove(struct platform_device *pdev)
+{
+       struct meson_audio_arb_data *arb = platform_get_drvdata(pdev);
+
+       /* Disable all access */
+       spin_lock(&arb->lock);
+       writel(0, arb->regs);
+       spin_unlock(&arb->lock);
+
+       clk_disable_unprepare(arb->clk);
+
+       return 0;
+}
+
+static int meson_audio_arb_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct meson_audio_arb_data *arb;
+       struct resource *res;
+       int ret;
+
+       arb = devm_kzalloc(dev, sizeof(*arb), GFP_KERNEL);
+       if (!arb)
+               return -ENOMEM;
+       platform_set_drvdata(pdev, arb);
+
+       arb->clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(arb->clk)) {
+               if (PTR_ERR(arb->clk) != -EPROBE_DEFER)
+                       dev_err(dev, "failed to get clock\n");
+               return PTR_ERR(arb->clk);
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       arb->regs = devm_ioremap_resource(dev, res);
+       if (IS_ERR(arb->regs))
+               return PTR_ERR(arb->regs);
+
+       spin_lock_init(&arb->lock);
+       arb->reset_bits = axg_audio_arb_reset_bits;
+       arb->rstc.nr_resets = ARRAY_SIZE(axg_audio_arb_reset_bits);
+       arb->rstc.ops = &meson_audio_arb_rstc_ops;
+       arb->rstc.of_node = dev->of_node;
+
+       /*
+        * Enable general :
+        * In the initial state, all memory interfaces are disabled
+        * and the general bit is on
+        */
+       ret = clk_prepare_enable(arb->clk);
+       if (ret) {
+               dev_err(dev, "failed to enable arb clock\n");
+               return ret;
+       }
+       writel(BIT(ARB_GENERAL_BIT), arb->regs);
+
+       /* Register reset controller */
+       ret = devm_reset_controller_register(dev, &arb->rstc);
+       if (ret) {
+               dev_err(dev, "failed to register arb reset controller\n");
+               meson_audio_arb_remove(pdev);
+       }
+
+       return ret;
+}
+
+static struct platform_driver meson_audio_arb_pdrv = {
+       .probe = meson_audio_arb_probe,
+       .remove = meson_audio_arb_remove,
+       .driver = {
+               .name = "meson-audio-arb-reset",
+               .of_match_table = meson_audio_arb_of_match,
+       },
+};
+module_platform_driver(meson_audio_arb_pdrv);
+
+MODULE_DESCRIPTION("Amlogic A113 Audio Memory Arbiter");
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/reset/reset-qcom-aoss.c b/drivers/reset/reset-qcom-aoss.c
new file mode 100644 (file)
index 0000000..36db967
--- /dev/null
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of_device.h>
+#include <dt-bindings/reset/qcom,sdm845-aoss.h>
+
+struct qcom_aoss_reset_map {
+       unsigned int reg;
+};
+
+struct qcom_aoss_desc {
+       const struct qcom_aoss_reset_map *resets;
+       size_t num_resets;
+};
+
+struct qcom_aoss_reset_data {
+       struct reset_controller_dev rcdev;
+       void __iomem *base;
+       const struct qcom_aoss_desc *desc;
+};
+
+static const struct qcom_aoss_reset_map sdm845_aoss_resets[] = {
+       [AOSS_CC_MSS_RESTART] = {0x10000},
+       [AOSS_CC_CAMSS_RESTART] = {0x11000},
+       [AOSS_CC_VENUS_RESTART] = {0x12000},
+       [AOSS_CC_GPU_RESTART] = {0x13000},
+       [AOSS_CC_DISPSS_RESTART] = {0x14000},
+       [AOSS_CC_WCSS_RESTART] = {0x20000},
+       [AOSS_CC_LPASS_RESTART] = {0x30000},
+};
+
+static const struct qcom_aoss_desc sdm845_aoss_desc = {
+       .resets = sdm845_aoss_resets,
+       .num_resets = ARRAY_SIZE(sdm845_aoss_resets),
+};
+
+static inline struct qcom_aoss_reset_data *to_qcom_aoss_reset_data(
+                               struct reset_controller_dev *rcdev)
+{
+       return container_of(rcdev, struct qcom_aoss_reset_data, rcdev);
+}
+
+static int qcom_aoss_control_assert(struct reset_controller_dev *rcdev,
+                                   unsigned long idx)
+{
+       struct qcom_aoss_reset_data *data = to_qcom_aoss_reset_data(rcdev);
+       const struct qcom_aoss_reset_map *map = &data->desc->resets[idx];
+
+       writel(1, data->base + map->reg);
+       /* Wait 6 32kHz sleep cycles for reset */
+       usleep_range(200, 300);
+       return 0;
+}
+
+static int qcom_aoss_control_deassert(struct reset_controller_dev *rcdev,
+                                     unsigned long idx)
+{
+       struct qcom_aoss_reset_data *data = to_qcom_aoss_reset_data(rcdev);
+       const struct qcom_aoss_reset_map *map = &data->desc->resets[idx];
+
+       writel(0, data->base + map->reg);
+       /* Wait 6 32kHz sleep cycles for reset */
+       usleep_range(200, 300);
+       return 0;
+}
+
+static int qcom_aoss_control_reset(struct reset_controller_dev *rcdev,
+                                       unsigned long idx)
+{
+       qcom_aoss_control_assert(rcdev, idx);
+
+       return qcom_aoss_control_deassert(rcdev, idx);
+}
+
+static const struct reset_control_ops qcom_aoss_reset_ops = {
+       .reset = qcom_aoss_control_reset,
+       .assert = qcom_aoss_control_assert,
+       .deassert = qcom_aoss_control_deassert,
+};
+
+static int qcom_aoss_reset_probe(struct platform_device *pdev)
+{
+       struct qcom_aoss_reset_data *data;
+       struct device *dev = &pdev->dev;
+       const struct qcom_aoss_desc *desc;
+       struct resource *res;
+
+       desc = of_device_get_match_data(dev);
+       if (!desc)
+               return -EINVAL;
+
+       data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       data->desc = desc;
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       data->base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(data->base))
+               return PTR_ERR(data->base);
+
+       data->rcdev.owner = THIS_MODULE;
+       data->rcdev.ops = &qcom_aoss_reset_ops;
+       data->rcdev.nr_resets = desc->num_resets;
+       data->rcdev.of_node = dev->of_node;
+
+       return devm_reset_controller_register(dev, &data->rcdev);
+}
+
+static const struct of_device_id qcom_aoss_reset_of_match[] = {
+       { .compatible = "qcom,sdm845-aoss-cc", .data = &sdm845_aoss_desc },
+       {}
+};
+
+static struct platform_driver qcom_aoss_reset_driver = {
+       .probe = qcom_aoss_reset_probe,
+       .driver  = {
+               .name = "qcom_aoss_reset",
+               .of_match_table = qcom_aoss_reset_of_match,
+       },
+};
+
+builtin_platform_driver(qcom_aoss_reset_driver);
+
+MODULE_DESCRIPTION("Qualcomm AOSS Reset Driver");
+MODULE_LICENSE("GPL v2");
index f7ce8910a392ca77e235880f795e3e298ccf7eba..a91107fc9e272352a798301cddb34bae8bb3891c 100644 (file)
@@ -87,6 +87,7 @@ const struct reset_control_ops reset_simple_ops = {
        .deassert       = reset_simple_deassert,
        .status         = reset_simple_status,
 };
+EXPORT_SYMBOL_GPL(reset_simple_ops);
 
 /**
  * struct reset_simple_devdata - simple reset controller properties
diff --git a/drivers/reset/reset-uniphier-usb3.c b/drivers/reset/reset-uniphier-usb3.c
new file mode 100644 (file)
index 0000000..ffa1b19
--- /dev/null
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// reset-uniphier-usb3.c - USB3 reset driver for UniPhier
+// Copyright 2018 Socionext Inc.
+// Author: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+#include "reset-simple.h"
+
+#define MAX_CLKS       2
+#define MAX_RSTS       2
+
+struct uniphier_usb3_reset_soc_data {
+       int nclks;
+       const char * const *clock_names;
+       int nrsts;
+       const char * const *reset_names;
+};
+
+struct uniphier_usb3_reset_priv {
+       struct clk_bulk_data clk[MAX_CLKS];
+       struct reset_control *rst[MAX_RSTS];
+       struct reset_simple_data rdata;
+       const struct uniphier_usb3_reset_soc_data *data;
+};
+
+static int uniphier_usb3_reset_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct uniphier_usb3_reset_priv *priv;
+       struct resource *res;
+       resource_size_t size;
+       const char *name;
+       int i, ret, nr;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->data = of_device_get_match_data(dev);
+       if (WARN_ON(!priv->data || priv->data->nclks > MAX_CLKS ||
+                   priv->data->nrsts > MAX_RSTS))
+               return -EINVAL;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       size = resource_size(res);
+       priv->rdata.membase = devm_ioremap_resource(dev, res);
+       if (IS_ERR(priv->rdata.membase))
+               return PTR_ERR(priv->rdata.membase);
+
+       for (i = 0; i < priv->data->nclks; i++)
+               priv->clk[i].id = priv->data->clock_names[i];
+       ret = devm_clk_bulk_get(dev, priv->data->nclks, priv->clk);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < priv->data->nrsts; i++) {
+               name = priv->data->reset_names[i];
+               priv->rst[i] = devm_reset_control_get_shared(dev, name);
+               if (IS_ERR(priv->rst[i]))
+                       return PTR_ERR(priv->rst[i]);
+       }
+
+       ret = clk_bulk_prepare_enable(priv->data->nclks, priv->clk);
+       if (ret)
+               return ret;
+
+       for (nr = 0; nr < priv->data->nrsts; nr++) {
+               ret = reset_control_deassert(priv->rst[nr]);
+               if (ret)
+                       goto out_rst_assert;
+       }
+
+       spin_lock_init(&priv->rdata.lock);
+       priv->rdata.rcdev.owner = THIS_MODULE;
+       priv->rdata.rcdev.nr_resets = size * BITS_PER_BYTE;
+       priv->rdata.rcdev.ops = &reset_simple_ops;
+       priv->rdata.rcdev.of_node = dev->of_node;
+       priv->rdata.active_low = true;
+
+       platform_set_drvdata(pdev, priv);
+
+       ret = devm_reset_controller_register(dev, &priv->rdata.rcdev);
+       if (ret)
+               goto out_rst_assert;
+
+       return 0;
+
+out_rst_assert:
+       while (nr--)
+               reset_control_assert(priv->rst[nr]);
+
+       clk_bulk_disable_unprepare(priv->data->nclks, priv->clk);
+
+       return ret;
+}
+
+static int uniphier_usb3_reset_remove(struct platform_device *pdev)
+{
+       struct uniphier_usb3_reset_priv *priv = platform_get_drvdata(pdev);
+       int i;
+
+       for (i = 0; i < priv->data->nrsts; i++)
+               reset_control_assert(priv->rst[i]);
+
+       clk_bulk_disable_unprepare(priv->data->nclks, priv->clk);
+
+       return 0;
+}
+
+static const char * const uniphier_pro4_clock_reset_names[] = {
+       "gio", "link",
+};
+
+static const struct uniphier_usb3_reset_soc_data uniphier_pro4_data = {
+       .nclks = ARRAY_SIZE(uniphier_pro4_clock_reset_names),
+       .clock_names = uniphier_pro4_clock_reset_names,
+       .nrsts = ARRAY_SIZE(uniphier_pro4_clock_reset_names),
+       .reset_names = uniphier_pro4_clock_reset_names,
+};
+
+static const char * const uniphier_pxs2_clock_reset_names[] = {
+       "link",
+};
+
+static const struct uniphier_usb3_reset_soc_data uniphier_pxs2_data = {
+       .nclks = ARRAY_SIZE(uniphier_pxs2_clock_reset_names),
+       .clock_names = uniphier_pxs2_clock_reset_names,
+       .nrsts = ARRAY_SIZE(uniphier_pxs2_clock_reset_names),
+       .reset_names = uniphier_pxs2_clock_reset_names,
+};
+
+static const struct of_device_id uniphier_usb3_reset_match[] = {
+       {
+               .compatible = "socionext,uniphier-pro4-usb3-reset",
+               .data = &uniphier_pro4_data,
+       },
+       {
+               .compatible = "socionext,uniphier-pxs2-usb3-reset",
+               .data = &uniphier_pxs2_data,
+       },
+       {
+               .compatible = "socionext,uniphier-ld20-usb3-reset",
+               .data = &uniphier_pxs2_data,
+       },
+       {
+               .compatible = "socionext,uniphier-pxs3-usb3-reset",
+               .data = &uniphier_pxs2_data,
+       },
+       { /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, uniphier_usb3_reset_match);
+
+static struct platform_driver uniphier_usb3_reset_driver = {
+       .probe = uniphier_usb3_reset_probe,
+       .remove = uniphier_usb3_reset_remove,
+       .driver = {
+               .name = "uniphier-usb3-reset",
+               .of_match_table = uniphier_usb3_reset_match,
+       },
+};
+module_platform_driver(uniphier_usb3_reset_driver);
+
+MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>");
+MODULE_DESCRIPTION("UniPhier USB3 Reset Driver");
+MODULE_LICENSE("GPL");
index e9030ff1bf2fa3d27e83b9848f012a13becb4500..5605745663ae0d76122ed1e52e417e741b5ea8b2 100644 (file)
@@ -202,6 +202,12 @@ static const struct uniphier_reset_data uniphier_pro5_sd_reset_data[] = {
 #define UNIPHIER_PERI_RESET_FI2C(id, ch)               \
        UNIPHIER_RESETX((id), 0x114, 24 + (ch))
 
+#define UNIPHIER_PERI_RESET_SCSSI(id)                  \
+       UNIPHIER_RESETX((id), 0x110, 17)
+
+#define UNIPHIER_PERI_RESET_MCSSI(id)                  \
+       UNIPHIER_RESETX((id), 0x114, 14)
+
 static const struct uniphier_reset_data uniphier_ld4_peri_reset_data[] = {
        UNIPHIER_PERI_RESET_UART(0, 0),
        UNIPHIER_PERI_RESET_UART(1, 1),
@@ -212,6 +218,7 @@ static const struct uniphier_reset_data uniphier_ld4_peri_reset_data[] = {
        UNIPHIER_PERI_RESET_I2C(6, 2),
        UNIPHIER_PERI_RESET_I2C(7, 3),
        UNIPHIER_PERI_RESET_I2C(8, 4),
+       UNIPHIER_PERI_RESET_SCSSI(11),
        UNIPHIER_RESET_END,
 };
 
@@ -227,6 +234,8 @@ static const struct uniphier_reset_data uniphier_pro4_peri_reset_data[] = {
        UNIPHIER_PERI_RESET_FI2C(8, 4),
        UNIPHIER_PERI_RESET_FI2C(9, 5),
        UNIPHIER_PERI_RESET_FI2C(10, 6),
+       UNIPHIER_PERI_RESET_SCSSI(11),
+       UNIPHIER_PERI_RESET_MCSSI(12),
        UNIPHIER_RESET_END,
 };
 
index a2ba5db36145c90ec8c842e28d362e6deb34659b..7d7be60a2413f060fe3f6e86b7ab51a9407f0c8f 100644 (file)
@@ -244,15 +244,6 @@ config RTC_DRV_DS1307
          This driver can also be built as a module. If so, the module
          will be called rtc-ds1307.
 
-config RTC_DRV_DS1307_HWMON
-       bool "HWMON support for rtc-ds1307"
-       depends on RTC_DRV_DS1307 && HWMON
-       depends on !(RTC_DRV_DS1307=y && HWMON=m)
-       default y
-       help
-         Say Y here if you want to expose temperature sensor data on
-         rtc-ds1307 (only DS3231)
-
 config RTC_DRV_DS1307_CENTURY
        bool "Century bit support for rtc-ds1307"
        depends on RTC_DRV_DS1307
@@ -1027,18 +1018,6 @@ config RTC_DS1685_PROC_REGS
 
          Unless you are debugging this driver, choose N.
 
-config RTC_DS1685_SYSFS_REGS
-       bool "SysFS access to RTC register bits"
-       depends on RTC_DRV_DS1685_FAMILY && SYSFS
-       help
-         Enable this to provide access to the RTC control register bits
-         in /sys.  Some of the bits are read-write, others are read-only.
-
-         Keep in mind that reading Control C's bits automatically clears
-         all pending IRQ flags - this can cause lost interrupts.
-
-         If you know that you need access to these bits, choose Y, Else N.
-
 config RTC_DRV_DS1742
        tristate "Maxim/Dallas DS1742/1743"
        depends on HAS_IOMEM
index d37588f080556d16af315862b99370ef4a948ea5..0fca4d74c76b34a645d3b65382a46f16c9bf9501 100644 (file)
@@ -68,7 +68,7 @@ static int rtc_suspend(struct device *dev)
                return 0;
        }
 
-       getnstimeofday64(&old_system);
+       ktime_get_real_ts64(&old_system);
        old_rtc.tv_sec = rtc_tm_to_time64(&tm);
 
 
@@ -110,7 +110,7 @@ static int rtc_resume(struct device *dev)
                return 0;
 
        /* snapshot the current rtc and system time at resume */
-       getnstimeofday64(&new_system);
+       ktime_get_real_ts64(&new_system);
        err = rtc_read_time(rtc, &tm);
        if (err < 0) {
                pr_debug("%s:  fail to read rtc time\n", dev_name(&rtc->dev));
@@ -172,7 +172,6 @@ static struct rtc_device *rtc_allocate_device(void)
 
        mutex_init(&rtc->ops_lock);
        spin_lock_init(&rtc->irq_lock);
-       spin_lock_init(&rtc->irq_task_lock);
        init_waitqueue_head(&rtc->irq_queue);
 
        /* Init timerqueue */
index bac1eeb3d31204d9e99a93e1e682972b5f7177bb..3d577e259e91b94f6e1b5abbce60bf3746308803 100644 (file)
@@ -607,12 +607,6 @@ void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode)
        rtc->irq_data = (rtc->irq_data + (num << 8)) | (RTC_IRQF|mode);
        spin_unlock_irqrestore(&rtc->irq_lock, flags);
 
-       /* call the task func */
-       spin_lock_irqsave(&rtc->irq_task_lock, flags);
-       if (rtc->irq_task)
-               rtc->irq_task->func(rtc->irq_task->private_data);
-       spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
-
        wake_up_interruptible(&rtc->irq_queue);
        kill_fasync(&rtc->async_queue, SIGIO, POLL_IN);
 }
@@ -721,39 +715,6 @@ void rtc_class_close(struct rtc_device *rtc)
 }
 EXPORT_SYMBOL_GPL(rtc_class_close);
 
-int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task)
-{
-       int retval = -EBUSY;
-
-       if (task == NULL || task->func == NULL)
-               return -EINVAL;
-
-       /* Cannot register while the char dev is in use */
-       if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags))
-               return -EBUSY;
-
-       spin_lock_irq(&rtc->irq_task_lock);
-       if (rtc->irq_task == NULL) {
-               rtc->irq_task = task;
-               retval = 0;
-       }
-       spin_unlock_irq(&rtc->irq_task_lock);
-
-       clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags);
-
-       return retval;
-}
-EXPORT_SYMBOL_GPL(rtc_irq_register);
-
-void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task)
-{
-       spin_lock_irq(&rtc->irq_task_lock);
-       if (rtc->irq_task == task)
-               rtc->irq_task = NULL;
-       spin_unlock_irq(&rtc->irq_task_lock);
-}
-EXPORT_SYMBOL_GPL(rtc_irq_unregister);
-
 static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled)
 {
        /*
@@ -785,71 +746,45 @@ static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled)
  * Context: any
  *
  * Note that rtc_irq_set_freq() should previously have been used to
- * specify the desired frequency of periodic IRQ task->func() callbacks.
+ * specify the desired frequency of periodic IRQ.
  */
-int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled)
+int rtc_irq_set_state(struct rtc_device *rtc, int enabled)
 {
        int err = 0;
-       unsigned long flags;
 
-retry:
-       spin_lock_irqsave(&rtc->irq_task_lock, flags);
-       if (rtc->irq_task != NULL && task == NULL)
-               err = -EBUSY;
-       else if (rtc->irq_task != task)
-               err = -EACCES;
-       else {
-               if (rtc_update_hrtimer(rtc, enabled) < 0) {
-                       spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
-                       cpu_relax();
-                       goto retry;
-               }
-               rtc->pie_enabled = enabled;
-       }
-       spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
+       while (rtc_update_hrtimer(rtc, enabled) < 0)
+               cpu_relax();
+
+       rtc->pie_enabled = enabled;
 
        trace_rtc_irq_set_state(enabled, err);
        return err;
 }
-EXPORT_SYMBOL_GPL(rtc_irq_set_state);
 
 /**
  * rtc_irq_set_freq - set 2^N Hz periodic IRQ frequency for IRQ
  * @rtc: the rtc device
  * @task: currently registered with rtc_irq_register()
- * @freq: positive frequency with which task->func() will be called
+ * @freq: positive frequency
  * Context: any
  *
  * Note that rtc_irq_set_state() is used to enable or disable the
  * periodic IRQs.
  */
-int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
+int rtc_irq_set_freq(struct rtc_device *rtc, int freq)
 {
        int err = 0;
-       unsigned long flags;
 
        if (freq <= 0 || freq > RTC_MAX_FREQ)
                return -EINVAL;
-retry:
-       spin_lock_irqsave(&rtc->irq_task_lock, flags);
-       if (rtc->irq_task != NULL && task == NULL)
-               err = -EBUSY;
-       else if (rtc->irq_task != task)
-               err = -EACCES;
-       else {
-               rtc->irq_freq = freq;
-               if (rtc->pie_enabled && rtc_update_hrtimer(rtc, 1) < 0) {
-                       spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
-                       cpu_relax();
-                       goto retry;
-               }
-       }
-       spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
+
+       rtc->irq_freq = freq;
+       while (rtc->pie_enabled && rtc_update_hrtimer(rtc, 1) < 0)
+               cpu_relax();
 
        trace_rtc_irq_set_freq(freq, err);
        return err;
 }
-EXPORT_SYMBOL_GPL(rtc_irq_set_freq);
 
 /**
  * rtc_timer_enqueue - Adds a rtc_timer to the rtc_device timerqueue
@@ -979,8 +914,8 @@ again:
                timerqueue_del(&rtc->timerqueue, &timer->node);
                trace_rtc_timer_dequeue(timer);
                timer->enabled = 0;
-               if (timer->task.func)
-                       timer->task.func(timer->task.private_data);
+               if (timer->func)
+                       timer->func(timer->private_data);
 
                trace_rtc_timer_fired(timer);
                /* Re-add/fwd periodic timers */
@@ -1035,8 +970,8 @@ void rtc_timer_init(struct rtc_timer *timer, void (*f)(void *p), void *data)
 {
        timerqueue_init(&timer->node);
        timer->enabled = 0;
-       timer->task.func = f;
-       timer->task.private_data = data;
+       timer->func = f;
+       timer->private_data = data;
 }
 
 /* rtc_timer_start - Sets an rtc_timer to fire in the future
index 1e4978c96ffd273c617e9c8d89f49a9b2a0838ec..bde53c8ccee2cbbcac52120dde4cc217e9c10f93 100644 (file)
@@ -30,6 +30,8 @@
 #define RTC_IRQ_FREQ_1HZ           BIT(2)
 #define RTC_CCR                    0x18
 #define RTC_CCR_MODE               BIT(15)
+#define RTC_CONF_TEST      0x1C
+#define RTC_NOMINAL_TIMING         BIT(13)
 
 #define RTC_TIME           0xC
 #define RTC_ALARM1         0x10
@@ -75,6 +77,7 @@ struct armada38x_rtc {
        void __iomem        *regs_soc;
        spinlock_t          lock;
        int                 irq;
+       bool                initialized;
        struct value_to_freq *val_to_freq;
        struct armada38x_rtc_data *data;
 };
@@ -226,6 +229,23 @@ static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
        return 0;
 }
 
+static void armada38x_rtc_reset(struct armada38x_rtc *rtc)
+{
+       u32 reg;
+
+       reg = rtc->data->read_rtc_reg(rtc, RTC_CONF_TEST);
+       /* If bits [7:0] are non-zero, assume RTC was uninitialized */
+       if (reg & 0xff) {
+               rtc_delayed_write(0, rtc, RTC_CONF_TEST);
+               msleep(500); /* Oscillator startup time */
+               rtc_delayed_write(0, rtc, RTC_TIME);
+               rtc_delayed_write(SOC_RTC_ALARM1 | SOC_RTC_ALARM2, rtc,
+                                 RTC_STATUS);
+               rtc_delayed_write(RTC_NOMINAL_TIMING, rtc, RTC_CCR);
+       }
+       rtc->initialized = true;
+}
+
 static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
        struct armada38x_rtc *rtc = dev_get_drvdata(dev);
@@ -237,6 +257,9 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
        if (ret)
                goto out;
 
+       if (!rtc->initialized)
+               armada38x_rtc_reset(rtc);
+
        spin_lock_irqsave(&rtc->lock, flags);
        rtc_delayed_write(time, rtc, RTC_TIME);
        spin_unlock_irqrestore(&rtc->lock, flags);
index d768f6747961cc206c3c1d14e8e3caaec2e971d9..113493b5214952b2740a9c1f270525572bc07545 100644 (file)
@@ -162,6 +162,10 @@ static int bq4802_probe(struct platform_device *pdev)
        } else if (p->r->flags & IORESOURCE_MEM) {
                p->regs = devm_ioremap(&pdev->dev, p->r->start,
                                        resource_size(p->r));
+               if (!p->regs){
+                       err = -ENOMEM;
+                       goto out;
+               }
                p->read = bq4802_read_mem;
                p->write = bq4802_write_mem;
        } else {
index 0abf98983e13f6353e75e7d732d78a361b189dd7..ccc17a2e293d178985a496fa87e696cac5491fe9 100644 (file)
@@ -40,9 +40,23 @@ static inline void rtc_proc_del_device(struct rtc_device *rtc)
 
 #ifdef CONFIG_RTC_INTF_SYSFS
 const struct attribute_group **rtc_get_dev_attribute_groups(void);
+int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp);
+int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps);
 #else
 static inline const struct attribute_group **rtc_get_dev_attribute_groups(void)
 {
        return NULL;
 }
+
+static inline
+int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp)
+{
+       return 0;
+}
+
+static inline
+int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps)
+{
+       return 0;
+}
 #endif
index efa221e8bc22da4b60f788b48768f59ef5fff220..43d962a9c2105a2f8f4aa84c35583a37cffe5e26 100644 (file)
@@ -341,11 +341,11 @@ static long rtc_dev_ioctl(struct file *file,
                return rtc_set_time(rtc, &tm);
 
        case RTC_PIE_ON:
-               err = rtc_irq_set_state(rtc, NULL, 1);
+               err = rtc_irq_set_state(rtc, 1);
                break;
 
        case RTC_PIE_OFF:
-               err = rtc_irq_set_state(rtc, NULL, 0);
+               err = rtc_irq_set_state(rtc, 0);
                break;
 
        case RTC_AIE_ON:
@@ -365,7 +365,7 @@ static long rtc_dev_ioctl(struct file *file,
                return rtc_update_irq_enable(rtc, 0);
 
        case RTC_IRQP_SET:
-               err = rtc_irq_set_freq(rtc, NULL, arg);
+               err = rtc_irq_set_freq(rtc, arg);
                break;
 
        case RTC_IRQP_READ:
@@ -427,7 +427,7 @@ static int rtc_dev_release(struct inode *inode, struct file *file)
        /* Keep ioctl until all drivers are converted */
        rtc_dev_ioctl(file, RTC_UIE_OFF, 0);
        rtc_update_irq_enable(rtc, 0);
-       rtc_irq_set_state(rtc, NULL, 0);
+       rtc_irq_set_state(rtc, 0);
 
        clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags);
        return 0;
index e9ec4160d7f6bff6aeeebd70c2d88c4689b53597..4b2b4627daebfb89b77121d499110d7f553a7394 100644 (file)
@@ -44,6 +44,7 @@ enum ds_type {
        ds_3231,
        m41t0,
        m41t00,
+       m41t11,
        mcp794xx,
        rx_8025,
        rx_8130,
@@ -227,6 +228,11 @@ static const struct chip_desc chips[last_ds_type] = {
                .irq_handler = rx8130_irq,
                .rtc_ops = &rx8130_rtc_ops,
        },
+       [m41t11] = {
+               /* this is battery backed SRAM */
+               .nvram_offset   = 8,
+               .nvram_size     = 56,
+       },
        [mcp794xx] = {
                .alarm          = 1,
                /* this is battery backed SRAM */
@@ -249,6 +255,7 @@ static const struct i2c_device_id ds1307_id[] = {
        { "ds3231", ds_3231 },
        { "m41t0", m41t0 },
        { "m41t00", m41t00 },
+       { "m41t11", m41t11 },
        { "mcp7940x", mcp794xx },
        { "mcp7941x", mcp794xx },
        { "pt7c4338", ds_1307 },
@@ -299,12 +306,16 @@ static const struct of_device_id ds1307_of_match[] = {
        },
        {
                .compatible = "st,m41t0",
-               .data = (void *)m41t00
+               .data = (void *)m41t0
        },
        {
                .compatible = "st,m41t00",
                .data = (void *)m41t00
        },
+       {
+               .compatible = "st,m41t11",
+               .data = (void *)m41t11
+       },
        {
                .compatible = "microchip,mcp7940x",
                .data = (void *)mcp794xx
@@ -347,6 +358,7 @@ static const struct acpi_device_id ds1307_acpi_ids[] = {
        { .id = "DS3231", .driver_data = ds_3231 },
        { .id = "M41T0", .driver_data = m41t0 },
        { .id = "M41T00", .driver_data = m41t00 },
+       { .id = "M41T11", .driver_data = m41t11 },
        { .id = "MCP7940X", .driver_data = mcp794xx },
        { .id = "MCP7941X", .driver_data = mcp794xx },
        { .id = "PT7C4338", .driver_data = ds_1307 },
@@ -1030,7 +1042,7 @@ static u8 ds1307_trickle_init(struct ds1307 *ds1307,
 
 /*----------------------------------------------------------------------*/
 
-#ifdef CONFIG_RTC_DRV_DS1307_HWMON
+#if IS_REACHABLE(CONFIG_HWMON)
 
 /*
  * Temperature sensor support for ds3231 devices.
@@ -1576,6 +1588,7 @@ read_rtc:
        case ds_1307:
        case m41t0:
        case m41t00:
+       case m41t11:
                /* clock halted?  turn it on, so clock can tick. */
                if (tmp & DS1307_BIT_CH) {
                        regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
@@ -1641,6 +1654,7 @@ read_rtc:
        case ds_1340:
        case m41t0:
        case m41t00:
+       case m41t11:
                /*
                 * NOTE: ignores century bits; fix before deploying
                 * systems that will run through year 2100.
index 5c0db6c8134cb23362896dbb618af72cfa74eebc..6f39f683a98c6385f208473459b705bfe91e1f74 100644 (file)
@@ -1188,552 +1188,6 @@ ds1685_rtc_sysfs_misc_grp = {
        .attrs = ds1685_rtc_sysfs_misc_attrs,
 };
 
-#ifdef CONFIG_RTC_DS1685_SYSFS_REGS
-/**
- * struct ds1685_rtc_ctrl_regs.
- * @name: char pointer for the bit name.
- * @reg: control register the bit is in.
- * @bit: the bit's offset in the register.
- */
-struct ds1685_rtc_ctrl_regs {
-       const char *name;
-       const u8 reg;
-       const u8 bit;
-};
-
-/*
- * Ctrl register bit lookup table.
- */
-static const struct ds1685_rtc_ctrl_regs
-ds1685_ctrl_regs_table[] = {
-       { "uip",  RTC_CTRL_A,      RTC_CTRL_A_UIP   },
-       { "dv2",  RTC_CTRL_A,      RTC_CTRL_A_DV2   },
-       { "dv1",  RTC_CTRL_A,      RTC_CTRL_A_DV1   },
-       { "dv0",  RTC_CTRL_A,      RTC_CTRL_A_DV0   },
-       { "rs3",  RTC_CTRL_A,      RTC_CTRL_A_RS3   },
-       { "rs2",  RTC_CTRL_A,      RTC_CTRL_A_RS2   },
-       { "rs1",  RTC_CTRL_A,      RTC_CTRL_A_RS1   },
-       { "rs0",  RTC_CTRL_A,      RTC_CTRL_A_RS0   },
-       { "set",  RTC_CTRL_B,      RTC_CTRL_B_SET   },
-       { "pie",  RTC_CTRL_B,      RTC_CTRL_B_PIE   },
-       { "aie",  RTC_CTRL_B,      RTC_CTRL_B_AIE   },
-       { "uie",  RTC_CTRL_B,      RTC_CTRL_B_UIE   },
-       { "sqwe", RTC_CTRL_B,      RTC_CTRL_B_SQWE  },
-       { "dm",   RTC_CTRL_B,      RTC_CTRL_B_DM    },
-       { "2412", RTC_CTRL_B,      RTC_CTRL_B_2412  },
-       { "dse",  RTC_CTRL_B,      RTC_CTRL_B_DSE   },
-       { "irqf", RTC_CTRL_C,      RTC_CTRL_C_IRQF  },
-       { "pf",   RTC_CTRL_C,      RTC_CTRL_C_PF    },
-       { "af",   RTC_CTRL_C,      RTC_CTRL_C_AF    },
-       { "uf",   RTC_CTRL_C,      RTC_CTRL_C_UF    },
-       { "vrt",  RTC_CTRL_D,      RTC_CTRL_D_VRT   },
-       { "vrt2", RTC_EXT_CTRL_4A, RTC_CTRL_4A_VRT2 },
-       { "incr", RTC_EXT_CTRL_4A, RTC_CTRL_4A_INCR },
-       { "pab",  RTC_EXT_CTRL_4A, RTC_CTRL_4A_PAB  },
-       { "rf",   RTC_EXT_CTRL_4A, RTC_CTRL_4A_RF   },
-       { "wf",   RTC_EXT_CTRL_4A, RTC_CTRL_4A_WF   },
-       { "kf",   RTC_EXT_CTRL_4A, RTC_CTRL_4A_KF   },
-#if !defined(CONFIG_RTC_DRV_DS1685) && !defined(CONFIG_RTC_DRV_DS1689)
-       { "bme",  RTC_EXT_CTRL_4A, RTC_CTRL_4A_BME  },
-#endif
-       { "abe",  RTC_EXT_CTRL_4B, RTC_CTRL_4B_ABE  },
-       { "e32k", RTC_EXT_CTRL_4B, RTC_CTRL_4B_E32K },
-       { "cs",   RTC_EXT_CTRL_4B, RTC_CTRL_4B_CS   },
-       { "rce",  RTC_EXT_CTRL_4B, RTC_CTRL_4B_RCE  },
-       { "prs",  RTC_EXT_CTRL_4B, RTC_CTRL_4B_PRS  },
-       { "rie",  RTC_EXT_CTRL_4B, RTC_CTRL_4B_RIE  },
-       { "wie",  RTC_EXT_CTRL_4B, RTC_CTRL_4B_WIE  },
-       { "kse",  RTC_EXT_CTRL_4B, RTC_CTRL_4B_KSE  },
-       { NULL,   0,               0                },
-};
-
-/**
- * ds1685_rtc_sysfs_ctrl_regs_lookup - ctrl register bit lookup function.
- * @name: ctrl register bit to look up in ds1685_ctrl_regs_table.
- */
-static const struct ds1685_rtc_ctrl_regs*
-ds1685_rtc_sysfs_ctrl_regs_lookup(const char *name)
-{
-       const struct ds1685_rtc_ctrl_regs *p = ds1685_ctrl_regs_table;
-
-       for (; p->name != NULL; ++p)
-               if (strcmp(p->name, name) == 0)
-                       return p;
-
-       return NULL;
-}
-
-/**
- * ds1685_rtc_sysfs_ctrl_regs_show - reads a ctrl register bit via sysfs.
- * @dev: pointer to device structure.
- * @attr: pointer to device_attribute structure.
- * @buf: pointer to char array to hold the output.
- */
-static ssize_t
-ds1685_rtc_sysfs_ctrl_regs_show(struct device *dev,
-                               struct device_attribute *attr, char *buf)
-{
-       u8 tmp;
-       struct ds1685_priv *rtc = dev_get_drvdata(dev);
-       const struct ds1685_rtc_ctrl_regs *reg_info =
-               ds1685_rtc_sysfs_ctrl_regs_lookup(attr->attr.name);
-
-       /* Make sure we actually matched something. */
-       if (!reg_info)
-               return -EINVAL;
-
-       /* No spinlock during a read -- mutex is already held. */
-       ds1685_rtc_switch_to_bank1(rtc);
-       tmp = rtc->read(rtc, reg_info->reg) & reg_info->bit;
-       ds1685_rtc_switch_to_bank0(rtc);
-
-       return sprintf(buf, "%d\n", (tmp ? 1 : 0));
-}
-
-/**
- * ds1685_rtc_sysfs_ctrl_regs_store - writes a ctrl register bit via sysfs.
- * @dev: pointer to device structure.
- * @attr: pointer to device_attribute structure.
- * @buf: pointer to char array to hold the output.
- * @count: number of bytes written.
- */
-static ssize_t
-ds1685_rtc_sysfs_ctrl_regs_store(struct device *dev,
-                                struct device_attribute *attr,
-                                const char *buf, size_t count)
-{
-       struct ds1685_priv *rtc = dev_get_drvdata(dev);
-       u8 reg = 0, bit = 0, tmp;
-       unsigned long flags;
-       long int val = 0;
-       const struct ds1685_rtc_ctrl_regs *reg_info =
-               ds1685_rtc_sysfs_ctrl_regs_lookup(attr->attr.name);
-
-       /* We only accept numbers. */
-       if (kstrtol(buf, 10, &val) < 0)
-               return -EINVAL;
-
-       /* bits are binary, 0 or 1 only. */
-       if ((val != 0) && (val != 1))
-               return -ERANGE;
-
-       /* Make sure we actually matched something. */
-       if (!reg_info)
-               return -EINVAL;
-
-       reg = reg_info->reg;
-       bit = reg_info->bit;
-
-       /* Safe to spinlock during a write. */
-       ds1685_rtc_begin_ctrl_access(rtc, &flags);
-       tmp = rtc->read(rtc, reg);
-       rtc->write(rtc, reg, (val ? (tmp | bit) : (tmp & ~(bit))));
-       ds1685_rtc_end_ctrl_access(rtc, flags);
-
-       return count;
-}
-
-/**
- * DS1685_RTC_SYSFS_CTRL_REG_RO - device_attribute for read-only register bit.
- * @bit: bit to read.
- */
-#define DS1685_RTC_SYSFS_CTRL_REG_RO(bit)                              \
-       static DEVICE_ATTR(bit, S_IRUGO,                                \
-       ds1685_rtc_sysfs_ctrl_regs_show, NULL)
-
-/**
- * DS1685_RTC_SYSFS_CTRL_REG_RW - device_attribute for read-write register bit.
- * @bit: bit to read or write.
- */
-#define DS1685_RTC_SYSFS_CTRL_REG_RW(bit)                              \
-       static DEVICE_ATTR(bit, S_IRUGO | S_IWUSR,                      \
-       ds1685_rtc_sysfs_ctrl_regs_show,                                \
-       ds1685_rtc_sysfs_ctrl_regs_store)
-
-/*
- * Control Register A bits.
- */
-DS1685_RTC_SYSFS_CTRL_REG_RO(uip);
-DS1685_RTC_SYSFS_CTRL_REG_RW(dv2);
-DS1685_RTC_SYSFS_CTRL_REG_RW(dv1);
-DS1685_RTC_SYSFS_CTRL_REG_RO(dv0);
-DS1685_RTC_SYSFS_CTRL_REG_RW(rs3);
-DS1685_RTC_SYSFS_CTRL_REG_RW(rs2);
-DS1685_RTC_SYSFS_CTRL_REG_RW(rs1);
-DS1685_RTC_SYSFS_CTRL_REG_RW(rs0);
-
-static struct attribute*
-ds1685_rtc_sysfs_ctrla_attrs[] = {
-       &dev_attr_uip.attr,
-       &dev_attr_dv2.attr,
-       &dev_attr_dv1.attr,
-       &dev_attr_dv0.attr,
-       &dev_attr_rs3.attr,
-       &dev_attr_rs2.attr,
-       &dev_attr_rs1.attr,
-       &dev_attr_rs0.attr,
-       NULL,
-};
-
-static const struct attribute_group
-ds1685_rtc_sysfs_ctrla_grp = {
-       .name = "ctrla",
-       .attrs = ds1685_rtc_sysfs_ctrla_attrs,
-};
-
-
-/*
- * Control Register B bits.
- */
-DS1685_RTC_SYSFS_CTRL_REG_RO(set);
-DS1685_RTC_SYSFS_CTRL_REG_RW(pie);
-DS1685_RTC_SYSFS_CTRL_REG_RW(aie);
-DS1685_RTC_SYSFS_CTRL_REG_RW(uie);
-DS1685_RTC_SYSFS_CTRL_REG_RW(sqwe);
-DS1685_RTC_SYSFS_CTRL_REG_RO(dm);
-DS1685_RTC_SYSFS_CTRL_REG_RO(2412);
-DS1685_RTC_SYSFS_CTRL_REG_RO(dse);
-
-static struct attribute*
-ds1685_rtc_sysfs_ctrlb_attrs[] = {
-       &dev_attr_set.attr,
-       &dev_attr_pie.attr,
-       &dev_attr_aie.attr,
-       &dev_attr_uie.attr,
-       &dev_attr_sqwe.attr,
-       &dev_attr_dm.attr,
-       &dev_attr_2412.attr,
-       &dev_attr_dse.attr,
-       NULL,
-};
-
-static const struct attribute_group
-ds1685_rtc_sysfs_ctrlb_grp = {
-       .name = "ctrlb",
-       .attrs = ds1685_rtc_sysfs_ctrlb_attrs,
-};
-
-/*
- * Control Register C bits.
- *
- * Reading Control C clears these bits!  Reading them individually can
- * possibly cause an interrupt to be missed.  Use the /proc interface
- * to see all the bits in this register simultaneously.
- */
-DS1685_RTC_SYSFS_CTRL_REG_RO(irqf);
-DS1685_RTC_SYSFS_CTRL_REG_RO(pf);
-DS1685_RTC_SYSFS_CTRL_REG_RO(af);
-DS1685_RTC_SYSFS_CTRL_REG_RO(uf);
-
-static struct attribute*
-ds1685_rtc_sysfs_ctrlc_attrs[] = {
-       &dev_attr_irqf.attr,
-       &dev_attr_pf.attr,
-       &dev_attr_af.attr,
-       &dev_attr_uf.attr,
-       NULL,
-};
-
-static const struct attribute_group
-ds1685_rtc_sysfs_ctrlc_grp = {
-       .name = "ctrlc",
-       .attrs = ds1685_rtc_sysfs_ctrlc_attrs,
-};
-
-/*
- * Control Register D bits.
- */
-DS1685_RTC_SYSFS_CTRL_REG_RO(vrt);
-
-static struct attribute*
-ds1685_rtc_sysfs_ctrld_attrs[] = {
-       &dev_attr_vrt.attr,
-       NULL,
-};
-
-static const struct attribute_group
-ds1685_rtc_sysfs_ctrld_grp = {
-       .name = "ctrld",
-       .attrs = ds1685_rtc_sysfs_ctrld_attrs,
-};
-
-/*
- * Control Register 4A bits.
- */
-DS1685_RTC_SYSFS_CTRL_REG_RO(vrt2);
-DS1685_RTC_SYSFS_CTRL_REG_RO(incr);
-DS1685_RTC_SYSFS_CTRL_REG_RW(pab);
-DS1685_RTC_SYSFS_CTRL_REG_RW(rf);
-DS1685_RTC_SYSFS_CTRL_REG_RW(wf);
-DS1685_RTC_SYSFS_CTRL_REG_RW(kf);
-#if !defined(CONFIG_RTC_DRV_DS1685) && !defined(CONFIG_RTC_DRV_DS1689)
-DS1685_RTC_SYSFS_CTRL_REG_RO(bme);
-#endif
-
-static struct attribute*
-ds1685_rtc_sysfs_ctrl4a_attrs[] = {
-       &dev_attr_vrt2.attr,
-       &dev_attr_incr.attr,
-       &dev_attr_pab.attr,
-       &dev_attr_rf.attr,
-       &dev_attr_wf.attr,
-       &dev_attr_kf.attr,
-#if !defined(CONFIG_RTC_DRV_DS1685) && !defined(CONFIG_RTC_DRV_DS1689)
-       &dev_attr_bme.attr,
-#endif
-       NULL,
-};
-
-static const struct attribute_group
-ds1685_rtc_sysfs_ctrl4a_grp = {
-       .name = "ctrl4a",
-       .attrs = ds1685_rtc_sysfs_ctrl4a_attrs,
-};
-
-/*
- * Control Register 4B bits.
- */
-DS1685_RTC_SYSFS_CTRL_REG_RW(abe);
-DS1685_RTC_SYSFS_CTRL_REG_RW(e32k);
-DS1685_RTC_SYSFS_CTRL_REG_RO(cs);
-DS1685_RTC_SYSFS_CTRL_REG_RW(rce);
-DS1685_RTC_SYSFS_CTRL_REG_RW(prs);
-DS1685_RTC_SYSFS_CTRL_REG_RW(rie);
-DS1685_RTC_SYSFS_CTRL_REG_RW(wie);
-DS1685_RTC_SYSFS_CTRL_REG_RW(kse);
-
-static struct attribute*
-ds1685_rtc_sysfs_ctrl4b_attrs[] = {
-       &dev_attr_abe.attr,
-       &dev_attr_e32k.attr,
-       &dev_attr_cs.attr,
-       &dev_attr_rce.attr,
-       &dev_attr_prs.attr,
-       &dev_attr_rie.attr,
-       &dev_attr_wie.attr,
-       &dev_attr_kse.attr,
-       NULL,
-};
-
-static const struct attribute_group
-ds1685_rtc_sysfs_ctrl4b_grp = {
-       .name = "ctrl4b",
-       .attrs = ds1685_rtc_sysfs_ctrl4b_attrs,
-};
-
-
-/**
- * struct ds1685_rtc_ctrl_regs.
- * @name: char pointer for the bit name.
- * @reg: control register the bit is in.
- * @bit: the bit's offset in the register.
- */
-struct ds1685_rtc_time_regs {
-       const char *name;
-       const u8 reg;
-       const u8 mask;
-       const u8 min;
-       const u8 max;
-};
-
-/*
- * Time/Date register lookup tables.
- */
-static const struct ds1685_rtc_time_regs
-ds1685_time_regs_bcd_table[] = {
-       { "seconds",       RTC_SECS,       RTC_SECS_BCD_MASK,   0, 59 },
-       { "minutes",       RTC_MINS,       RTC_MINS_BCD_MASK,   0, 59 },
-       { "hours",         RTC_HRS,        RTC_HRS_24_BCD_MASK, 0, 23 },
-       { "wday",          RTC_WDAY,       RTC_WDAY_MASK,       1,  7 },
-       { "mday",          RTC_MDAY,       RTC_MDAY_BCD_MASK,   1, 31 },
-       { "month",         RTC_MONTH,      RTC_MONTH_BCD_MASK,  1, 12 },
-       { "year",          RTC_YEAR,       RTC_YEAR_BCD_MASK,   0, 99 },
-       { "century",       RTC_CENTURY,    RTC_CENTURY_MASK,    0, 99 },
-       { "alarm_seconds", RTC_SECS_ALARM, RTC_SECS_BCD_MASK,   0, 59 },
-       { "alarm_minutes", RTC_MINS_ALARM, RTC_MINS_BCD_MASK,   0, 59 },
-       { "alarm_hours",   RTC_HRS_ALARM,  RTC_HRS_24_BCD_MASK, 0, 23 },
-       { "alarm_mday",    RTC_MDAY_ALARM, RTC_MDAY_ALARM_MASK, 1, 31 },
-       { NULL,            0,              0,                   0,  0 },
-};
-
-static const struct ds1685_rtc_time_regs
-ds1685_time_regs_bin_table[] = {
-       { "seconds",       RTC_SECS,       RTC_SECS_BIN_MASK,   0x00, 0x3b },
-       { "minutes",       RTC_MINS,       RTC_MINS_BIN_MASK,   0x00, 0x3b },
-       { "hours",         RTC_HRS,        RTC_HRS_24_BIN_MASK, 0x00, 0x17 },
-       { "wday",          RTC_WDAY,       RTC_WDAY_MASK,       0x01, 0x07 },
-       { "mday",          RTC_MDAY,       RTC_MDAY_BIN_MASK,   0x01, 0x1f },
-       { "month",         RTC_MONTH,      RTC_MONTH_BIN_MASK,  0x01, 0x0c },
-       { "year",          RTC_YEAR,       RTC_YEAR_BIN_MASK,   0x00, 0x63 },
-       { "century",       RTC_CENTURY,    RTC_CENTURY_MASK,    0x00, 0x63 },
-       { "alarm_seconds", RTC_SECS_ALARM, RTC_SECS_BIN_MASK,   0x00, 0x3b },
-       { "alarm_minutes", RTC_MINS_ALARM, RTC_MINS_BIN_MASK,   0x00, 0x3b },
-       { "alarm_hours",   RTC_HRS_ALARM,  RTC_HRS_24_BIN_MASK, 0x00, 0x17 },
-       { "alarm_mday",    RTC_MDAY_ALARM, RTC_MDAY_ALARM_MASK, 0x01, 0x1f },
-       { NULL,            0,              0,                   0x00, 0x00 },
-};
-
-/**
- * ds1685_rtc_sysfs_time_regs_bcd_lookup - time/date reg bit lookup function.
- * @name: register bit to look up in ds1685_time_regs_bcd_table.
- */
-static const struct ds1685_rtc_time_regs*
-ds1685_rtc_sysfs_time_regs_lookup(const char *name, bool bcd_mode)
-{
-       const struct ds1685_rtc_time_regs *p;
-
-       if (bcd_mode)
-               p = ds1685_time_regs_bcd_table;
-       else
-               p = ds1685_time_regs_bin_table;
-
-       for (; p->name != NULL; ++p)
-               if (strcmp(p->name, name) == 0)
-                       return p;
-
-       return NULL;
-}
-
-/**
- * ds1685_rtc_sysfs_time_regs_show - reads a time/date register via sysfs.
- * @dev: pointer to device structure.
- * @attr: pointer to device_attribute structure.
- * @buf: pointer to char array to hold the output.
- */
-static ssize_t
-ds1685_rtc_sysfs_time_regs_show(struct device *dev,
-                               struct device_attribute *attr, char *buf)
-{
-       u8 tmp;
-       struct ds1685_priv *rtc = dev_get_drvdata(dev);
-       const struct ds1685_rtc_time_regs *bcd_reg_info =
-               ds1685_rtc_sysfs_time_regs_lookup(attr->attr.name, true);
-       const struct ds1685_rtc_time_regs *bin_reg_info =
-               ds1685_rtc_sysfs_time_regs_lookup(attr->attr.name, false);
-
-       /* Make sure we actually matched something. */
-       if (!bcd_reg_info || !bin_reg_info)
-               return -EINVAL;
-
-       /* bcd_reg_info->reg == bin_reg_info->reg. */
-       ds1685_rtc_begin_data_access(rtc);
-       tmp = rtc->read(rtc, bcd_reg_info->reg);
-       ds1685_rtc_end_data_access(rtc);
-
-       tmp = ds1685_rtc_bcd2bin(rtc, tmp, bcd_reg_info->mask,
-                                bin_reg_info->mask);
-
-       return sprintf(buf, "%d\n", tmp);
-}
-
-/**
- * ds1685_rtc_sysfs_time_regs_store - writes a time/date register via sysfs.
- * @dev: pointer to device structure.
- * @attr: pointer to device_attribute structure.
- * @buf: pointer to char array to hold the output.
- * @count: number of bytes written.
- */
-static ssize_t
-ds1685_rtc_sysfs_time_regs_store(struct device *dev,
-                                struct device_attribute *attr,
-                                const char *buf, size_t count)
-{
-       long int val = 0;
-       struct ds1685_priv *rtc = dev_get_drvdata(dev);
-       const struct ds1685_rtc_time_regs *bcd_reg_info =
-               ds1685_rtc_sysfs_time_regs_lookup(attr->attr.name, true);
-       const struct ds1685_rtc_time_regs *bin_reg_info =
-               ds1685_rtc_sysfs_time_regs_lookup(attr->attr.name, false);
-
-       /* We only accept numbers. */
-       if (kstrtol(buf, 10, &val) < 0)
-               return -EINVAL;
-
-       /* Make sure we actually matched something. */
-       if (!bcd_reg_info || !bin_reg_info)
-               return -EINVAL;
-
-       /* Check for a valid range. */
-       if (rtc->bcd_mode) {
-               if ((val < bcd_reg_info->min) || (val > bcd_reg_info->max))
-                       return -ERANGE;
-       } else {
-               if ((val < bin_reg_info->min) || (val > bin_reg_info->max))
-                       return -ERANGE;
-       }
-
-       val = ds1685_rtc_bin2bcd(rtc, val, bin_reg_info->mask,
-                                bcd_reg_info->mask);
-
-       /* bcd_reg_info->reg == bin_reg_info->reg. */
-       ds1685_rtc_begin_data_access(rtc);
-       rtc->write(rtc, bcd_reg_info->reg, val);
-       ds1685_rtc_end_data_access(rtc);
-
-       return count;
-}
-
-/**
- * DS1685_RTC_SYSFS_REG_RW - device_attribute for a read-write time register.
- * @reg: time/date register to read or write.
- */
-#define DS1685_RTC_SYSFS_TIME_REG_RW(reg)                              \
-       static DEVICE_ATTR(reg, S_IRUGO | S_IWUSR,                      \
-       ds1685_rtc_sysfs_time_regs_show,                                \
-       ds1685_rtc_sysfs_time_regs_store)
-
-/*
- * Time/Date Register bits.
- */
-DS1685_RTC_SYSFS_TIME_REG_RW(seconds);
-DS1685_RTC_SYSFS_TIME_REG_RW(minutes);
-DS1685_RTC_SYSFS_TIME_REG_RW(hours);
-DS1685_RTC_SYSFS_TIME_REG_RW(wday);
-DS1685_RTC_SYSFS_TIME_REG_RW(mday);
-DS1685_RTC_SYSFS_TIME_REG_RW(month);
-DS1685_RTC_SYSFS_TIME_REG_RW(year);
-DS1685_RTC_SYSFS_TIME_REG_RW(century);
-DS1685_RTC_SYSFS_TIME_REG_RW(alarm_seconds);
-DS1685_RTC_SYSFS_TIME_REG_RW(alarm_minutes);
-DS1685_RTC_SYSFS_TIME_REG_RW(alarm_hours);
-DS1685_RTC_SYSFS_TIME_REG_RW(alarm_mday);
-
-static struct attribute*
-ds1685_rtc_sysfs_time_attrs[] = {
-       &dev_attr_seconds.attr,
-       &dev_attr_minutes.attr,
-       &dev_attr_hours.attr,
-       &dev_attr_wday.attr,
-       &dev_attr_mday.attr,
-       &dev_attr_month.attr,
-       &dev_attr_year.attr,
-       &dev_attr_century.attr,
-       NULL,
-};
-
-static const struct attribute_group
-ds1685_rtc_sysfs_time_grp = {
-       .name = "datetime",
-       .attrs = ds1685_rtc_sysfs_time_attrs,
-};
-
-static struct attribute*
-ds1685_rtc_sysfs_alarm_attrs[] = {
-       &dev_attr_alarm_seconds.attr,
-       &dev_attr_alarm_minutes.attr,
-       &dev_attr_alarm_hours.attr,
-       &dev_attr_alarm_mday.attr,
-       NULL,
-};
-
-static const struct attribute_group
-ds1685_rtc_sysfs_alarm_grp = {
-       .name = "alarm",
-       .attrs = ds1685_rtc_sysfs_alarm_attrs,
-};
-#endif /* CONFIG_RTC_DS1685_SYSFS_REGS */
-
-
 /**
  * ds1685_rtc_sysfs_register - register sysfs files.
  * @dev: pointer to device structure.
@@ -1752,39 +1206,6 @@ ds1685_rtc_sysfs_register(struct device *dev)
        if (ret)
                return ret;
 
-#ifdef CONFIG_RTC_DS1685_SYSFS_REGS
-       ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrla_grp);
-       if (ret)
-               return ret;
-
-       ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrlb_grp);
-       if (ret)
-               return ret;
-
-       ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrlc_grp);
-       if (ret)
-               return ret;
-
-       ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrld_grp);
-       if (ret)
-               return ret;
-
-       ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrl4a_grp);
-       if (ret)
-               return ret;
-
-       ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrl4b_grp);
-       if (ret)
-               return ret;
-
-       ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_time_grp);
-       if (ret)
-               return ret;
-
-       ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_alarm_grp);
-       if (ret)
-               return ret;
-#endif
        return 0;
 }
 
@@ -1798,17 +1219,6 @@ ds1685_rtc_sysfs_unregister(struct device *dev)
        sysfs_remove_bin_file(&dev->kobj, &ds1685_rtc_sysfs_nvram_attr);
        sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_misc_grp);
 
-#ifdef CONFIG_RTC_DS1685_SYSFS_REGS
-       sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrla_grp);
-       sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrlb_grp);
-       sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrlc_grp);
-       sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrld_grp);
-       sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrl4a_grp);
-       sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrl4b_grp);
-       sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_time_grp);
-       sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_alarm_grp);
-#endif
-
        return 0;
 }
 #endif /* CONFIG_SYSFS */
index 1a2c38cc01785c573c5bfeccbf332290020296a9..ea18a8f4bce063a91587d4424c8d615788af5dfd 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/i2c.h>
 #include <linux/bcd.h>
 #include <linux/rtc.h>
+#include "rtc-core.h"
+#include <linux/of_irq.h>
 
 /* Register map */
 /* rtc section */
 #define ISL1208_REG_SR_ARST    (1<<7)  /* auto reset */
 #define ISL1208_REG_SR_XTOSCB  (1<<6)  /* crystal oscillator */
 #define ISL1208_REG_SR_WRTC    (1<<4)  /* write rtc */
+#define ISL1208_REG_SR_EVT     (1<<3)  /* event */
 #define ISL1208_REG_SR_ALM     (1<<2)  /* alarm */
 #define ISL1208_REG_SR_BAT     (1<<1)  /* battery */
 #define ISL1208_REG_SR_RTCF    (1<<0)  /* rtc fail */
 #define ISL1208_REG_INT 0x08
 #define ISL1208_REG_INT_ALME   (1<<6)   /* alarm enable */
 #define ISL1208_REG_INT_IM     (1<<7)   /* interrupt/alarm mode */
-#define ISL1208_REG_09  0x09   /* reserved */
+#define ISL1219_REG_EV  0x09
+#define ISL1219_REG_EV_EVEN    (1<<4)   /* event detection enable */
+#define ISL1219_REG_EV_EVIENB  (1<<7)   /* event in pull-up disable */
 #define ISL1208_REG_ATR 0x0a
 #define ISL1208_REG_DTR 0x0b
 
 #define ISL1208_REG_USR2 0x13
 #define ISL1208_USR_SECTION_LEN 2
 
+/* event section */
+#define ISL1219_REG_SCT 0x14
+#define ISL1219_REG_MNT 0x15
+#define ISL1219_REG_HRT 0x16
+#define ISL1219_REG_DTT 0x17
+#define ISL1219_REG_MOT 0x18
+#define ISL1219_REG_YRT 0x19
+#define ISL1219_EVT_SECTION_LEN 6
+
 static struct i2c_driver isl1208_driver;
 
+/* ISL1208 various variants */
+enum {
+       TYPE_ISL1208 = 0,
+       TYPE_ISL1218,
+       TYPE_ISL1219,
+};
+
 /* block read */
 static int
 isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[],
@@ -80,8 +101,8 @@ isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[],
        };
        int ret;
 
-       BUG_ON(reg > ISL1208_REG_USR2);
-       BUG_ON(reg + len > ISL1208_REG_USR2 + 1);
+       WARN_ON(reg > ISL1219_REG_YRT);
+       WARN_ON(reg + len > ISL1219_REG_YRT + 1);
 
        ret = i2c_transfer(client->adapter, msgs, 2);
        if (ret > 0)
@@ -104,8 +125,8 @@ isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[],
        };
        int ret;
 
-       BUG_ON(reg > ISL1208_REG_USR2);
-       BUG_ON(reg + len > ISL1208_REG_USR2 + 1);
+       WARN_ON(reg > ISL1219_REG_YRT);
+       WARN_ON(reg + len > ISL1219_REG_YRT + 1);
 
        i2c_buf[0] = reg;
        memcpy(&i2c_buf[1], &buf[0], len);
@@ -493,6 +514,73 @@ isl1208_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
        return isl1208_i2c_set_alarm(to_i2c_client(dev), alarm);
 }
 
+static ssize_t timestamp0_store(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf, size_t count)
+{
+       struct i2c_client *client = dev_get_drvdata(dev);
+       int sr;
+
+       sr = isl1208_i2c_get_sr(client);
+       if (sr < 0) {
+               dev_err(dev, "%s: reading SR failed\n", __func__);
+               return sr;
+       }
+
+       sr &= ~ISL1208_REG_SR_EVT;
+
+       sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr);
+       if (sr < 0)
+               dev_err(dev, "%s: writing SR failed\n",
+                       __func__);
+
+       return count;
+};
+
+static ssize_t timestamp0_show(struct device *dev,
+                              struct device_attribute *attr, char *buf)
+{
+       struct i2c_client *client = dev_get_drvdata(dev);
+       u8 regs[ISL1219_EVT_SECTION_LEN] = { 0, };
+       struct rtc_time tm;
+       int sr;
+
+       sr = isl1208_i2c_get_sr(client);
+       if (sr < 0) {
+               dev_err(dev, "%s: reading SR failed\n", __func__);
+               return sr;
+       }
+
+       if (!(sr & ISL1208_REG_SR_EVT))
+               return 0;
+
+       sr = isl1208_i2c_read_regs(client, ISL1219_REG_SCT, regs,
+                                  ISL1219_EVT_SECTION_LEN);
+       if (sr < 0) {
+               dev_err(dev, "%s: reading event section failed\n",
+                       __func__);
+               return 0;
+       }
+
+       /* MSB of each alarm register is an enable bit */
+       tm.tm_sec = bcd2bin(regs[ISL1219_REG_SCT - ISL1219_REG_SCT] & 0x7f);
+       tm.tm_min = bcd2bin(regs[ISL1219_REG_MNT - ISL1219_REG_SCT] & 0x7f);
+       tm.tm_hour = bcd2bin(regs[ISL1219_REG_HRT - ISL1219_REG_SCT] & 0x3f);
+       tm.tm_mday = bcd2bin(regs[ISL1219_REG_DTT - ISL1219_REG_SCT] & 0x3f);
+       tm.tm_mon =
+               bcd2bin(regs[ISL1219_REG_MOT - ISL1219_REG_SCT] & 0x1f) - 1;
+       tm.tm_year = bcd2bin(regs[ISL1219_REG_YRT - ISL1219_REG_SCT]) + 100;
+
+       sr = rtc_valid_tm(&tm);
+       if (sr)
+               return sr;
+
+       return sprintf(buf, "%llu\n",
+                               (unsigned long long)rtc_tm_to_time64(&tm));
+};
+
+static DEVICE_ATTR_RW(timestamp0);
+
 static irqreturn_t
 isl1208_rtc_interrupt(int irq, void *data)
 {
@@ -538,6 +626,13 @@ isl1208_rtc_interrupt(int irq, void *data)
                        return err;
        }
 
+       if (sr & ISL1208_REG_SR_EVT) {
+               sysfs_notify(&rtc->dev.kobj, NULL,
+                            dev_attr_timestamp0.attr.name);
+               dev_warn(&client->dev, "event detected");
+               handled = 1;
+       }
+
        return handled ? IRQ_HANDLED : IRQ_NONE;
 }
 
@@ -623,11 +718,39 @@ static const struct attribute_group isl1208_rtc_sysfs_files = {
        .attrs  = isl1208_rtc_attrs,
 };
 
+static struct attribute *isl1219_rtc_attrs[] = {
+       &dev_attr_timestamp0.attr,
+       NULL
+};
+
+static const struct attribute_group isl1219_rtc_sysfs_files = {
+       .attrs  = isl1219_rtc_attrs,
+};
+
+static int isl1208_setup_irq(struct i2c_client *client, int irq)
+{
+       int rc = devm_request_threaded_irq(&client->dev, irq, NULL,
+                                       isl1208_rtc_interrupt,
+                                       IRQF_SHARED | IRQF_ONESHOT,
+                                       isl1208_driver.driver.name,
+                                       client);
+       if (!rc) {
+               device_init_wakeup(&client->dev, 1);
+               enable_irq_wake(irq);
+       } else {
+               dev_err(&client->dev,
+                       "Unable to request irq %d, no alarm support\n",
+                       irq);
+       }
+       return rc;
+}
+
 static int
 isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
        int rc = 0;
        struct rtc_device *rtc;
+       int evdet_irq = -1;
 
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
                return -ENODEV;
@@ -642,6 +765,7 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
        rtc->ops = &isl1208_rtc_ops;
 
        i2c_set_clientdata(client, rtc);
+       dev_set_drvdata(&rtc->dev, client);
 
        rc = isl1208_i2c_get_sr(client);
        if (rc < 0) {
@@ -653,26 +777,46 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
                dev_warn(&client->dev, "rtc power failure detected, "
                         "please set clock.\n");
 
+       if (id->driver_data == TYPE_ISL1219) {
+               struct device_node *np = client->dev.of_node;
+               u32 evienb;
+
+               rc = i2c_smbus_read_byte_data(client, ISL1219_REG_EV);
+               if (rc < 0) {
+                       dev_err(&client->dev, "failed to read EV reg\n");
+                       return rc;
+               }
+               rc |= ISL1219_REG_EV_EVEN;
+               if (!of_property_read_u32(np, "isil,ev-evienb", &evienb)) {
+                       if (evienb)
+                               rc |= ISL1219_REG_EV_EVIENB;
+                       else
+                               rc &= ~ISL1219_REG_EV_EVIENB;
+               }
+               rc = i2c_smbus_write_byte_data(client, ISL1219_REG_EV, rc);
+               if (rc < 0) {
+                       dev_err(&client->dev, "could not enable tamper detection\n");
+                       return rc;
+               }
+               rc = rtc_add_group(rtc, &isl1219_rtc_sysfs_files);
+               if (rc)
+                       return rc;
+               evdet_irq = of_irq_get_byname(np, "evdet");
+       }
+
        rc = sysfs_create_group(&client->dev.kobj, &isl1208_rtc_sysfs_files);
        if (rc)
                return rc;
 
-       if (client->irq > 0) {
-               rc = devm_request_threaded_irq(&client->dev, client->irq, NULL,
-                                              isl1208_rtc_interrupt,
-                                              IRQF_SHARED | IRQF_ONESHOT,
-                                              isl1208_driver.driver.name,
-                                              client);
-               if (!rc) {
-                       device_init_wakeup(&client->dev, 1);
-                       enable_irq_wake(client->irq);
-               } else {
-                       dev_err(&client->dev,
-                               "Unable to request irq %d, no alarm support\n",
-                               client->irq);
-                       client->irq = 0;
-               }
-       }
+       if (client->irq > 0)
+               rc = isl1208_setup_irq(client, client->irq);
+       if (rc)
+               return rc;
+
+       if (evdet_irq > 0 && evdet_irq != client->irq)
+               rc = isl1208_setup_irq(client, evdet_irq);
+       if (rc)
+               return rc;
 
        return rtc_register_device(rtc);
 }
@@ -686,8 +830,9 @@ isl1208_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id isl1208_id[] = {
-       { "isl1208", 0 },
-       { "isl1218", 0 },
+       { "isl1208", TYPE_ISL1208 },
+       { "isl1218", TYPE_ISL1218 },
+       { "isl1219", TYPE_ISL1219 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, isl1208_id);
@@ -695,6 +840,7 @@ MODULE_DEVICE_TABLE(i2c, isl1208_id);
 static const struct of_device_id isl1208_of_match[] = {
        { .compatible = "isil,isl1208" },
        { .compatible = "isil,isl1218" },
+       { .compatible = "isil,isl1219" },
        { }
 };
 MODULE_DEVICE_TABLE(of, isl1208_of_match);
index 1053a406b3aaa9cc5ffb3c2b5dad221102b82b66..ac9ca104288946dfcc5b06c12e122e004bf4dea3 100644 (file)
@@ -373,7 +373,6 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
        struct m48t59_private *m48t59 = NULL;
        struct resource *res;
        int ret = -ENOMEM;
-       char *name;
        const struct rtc_class_ops *ops;
        struct nvmem_config nvmem_cfg = {
                .name = "m48t59-",
@@ -448,17 +447,14 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
        }
        switch (pdata->type) {
        case M48T59RTC_TYPE_M48T59:
-               name = "m48t59";
                ops = &m48t59_rtc_ops;
                pdata->offset = 0x1ff0;
                break;
        case M48T59RTC_TYPE_M48T02:
-               name = "m48t02";
                ops = &m48t02_rtc_ops;
                pdata->offset = 0x7f0;
                break;
        case M48T59RTC_TYPE_M48T08:
-               name = "m48t08";
                ops = &m48t02_rtc_ops;
                pdata->offset = 0x1ff0;
                break;
index cefde273fae6e36494f3e79a7625424ea52422aa..8a60900d6b8b53af51d348355c065590bc6518a1 100644 (file)
@@ -1,16 +1,10 @@
-/*
- * RTC driver for Maxim MAX77686 and MAX77802
- *
- * Copyright (C) 2012 Samsung Electronics Co.Ltd
- *
- *  based on rtc-max8997.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.
- *
- */
+// SPDX-License-Identifier: GPL-2.0+
+//
+// RTC driver for Maxim MAX77686 and MAX77802
+//
+// Copyright (C) 2012 Samsung Electronics Co.Ltd
+//
+//  based on rtc-max8997.c
 
 #include <linux/i2c.h>
 #include <linux/slab.h>
index e8cee123e8aae3b1c08774d6d01796dd34ef71be..08c661a332ec0e73b47e08522feb39ad1f8ff5ae 100644 (file)
@@ -1,16 +1,10 @@
-/*
- * RTC driver for Maxim MAX8997
- *
- * Copyright (C) 2013 Samsung Electronics Co.Ltd
- *
- *  based on rtc-max8998.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.
- *
- */
+// SPDX-License-Identifier: GPL-2.0+
+//
+// RTC driver for Maxim MAX8997
+//
+// Copyright (C) 2013 Samsung Electronics Co.Ltd
+//
+//  based on rtc-max8998.c
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
index d8c0f9b3f87d5e330c943a575eaca6b16b7345f7..c873b4509b3cfe9fa6a17ee826d67d586b7530a2 100644 (file)
@@ -1,16 +1,10 @@
-/*
- * RTC driver for Maxim MAX8998
- *
- * Copyright (C) 2010 Samsung Electronics Co.Ltd
- * Author: Minkyu Kang <mk7.kang@samsung.com>
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- */
+// SPDX-License-Identifier: GPL-2.0+
+//
+// RTC driver for Maxim MAX8998
+//
+// Copyright (C) 2010 Samsung Electronics Co.Ltd
+// Author: Minkyu Kang <mk7.kang@samsung.com>
+// Author: Joonyoung Shim <jy0922.shim@samsung.com>
 
 #include <linux/module.h>
 #include <linux/i2c.h>
index 39086398833e0f8ea95d272f91e4f09fec7cf68f..323ff55cc16564833d75ed4b0fa682642ad4fc0f 100644 (file)
@@ -449,6 +449,7 @@ static void omap_rtc_power_off(void)
 
        if (tm2bcd(&tm) < 0) {
                dev_err(&rtc->rtc->dev, "power off failed\n");
+               rtc->type->lock(rtc);
                return;
        }
 
@@ -582,9 +583,7 @@ static int rtc_pinconf_get(struct pinctrl_dev *pctldev,
        u32 val;
        u16 arg = 0;
 
-       rtc->type->unlock(rtc);
        val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
-       rtc->type->lock(rtc);
 
        switch (param) {
        case PIN_CONFIG_INPUT_ENABLE:
@@ -614,9 +613,7 @@ static int rtc_pinconf_set(struct pinctrl_dev *pctldev,
        u32 param_val;
        int i;
 
-       rtc->type->unlock(rtc);
        val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
-       rtc->type->lock(rtc);
 
        /* active low by default */
        val |= OMAP_RTC_PMIC_EXT_WKUP_POL(pin);
@@ -861,13 +858,6 @@ static int omap_rtc_probe(struct platform_device *pdev)
                        goto err;
        }
 
-       if (rtc->is_pmic_controller) {
-               if (!pm_power_off) {
-                       omap_rtc_power_off_rtc = rtc;
-                       pm_power_off = omap_rtc_power_off;
-               }
-       }
-
        /* Support ext_wakeup pinconf */
        rtc_pinctrl_desc.name = dev_name(&pdev->dev);
 
@@ -880,12 +870,21 @@ static int omap_rtc_probe(struct platform_device *pdev)
 
        ret = rtc_register_device(rtc->rtc);
        if (ret)
-               goto err;
+               goto err_deregister_pinctrl;
 
        rtc_nvmem_register(rtc->rtc, &omap_rtc_nvmem_config);
 
+       if (rtc->is_pmic_controller) {
+               if (!pm_power_off) {
+                       omap_rtc_power_off_rtc = rtc;
+                       pm_power_off = omap_rtc_power_off;
+               }
+       }
+
        return 0;
 
+err_deregister_pinctrl:
+       pinctrl_unregister(rtc->pctldev);
 err:
        clk_disable_unprepare(rtc->clk);
        device_init_wakeup(&pdev->dev, false);
index e83be1852c2fb276b25f1ff112e2be240e5aae0c..9f99a0966550b5e77672e83cc707eda26b22ede5 100644 (file)
 #define PCF2127_REG_MO          (0x08)
 #define PCF2127_REG_YR          (0x09)
 
+/* the pcf2127 has 512 bytes nvmem, pcf2129 doesn't */
+#define PCF2127_REG_RAM_addr_MSB       0x1a
+#define PCF2127_REG_RAM_wrt_cmd        0x1c
+#define PCF2127_REG_RAM_rd_cmd         0x1d
+
 #define PCF2127_OSF             BIT(7)  /* Oscillator Fail flag */
 
 struct pcf2127 {
@@ -183,10 +188,47 @@ static const struct rtc_class_ops pcf2127_rtc_ops = {
        .set_time       = pcf2127_rtc_set_time,
 };
 
+static int pcf2127_nvmem_read(void *priv, unsigned int offset,
+                             void *val, size_t bytes)
+{
+       struct pcf2127 *pcf2127 = priv;
+       int ret;
+       unsigned char offsetbuf[] = { offset >> 8, offset };
+
+       ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_addr_MSB,
+                               offsetbuf, 2);
+       if (ret)
+               return ret;
+
+       ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_RAM_rd_cmd,
+                              val, bytes);
+
+       return ret ?: bytes;
+}
+
+static int pcf2127_nvmem_write(void *priv, unsigned int offset,
+                              void *val, size_t bytes)
+{
+       struct pcf2127 *pcf2127 = priv;
+       int ret;
+       unsigned char offsetbuf[] = { offset >> 8, offset };
+
+       ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_addr_MSB,
+                               offsetbuf, 2);
+       if (ret)
+               return ret;
+
+       ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_wrt_cmd,
+                               val, bytes);
+
+       return ret ?: bytes;
+}
+
 static int pcf2127_probe(struct device *dev, struct regmap *regmap,
-                       const char *name)
+                       const char *name, bool has_nvmem)
 {
        struct pcf2127 *pcf2127;
+       int ret = 0;
 
        dev_dbg(dev, "%s\n", __func__);
 
@@ -200,8 +242,21 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
 
        pcf2127->rtc = devm_rtc_device_register(dev, name, &pcf2127_rtc_ops,
                                                THIS_MODULE);
+       if (IS_ERR(pcf2127->rtc))
+               return PTR_ERR(pcf2127->rtc);
+
+       if (has_nvmem) {
+               struct nvmem_config nvmem_cfg = {
+                       .priv = pcf2127,
+                       .reg_read = pcf2127_nvmem_read,
+                       .reg_write = pcf2127_nvmem_write,
+                       .size = 512,
+               };
+
+               ret = rtc_nvmem_register(pcf2127->rtc, &nvmem_cfg);
+       }
 
-       return PTR_ERR_OR_ZERO(pcf2127->rtc);
+       return ret;
 }
 
 #ifdef CONFIG_OF
@@ -309,11 +364,11 @@ static int pcf2127_i2c_probe(struct i2c_client *client,
        }
 
        return pcf2127_probe(&client->dev, regmap,
-                               pcf2127_i2c_driver.driver.name);
+                            pcf2127_i2c_driver.driver.name, id->driver_data);
 }
 
 static const struct i2c_device_id pcf2127_i2c_id[] = {
-       { "pcf2127", 0 },
+       { "pcf2127", 1 },
        { "pcf2129", 0 },
        { }
 };
@@ -372,11 +427,12 @@ static int pcf2127_spi_probe(struct spi_device *spi)
                return PTR_ERR(regmap);
        }
 
-       return pcf2127_probe(&spi->dev, regmap, pcf2127_spi_driver.driver.name);
+       return pcf2127_probe(&spi->dev, regmap, pcf2127_spi_driver.driver.name,
+                            spi_get_device_id(spi)->driver_data);
 }
 
 static const struct spi_device_id pcf2127_spi_id[] = {
-       { "pcf2127", 0 },
+       { "pcf2127", 1 },
        { "pcf2129", 0 },
        { }
 };
index 49bcbb3d4a696160798a3bbaa36a2be8e8e81db2..283c2335b01b69b54a636680ec88d88852b11aa6 100644 (file)
@@ -43,37 +43,38 @@ static struct i2c_driver pcf85063_driver;
 
 static int pcf85063_stop_clock(struct i2c_client *client, u8 *ctrl1)
 {
-       s32 ret;
+       int rc;
+       u8 reg;
 
-       ret = i2c_smbus_read_byte_data(client, PCF85063_REG_CTRL1);
-       if (ret < 0) {
+       rc = i2c_smbus_read_byte_data(client, PCF85063_REG_CTRL1);
+       if (rc < 0) {
                dev_err(&client->dev, "Failing to stop the clock\n");
                return -EIO;
        }
 
        /* stop the clock */
-       ret |= PCF85063_REG_CTRL1_STOP;
+       reg = rc | PCF85063_REG_CTRL1_STOP;
 
-       ret = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, ret);
-       if (ret < 0) {
+       rc = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, reg);
+       if (rc < 0) {
                dev_err(&client->dev, "Failing to stop the clock\n");
                return -EIO;
        }
 
-       *ctrl1 = ret;
+       *ctrl1 = reg;
 
        return 0;
 }
 
 static int pcf85063_start_clock(struct i2c_client *client, u8 ctrl1)
 {
-       s32 ret;
+       int rc;
 
        /* start the clock */
        ctrl1 &= ~PCF85063_REG_CTRL1_STOP;
 
-       ret = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, ctrl1);
-       if (ret < 0) {
+       rc = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, ctrl1);
+       if (rc < 0) {
                dev_err(&client->dev, "Failing to start the clock\n");
                return -EIO;
        }
index 8428455432ca77c89790256cab801ab055c3fdd0..6495f84f74288cfda5e2a26274dbdedb152531b2 100644 (file)
@@ -1,19 +1,9 @@
-/*
- * Copyright (c) 2013-2014 Samsung Electronics Co., Ltd
- *     http://www.samsung.com
- *
- *  Copyright (C) 2013 Google, 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.
- */
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (c) 2013-2014 Samsung Electronics Co., Ltd
+//     http://www.samsung.com
+//
+//  Copyright (C) 2013 Google, Inc
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
index ed71d11136276d1259e976bb0814909726d1f75a..304d905cb23fd20240cdb8b4953310cb5d1a1609 100644 (file)
@@ -224,7 +224,6 @@ int sa1100_rtc_init(struct platform_device *pdev, struct sa1100_rtc *info)
        info->rtc = rtc;
 
        rtc->max_user_freq = RTC_FREQ;
-       rtc_irq_set_freq(rtc, NULL, RTC_FREQ);
 
        /* Fix for a nasty initialization problem the in SA11xx RTSR register.
         * See also the comments in sa1100_rtc_interrupt().
index 776b70a14e036e45808a86442577adb2d00645a7..51ba414798a83f0a2dfd1b6610fbf5dbaf4375d4 100644 (file)
@@ -143,8 +143,6 @@ static int __sh_rtc_alarm(struct sh_rtc *rtc)
 
 static int __sh_rtc_periodic(struct sh_rtc *rtc)
 {
-       struct rtc_device *rtc_dev = rtc->rtc_dev;
-       struct rtc_task *irq_task;
        unsigned int tmp, pending;
 
        tmp = readb(rtc->regbase + RCR2);
@@ -161,14 +159,7 @@ static int __sh_rtc_periodic(struct sh_rtc *rtc)
        else {
                if (rtc->periodic_freq & PF_HP)
                        rtc->periodic_freq |= PF_COUNT;
-               if (rtc->periodic_freq & PF_KOU) {
-                       spin_lock(&rtc_dev->irq_task_lock);
-                       irq_task = rtc_dev->irq_task;
-                       if (irq_task)
-                               irq_task->func(irq_task->private_data);
-                       spin_unlock(&rtc_dev->irq_task_lock);
-               } else
-                       rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF);
+               rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF);
        }
 
        return pending;
@@ -224,81 +215,6 @@ static irqreturn_t sh_rtc_shared(int irq, void *dev_id)
        return IRQ_RETVAL(ret);
 }
 
-static int sh_rtc_irq_set_state(struct device *dev, int enable)
-{
-       struct sh_rtc *rtc = dev_get_drvdata(dev);
-       unsigned int tmp;
-
-       spin_lock_irq(&rtc->lock);
-
-       tmp = readb(rtc->regbase + RCR2);
-
-       if (enable) {
-               rtc->periodic_freq |= PF_KOU;
-               tmp &= ~RCR2_PEF;       /* Clear PES bit */
-               tmp |= (rtc->periodic_freq & ~PF_HP);   /* Set PES2-0 */
-       } else {
-               rtc->periodic_freq &= ~PF_KOU;
-               tmp &= ~(RCR2_PESMASK | RCR2_PEF);
-       }
-
-       writeb(tmp, rtc->regbase + RCR2);
-
-       spin_unlock_irq(&rtc->lock);
-
-       return 0;
-}
-
-static int sh_rtc_irq_set_freq(struct device *dev, int freq)
-{
-       struct sh_rtc *rtc = dev_get_drvdata(dev);
-       int tmp, ret = 0;
-
-       spin_lock_irq(&rtc->lock);
-       tmp = rtc->periodic_freq & PF_MASK;
-
-       switch (freq) {
-       case 0:
-               rtc->periodic_freq = 0x00;
-               break;
-       case 1:
-               rtc->periodic_freq = 0x60;
-               break;
-       case 2:
-               rtc->periodic_freq = 0x50;
-               break;
-       case 4:
-               rtc->periodic_freq = 0x40;
-               break;
-       case 8:
-               rtc->periodic_freq = 0x30 | PF_HP;
-               break;
-       case 16:
-               rtc->periodic_freq = 0x30;
-               break;
-       case 32:
-               rtc->periodic_freq = 0x20 | PF_HP;
-               break;
-       case 64:
-               rtc->periodic_freq = 0x20;
-               break;
-       case 128:
-               rtc->periodic_freq = 0x10 | PF_HP;
-               break;
-       case 256:
-               rtc->periodic_freq = 0x10;
-               break;
-       default:
-               ret = -ENOTSUPP;
-       }
-
-       if (ret == 0)
-               rtc->periodic_freq |= tmp;
-
-       spin_unlock_irq(&rtc->lock);
-       return ret;
-}
-
 static inline void sh_rtc_setaie(struct device *dev, unsigned int enable)
 {
        struct sh_rtc *rtc = dev_get_drvdata(dev);
@@ -675,8 +591,6 @@ static int __init sh_rtc_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, rtc);
 
        /* everything disabled by default */
-       sh_rtc_irq_set_freq(&pdev->dev, 0);
-       sh_rtc_irq_set_state(&pdev->dev, 0);
        sh_rtc_setaie(&pdev->dev, 0);
        sh_rtc_setcie(&pdev->dev, 0);
 
@@ -708,8 +622,6 @@ static int __exit sh_rtc_remove(struct platform_device *pdev)
 {
        struct sh_rtc *rtc = platform_get_drvdata(pdev);
 
-       sh_rtc_irq_set_state(&pdev->dev, 0);
-
        sh_rtc_setaie(&pdev->dev, 0);
        sh_rtc_setcie(&pdev->dev, 0);
 
index 8a75cc3af6e706f23b0b33767e960fae0d2d4fae..b2483a749ac45fa58c4f9a7dd507ca19775222ca 100644 (file)
@@ -40,49 +40,83 @@ struct snvs_rtc_data {
        struct clk *clk;
 };
 
+/* Read 64 bit timer register, which could be in inconsistent state */
+static u64 rtc_read_lpsrt(struct snvs_rtc_data *data)
+{
+       u32 msb, lsb;
+
+       regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &msb);
+       regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &lsb);
+       return (u64)msb << 32 | lsb;
+}
+
+/* Read the secure real time counter, taking care to deal with the cases of the
+ * counter updating while being read.
+ */
 static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
 {
        u64 read1, read2;
-       u32 val;
+       unsigned int timeout = 100;
 
+       /* As expected, the registers might update between the read of the LSB
+        * reg and the MSB reg.  It's also possible that one register might be
+        * in partially modified state as well.
+        */
+       read1 = rtc_read_lpsrt(data);
        do {
-               regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &val);
-               read1 = val;
-               read1 <<= 32;
-               regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &val);
-               read1 |= val;
-
-               regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &val);
-               read2 = val;
-               read2 <<= 32;
-               regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &val);
-               read2 |= val;
-       } while (read1 != read2);
+               read2 = read1;
+               read1 = rtc_read_lpsrt(data);
+       } while (read1 != read2 && --timeout);
+       if (!timeout)
+               dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n");
 
        /* Convert 47-bit counter to 32-bit raw second count */
        return (u32) (read1 >> CNTR_TO_SECS_SH);
 }
 
-static void rtc_write_sync_lp(struct snvs_rtc_data *data)
+/* Just read the lsb from the counter, dealing with inconsistent state */
+static int rtc_read_lp_counter_lsb(struct snvs_rtc_data *data, u32 *lsb)
+{
+       u32 count1, count2;
+       unsigned int timeout = 100;
+
+       regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
+       do {
+               count2 = count1;
+               regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
+       } while (count1 != count2 && --timeout);
+       if (!timeout) {
+               dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n");
+               return -ETIMEDOUT;
+       }
+
+       *lsb = count1;
+       return 0;
+}
+
+static int rtc_write_sync_lp(struct snvs_rtc_data *data)
 {
-       u32 count1, count2, count3;
-       int i;
-
-       /* Wait for 3 CKIL cycles */
-       for (i = 0; i < 3; i++) {
-               do {
-                       regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
-                       regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count2);
-               } while (count1 != count2);
-
-               /* Now wait until counter value changes */
-               do {
-                       do {
-                               regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count2);
-                               regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count3);
-                       } while (count2 != count3);
-               } while (count3 == count1);
+       u32 count1, count2;
+       u32 elapsed;
+       unsigned int timeout = 1000;
+       int ret;
+
+       ret = rtc_read_lp_counter_lsb(data, &count1);
+       if (ret)
+               return ret;
+
+       /* Wait for 3 CKIL cycles, about 61.0-91.5 µs */
+       do {
+               ret = rtc_read_lp_counter_lsb(data, &count2);
+               if (ret)
+                       return ret;
+               elapsed = count2 - count1; /* wrap around _is_ handled! */
+       } while (elapsed < 3 && --timeout);
+       if (!timeout) {
+               dev_err(&data->rtc->dev, "Timeout waiting for LPSRT Counter to change\n");
+               return -ETIMEDOUT;
        }
+       return 0;
 }
 
 static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable)
@@ -166,9 +200,7 @@ static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
                           (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN),
                           enable ? (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN) : 0);
 
-       rtc_write_sync_lp(data);
-
-       return 0;
+       return rtc_write_sync_lp(data);
 }
 
 static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
@@ -176,11 +208,14 @@ static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
        struct snvs_rtc_data *data = dev_get_drvdata(dev);
        struct rtc_time *alrm_tm = &alrm->time;
        unsigned long time;
+       int ret;
 
        rtc_tm_to_time(alrm_tm, &time);
 
        regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0);
-       rtc_write_sync_lp(data);
+       ret = rtc_write_sync_lp(data);
+       if (ret)
+               return ret;
        regmap_write(data->regmap, data->offset + SNVS_LPTAR, time);
 
        /* Clear alarm interrupt status bit */
index d578e40d5a506308a76307a5050fd61552fc9420..b76318fd5bb004b4fa492de45df151e9b46b9a35 100644 (file)
@@ -288,10 +288,22 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, rtc_data);
 
-       err = stmp_reset_block(rtc_data->io);
-       if (err) {
-               dev_err(&pdev->dev, "stmp_reset_block failed: %d\n", err);
-               return err;
+       /*
+        * Resetting the rtc stops the watchdog timer that is potentially
+        * running. So (assuming it is running on purpose) don't reset if the
+        * watchdog is enabled.
+        */
+       if (readl(rtc_data->io + STMP3XXX_RTC_CTRL) &
+           STMP3XXX_RTC_CTRL_WATCHDOGEN) {
+               dev_info(&pdev->dev,
+                        "Watchdog is running, skip resetting rtc\n");
+       } else {
+               err = stmp_reset_block(rtc_data->io);
+               if (err) {
+                       dev_err(&pdev->dev, "stmp_reset_block failed: %d\n",
+                               err);
+                       return err;
+               }
        }
 
        /*
index 454da38c60122d3a91ffb3fef3369b7de3f6e203..f1ff30ade5343b07ff54d05bcd82fddbc3bea0d6 100644 (file)
@@ -317,3 +317,46 @@ const struct attribute_group **rtc_get_dev_attribute_groups(void)
 {
        return rtc_attr_groups;
 }
+
+int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps)
+{
+       size_t old_cnt = 0, add_cnt = 0, new_cnt;
+       const struct attribute_group **groups, **old;
+
+       if (rtc->registered)
+               return -EINVAL;
+       if (!grps)
+               return -EINVAL;
+
+       groups = rtc->dev.groups;
+       if (groups)
+               for (; *groups; groups++)
+                       old_cnt++;
+
+       for (groups = grps; *groups; groups++)
+               add_cnt++;
+
+       new_cnt = old_cnt + add_cnt + 1;
+       groups = devm_kcalloc(&rtc->dev, new_cnt, sizeof(*groups), GFP_KERNEL);
+       if (IS_ERR_OR_NULL(groups))
+               return PTR_ERR(groups);
+       memcpy(groups, rtc->dev.groups, old_cnt * sizeof(*groups));
+       memcpy(groups + old_cnt, grps, add_cnt * sizeof(*groups));
+       groups[old_cnt + add_cnt] = NULL;
+
+       old = rtc->dev.groups;
+       rtc->dev.groups = groups;
+       if (old && old != rtc_attr_groups)
+               devm_kfree(&rtc->dev, old);
+
+       return 0;
+}
+EXPORT_SYMBOL(rtc_add_groups);
+
+int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp)
+{
+       const struct attribute_group *groups[] = { grp, NULL };
+
+       return rtc_add_groups(rtc, groups);
+}
+EXPORT_SYMBOL(rtc_add_group);
index 8469256edc2af906fa8991b7fd910348f3761f7b..ade6a82709bee792c912dcc6f81c26f6f8b56d5b 100644 (file)
@@ -22,7 +22,7 @@ struct rtc_test_data {
        bool alarm_en;
 };
 
-struct platform_device *pdev[MAX_RTC_TEST];
+static struct platform_device *pdev[MAX_RTC_TEST];
 
 static int test_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
index ed607288e696f64c7d041e4b791ef74836017640..23e526cda5c10b7e61a059a63c3c83f8ed0dc0d8 100644 (file)
@@ -922,9 +922,11 @@ __dcssblk_direct_access(struct dcssblk_dev_info *dev_info, pgoff_t pgoff,
        unsigned long dev_sz;
 
        dev_sz = dev_info->end - dev_info->start + 1;
-       *kaddr = (void *) dev_info->start + offset;
-       *pfn = __pfn_to_pfn_t(PFN_DOWN(dev_info->start + offset),
-                       PFN_DEV|PFN_SPECIAL);
+       if (kaddr)
+               *kaddr = (void *) dev_info->start + offset;
+       if (pfn)
+               *pfn = __pfn_to_pfn_t(PFN_DOWN(dev_info->start + offset),
+                               PFN_DEV|PFN_SPECIAL);
 
        return (dev_sz - offset) / PAGE_SIZE;
 }
index bf27fc4d1335911850dd073ae13a42bf43101c4b..ec891bc7d10a69b4aa2771ae3da4fc9f50028fa9 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/crypto.h>
 #include <linux/mod_devicetable.h>
 #include <linux/debugfs.h>
+#include <linux/ctype.h>
 
 #include "ap_bus.h"
 #include "ap_debug.h"
  */
 int ap_domain_index = -1;      /* Adjunct Processor Domain Index */
 static DEFINE_SPINLOCK(ap_domain_lock);
-module_param_named(domain, ap_domain_index, int, S_IRUSR|S_IRGRP);
+module_param_named(domain, ap_domain_index, int, 0440);
 MODULE_PARM_DESC(domain, "domain index for ap devices");
 EXPORT_SYMBOL(ap_domain_index);
 
-static int ap_thread_flag = 0;
-module_param_named(poll_thread, ap_thread_flag, int, S_IRUSR|S_IRGRP);
+static int ap_thread_flag;
+module_param_named(poll_thread, ap_thread_flag, int, 0440);
 MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off).");
 
+static char *apm_str;
+module_param_named(apmask, apm_str, charp, 0440);
+MODULE_PARM_DESC(apmask, "AP bus adapter mask.");
+
+static char *aqm_str;
+module_param_named(aqmask, aqm_str, charp, 0440);
+MODULE_PARM_DESC(aqmask, "AP bus domain mask.");
+
 static struct device *ap_root_device;
 
 DEFINE_SPINLOCK(ap_list_lock);
 LIST_HEAD(ap_card_list);
 
+/* Default permissions (card and domain masking) */
+static struct ap_perms {
+       DECLARE_BITMAP(apm, AP_DEVICES);
+       DECLARE_BITMAP(aqm, AP_DOMAINS);
+} ap_perms;
+static DEFINE_MUTEX(ap_perms_mutex);
+
 static struct ap_config_info *ap_configuration;
 static bool initialised;
 
@@ -78,22 +94,26 @@ static DECLARE_WORK(ap_scan_work, ap_scan_bus);
 static void ap_tasklet_fn(unsigned long);
 static DECLARE_TASKLET(ap_tasklet, ap_tasklet_fn, 0);
 static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
-static struct task_struct *ap_poll_kthread = NULL;
+static struct task_struct *ap_poll_kthread;
 static DEFINE_MUTEX(ap_poll_thread_mutex);
 static DEFINE_SPINLOCK(ap_poll_timer_lock);
 static struct hrtimer ap_poll_timer;
-/* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds.
- * If z/VM change to 1500000 nanoseconds to adjust to z/VM polling.*/
+/*
+ * In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds.
+ * If z/VM change to 1500000 nanoseconds to adjust to z/VM polling.
+ */
 static unsigned long long poll_timeout = 250000;
 
 /* Suspend flag */
 static int ap_suspend_flag;
 /* Maximum domain id */
 static int ap_max_domain_id;
-/* Flag to check if domain was set through module parameter domain=. This is
+/*
+ * Flag to check if domain was set through module parameter domain=. This is
  * important when supsend and resume is done in a z/VM environment where the
- * domain might change. */
-static int user_set_domain = 0;
+ * domain might change.
+ */
+static int user_set_domain;
 static struct bus_type ap_bus_type;
 
 /* Adapter interrupt definitions */
@@ -531,7 +551,7 @@ static int ap_bus_match(struct device *dev, struct device_driver *drv)
  * It sets up a single environment variable DEV_TYPE which contains the
  * hardware device type.
  */
-static int ap_uevent (struct device *dev, struct kobj_uevent_env *env)
+static int ap_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
        struct ap_device *ap_dev = to_ap_dev(dev);
        int retval = 0;
@@ -570,7 +590,7 @@ static int ap_dev_resume(struct device *dev)
 
 static void ap_bus_suspend(void)
 {
-       AP_DBF(DBF_DEBUG, "ap_bus_suspend running\n");
+       AP_DBF(DBF_DEBUG, "%s running\n", __func__);
 
        ap_suspend_flag = 1;
        /*
@@ -607,7 +627,7 @@ static void ap_bus_resume(void)
 {
        int rc;
 
-       AP_DBF(DBF_DEBUG, "ap_bus_resume running\n");
+       AP_DBF(DBF_DEBUG, "%s running\n", __func__);
 
        /* remove all queue devices */
        bus_for_each_dev(&ap_bus_type, NULL, NULL,
@@ -666,11 +686,97 @@ static struct bus_type ap_bus_type = {
        .pm = &ap_bus_pm_ops,
 };
 
+static int __ap_revise_reserved(struct device *dev, void *dummy)
+{
+       int rc, card, queue, devres, drvres;
+
+       if (is_queue_dev(dev)) {
+               card = AP_QID_CARD(to_ap_queue(dev)->qid);
+               queue = AP_QID_QUEUE(to_ap_queue(dev)->qid);
+               mutex_lock(&ap_perms_mutex);
+               devres = test_bit_inv(card, ap_perms.apm)
+                       && test_bit_inv(queue, ap_perms.aqm);
+               mutex_unlock(&ap_perms_mutex);
+               drvres = to_ap_drv(dev->driver)->flags
+                       & AP_DRIVER_FLAG_DEFAULT;
+               if (!!devres != !!drvres) {
+                       AP_DBF(DBF_DEBUG, "reprobing queue=%02x.%04x\n",
+                              card, queue);
+                       rc = device_reprobe(dev);
+               }
+       }
+
+       return 0;
+}
+
+static void ap_bus_revise_bindings(void)
+{
+       bus_for_each_dev(&ap_bus_type, NULL, NULL, __ap_revise_reserved);
+}
+
+int ap_owned_by_def_drv(int card, int queue)
+{
+       int rc = 0;
+
+       if (card < 0 || card >= AP_DEVICES || queue < 0 || queue >= AP_DOMAINS)
+               return -EINVAL;
+
+       mutex_lock(&ap_perms_mutex);
+
+       if (test_bit_inv(card, ap_perms.apm)
+           && test_bit_inv(queue, ap_perms.aqm))
+               rc = 1;
+
+       mutex_unlock(&ap_perms_mutex);
+
+       return rc;
+}
+EXPORT_SYMBOL(ap_owned_by_def_drv);
+
+int ap_apqn_in_matrix_owned_by_def_drv(unsigned long *apm,
+                                      unsigned long *aqm)
+{
+       int card, queue, rc = 0;
+
+       mutex_lock(&ap_perms_mutex);
+
+       for (card = 0; !rc && card < AP_DEVICES; card++)
+               if (test_bit_inv(card, apm) &&
+                   test_bit_inv(card, ap_perms.apm))
+                       for (queue = 0; !rc && queue < AP_DOMAINS; queue++)
+                               if (test_bit_inv(queue, aqm) &&
+                                   test_bit_inv(queue, ap_perms.aqm))
+                                       rc = 1;
+
+       mutex_unlock(&ap_perms_mutex);
+
+       return rc;
+}
+EXPORT_SYMBOL(ap_apqn_in_matrix_owned_by_def_drv);
+
 static int ap_device_probe(struct device *dev)
 {
        struct ap_device *ap_dev = to_ap_dev(dev);
        struct ap_driver *ap_drv = to_ap_drv(dev->driver);
-       int rc;
+       int card, queue, devres, drvres, rc;
+
+       if (is_queue_dev(dev)) {
+               /*
+                * If the apqn is marked as reserved/used by ap bus and
+                * default drivers, only probe with drivers with the default
+                * flag set. If it is not marked, only probe with drivers
+                * with the default flag not set.
+                */
+               card = AP_QID_CARD(to_ap_queue(dev)->qid);
+               queue = AP_QID_QUEUE(to_ap_queue(dev)->qid);
+               mutex_lock(&ap_perms_mutex);
+               devres = test_bit_inv(card, ap_perms.apm)
+                       && test_bit_inv(queue, ap_perms.aqm);
+               mutex_unlock(&ap_perms_mutex);
+               drvres = ap_drv->flags & AP_DRIVER_FLAG_DEFAULT;
+               if (!!devres != !!drvres)
+                       return -ENODEV;
+       }
 
        /* Add queue/card to list of active queues/cards */
        spin_lock_bh(&ap_list_lock);
@@ -750,9 +856,164 @@ void ap_bus_force_rescan(void)
 }
 EXPORT_SYMBOL(ap_bus_force_rescan);
 
+/*
+ * hex2bitmap() - parse hex mask string and set bitmap.
+ * Valid strings are "0x012345678" with at least one valid hex number.
+ * Rest of the bitmap to the right is padded with 0. No spaces allowed
+ * within the string, the leading 0x may be omitted.
+ * Returns the bitmask with exactly the bits set as given by the hex
+ * string (both in big endian order).
+ */
+static int hex2bitmap(const char *str, unsigned long *bitmap, int bits)
+{
+       int i, n, b;
+
+       /* bits needs to be a multiple of 8 */
+       if (bits & 0x07)
+               return -EINVAL;
+
+       memset(bitmap, 0, bits / 8);
+
+       if (str[0] == '0' && str[1] == 'x')
+               str++;
+       if (*str == 'x')
+               str++;
+
+       for (i = 0; isxdigit(*str) && i < bits; str++) {
+               b = hex_to_bin(*str);
+               for (n = 0; n < 4; n++)
+                       if (b & (0x08 >> n))
+                               set_bit_inv(i + n, bitmap);
+               i += 4;
+       }
+
+       if (*str == '\n')
+               str++;
+       if (*str)
+               return -EINVAL;
+       return 0;
+}
+
+/*
+ * str2clrsetmasks() - parse bitmask argument and set the clear and
+ * the set bitmap mask. A concatenation (done with ',') of these terms
+ * is recognized:
+ *   +<bitnr>[-<bitnr>] or -<bitnr>[-<bitnr>]
+ * <bitnr> may be any valid number (hex, decimal or octal) in the range
+ * 0...bits-1; the leading + or - is required. Here are some examples:
+ *   +0-15,+32,-128,-0xFF
+ *   -0-255,+1-16,+0x128
+ *   +1,+2,+3,+4,-5,-7-10
+ * Returns a clear and a set bitmask. Every positive value in the string
+ * results in a bit set in the set mask and every negative value in the
+ * string results in a bit SET in the clear mask. As a bit may be touched
+ * more than once, the last 'operation' wins: +0-255,-128 = all but bit
+ * 128 set in the set mask, only bit 128 set in the clear mask.
+ */
+static int str2clrsetmasks(const char *str,
+                          unsigned long *clrmap,
+                          unsigned long *setmap,
+                          int bits)
+{
+       int a, i, z;
+       char *np, sign;
+
+       /* bits needs to be a multiple of 8 */
+       if (bits & 0x07)
+               return -EINVAL;
+
+       memset(clrmap, 0, bits / 8);
+       memset(setmap, 0, bits / 8);
+
+       while (*str) {
+               sign = *str++;
+               if (sign != '+' && sign != '-')
+                       return -EINVAL;
+               a = z = simple_strtoul(str, &np, 0);
+               if (str == np || a >= bits)
+                       return -EINVAL;
+               str = np;
+               if (*str == '-') {
+                       z = simple_strtoul(++str, &np, 0);
+                       if (str == np || a > z || z >= bits)
+                               return -EINVAL;
+                       str = np;
+               }
+               for (i = a; i <= z; i++)
+                       if (sign == '+') {
+                               set_bit_inv(i, setmap);
+                               clear_bit_inv(i, clrmap);
+                       } else {
+                               clear_bit_inv(i, setmap);
+                               set_bit_inv(i, clrmap);
+                       }
+               while (*str == ',' || *str == '\n')
+                       str++;
+       }
+
+       return 0;
+}
+
+/*
+ * process_mask_arg() - parse a bitmap string and clear/set the
+ * bits in the bitmap accordingly. The string may be given as
+ * absolute value, a hex string like 0x1F2E3D4C5B6A" simple over-
+ * writing the current content of the bitmap. Or as relative string
+ * like "+1-16,-32,-0x40,+128" where only single bits or ranges of
+ * bits are cleared or set. Distinction is done based on the very
+ * first character which may be '+' or '-' for the relative string
+ * and othewise assume to be an absolute value string. If parsing fails
+ * a negative errno value is returned. All arguments and bitmaps are
+ * big endian order.
+ */
+static int process_mask_arg(const char *str,
+                           unsigned long *bitmap, int bits,
+                           struct mutex *lock)
+{
+       int i;
+
+       /* bits needs to be a multiple of 8 */
+       if (bits & 0x07)
+               return -EINVAL;
+
+       if (*str == '+' || *str == '-') {
+               DECLARE_BITMAP(clrm, bits);
+               DECLARE_BITMAP(setm, bits);
+
+               i = str2clrsetmasks(str, clrm, setm, bits);
+               if (i)
+                       return i;
+               if (mutex_lock_interruptible(lock))
+                       return -ERESTARTSYS;
+               for (i = 0; i < bits; i++) {
+                       if (test_bit_inv(i, clrm))
+                               clear_bit_inv(i, bitmap);
+                       if (test_bit_inv(i, setm))
+                               set_bit_inv(i, bitmap);
+               }
+       } else {
+               DECLARE_BITMAP(setm, bits);
+
+               i = hex2bitmap(str, setm, bits);
+               if (i)
+                       return i;
+               if (mutex_lock_interruptible(lock))
+                       return -ERESTARTSYS;
+               for (i = 0; i < bits; i++)
+                       if (test_bit_inv(i, setm))
+                               set_bit_inv(i, bitmap);
+                       else
+                               clear_bit_inv(i, bitmap);
+       }
+       mutex_unlock(lock);
+
+       return 0;
+}
+
 /*
  * AP bus attributes.
  */
+
 static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
 {
        return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index);
@@ -764,7 +1025,8 @@ static ssize_t ap_domain_store(struct bus_type *bus,
        int domain;
 
        if (sscanf(buf, "%i\n", &domain) != 1 ||
-           domain < 0 || domain > ap_max_domain_id)
+           domain < 0 || domain > ap_max_domain_id ||
+           !test_bit_inv(domain, ap_perms.aqm))
                return -EINVAL;
        spin_lock_bh(&ap_domain_lock);
        ap_domain_index = domain;
@@ -775,7 +1037,7 @@ static ssize_t ap_domain_store(struct bus_type *bus,
        return count;
 }
 
-static BUS_ATTR(ap_domain, 0644, ap_domain_show, ap_domain_store);
+static BUS_ATTR_RW(ap_domain);
 
 static ssize_t ap_control_domain_mask_show(struct bus_type *bus, char *buf)
 {
@@ -790,8 +1052,7 @@ static ssize_t ap_control_domain_mask_show(struct bus_type *bus, char *buf)
                        ap_configuration->adm[6], ap_configuration->adm[7]);
 }
 
-static BUS_ATTR(ap_control_domain_mask, 0444,
-               ap_control_domain_mask_show, NULL);
+static BUS_ATTR_RO(ap_control_domain_mask);
 
 static ssize_t ap_usage_domain_mask_show(struct bus_type *bus, char *buf)
 {
@@ -806,13 +1067,7 @@ static ssize_t ap_usage_domain_mask_show(struct bus_type *bus, char *buf)
                        ap_configuration->aqm[6], ap_configuration->aqm[7]);
 }
 
-static BUS_ATTR(ap_usage_domain_mask, 0444,
-               ap_usage_domain_mask_show, NULL);
-
-static ssize_t ap_config_time_show(struct bus_type *bus, char *buf)
-{
-       return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time);
-}
+static BUS_ATTR_RO(ap_usage_domain_mask);
 
 static ssize_t ap_interrupts_show(struct bus_type *bus, char *buf)
 {
@@ -820,10 +1075,15 @@ static ssize_t ap_interrupts_show(struct bus_type *bus, char *buf)
                        ap_using_interrupts() ? 1 : 0);
 }
 
-static BUS_ATTR(ap_interrupts, 0444, ap_interrupts_show, NULL);
+static BUS_ATTR_RO(ap_interrupts);
+
+static ssize_t config_time_show(struct bus_type *bus, char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time);
+}
 
-static ssize_t ap_config_time_store(struct bus_type *bus,
-                                   const char *buf, size_t count)
+static ssize_t config_time_store(struct bus_type *bus,
+                                const char *buf, size_t count)
 {
        int time;
 
@@ -834,15 +1094,15 @@ static ssize_t ap_config_time_store(struct bus_type *bus,
        return count;
 }
 
-static BUS_ATTR(config_time, 0644, ap_config_time_show, ap_config_time_store);
+static BUS_ATTR_RW(config_time);
 
-static ssize_t ap_poll_thread_show(struct bus_type *bus, char *buf)
+static ssize_t poll_thread_show(struct bus_type *bus, char *buf)
 {
        return snprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0);
 }
 
-static ssize_t ap_poll_thread_store(struct bus_type *bus,
-                                   const char *buf, size_t count)
+static ssize_t poll_thread_store(struct bus_type *bus,
+                                const char *buf, size_t count)
 {
        int flag, rc;
 
@@ -857,7 +1117,7 @@ static ssize_t ap_poll_thread_store(struct bus_type *bus,
        return count;
 }
 
-static BUS_ATTR(poll_thread, 0644, ap_poll_thread_show, ap_poll_thread_store);
+static BUS_ATTR_RW(poll_thread);
 
 static ssize_t poll_timeout_show(struct bus_type *bus, char *buf)
 {
@@ -886,7 +1146,7 @@ static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf,
        return count;
 }
 
-static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store);
+static BUS_ATTR_RW(poll_timeout);
 
 static ssize_t ap_max_domain_id_show(struct bus_type *bus, char *buf)
 {
@@ -899,7 +1159,69 @@ static ssize_t ap_max_domain_id_show(struct bus_type *bus, char *buf)
        return snprintf(buf, PAGE_SIZE, "%d\n", max_domain_id);
 }
 
-static BUS_ATTR(ap_max_domain_id, 0444, ap_max_domain_id_show, NULL);
+static BUS_ATTR_RO(ap_max_domain_id);
+
+static ssize_t apmask_show(struct bus_type *bus, char *buf)
+{
+       int rc;
+
+       if (mutex_lock_interruptible(&ap_perms_mutex))
+               return -ERESTARTSYS;
+       rc = snprintf(buf, PAGE_SIZE,
+                     "0x%016lx%016lx%016lx%016lx\n",
+                     ap_perms.apm[0], ap_perms.apm[1],
+                     ap_perms.apm[2], ap_perms.apm[3]);
+       mutex_unlock(&ap_perms_mutex);
+
+       return rc;
+}
+
+static ssize_t apmask_store(struct bus_type *bus, const char *buf,
+                           size_t count)
+{
+       int rc;
+
+       rc = process_mask_arg(buf, ap_perms.apm, AP_DEVICES, &ap_perms_mutex);
+       if (rc)
+               return rc;
+
+       ap_bus_revise_bindings();
+
+       return count;
+}
+
+static BUS_ATTR_RW(apmask);
+
+static ssize_t aqmask_show(struct bus_type *bus, char *buf)
+{
+       int rc;
+
+       if (mutex_lock_interruptible(&ap_perms_mutex))
+               return -ERESTARTSYS;
+       rc = snprintf(buf, PAGE_SIZE,
+                     "0x%016lx%016lx%016lx%016lx\n",
+                     ap_perms.aqm[0], ap_perms.aqm[1],
+                     ap_perms.aqm[2], ap_perms.aqm[3]);
+       mutex_unlock(&ap_perms_mutex);
+
+       return rc;
+}
+
+static ssize_t aqmask_store(struct bus_type *bus, const char *buf,
+                           size_t count)
+{
+       int rc;
+
+       rc = process_mask_arg(buf, ap_perms.aqm, AP_DOMAINS, &ap_perms_mutex);
+       if (rc)
+               return rc;
+
+       ap_bus_revise_bindings();
+
+       return count;
+}
+
+static BUS_ATTR_RW(aqmask);
 
 static struct bus_attribute *const ap_bus_attrs[] = {
        &bus_attr_ap_domain,
@@ -910,6 +1232,8 @@ static struct bus_attribute *const ap_bus_attrs[] = {
        &bus_attr_ap_interrupts,
        &bus_attr_poll_timeout,
        &bus_attr_ap_max_domain_id,
+       &bus_attr_apmask,
+       &bus_attr_aqmask,
        NULL,
 };
 
@@ -938,7 +1262,8 @@ static int ap_select_domain(void)
        best_domain = -1;
        max_count = 0;
        for (i = 0; i < AP_DOMAINS; i++) {
-               if (!ap_test_config_domain(i))
+               if (!ap_test_config_domain(i) ||
+                   !test_bit_inv(i, ap_perms.aqm))
                        continue;
                count = 0;
                for (j = 0; j < AP_DEVICES; j++) {
@@ -956,7 +1281,7 @@ static int ap_select_domain(void)
                        best_domain = i;
                }
        }
-       if (best_domain >= 0){
+       if (best_domain >= 0) {
                ap_domain_index = best_domain;
                AP_DBF(DBF_DEBUG, "new ap_domain_index=%d\n", ap_domain_index);
                spin_unlock_bh(&ap_domain_lock);
@@ -1038,7 +1363,7 @@ static void ap_scan_bus(struct work_struct *unused)
        unsigned int func = 0;
        int rc, id, dom, borked, domains, defdomdevs = 0;
 
-       AP_DBF(DBF_DEBUG, "ap_scan_bus running\n");
+       AP_DBF(DBF_DEBUG, "%s running\n", __func__);
 
        ap_query_configuration(ap_configuration);
        if (ap_select_domain() != 0)
@@ -1163,7 +1488,8 @@ static void ap_scan_bus(struct work_struct *unused)
        } /* end device loop */
 
        if (defdomdevs < 1)
-               AP_DBF(DBF_INFO, "no queue device with default domain %d available\n",
+               AP_DBF(DBF_INFO,
+                      "no queue device with default domain %d available\n",
                       ap_domain_index);
 
 out:
@@ -1187,6 +1513,27 @@ static int __init ap_debug_init(void)
        return 0;
 }
 
+static void __init ap_perms_init(void)
+{
+       /* all resources useable if no kernel parameter string given */
+       memset(&ap_perms.apm, 0xFF, sizeof(ap_perms.apm));
+       memset(&ap_perms.aqm, 0xFF, sizeof(ap_perms.aqm));
+
+       /* apm kernel parameter string */
+       if (apm_str) {
+               memset(&ap_perms.apm, 0, sizeof(ap_perms.apm));
+               process_mask_arg(apm_str, ap_perms.apm, AP_DEVICES,
+                                &ap_perms_mutex);
+       }
+
+       /* aqm kernel parameter string */
+       if (aqm_str) {
+               memset(&ap_perms.aqm, 0, sizeof(ap_perms.aqm));
+               process_mask_arg(aqm_str, ap_perms.aqm, AP_DOMAINS,
+                                &ap_perms_mutex);
+       }
+}
+
 /**
  * ap_module_init(): The module initialization code.
  *
@@ -1201,11 +1548,14 @@ static int __init ap_module_init(void)
        if (rc)
                return rc;
 
-       if (ap_instructions_available() != 0) {
+       if (!ap_instructions_available()) {
                pr_warn("The hardware system does not support AP instructions\n");
                return -ENODEV;
        }
 
+       /* set up the AP permissions (ap and aq masks) */
+       ap_perms_init();
+
        /* Get AP configuration data if available */
        ap_init_configuration();
 
@@ -1214,7 +1564,9 @@ static int __init ap_module_init(void)
                        ap_max_domain_id ? ap_max_domain_id : AP_DOMAINS - 1;
        else
                max_domain_id = 15;
-       if (ap_domain_index < -1 || ap_domain_index > max_domain_id) {
+       if (ap_domain_index < -1 || ap_domain_index > max_domain_id ||
+           (ap_domain_index >= 0 &&
+            !test_bit_inv(ap_domain_index, ap_perms.aqm))) {
                pr_warn("%d is not a valid cryptographic domain\n",
                        ap_domain_index);
                ap_domain_index = -1;
index 936541937e15d18016ee1debcec0208a30a6a3a3..5246cd8c16a605f6748884b47bdc59d963c3b578 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright IBM Corp. 2006, 2012
  * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
@@ -117,9 +117,18 @@ enum ap_wait {
 struct ap_device;
 struct ap_message;
 
+/*
+ * The ap driver struct includes a flags field which holds some info for
+ * the ap bus about the driver. Currently only one flag is supported and
+ * used: The DEFAULT flag marks an ap driver as a default driver which is
+ * used together with the apmask and aqmask whitelisting of the ap bus.
+ */
+#define AP_DRIVER_FLAG_DEFAULT 0x0001
+
 struct ap_driver {
        struct device_driver driver;
        struct ap_device_id *ids;
+       unsigned int flags;
 
        int (*probe)(struct ap_device *);
        void (*remove)(struct ap_device *);
@@ -167,7 +176,7 @@ struct ap_queue {
        int pendingq_count;             /* # requests on pendingq list. */
        int requestq_count;             /* # requests on requestq list. */
        int total_request_count;        /* # requests ever for this AP device.*/
-       int request_timeout;            /* Request timout in jiffies. */
+       int request_timeout;            /* Request timeout in jiffies. */
        struct timer_list timeout;      /* Timer for request timeouts. */
        struct list_head pendingq;      /* List of message sent to AP queue. */
        struct list_head requestq;      /* List of message yet to be sent. */
@@ -248,4 +257,27 @@ void ap_queue_resume(struct ap_device *ap_dev);
 struct ap_card *ap_card_create(int id, int queue_depth, int raw_device_type,
                               int comp_device_type, unsigned int functions);
 
+/*
+ * check APQN for owned/reserved by ap bus and default driver(s).
+ * Checks if this APQN is or will be in use by the ap bus
+ * and the default set of drivers.
+ * If yes, returns 1, if not returns 0. On error a negative
+ * errno value is returned.
+ */
+int ap_owned_by_def_drv(int card, int queue);
+
+/*
+ * check 'matrix' of APQNs for owned/reserved by ap bus and
+ * default driver(s).
+ * Checks if there is at least one APQN in the given 'matrix'
+ * marked as owned/reserved by the ap bus and default driver(s).
+ * If such an APQN is found the return value is 1, otherwise
+ * 0 is returned. On error a negative errno value is returned.
+ * The parameter apm is a bitmask which should be declared
+ * as DECLARE_BITMAP(apm, AP_DEVICES), the aqm parameter is
+ * similar, should be declared as DECLARE_BITMAP(aqm, AP_DOMAINS).
+ */
+int ap_apqn_in_matrix_owned_by_def_drv(unsigned long *apm,
+                                      unsigned long *aqm);
+
 #endif /* _AP_BUS_H_ */
index c13e43292cb7400a0412951aabb42c7aac8a7e20..63b4cc6cd7e596f7b51681391eb17ddffb6d0512 100644 (file)
 /*
  * AP card related attributes.
  */
-static ssize_t ap_hwtype_show(struct device *dev,
-                             struct device_attribute *attr, char *buf)
+static ssize_t hwtype_show(struct device *dev,
+                          struct device_attribute *attr, char *buf)
 {
        struct ap_card *ac = to_ap_card(dev);
 
        return snprintf(buf, PAGE_SIZE, "%d\n", ac->ap_dev.device_type);
 }
 
-static DEVICE_ATTR(hwtype, 0444, ap_hwtype_show, NULL);
+static DEVICE_ATTR_RO(hwtype);
 
-static ssize_t ap_raw_hwtype_show(struct device *dev,
-                                 struct device_attribute *attr, char *buf)
+static ssize_t raw_hwtype_show(struct device *dev,
+                              struct device_attribute *attr, char *buf)
 {
        struct ap_card *ac = to_ap_card(dev);
 
        return snprintf(buf, PAGE_SIZE, "%d\n", ac->raw_hwtype);
 }
 
-static DEVICE_ATTR(raw_hwtype, 0444, ap_raw_hwtype_show, NULL);
+static DEVICE_ATTR_RO(raw_hwtype);
 
-static ssize_t ap_depth_show(struct device *dev, struct device_attribute *attr,
-                            char *buf)
+static ssize_t depth_show(struct device *dev, struct device_attribute *attr,
+                         char *buf)
 {
        struct ap_card *ac = to_ap_card(dev);
 
        return snprintf(buf, PAGE_SIZE, "%d\n", ac->queue_depth);
 }
 
-static DEVICE_ATTR(depth, 0444, ap_depth_show, NULL);
+static DEVICE_ATTR_RO(depth);
 
 static ssize_t ap_functions_show(struct device *dev,
                                 struct device_attribute *attr, char *buf)
@@ -58,9 +58,9 @@ static ssize_t ap_functions_show(struct device *dev,
 
 static DEVICE_ATTR_RO(ap_functions);
 
-static ssize_t ap_req_count_show(struct device *dev,
-                                struct device_attribute *attr,
-                                char *buf)
+static ssize_t request_count_show(struct device *dev,
+                                 struct device_attribute *attr,
+                                 char *buf)
 {
        struct ap_card *ac = to_ap_card(dev);
        unsigned int req_cnt;
@@ -72,9 +72,9 @@ static ssize_t ap_req_count_show(struct device *dev,
        return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt);
 }
 
-static ssize_t ap_req_count_store(struct device *dev,
-                                 struct device_attribute *attr,
-                                 const char *buf, size_t count)
+static ssize_t request_count_store(struct device *dev,
+                                  struct device_attribute *attr,
+                                  const char *buf, size_t count)
 {
        struct ap_card *ac = to_ap_card(dev);
        struct ap_queue *aq;
@@ -88,10 +88,10 @@ static ssize_t ap_req_count_store(struct device *dev,
        return count;
 }
 
-static DEVICE_ATTR(request_count, 0644, ap_req_count_show, ap_req_count_store);
+static DEVICE_ATTR_RW(request_count);
 
-static ssize_t ap_requestq_count_show(struct device *dev,
-                                     struct device_attribute *attr, char *buf)
+static ssize_t requestq_count_show(struct device *dev,
+                                  struct device_attribute *attr, char *buf)
 {
        struct ap_card *ac = to_ap_card(dev);
        struct ap_queue *aq;
@@ -105,10 +105,10 @@ static ssize_t ap_requestq_count_show(struct device *dev,
        return snprintf(buf, PAGE_SIZE, "%d\n", reqq_cnt);
 }
 
-static DEVICE_ATTR(requestq_count, 0444, ap_requestq_count_show, NULL);
+static DEVICE_ATTR_RO(requestq_count);
 
-static ssize_t ap_pendingq_count_show(struct device *dev,
-                                     struct device_attribute *attr, char *buf)
+static ssize_t pendingq_count_show(struct device *dev,
+                                  struct device_attribute *attr, char *buf)
 {
        struct ap_card *ac = to_ap_card(dev);
        struct ap_queue *aq;
@@ -122,15 +122,15 @@ static ssize_t ap_pendingq_count_show(struct device *dev,
        return snprintf(buf, PAGE_SIZE, "%d\n", penq_cnt);
 }
 
-static DEVICE_ATTR(pendingq_count, 0444, ap_pendingq_count_show, NULL);
+static DEVICE_ATTR_RO(pendingq_count);
 
-static ssize_t ap_modalias_show(struct device *dev,
-                               struct device_attribute *attr, char *buf)
+static ssize_t modalias_show(struct device *dev,
+                            struct device_attribute *attr, char *buf)
 {
        return sprintf(buf, "ap:t%02X\n", to_ap_dev(dev)->device_type);
 }
 
-static DEVICE_ATTR(modalias, 0444, ap_modalias_show, NULL);
+static DEVICE_ATTR_RO(modalias);
 
 static struct attribute *ap_card_dev_attrs[] = {
        &dev_attr_hwtype.attr,
index e365171fe28f3b927d9fc7efde8abf259b982954..66f7334bcb03214307fb4f3fecebf91dbb3ba341 100644 (file)
@@ -462,9 +462,9 @@ EXPORT_SYMBOL(ap_queue_resume);
 /*
  * AP queue related attributes.
  */
-static ssize_t ap_req_count_show(struct device *dev,
-                                struct device_attribute *attr,
-                                char *buf)
+static ssize_t request_count_show(struct device *dev,
+                                 struct device_attribute *attr,
+                                 char *buf)
 {
        struct ap_queue *aq = to_ap_queue(dev);
        unsigned int req_cnt;
@@ -475,9 +475,9 @@ static ssize_t ap_req_count_show(struct device *dev,
        return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt);
 }
 
-static ssize_t ap_req_count_store(struct device *dev,
-                                 struct device_attribute *attr,
-                                 const char *buf, size_t count)
+static ssize_t request_count_store(struct device *dev,
+                                  struct device_attribute *attr,
+                                  const char *buf, size_t count)
 {
        struct ap_queue *aq = to_ap_queue(dev);
 
@@ -488,10 +488,10 @@ static ssize_t ap_req_count_store(struct device *dev,
        return count;
 }
 
-static DEVICE_ATTR(request_count, 0644, ap_req_count_show, ap_req_count_store);
+static DEVICE_ATTR_RW(request_count);
 
-static ssize_t ap_requestq_count_show(struct device *dev,
-                                     struct device_attribute *attr, char *buf)
+static ssize_t requestq_count_show(struct device *dev,
+                                  struct device_attribute *attr, char *buf)
 {
        struct ap_queue *aq = to_ap_queue(dev);
        unsigned int reqq_cnt = 0;
@@ -502,10 +502,10 @@ static ssize_t ap_requestq_count_show(struct device *dev,
        return snprintf(buf, PAGE_SIZE, "%d\n", reqq_cnt);
 }
 
-static DEVICE_ATTR(requestq_count, 0444, ap_requestq_count_show, NULL);
+static DEVICE_ATTR_RO(requestq_count);
 
-static ssize_t ap_pendingq_count_show(struct device *dev,
-                                     struct device_attribute *attr, char *buf)
+static ssize_t pendingq_count_show(struct device *dev,
+                                  struct device_attribute *attr, char *buf)
 {
        struct ap_queue *aq = to_ap_queue(dev);
        unsigned int penq_cnt = 0;
@@ -516,10 +516,10 @@ static ssize_t ap_pendingq_count_show(struct device *dev,
        return snprintf(buf, PAGE_SIZE, "%d\n", penq_cnt);
 }
 
-static DEVICE_ATTR(pendingq_count, 0444, ap_pendingq_count_show, NULL);
+static DEVICE_ATTR_RO(pendingq_count);
 
-static ssize_t ap_reset_show(struct device *dev,
-                                     struct device_attribute *attr, char *buf)
+static ssize_t reset_show(struct device *dev,
+                         struct device_attribute *attr, char *buf)
 {
        struct ap_queue *aq = to_ap_queue(dev);
        int rc = 0;
@@ -541,10 +541,10 @@ static ssize_t ap_reset_show(struct device *dev,
        return rc;
 }
 
-static DEVICE_ATTR(reset, 0444, ap_reset_show, NULL);
+static DEVICE_ATTR_RO(reset);
 
-static ssize_t ap_interrupt_show(struct device *dev,
-                                struct device_attribute *attr, char *buf)
+static ssize_t interrupt_show(struct device *dev,
+                             struct device_attribute *attr, char *buf)
 {
        struct ap_queue *aq = to_ap_queue(dev);
        int rc = 0;
@@ -560,7 +560,7 @@ static ssize_t ap_interrupt_show(struct device *dev,
        return rc;
 }
 
-static DEVICE_ATTR(interrupt, 0444, ap_interrupt_show, NULL);
+static DEVICE_ATTR_RO(interrupt);
 
 static struct attribute *ap_queue_dev_attrs[] = {
        &dev_attr_request_count.attr,
index e663432395c1da374f47187156d50fb9cdf36f72..1b4001e0285fe0a5979558e2e9e2ce8f60e0808e 100644 (file)
@@ -82,20 +82,20 @@ static int check_secaeskeytoken(const u8 *token, int keybitsize)
 
        if (t->type != 0x01) {
                DEBUG_ERR(
-                       "check_secaeskeytoken secure token check failed, type mismatch 0x%02x != 0x01\n",
-                       (int) t->type);
+                       "%s secure token check failed, type mismatch 0x%02x != 0x01\n",
+                       __func__, (int) t->type);
                return -EINVAL;
        }
        if (t->version != 0x04) {
                DEBUG_ERR(
-                       "check_secaeskeytoken secure token check failed, version mismatch 0x%02x != 0x04\n",
-                       (int) t->version);
+                       "%s secure token check failed, version mismatch 0x%02x != 0x04\n",
+                       __func__, (int) t->version);
                return -EINVAL;
        }
        if (keybitsize > 0 && t->bitsize != keybitsize) {
                DEBUG_ERR(
-                       "check_secaeskeytoken secure token check failed, bitsize mismatch %d != %d\n",
-                       (int) t->bitsize, keybitsize);
+                       "%s secure token check failed, bitsize mismatch %d != %d\n",
+                       __func__, (int) t->bitsize, keybitsize);
                return -EINVAL;
        }
 
@@ -270,8 +270,8 @@ int pkey_genseckey(u16 cardnr, u16 domain,
                break;
        default:
                DEBUG_ERR(
-                       "pkey_genseckey unknown/unsupported keytype %d\n",
-                       keytype);
+                       "%s unknown/unsupported keytype %d\n",
+                       __func__, keytype);
                rc = -EINVAL;
                goto out;
        }
@@ -290,15 +290,16 @@ int pkey_genseckey(u16 cardnr, u16 domain,
        rc = _zcrypt_send_cprb(&xcrb);
        if (rc) {
                DEBUG_ERR(
-                       "pkey_genseckey zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
-                       (int) cardnr, (int) domain, rc);
+                       "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
+                       __func__, (int) cardnr, (int) domain, rc);
                goto out;
        }
 
        /* check response returncode and reasoncode */
        if (prepcblk->ccp_rtcode != 0) {
                DEBUG_ERR(
-                       "pkey_genseckey secure key generate failure, card response %d/%d\n",
+                       "%s secure key generate failure, card response %d/%d\n",
+                       __func__,
                        (int) prepcblk->ccp_rtcode,
                        (int) prepcblk->ccp_rscode);
                rc = -EIO;
@@ -315,8 +316,8 @@ int pkey_genseckey(u16 cardnr, u16 domain,
                - sizeof(prepparm->lv3.keyblock.tokattr);
        if (seckeysize != SECKEYBLOBSIZE) {
                DEBUG_ERR(
-                       "pkey_genseckey secure token size mismatch %d != %d bytes\n",
-                       seckeysize, SECKEYBLOBSIZE);
+                       "%s secure token size mismatch %d != %d bytes\n",
+                       __func__, seckeysize, SECKEYBLOBSIZE);
                rc = -EIO;
                goto out;
        }
@@ -407,8 +408,8 @@ int pkey_clr2seckey(u16 cardnr, u16 domain, u32 keytype,
                break;
        default:
                DEBUG_ERR(
-                       "pkey_clr2seckey unknown/unsupported keytype %d\n",
-                       keytype);
+                       "%s unknown/unsupported keytype %d\n",
+                       __func__, keytype);
                rc = -EINVAL;
                goto out;
        }
@@ -427,15 +428,16 @@ int pkey_clr2seckey(u16 cardnr, u16 domain, u32 keytype,
        rc = _zcrypt_send_cprb(&xcrb);
        if (rc) {
                DEBUG_ERR(
-                       "pkey_clr2seckey zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
-                       (int) cardnr, (int) domain, rc);
+                       "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
+                       __func__, (int) cardnr, (int) domain, rc);
                goto out;
        }
 
        /* check response returncode and reasoncode */
        if (prepcblk->ccp_rtcode != 0) {
                DEBUG_ERR(
-                       "pkey_clr2seckey clear key import failure, card response %d/%d\n",
+                       "%s clear key import failure, card response %d/%d\n",
+                       __func__,
                        (int) prepcblk->ccp_rtcode,
                        (int) prepcblk->ccp_rscode);
                rc = -EIO;
@@ -452,8 +454,8 @@ int pkey_clr2seckey(u16 cardnr, u16 domain, u32 keytype,
                - sizeof(prepparm->lv3.keyblock.tokattr);
        if (seckeysize != SECKEYBLOBSIZE) {
                DEBUG_ERR(
-                       "pkey_clr2seckey secure token size mismatch %d != %d bytes\n",
-                       seckeysize, SECKEYBLOBSIZE);
+                       "%s secure token size mismatch %d != %d bytes\n",
+                       __func__, seckeysize, SECKEYBLOBSIZE);
                rc = -EIO;
                goto out;
        }
@@ -553,15 +555,16 @@ int pkey_sec2protkey(u16 cardnr, u16 domain,
        rc = _zcrypt_send_cprb(&xcrb);
        if (rc) {
                DEBUG_ERR(
-                       "pkey_sec2protkey zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
-                       (int) cardnr, (int) domain, rc);
+                       "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
+                       __func__, (int) cardnr, (int) domain, rc);
                goto out;
        }
 
        /* check response returncode and reasoncode */
        if (prepcblk->ccp_rtcode != 0) {
                DEBUG_ERR(
-                       "pkey_sec2protkey unwrap secure key failure, card response %d/%d\n",
+                       "%s unwrap secure key failure, card response %d/%d\n",
+                       __func__,
                        (int) prepcblk->ccp_rtcode,
                        (int) prepcblk->ccp_rscode);
                rc = -EIO;
@@ -569,7 +572,8 @@ int pkey_sec2protkey(u16 cardnr, u16 domain,
        }
        if (prepcblk->ccp_rscode != 0) {
                DEBUG_WARN(
-                       "pkey_sec2protkey unwrap secure key warning, card response %d/%d\n",
+                       "%s unwrap secure key warning, card response %d/%d\n",
+                       __func__,
                        (int) prepcblk->ccp_rtcode,
                        (int) prepcblk->ccp_rscode);
        }
@@ -581,8 +585,8 @@ int pkey_sec2protkey(u16 cardnr, u16 domain,
        /* check the returned keyblock */
        if (prepparm->lv3.keyblock.version != 0x01) {
                DEBUG_ERR(
-                       "pkey_sec2protkey reply param keyblock version mismatch 0x%02x != 0x01\n",
-                       (int) prepparm->lv3.keyblock.version);
+                       "%s reply param keyblock version mismatch 0x%02x != 0x01\n",
+                       __func__, (int) prepparm->lv3.keyblock.version);
                rc = -EIO;
                goto out;
        }
@@ -599,8 +603,8 @@ int pkey_sec2protkey(u16 cardnr, u16 domain,
                protkey->type = PKEY_KEYTYPE_AES_256;
                break;
        default:
-               DEBUG_ERR("pkey_sec2protkey unknown/unsupported keytype %d\n",
-                         prepparm->lv3.keyblock.keylen);
+               DEBUG_ERR("%s unknown/unsupported keytype %d\n",
+                         __func__, prepparm->lv3.keyblock.keylen);
                rc = -EIO;
                goto out;
        }
@@ -638,8 +642,8 @@ int pkey_clr2protkey(u32 keytype,
                fc = CPACF_PCKMO_ENC_AES_256_KEY;
                break;
        default:
-               DEBUG_ERR("pkey_clr2protkey unknown/unsupported keytype %d\n",
-                         keytype);
+               DEBUG_ERR("%s unknown/unsupported keytype %d\n",
+                         __func__, keytype);
                return -EINVAL;
        }
 
@@ -713,15 +717,16 @@ static int query_crypto_facility(u16 cardnr, u16 domain,
        rc = _zcrypt_send_cprb(&xcrb);
        if (rc) {
                DEBUG_ERR(
-                       "query_crypto_facility zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
-                       (int) cardnr, (int) domain, rc);
+                       "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n",
+                       __func__, (int) cardnr, (int) domain, rc);
                goto out;
        }
 
        /* check response returncode and reasoncode */
        if (prepcblk->ccp_rtcode != 0) {
                DEBUG_ERR(
-                       "query_crypto_facility unwrap secure key failure, card response %d/%d\n",
+                       "%s unwrap secure key failure, card response %d/%d\n",
+                       __func__,
                        (int) prepcblk->ccp_rtcode,
                        (int) prepcblk->ccp_rscode);
                rc = -EIO;
@@ -993,7 +998,7 @@ int pkey_skey2pkey(const struct pkey_seckey *seckey,
        }
 
        if (rc)
-               DEBUG_DBG("pkey_skey2pkey failed rc=%d\n", rc);
+               DEBUG_DBG("%s failed rc=%d\n", __func__, rc);
 
        return rc;
 }
@@ -1030,7 +1035,7 @@ int pkey_verifykey(const struct pkey_seckey *seckey,
        if (rc)
                goto out;
        if (t->mkvp == mkvp[1]) {
-               DEBUG_DBG("pkey_verifykey secure key has old mkvp\n");
+               DEBUG_DBG("%s secure key has old mkvp\n", __func__);
                if (pattributes)
                        *pattributes |= PKEY_VERIFY_ATTR_OLD_MKVP;
        }
@@ -1041,7 +1046,7 @@ int pkey_verifykey(const struct pkey_seckey *seckey,
                *pdomain = domain;
 
 out:
-       DEBUG_DBG("pkey_verifykey rc=%d\n", rc);
+       DEBUG_DBG("%s rc=%d\n", __func__, rc);
        return rc;
 }
 EXPORT_SYMBOL(pkey_verifykey);
@@ -1064,7 +1069,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
                        return -EFAULT;
                rc = pkey_genseckey(kgs.cardnr, kgs.domain,
                                    kgs.keytype, &kgs.seckey);
-               DEBUG_DBG("pkey_ioctl pkey_genseckey()=%d\n", rc);
+               DEBUG_DBG("%s pkey_genseckey()=%d\n", __func__, rc);
                if (rc)
                        break;
                if (copy_to_user(ugs, &kgs, sizeof(kgs)))
@@ -1079,7 +1084,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
                        return -EFAULT;
                rc = pkey_clr2seckey(kcs.cardnr, kcs.domain, kcs.keytype,
                                     &kcs.clrkey, &kcs.seckey);
-               DEBUG_DBG("pkey_ioctl pkey_clr2seckey()=%d\n", rc);
+               DEBUG_DBG("%s pkey_clr2seckey()=%d\n", __func__, rc);
                if (rc)
                        break;
                if (copy_to_user(ucs, &kcs, sizeof(kcs)))
@@ -1095,7 +1100,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
                        return -EFAULT;
                rc = pkey_sec2protkey(ksp.cardnr, ksp.domain,
                                      &ksp.seckey, &ksp.protkey);
-               DEBUG_DBG("pkey_ioctl pkey_sec2protkey()=%d\n", rc);
+               DEBUG_DBG("%s pkey_sec2protkey()=%d\n", __func__, rc);
                if (rc)
                        break;
                if (copy_to_user(usp, &ksp, sizeof(ksp)))
@@ -1110,7 +1115,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
                        return -EFAULT;
                rc = pkey_clr2protkey(kcp.keytype,
                                      &kcp.clrkey, &kcp.protkey);
-               DEBUG_DBG("pkey_ioctl pkey_clr2protkey()=%d\n", rc);
+               DEBUG_DBG("%s pkey_clr2protkey()=%d\n", __func__, rc);
                if (rc)
                        break;
                if (copy_to_user(ucp, &kcp, sizeof(kcp)))
@@ -1126,7 +1131,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
                        return -EFAULT;
                rc = pkey_findcard(&kfc.seckey,
                                   &kfc.cardnr, &kfc.domain, 1);
-               DEBUG_DBG("pkey_ioctl pkey_findcard()=%d\n", rc);
+               DEBUG_DBG("%s pkey_findcard()=%d\n", __func__, rc);
                if (rc)
                        break;
                if (copy_to_user(ufc, &kfc, sizeof(kfc)))
@@ -1140,7 +1145,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
                if (copy_from_user(&ksp, usp, sizeof(ksp)))
                        return -EFAULT;
                rc = pkey_skey2pkey(&ksp.seckey, &ksp.protkey);
-               DEBUG_DBG("pkey_ioctl pkey_skey2pkey()=%d\n", rc);
+               DEBUG_DBG("%s pkey_skey2pkey()=%d\n", __func__, rc);
                if (rc)
                        break;
                if (copy_to_user(usp, &ksp, sizeof(ksp)))
@@ -1155,7 +1160,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
                        return -EFAULT;
                rc = pkey_verifykey(&kvk.seckey, &kvk.cardnr, &kvk.domain,
                                    &kvk.keysize, &kvk.attributes);
-               DEBUG_DBG("pkey_ioctl pkey_verifykey()=%d\n", rc);
+               DEBUG_DBG("%s pkey_verifykey()=%d\n", __func__, rc);
                if (rc)
                        break;
                if (copy_to_user(uvk, &kvk, sizeof(kvk)))
index febcdb5135bfd518475cb1fea82517727ab0d99e..e6854127b4343dc5ee73357472b4c97f7f8a377e 100644 (file)
@@ -50,7 +50,7 @@ EXPORT_TRACEPOINT_SYMBOL(s390_zcrypt_req);
 EXPORT_TRACEPOINT_SYMBOL(s390_zcrypt_rep);
 
 static int zcrypt_hwrng_seed = 1;
-module_param_named(hwrng_seed, zcrypt_hwrng_seed, int, S_IRUSR|S_IRGRP);
+module_param_named(hwrng_seed, zcrypt_hwrng_seed, int, 0440);
 MODULE_PARM_DESC(hwrng_seed, "Turn on/off hwrng auto seed, default is 1 (on).");
 
 DEFINE_SPINLOCK(zcrypt_list_lock);
@@ -182,7 +182,8 @@ static inline void zcrypt_drop_queue(struct zcrypt_card *zc,
 
 static inline bool zcrypt_card_compare(struct zcrypt_card *zc,
                                       struct zcrypt_card *pref_zc,
-                                      unsigned weight, unsigned pref_weight)
+                                      unsigned int weight,
+                                      unsigned int pref_weight)
 {
        if (!pref_zc)
                return false;
@@ -196,7 +197,8 @@ static inline bool zcrypt_card_compare(struct zcrypt_card *zc,
 
 static inline bool zcrypt_queue_compare(struct zcrypt_queue *zq,
                                        struct zcrypt_queue *pref_zq,
-                                       unsigned weight, unsigned pref_weight)
+                                       unsigned int weight,
+                                       unsigned int pref_weight)
 {
        if (!pref_zq)
                return false;
@@ -792,6 +794,7 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
        case ICARSAMODEXPO: {
                struct ica_rsa_modexpo __user *umex = (void __user *) arg;
                struct ica_rsa_modexpo mex;
+
                if (copy_from_user(&mex, umex, sizeof(mex)))
                        return -EFAULT;
                do {
@@ -811,6 +814,7 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
        case ICARSACRT: {
                struct ica_rsa_modexpo_crt __user *ucrt = (void __user *) arg;
                struct ica_rsa_modexpo_crt crt;
+
                if (copy_from_user(&crt, ucrt, sizeof(crt)))
                        return -EFAULT;
                do {
@@ -830,6 +834,7 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
        case ZSECSENDCPRB: {
                struct ica_xcRB __user *uxcRB = (void __user *) arg;
                struct ica_xcRB xcRB;
+
                if (copy_from_user(&xcRB, uxcRB, sizeof(xcRB)))
                        return -EFAULT;
                do {
@@ -849,6 +854,7 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
        case ZSENDEP11CPRB: {
                struct ep11_urb __user *uxcrb = (void __user *)arg;
                struct ep11_urb xcrb;
+
                if (copy_from_user(&xcrb, uxcrb, sizeof(xcrb)))
                        return -EFAULT;
                do {
@@ -1037,7 +1043,7 @@ static long trans_modexpo_crt32(struct file *filp, unsigned int cmd,
                return -EFAULT;
        crt64.inputdata = compat_ptr(crt32.inputdata);
        crt64.inputdatalength = crt32.inputdatalength;
-       crt64.outputdata compat_ptr(crt32.outputdata);
+       crt64.outputdata = compat_ptr(crt32.outputdata);
        crt64.outputdatalength = crt32.outputdatalength;
        crt64.bp_key = compat_ptr(crt32.bp_key);
        crt64.bq_key = compat_ptr(crt32.bq_key);
@@ -1063,20 +1069,20 @@ struct compat_ica_xcRB {
        unsigned int    user_defined;
        unsigned short  request_ID;
        unsigned int    request_control_blk_length;
-       unsigned char   padding1[16 - sizeof (compat_uptr_t)];
+       unsigned char   padding1[16 - sizeof(compat_uptr_t)];
        compat_uptr_t   request_control_blk_addr;
        unsigned int    request_data_length;
-       char            padding2[16 - sizeof (compat_uptr_t)];
+       char            padding2[16 - sizeof(compat_uptr_t)];
        compat_uptr_t   request_data_address;
        unsigned int    reply_control_blk_length;
-       char            padding3[16 - sizeof (compat_uptr_t)];
+       char            padding3[16 - sizeof(compat_uptr_t)];
        compat_uptr_t   reply_control_blk_addr;
        unsigned int    reply_data_length;
-       char            padding4[16 - sizeof (compat_uptr_t)];
+       char            padding4[16 - sizeof(compat_uptr_t)];
        compat_uptr_t   reply_data_addr;
        unsigned short  priority_window;
        unsigned int    status;
-} __attribute__((packed));
+} __packed;
 
 static long trans_xcRB32(struct file *filp, unsigned int cmd,
                         unsigned long arg)
@@ -1120,7 +1126,7 @@ static long trans_xcRB32(struct file *filp, unsigned int cmd,
        xcRB32.reply_data_length = xcRB64.reply_data_length;
        xcRB32.status = xcRB64.status;
        if (copy_to_user(uxcRB32, &xcRB32, sizeof(xcRB32)))
-                       return -EFAULT;
+               return -EFAULT;
        return rc;
 }
 
@@ -1182,10 +1188,10 @@ static int zcrypt_rng_data_read(struct hwrng *rng, u32 *data)
                        rc = zcrypt_rng((char *) zcrypt_rng_buffer);
                if (rc < 0)
                        return -EIO;
-               zcrypt_rng_buffer_index = rc / sizeof *data;
+               zcrypt_rng_buffer_index = rc / sizeof(*data);
        }
        *data = zcrypt_rng_buffer[--zcrypt_rng_buffer_index];
-       return sizeof *data;
+       return sizeof(*data);
 }
 
 static struct hwrng zcrypt_rng_dev = {
index f149a8fee60dfac7166e5266020078d236118159..a848625c1a5a370ff8d175555b1e499c2f1448f1 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  *  zcrypt 2.1.0
  *
index da2c8dfd4d741edc6c8b380e850667f79a44440f..40cd4c1c2de8db67267f664fd798dadbf740d2f3 100644 (file)
  * Device attributes common for all crypto card devices.
  */
 
-static ssize_t zcrypt_card_type_show(struct device *dev,
-                                    struct device_attribute *attr, char *buf)
+static ssize_t type_show(struct device *dev,
+                        struct device_attribute *attr, char *buf)
 {
        struct zcrypt_card *zc = to_ap_card(dev)->private;
 
        return snprintf(buf, PAGE_SIZE, "%s\n", zc->type_string);
 }
 
-static DEVICE_ATTR(type, 0444, zcrypt_card_type_show, NULL);
+static DEVICE_ATTR_RO(type);
 
-static ssize_t zcrypt_card_online_show(struct device *dev,
-                                      struct device_attribute *attr,
-                                      char *buf)
+static ssize_t online_show(struct device *dev,
+                          struct device_attribute *attr,
+                          char *buf)
 {
        struct zcrypt_card *zc = to_ap_card(dev)->private;
 
        return snprintf(buf, PAGE_SIZE, "%d\n", zc->online);
 }
 
-static ssize_t zcrypt_card_online_store(struct device *dev,
-                                       struct device_attribute *attr,
-                                       const char *buf, size_t count)
+static ssize_t online_store(struct device *dev,
+                           struct device_attribute *attr,
+                           const char *buf, size_t count)
 {
        struct zcrypt_card *zc = to_ap_card(dev)->private;
        struct zcrypt_queue *zq;
@@ -80,19 +80,18 @@ static ssize_t zcrypt_card_online_store(struct device *dev,
        return count;
 }
 
-static DEVICE_ATTR(online, 0644, zcrypt_card_online_show,
-                  zcrypt_card_online_store);
+static DEVICE_ATTR_RW(online);
 
-static ssize_t zcrypt_card_load_show(struct device *dev,
-                                    struct device_attribute *attr,
-                                    char *buf)
+static ssize_t load_show(struct device *dev,
+                        struct device_attribute *attr,
+                        char *buf)
 {
        struct zcrypt_card *zc = to_ap_card(dev)->private;
 
        return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&zc->load));
 }
 
-static DEVICE_ATTR(load, 0444, zcrypt_card_load_show, NULL);
+static DEVICE_ATTR_RO(load);
 
 static struct attribute *zcrypt_card_attrs[] = {
        &dev_attr_type.attr,
index 1752622b95f701eca7f1f3604251929983117d60..e5b5c02c9d67819a66b73d87b9857641cdec24f1 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  *  zcrypt 2.1.0
  *
@@ -31,7 +31,7 @@ struct cca_token_hdr {
        unsigned char  version;
        unsigned short token_length;
        unsigned char  reserved[4];
-} __attribute__((packed));
+} __packed;
 
 #define CCA_TKN_HDR_ID_EXT 0x1E
 
@@ -51,7 +51,7 @@ struct cca_public_sec {
        unsigned short exponent_len;
        unsigned short modulus_bit_len;
        unsigned short modulus_byte_len;    /* In a private key, this is 0 */
-} __attribute__((packed));
+} __packed;
 
 /**
  * mapping for the cca private CRT key 'token'
@@ -85,7 +85,7 @@ struct cca_pvt_ext_CRT_sec {
        unsigned short pad_len;
        unsigned char  reserved4[52];
        unsigned char  confounder[8];
-} __attribute__((packed));
+} __packed;
 
 #define CCA_PVT_EXT_CRT_SEC_ID_PVT 0x08
 #define CCA_PVT_EXT_CRT_SEC_FMT_CL 0x40
@@ -114,7 +114,7 @@ static inline int zcrypt_type6_mex_key_en(struct ica_rsa_modexpo *mex, void *p)
                struct cca_token_hdr pubHdr;
                struct cca_public_sec pubSec;
                char exponent[0];
-       } __attribute__((packed)) *key = p;
+       } __packed *key = p;
        unsigned char *temp;
        int i;
 
@@ -183,7 +183,7 @@ static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt *crt, void *p)
                struct cca_token_hdr token;
                struct cca_pvt_ext_CRT_sec pvt;
                char key_parts[0];
-       } __attribute__((packed)) *key = p;
+       } __packed *key = p;
        struct cca_public_sec *pub;
        int short_len, long_len, pad_len, key_len, size;
 
index e701194d36115c06d4435df2b1dcc4dbc9cc103e..f4ae5fa30ec970e99a39387b2b0a7a4b13903889 100644 (file)
@@ -145,6 +145,7 @@ static struct ap_driver zcrypt_cex2a_card_driver = {
        .probe = zcrypt_cex2a_card_probe,
        .remove = zcrypt_cex2a_card_remove,
        .ids = zcrypt_cex2a_card_ids,
+       .flags = AP_DRIVER_FLAG_DEFAULT,
 };
 
 /**
@@ -208,6 +209,7 @@ static struct ap_driver zcrypt_cex2a_queue_driver = {
        .suspend = ap_queue_suspend,
        .resume = ap_queue_resume,
        .ids = zcrypt_cex2a_queue_ids,
+       .flags = AP_DRIVER_FLAG_DEFAULT,
 };
 
 int __init zcrypt_cex2a_init(void)
index c3c116777c937cd4fafbe974f765cd5725327f27..66d58bc87c6646c79f32871cb70d2908919d691c 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  *  zcrypt 2.1.0
  *
@@ -30,7 +30,7 @@ struct type50_hdr {
        unsigned char   reserved2;
        unsigned char   ignored;
        unsigned short  reserved3;
-} __attribute__((packed));
+} __packed;
 
 #define TYPE50_TYPE_CODE       0x50
 
@@ -49,7 +49,7 @@ struct type50_meb1_msg {
        unsigned char   exponent[128];
        unsigned char   modulus[128];
        unsigned char   message[128];
-} __attribute__((packed));
+} __packed;
 
 /* Mod-Exp, with a large modulus */
 struct type50_meb2_msg {
@@ -59,7 +59,7 @@ struct type50_meb2_msg {
        unsigned char   exponent[256];
        unsigned char   modulus[256];
        unsigned char   message[256];
-} __attribute__((packed));
+} __packed;
 
 /* Mod-Exp, with a larger modulus */
 struct type50_meb3_msg {
@@ -69,7 +69,7 @@ struct type50_meb3_msg {
        unsigned char   exponent[512];
        unsigned char   modulus[512];
        unsigned char   message[512];
-} __attribute__((packed));
+} __packed;
 
 /* CRT, with a small modulus */
 struct type50_crb1_msg {
@@ -82,7 +82,7 @@ struct type50_crb1_msg {
        unsigned char   dq[64];
        unsigned char   u[64];
        unsigned char   message[128];
-} __attribute__((packed));
+} __packed;
 
 /* CRT, with a large modulus */
 struct type50_crb2_msg {
@@ -95,7 +95,7 @@ struct type50_crb2_msg {
        unsigned char   dq[128];
        unsigned char   u[128];
        unsigned char   message[256];
-} __attribute__((packed));
+} __packed;
 
 /* CRT, with a larger modulus */
 struct type50_crb3_msg {
@@ -108,7 +108,7 @@ struct type50_crb3_msg {
        unsigned char   dq[256];
        unsigned char   u[256];
        unsigned char   message[512];
-} __attribute__((packed));
+} __packed;
 
 /**
  * The type 80 response family is associated with a CEX2A card.
@@ -128,7 +128,7 @@ struct type80_hdr {
        unsigned char   code;           /* 0x00 */
        unsigned char   reserved2[3];
        unsigned char   reserved3[8];
-} __attribute__((packed));
+} __packed;
 
 int zcrypt_cex2a_init(void);
 void zcrypt_cex2a_exit(void);
index f305538334adb14f0dd296fd2466cb478a2ba3ba..35d58dbbc4da3dcc5fa47f5d23a8dfcbe08ff9ae 100644 (file)
@@ -214,6 +214,7 @@ static struct ap_driver zcrypt_cex4_card_driver = {
        .probe = zcrypt_cex4_card_probe,
        .remove = zcrypt_cex4_card_remove,
        .ids = zcrypt_cex4_card_ids,
+       .flags = AP_DRIVER_FLAG_DEFAULT,
 };
 
 /**
@@ -283,6 +284,7 @@ static struct ap_driver zcrypt_cex4_queue_driver = {
        .suspend = ap_queue_suspend,
        .resume = ap_queue_resume,
        .ids = zcrypt_cex4_queue_ids,
+       .flags = AP_DRIVER_FLAG_DEFAULT,
 };
 
 int __init zcrypt_cex4_init(void)
index 01598d83c60a0a1c478c1ade86ea603feb05eab0..6f7ebc1dbe1033af41b51150295fedc663e8be13 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  *  zcrypt 2.1.0
  *
index afe1b2bcd7ecf5e211712b567ca186f3a32e4a57..f159662c907b240333fb60bb7b0ba22d5d883820 100644 (file)
 #include "zcrypt_error.h"
 #include "zcrypt_msgtype50.h"
 
-#define CEX3A_MAX_MOD_SIZE     512     /* 4096 bits    */
+/* 4096 bits */
+#define CEX3A_MAX_MOD_SIZE 512
 
-#define CEX2A_MAX_RESPONSE_SIZE 0x110  /* max outputdatalength + type80_hdr */
+/* max outputdatalength + type80_hdr */
+#define CEX2A_MAX_RESPONSE_SIZE 0x110
 
-#define CEX3A_MAX_RESPONSE_SIZE        0x210   /* 512 bit modulus
-                                        * (max outputdatalength) +
-                                        * type80_hdr*/
+/* 512 bit modulus, (max outputdatalength) + type80_hdr */
+#define CEX3A_MAX_RESPONSE_SIZE 0x210
 
 MODULE_AUTHOR("IBM Corporation");
 MODULE_DESCRIPTION("Cryptographic Accelerator (message type 50), " \
@@ -209,6 +210,7 @@ static int ICAMEX_msg_to_type50MEX_msg(struct zcrypt_queue *zq,
 
        if (mod_len <= 128) {
                struct type50_meb1_msg *meb1 = ap_msg->message;
+
                memset(meb1, 0, sizeof(*meb1));
                ap_msg->length = sizeof(*meb1);
                meb1->header.msg_type_code = TYPE50_TYPE_CODE;
@@ -219,6 +221,7 @@ static int ICAMEX_msg_to_type50MEX_msg(struct zcrypt_queue *zq,
                inp = meb1->message + sizeof(meb1->message) - mod_len;
        } else if (mod_len <= 256) {
                struct type50_meb2_msg *meb2 = ap_msg->message;
+
                memset(meb2, 0, sizeof(*meb2));
                ap_msg->length = sizeof(*meb2);
                meb2->header.msg_type_code = TYPE50_TYPE_CODE;
@@ -229,6 +232,7 @@ static int ICAMEX_msg_to_type50MEX_msg(struct zcrypt_queue *zq,
                inp = meb2->message + sizeof(meb2->message) - mod_len;
        } else if (mod_len <= 512) {
                struct type50_meb3_msg *meb3 = ap_msg->message;
+
                memset(meb3, 0, sizeof(*meb3));
                ap_msg->length = sizeof(*meb3);
                meb3->header.msg_type_code = TYPE50_TYPE_CODE;
@@ -274,6 +278,7 @@ static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_queue *zq,
         */
        if (mod_len <= 128) {           /* up to 1024 bit key size */
                struct type50_crb1_msg *crb1 = ap_msg->message;
+
                memset(crb1, 0, sizeof(*crb1));
                ap_msg->length = sizeof(*crb1);
                crb1->header.msg_type_code = TYPE50_TYPE_CODE;
@@ -287,6 +292,7 @@ static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_queue *zq,
                inp = crb1->message + sizeof(crb1->message) - mod_len;
        } else if (mod_len <= 256) {    /* up to 2048 bit key size */
                struct type50_crb2_msg *crb2 = ap_msg->message;
+
                memset(crb2, 0, sizeof(*crb2));
                ap_msg->length = sizeof(*crb2);
                crb2->header.msg_type_code = TYPE50_TYPE_CODE;
@@ -301,6 +307,7 @@ static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_queue *zq,
        } else if ((mod_len <= 512) &&  /* up to 4096 bit key size */
                   (zq->zcard->max_mod_size == CEX3A_MAX_MOD_SIZE)) {
                struct type50_crb3_msg *crb3 = ap_msg->message;
+
                memset(crb3, 0, sizeof(*crb3));
                ap_msg->length = sizeof(*crb3);
                crb3->header.msg_type_code = TYPE50_TYPE_CODE;
index 0a36545cfb8eeb09da1f2136ba31adde5b54775d..8530f652ea4f90e165a8112b01840d9d7bb3962d 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  *  zcrypt 2.1.0
  *
 #define MSGTYPE50_NAME                 "zcrypt_msgtype50"
 #define MSGTYPE50_VARIANT_DEFAULT      0
 
-#define MSGTYPE50_CRB2_MAX_MSG_SIZE    0x390 /*sizeof(struct type50_crb2_msg)*/
-#define MSGTYPE50_CRB3_MAX_MSG_SIZE    0x710 /*sizeof(struct type50_crb3_msg)*/
+#define MSGTYPE50_CRB2_MAX_MSG_SIZE 0x390 /* sizeof(struct type50_crb2_msg) */
+#define MSGTYPE50_CRB3_MAX_MSG_SIZE 0x710 /* sizeof(struct type50_crb3_msg) */
 
-#define MSGTYPE_ADJUSTMENT             0x08  /*type04 extension (not needed in type50)*/
+#define MSGTYPE_ADJUSTMENT 0x08  /* type04 extension (not needed in type50) */
 
 unsigned int get_rsa_modex_fc(struct ica_rsa_modexpo *, int *);
 unsigned int get_rsa_crt_fc(struct ica_rsa_modexpo_crt *, int *);
index e70ae078c86b8542fa5d3c2799583bf8b55775f7..2101776a81485d5acfec1f62ee7278fdfb433da5 100644 (file)
@@ -421,8 +421,10 @@ static int XCRB_msg_to_type6CPRB_msgX(struct ap_message *ap_msg,
        if (ap_msg->length > MSGTYPE06_MAX_MSG_SIZE)
                return -EINVAL;
 
-       /* Overflow check
-          sum must be greater (or equal) than the largest operand */
+       /*
+        * Overflow check
+        * sum must be greater (or equal) than the largest operand
+        */
        req_sumlen = CEIL4(xcRB->request_control_blk_length) +
                        xcRB->request_data_length;
        if ((CEIL4(xcRB->request_control_blk_length) <=
@@ -442,8 +444,10 @@ static int XCRB_msg_to_type6CPRB_msgX(struct ap_message *ap_msg,
        if (replylen > MSGTYPE06_MAX_MSG_SIZE)
                return -EINVAL;
 
-       /* Overflow check
-          sum must be greater (or equal) than the largest operand */
+       /*
+        * Overflow check
+        * sum must be greater (or equal) than the largest operand
+        */
        resp_sumlen = CEIL4(xcRB->reply_control_blk_length) +
                        xcRB->reply_data_length;
        if ((CEIL4(xcRB->reply_control_blk_length) <= xcRB->reply_data_length) ?
@@ -454,7 +458,7 @@ static int XCRB_msg_to_type6CPRB_msgX(struct ap_message *ap_msg,
 
        /* prepare type6 header */
        msg->hdr = static_type6_hdrX;
-       memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID));
+       memcpy(msg->hdr.agent_id, &(xcRB->agent_ID), sizeof(xcRB->agent_ID));
        msg->hdr.ToCardLen1 = xcRB->request_control_blk_length;
        if (xcRB->request_data_length) {
                msg->hdr.offset2 = msg->hdr.offset1 + rcblen;
@@ -806,8 +810,10 @@ static int convert_response_ica(struct zcrypt_queue *zq,
                if (msg->cprbx.cprb_ver_id == 0x02)
                        return convert_type86_ica(zq, reply,
                                                  outputdata, outputdatalength);
-               /* Fall through, no break, incorrect cprb version is an unknown
-                * response */
+               /*
+                * Fall through, no break, incorrect cprb version is an unknown
+                * response
+                */
        default: /* Unknown response type, this should NEVER EVER happen */
                zq->online = 0;
                pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
@@ -840,8 +846,10 @@ static int convert_response_xcrb(struct zcrypt_queue *zq,
                }
                if (msg->cprbx.cprb_ver_id == 0x02)
                        return convert_type86_xcrb(zq, reply, xcRB);
-               /* Fall through, no break, incorrect cprb version is an unknown
-                * response */
+               /*
+                * Fall through, no break, incorrect cprb version is an unknown
+                * response
+                */
        default: /* Unknown response type, this should NEVER EVER happen */
                xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
                zq->online = 0;
@@ -901,8 +909,10 @@ static int convert_response_rng(struct zcrypt_queue *zq,
                        return -EINVAL;
                if (msg->cprbx.cprb_ver_id == 0x02)
                        return convert_type86_rng(zq, reply, data);
-               /* Fall through, no break, incorrect cprb version is an unknown
-                * response */
+               /*
+                * Fall through, no break, incorrect cprb version is an unknown
+                * response
+                */
        default: /* Unknown response type, this should NEVER EVER happen */
                zq->online = 0;
                pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
@@ -1004,7 +1014,7 @@ static void zcrypt_msgtype6_receive_ep11(struct ap_queue *aq,
                }
        } else {
                memcpy(msg->message, reply->message, sizeof(error_reply));
-         }
+       }
 out:
        complete(&(resp_type->work));
 }
index d314f4525518b63693d70df42e768a8dc9e8af33..e4c2f37d7ad9bf908cbec2324f20f40d23ef406f 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  *  zcrypt 2.1.0
  *
index 159b0a0dd211b9a561cad4d326c5d481b1a8418d..94d9f7224aea3acbb394c424a88ed2e6ba867c04 100644 (file)
@@ -95,7 +95,7 @@ static int zcrypt_pcixcc_rng_supported(struct ap_queue *aq)
                struct type86_hdr hdr;
                struct type86_fmt2_ext fmt2;
                struct CPRBX cprbx;
-       } __attribute__((packed)) *reply;
+       } __packed *reply;
        struct {
                struct type6_hdr hdr;
                struct CPRBX cprbx;
@@ -104,7 +104,7 @@ static int zcrypt_pcixcc_rng_supported(struct ap_queue *aq)
                char rule[8];
                short int verb_length;
                short int key_length;
-       } __packed * msg;
+       } __packed *msg;
        int rc, i;
 
        ap_init_message(&ap_msg);
@@ -223,6 +223,7 @@ static struct ap_driver zcrypt_pcixcc_card_driver = {
        .probe = zcrypt_pcixcc_card_probe,
        .remove = zcrypt_pcixcc_card_remove,
        .ids = zcrypt_pcixcc_card_ids,
+       .flags = AP_DRIVER_FLAG_DEFAULT,
 };
 
 /**
@@ -286,6 +287,7 @@ static struct ap_driver zcrypt_pcixcc_queue_driver = {
        .suspend = ap_queue_suspend,
        .resume = ap_queue_resume,
        .ids = zcrypt_pcixcc_queue_ids,
+       .flags = AP_DRIVER_FLAG_DEFAULT,
 };
 
 int __init zcrypt_pcixcc_init(void)
index d678a3af83a7baa9dda7b1dfdcba632014b975a1..cf73a0f91e9c6782cc445463afc6cd85b3e10cc9 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  *  zcrypt 2.1.0
  *
index 91a52f26835307f3b04c54a8bb9544fe694495a2..8df82c6ef66edeccb60099f0421b7bfdfba37c85 100644 (file)
  * Device attributes common for all crypto queue devices.
  */
 
-static ssize_t zcrypt_queue_online_show(struct device *dev,
-                                       struct device_attribute *attr,
-                                       char *buf)
+static ssize_t online_show(struct device *dev,
+                          struct device_attribute *attr,
+                          char *buf)
 {
        struct zcrypt_queue *zq = to_ap_queue(dev)->private;
 
        return snprintf(buf, PAGE_SIZE, "%d\n", zq->online);
 }
 
-static ssize_t zcrypt_queue_online_store(struct device *dev,
-                                        struct device_attribute *attr,
-                                        const char *buf, size_t count)
+static ssize_t online_store(struct device *dev,
+                           struct device_attribute *attr,
+                           const char *buf, size_t count)
 {
        struct zcrypt_queue *zq = to_ap_queue(dev)->private;
        struct zcrypt_card *zc = zq->zcard;
@@ -72,19 +72,18 @@ static ssize_t zcrypt_queue_online_store(struct device *dev,
        return count;
 }
 
-static DEVICE_ATTR(online, 0644, zcrypt_queue_online_show,
-                  zcrypt_queue_online_store);
+static DEVICE_ATTR_RW(online);
 
-static ssize_t zcrypt_queue_load_show(struct device *dev,
-                                     struct device_attribute *attr,
-                                     char *buf)
+static ssize_t load_show(struct device *dev,
+                        struct device_attribute *attr,
+                        char *buf)
 {
        struct zcrypt_queue *zq = to_ap_queue(dev)->private;
 
        return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&zq->load));
 }
 
-static DEVICE_ATTR(load, 0444, zcrypt_queue_load_show, NULL);
+static DEVICE_ATTR_RO(load);
 
 static struct attribute *zcrypt_queue_attrs[] = {
        &dev_attr_online.attr,
index 8fc851a9e1162a5695c1a344445b3fad7685f4dc..7c097006c54db679c40ebd51ca5efcc8d8dc297d 100644 (file)
@@ -52,12 +52,12 @@ config SCSI_MQ_DEFAULT
        default y
        depends on SCSI
        ---help---
-         This option enables the new blk-mq based I/O path for SCSI
-         devices by default.  With the option the scsi_mod.use_blk_mq
-         module/boot option defaults to Y, without it to N, but it can
-         still be overridden either way.
+         This option enables the blk-mq based I/O path for SCSI devices by
+         default.  With this option the scsi_mod.use_blk_mq module/boot
+         option defaults to Y, without it to N, but it can still be
+         overridden either way.
 
-         If unsure say N.
+         If unsure say Y.
 
 config SCSI_PROC_FS
        bool "legacy /proc/scsi/ support"
index 29bf1e60f5428ab4542cf0bd838342bd8d405f8b..39eb415987fc9fd901ba9ee157dedfcf76910829 100644 (file)
@@ -1346,7 +1346,7 @@ struct fib {
 struct aac_hba_map_info {
        __le32  rmw_nexus;              /* nexus for native HBA devices */
        u8              devtype;        /* device type */
-       u8              reset_state;    /* 0 - no reset, 1..x - */
+       s8              reset_state;    /* 0 - no reset, 1..x - */
                                        /* after xth TM LUN reset */
        u16             qd_limit;
        u32             scan_counter;
index 23d07e9f87d0d1e0357547c4f168ab966a0a809e..e5192388647580903b45f885c7995a5b8bbe4bbb 100644 (file)
@@ -1601,6 +1601,46 @@ fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16)
        return caps32;
 }
 
+/**
+ *     fwcaps32_to_caps16 - convert 32-bit Port Capabilities to 16-bits
+ *     @caps32: a 32-bit Port Capabilities value
+ *
+ *     Returns the equivalent 16-bit Port Capabilities value.  Note that
+ *     not all 32-bit Port Capabilities can be represented in the 16-bit
+ *     Port Capabilities and some fields/values may not make it.
+ */
+fw_port_cap16_t fwcaps32_to_caps16(fw_port_cap32_t caps32)
+{
+       fw_port_cap16_t caps16 = 0;
+
+       #define CAP32_TO_CAP16(__cap) \
+               do { \
+                       if (caps32 & FW_PORT_CAP32_##__cap) \
+                               caps16 |= FW_PORT_CAP_##__cap; \
+               } while (0)
+
+       CAP32_TO_CAP16(SPEED_100M);
+       CAP32_TO_CAP16(SPEED_1G);
+       CAP32_TO_CAP16(SPEED_10G);
+       CAP32_TO_CAP16(SPEED_25G);
+       CAP32_TO_CAP16(SPEED_40G);
+       CAP32_TO_CAP16(SPEED_100G);
+       CAP32_TO_CAP16(FC_RX);
+       CAP32_TO_CAP16(FC_TX);
+       CAP32_TO_CAP16(802_3_PAUSE);
+       CAP32_TO_CAP16(802_3_ASM_DIR);
+       CAP32_TO_CAP16(ANEG);
+       CAP32_TO_CAP16(FORCE_PAUSE);
+       CAP32_TO_CAP16(MDIAUTO);
+       CAP32_TO_CAP16(MDISTRAIGHT);
+       CAP32_TO_CAP16(FEC_RS);
+       CAP32_TO_CAP16(FEC_BASER_RS);
+
+       #undef CAP32_TO_CAP16
+
+       return caps16;
+}
+
 /**
  *      lstatus_to_fwcap - translate old lstatus to 32-bit Port Capabilities
  *      @lstatus: old FW_PORT_ACTION_GET_PORT_INFO lstatus value
@@ -1759,7 +1799,7 @@ csio_enable_ports(struct csio_hw *hw)
                        val = 1;
 
                        csio_mb_params(hw, mbp, CSIO_MB_DEFAULT_TMO,
-                                      hw->pfn, 0, 1, &param, &val, false,
+                                      hw->pfn, 0, 1, &param, &val, true,
                                       NULL);
 
                        if (csio_mb_issue(hw, mbp)) {
@@ -1769,16 +1809,9 @@ csio_enable_ports(struct csio_hw *hw)
                                return -EINVAL;
                        }
 
-                       csio_mb_process_read_params_rsp(hw, mbp, &retval, 1,
-                                                       &val);
-                       if (retval != FW_SUCCESS) {
-                               csio_err(hw, "FW_PARAMS_CMD(r) port:%d failed: 0x%x\n",
-                                        portid, retval);
-                               mempool_free(mbp, hw->mb_mempool);
-                               return -EINVAL;
-                       }
-
-                       fw_caps = val;
+                       csio_mb_process_read_params_rsp(hw, mbp, &retval,
+                                                       0, NULL);
+                       fw_caps = retval ? FW_CAPS16 : FW_CAPS32;
                }
 
                /* Read PORT information */
@@ -2364,8 +2397,8 @@ bye:
 }
 
 /*
- * Returns -EINVAL if attempts to flash the firmware failed
- * else returns 0,
+ * Returns -EINVAL if attempts to flash the firmware failed,
+ * -ENOMEM if memory allocation failed else returns 0,
  * if flashing was not attempted because the card had the
  * latest firmware ECANCELED is returned
  */
@@ -2393,6 +2426,13 @@ csio_hw_flash_fw(struct csio_hw *hw, int *reset)
                return -EINVAL;
        }
 
+       /* allocate memory to read the header of the firmware on the
+        * card
+        */
+       card_fw = kmalloc(sizeof(*card_fw), GFP_KERNEL);
+       if (!card_fw)
+               return -ENOMEM;
+
        if (csio_is_t5(pci_dev->device & CSIO_HW_CHIP_MASK))
                fw_bin_file = FW_FNAME_T5;
        else
@@ -2406,11 +2446,6 @@ csio_hw_flash_fw(struct csio_hw *hw, int *reset)
                fw_size = fw->size;
        }
 
-       /* allocate memory to read the header of the firmware on the
-        * card
-        */
-       card_fw = kmalloc(sizeof(*card_fw), GFP_KERNEL);
-
        /* upgrade FW logic */
        ret = csio_hw_prep_fw(hw, fw_info, fw_data, fw_size, card_fw,
                         hw->fw_state, reset);
index 9e73ef771eb739a8158bedc3d1d4d86b512e0749..e351af6e7c81c1d5fca398425dca662a49493981 100644 (file)
@@ -639,6 +639,7 @@ int csio_handle_intr_status(struct csio_hw *, unsigned int,
 
 fw_port_cap32_t fwcap_to_fwspeed(fw_port_cap32_t acaps);
 fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16);
+fw_port_cap16_t fwcaps32_to_caps16(fw_port_cap32_t caps32);
 fw_port_cap32_t lstatus_to_fwcap(u32 lstatus);
 
 int csio_hw_start(struct csio_hw *);
index c026417269c3c9f191ff948f1a0a3912d87052d8..6f13673d6aa054e4b2e71ec240215b3ad35dc6ee 100644 (file)
@@ -368,7 +368,7 @@ csio_mb_port(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo,
                        FW_CMD_LEN16_V(sizeof(*cmdp) / 16));
 
        if (fw_caps == FW_CAPS16)
-               cmdp->u.l1cfg.rcap = cpu_to_be32(fc);
+               cmdp->u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(fc));
        else
                cmdp->u.l1cfg32.rcap32 = cpu_to_be32(fc);
 }
@@ -395,8 +395,8 @@ csio_mb_process_read_port_rsp(struct csio_hw *hw, struct csio_mb *mbp,
                        *pcaps = fwcaps16_to_caps32(ntohs(rsp->u.info.pcap));
                        *acaps = fwcaps16_to_caps32(ntohs(rsp->u.info.acap));
                } else {
-                       *pcaps = ntohs(rsp->u.info32.pcaps32);
-                       *acaps = ntohs(rsp->u.info32.acaps32);
+                       *pcaps = be32_to_cpu(rsp->u.info32.pcaps32);
+                       *acaps = be32_to_cpu(rsp->u.info32.acaps32);
                }
        }
 }
index f02dcc875a09a6c6ece63e89e8256c512e11f01e..ea4b0bb0c1cd4e6b12748256741afae339311591 100644 (file)
@@ -563,35 +563,13 @@ struct Scsi_Host *scsi_host_get(struct Scsi_Host *shost)
 }
 EXPORT_SYMBOL(scsi_host_get);
 
-struct scsi_host_mq_in_flight {
-       int cnt;
-};
-
-static void scsi_host_check_in_flight(struct request *rq, void *data,
-               bool reserved)
-{
-       struct scsi_host_mq_in_flight *in_flight = data;
-
-       if (blk_mq_request_started(rq))
-               in_flight->cnt++;
-}
-
 /**
  * scsi_host_busy - Return the host busy counter
  * @shost:     Pointer to Scsi_Host to inc.
  **/
 int scsi_host_busy(struct Scsi_Host *shost)
 {
-       struct scsi_host_mq_in_flight in_flight = {
-               .cnt = 0,
-       };
-
-       if (!shost->use_blk_mq)
-               return atomic_read(&shost->host_busy);
-
-       blk_mq_tagset_busy_iter(&shost->tag_set, scsi_host_check_in_flight,
-                       &in_flight);
-       return in_flight.cnt;
+       return atomic_read(&shost->host_busy);
 }
 EXPORT_SYMBOL(scsi_host_busy);
 
index 58bb70b886d70d714ee6b448843aa113c2b313c0..c120929d4ffe52f3f24664226b7120b9057a2a1d 100644 (file)
@@ -976,7 +976,7 @@ static struct scsi_host_template hpsa_driver_template = {
 #endif
        .sdev_attrs = hpsa_sdev_attrs,
        .shost_attrs = hpsa_shost_attrs,
-       .max_sectors = 1024,
+       .max_sectors = 2048,
        .no_write_same = 1,
 };
 
index e0d0da5f43d6114e548974062d8a3118fdf384c3..43732e8d13473f84b88945072d7156d7a2982279 100644 (file)
@@ -672,7 +672,7 @@ struct lpfc_hba {
 #define LS_NPIV_FAB_SUPPORTED 0x2      /* Fabric supports NPIV */
 #define LS_IGNORE_ERATT       0x4      /* intr handler should ignore ERATT */
 #define LS_MDS_LINK_DOWN      0x8      /* MDS Diagnostics Link Down */
-#define LS_MDS_LOOPBACK      0x16      /* MDS Diagnostics Link Up (Loopback) */
+#define LS_MDS_LOOPBACK      0x10      /* MDS Diagnostics Link Up (Loopback) */
 
        uint32_t hba_flag;      /* hba generic flags */
 #define HBA_ERATT_HANDLED      0x1 /* This flag is set when eratt handled */
index 5a25553415f8bbb922883e9bbc8af18daebdda52..057a60abe664d269af64a2e85a4cea2faf740cfc 100644 (file)
@@ -5122,16 +5122,16 @@ LPFC_ATTR_R(enable_SmartSAN, 0, 0, 1, "Enable SmartSAN functionality");
 
 /*
 # lpfc_fdmi_on: Controls FDMI support.
-#       0       No FDMI support (default)
-#       1       Traditional FDMI support
+#       0       No FDMI support
+#       1       Traditional FDMI support (default)
 # Traditional FDMI support means the driver will assume FDMI-2 support;
 # however, if that fails, it will fallback to FDMI-1.
 # If lpfc_enable_SmartSAN is set to 1, the driver ignores lpfc_fdmi_on.
 # If lpfc_enable_SmartSAN is set 0, the driver uses the current value of
 # lpfc_fdmi_on.
-# Value range [0,1]. Default value is 0.
+# Value range [0,1]. Default value is 1.
 */
-LPFC_ATTR_R(fdmi_on, 0, 0, 1, "Enable FDMI support");
+LPFC_ATTR_R(fdmi_on, 1, 0, 1, "Enable FDMI support");
 
 /*
 # Specifies the maximum number of ELS cmds we can have outstanding (for
index 0e56f1eb05dc5caa711360dab68fcb7584d71b71..eaf36ccf58db55779033f73c936a5dec586b58c1 100644 (file)
@@ -423,19 +423,11 @@ static int osd_probe(struct device *dev)
        if (scsi_device->type != TYPE_OSD)
                return -ENODEV;
 
-       do {
-               if (!ida_pre_get(&osd_minor_ida, GFP_KERNEL))
-                       return -ENODEV;
-
-               error = ida_get_new(&osd_minor_ida, &minor);
-       } while (error == -EAGAIN);
-
-       if (error)
-               return error;
-       if (minor >= SCSI_OSD_MAX_MINOR) {
-               error = -EBUSY;
-               goto err_retract_minor;
-       }
+       minor = ida_alloc_max(&osd_minor_ida, SCSI_OSD_MAX_MINOR, GFP_KERNEL);
+       if (minor == -ENOSPC)
+               return -EBUSY;
+       if (minor < 0)
+               return -ENODEV;
 
        error = -ENOMEM;
        oud = kzalloc(sizeof(*oud), GFP_KERNEL);
@@ -499,7 +491,7 @@ static int osd_probe(struct device *dev)
 err_free_osd:
        put_device(&oud->class_dev);
 err_retract_minor:
-       ida_remove(&osd_minor_ida, minor);
+       ida_free(&osd_minor_ida, minor);
        return error;
 }
 
@@ -514,7 +506,7 @@ static int osd_remove(struct device *dev)
        }
 
        cdev_device_del(&oud->cdev, &oud->class_dev);
-       ida_remove(&osd_minor_ida, oud->minor);
+       ida_free(&osd_minor_ida, oud->minor);
        put_device(&oud->class_dev);
 
        return 0;
index 0adfb3bce0fd677ddae9f9d806472ccf2077ce25..eb97d2dd36516d0a3a5c0a9db1f255aaf5a9c56f 100644 (file)
@@ -345,8 +345,7 @@ static void scsi_dec_host_busy(struct Scsi_Host *shost)
        unsigned long flags;
 
        rcu_read_lock();
-       if (!shost->use_blk_mq)
-               atomic_dec(&shost->host_busy);
+       atomic_dec(&shost->host_busy);
        if (unlikely(scsi_host_in_recovery(shost))) {
                spin_lock_irqsave(shost->host_lock, flags);
                if (shost->host_failed || shost->host_eh_scheduled)
@@ -445,12 +444,7 @@ static inline bool scsi_target_is_busy(struct scsi_target *starget)
 
 static inline bool scsi_host_is_busy(struct Scsi_Host *shost)
 {
-       /*
-        * blk-mq can handle host queue busy efficiently via host-wide driver
-        * tag allocation
-        */
-
-       if (!shost->use_blk_mq && shost->can_queue > 0 &&
+       if (shost->can_queue > 0 &&
            atomic_read(&shost->host_busy) >= shost->can_queue)
                return true;
        if (atomic_read(&shost->host_blocked) > 0)
@@ -1606,10 +1600,7 @@ static inline int scsi_host_queue_ready(struct request_queue *q,
        if (scsi_host_in_recovery(shost))
                return 0;
 
-       if (!shost->use_blk_mq)
-               busy = atomic_inc_return(&shost->host_busy) - 1;
-       else
-               busy = 0;
+       busy = atomic_inc_return(&shost->host_busy) - 1;
        if (atomic_read(&shost->host_blocked) > 0) {
                if (busy)
                        goto starved;
@@ -1625,7 +1616,7 @@ static inline int scsi_host_queue_ready(struct request_queue *q,
                                     "unblocking host at zero depth\n"));
        }
 
-       if (!shost->use_blk_mq && shost->can_queue > 0 && busy >= shost->can_queue)
+       if (shost->can_queue > 0 && busy >= shost->can_queue)
                goto starved;
        if (shost->host_self_blocked)
                goto starved;
@@ -1711,9 +1702,7 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
         * with the locks as normal issue path does.
         */
        atomic_inc(&sdev->device_busy);
-
-       if (!shost->use_blk_mq)
-               atomic_inc(&shost->host_busy);
+       atomic_inc(&shost->host_busy);
        if (starget->can_queue > 0)
                atomic_inc(&starget->target_busy);
 
index a58cee7a85f2aef8daee2da9ba3960e6d4090276..b79b366a94f7993d2dc83c2b0c757c70ed753e75 100644 (file)
@@ -123,7 +123,6 @@ static void scsi_disk_release(struct device *cdev);
 static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
 static void sd_print_result(const struct scsi_disk *, const char *, int);
 
-static DEFINE_SPINLOCK(sd_index_lock);
 static DEFINE_IDA(sd_index_ida);
 
 /* This semaphore is used to mediate the 0->1 reference get in the
@@ -3340,16 +3339,8 @@ static int sd_probe(struct device *dev)
        if (!gd)
                goto out_free;
 
-       do {
-               if (!ida_pre_get(&sd_index_ida, GFP_KERNEL))
-                       goto out_put;
-
-               spin_lock(&sd_index_lock);
-               error = ida_get_new(&sd_index_ida, &index);
-               spin_unlock(&sd_index_lock);
-       } while (error == -EAGAIN);
-
-       if (error) {
+       index = ida_alloc(&sd_index_ida, GFP_KERNEL);
+       if (index < 0) {
                sdev_printk(KERN_WARNING, sdp, "sd_probe: memory exhausted.\n");
                goto out_put;
        }
@@ -3393,9 +3384,7 @@ static int sd_probe(struct device *dev)
        return 0;
 
  out_free_index:
-       spin_lock(&sd_index_lock);
-       ida_remove(&sd_index_ida, index);
-       spin_unlock(&sd_index_lock);
+       ida_free(&sd_index_ida, index);
  out_put:
        put_disk(gd);
  out_free:
@@ -3460,9 +3449,7 @@ static void scsi_disk_release(struct device *dev)
        struct scsi_disk *sdkp = to_scsi_disk(dev);
        struct gendisk *disk = sdkp->disk;
        
-       spin_lock(&sd_index_lock);
-       ida_remove(&sd_index_ida, sdkp->index);
-       spin_unlock(&sd_index_lock);
+       ida_free(&sd_index_ida, sdkp->index);
 
        disk->private_data = NULL;
        put_disk(disk);
index dcf8c8065508e0ddf8d182a909bfa401ac916e79..a5577dd5eb0870bccff391f38c69f47c8d708fde 100644 (file)
@@ -627,10 +627,26 @@ static const struct of_device_id ddr_shimphy_dt_ids[] = {
 };
 
 static const struct of_device_id brcmstb_memc_of_match[] = {
+       {
+               .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.1",
+               .data = &ddr_seq,
+       },
        {
                .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.2",
                .data = &ddr_seq_b22,
        },
+       {
+               .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.3",
+               .data = &ddr_seq_b22,
+       },
+       {
+               .compatible = "brcm,brcmstb-memc-ddr-rev-b.3.0",
+               .data = &ddr_seq_b22,
+       },
+       {
+               .compatible = "brcm,brcmstb-memc-ddr-rev-b.3.1",
+               .data = &ddr_seq_b22,
+       },
        {
                .compatible = "brcm,brcmstb-memc-ddr",
                .data = &ddr_seq,
index 7a9fb9baa66d27c6bb2b1c8f3a22ada6fad84309..8f80e8bbf29e2f4ea21996bc285df224eb509e10 100644 (file)
@@ -1,7 +1,9 @@
 #
-# Freescale SOC drivers
+# NXP/Freescale QorIQ series SOC drivers
 #
 
+menu "NXP/Freescale QorIQ SoC drivers"
+
 source "drivers/soc/fsl/qbman/Kconfig"
 source "drivers/soc/fsl/qe/Kconfig"
 
@@ -16,3 +18,14 @@ config FSL_GUTS
          Initially only reading SVR and registering soc device are supported.
          Other guts accesses, such as reading RCW, should eventually be moved
          into this driver as well.
+
+config FSL_MC_DPIO
+        tristate "QorIQ DPAA2 DPIO driver"
+        depends on FSL_MC_BUS
+        help
+         Driver for the DPAA2 DPIO object.  A DPIO provides queue and
+         buffer management facilities for software to interact with
+         other DPAA2 objects. This driver does not expose the DPIO
+         objects individually, but groups them under a service layer
+         API.
+endmenu
index 44b3bebef24a3dac1de85c1615ddfde51fa9453c..803ef1bfb5ff90bfb4febb7fe7c9b9cee0651426 100644 (file)
@@ -6,3 +6,4 @@ obj-$(CONFIG_FSL_DPAA)                 += qbman/
 obj-$(CONFIG_QUICC_ENGINE)             += qe/
 obj-$(CONFIG_CPM)                      += qe/
 obj-$(CONFIG_FSL_GUTS)                 += guts.o
+obj-$(CONFIG_FSL_MC_DPIO)              += dpio/
diff --git a/drivers/soc/fsl/dpio/Makefile b/drivers/soc/fsl/dpio/Makefile
new file mode 100644 (file)
index 0000000..b9ff24c
--- /dev/null
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# QorIQ DPAA2 DPIO driver
+#
+
+obj-$(CONFIG_FSL_MC_DPIO) += fsl-mc-dpio.o
+
+fsl-mc-dpio-objs := dpio.o qbman-portal.o dpio-service.o dpio-driver.o
diff --git a/drivers/soc/fsl/dpio/dpio-cmd.h b/drivers/soc/fsl/dpio/dpio-cmd.h
new file mode 100644 (file)
index 0000000..ab8f82e
--- /dev/null
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/*
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright 2016 NXP
+ *
+ */
+#ifndef _FSL_DPIO_CMD_H
+#define _FSL_DPIO_CMD_H
+
+/* DPIO Version */
+#define DPIO_VER_MAJOR                 4
+#define DPIO_VER_MINOR                 2
+
+/* Command Versioning */
+
+#define DPIO_CMD_ID_OFFSET             4
+#define DPIO_CMD_BASE_VERSION          1
+
+#define DPIO_CMD(id)   (((id) << DPIO_CMD_ID_OFFSET) | DPIO_CMD_BASE_VERSION)
+
+/* Command IDs */
+#define DPIO_CMDID_CLOSE                               DPIO_CMD(0x800)
+#define DPIO_CMDID_OPEN                                        DPIO_CMD(0x803)
+#define DPIO_CMDID_GET_API_VERSION                     DPIO_CMD(0xa03)
+#define DPIO_CMDID_ENABLE                              DPIO_CMD(0x002)
+#define DPIO_CMDID_DISABLE                             DPIO_CMD(0x003)
+#define DPIO_CMDID_GET_ATTR                            DPIO_CMD(0x004)
+
+struct dpio_cmd_open {
+       __le32 dpio_id;
+};
+
+#define DPIO_CHANNEL_MODE_MASK         0x3
+
+struct dpio_rsp_get_attr {
+       /* cmd word 0 */
+       __le32 id;
+       __le16 qbman_portal_id;
+       u8 num_priorities;
+       u8 channel_mode;
+       /* cmd word 1 */
+       __le64 qbman_portal_ce_addr;
+       /* cmd word 2 */
+       __le64 qbman_portal_ci_addr;
+       /* cmd word 3 */
+       __le32 qbman_version;
+};
+
+#endif /* _FSL_DPIO_CMD_H */
diff --git a/drivers/soc/fsl/dpio/dpio-driver.c b/drivers/soc/fsl/dpio/dpio-driver.c
new file mode 100644 (file)
index 0000000..b60b77b
--- /dev/null
@@ -0,0 +1,281 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright 2014-2016 Freescale Semiconductor Inc.
+ * Copyright NXP 2016
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/msi.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <linux/fsl/mc.h>
+#include <soc/fsl/dpaa2-io.h>
+
+#include "qbman-portal.h"
+#include "dpio.h"
+#include "dpio-cmd.h"
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Freescale Semiconductor, Inc");
+MODULE_DESCRIPTION("DPIO Driver");
+
+struct dpio_priv {
+       struct dpaa2_io *io;
+};
+
+static irqreturn_t dpio_irq_handler(int irq_num, void *arg)
+{
+       struct device *dev = (struct device *)arg;
+       struct dpio_priv *priv = dev_get_drvdata(dev);
+
+       return dpaa2_io_irq(priv->io);
+}
+
+static void unregister_dpio_irq_handlers(struct fsl_mc_device *dpio_dev)
+{
+       struct fsl_mc_device_irq *irq;
+
+       irq = dpio_dev->irqs[0];
+
+       /* clear the affinity hint */
+       irq_set_affinity_hint(irq->msi_desc->irq, NULL);
+}
+
+static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int cpu)
+{
+       struct dpio_priv *priv;
+       int error;
+       struct fsl_mc_device_irq *irq;
+       cpumask_t mask;
+
+       priv = dev_get_drvdata(&dpio_dev->dev);
+
+       irq = dpio_dev->irqs[0];
+       error = devm_request_irq(&dpio_dev->dev,
+                                irq->msi_desc->irq,
+                                dpio_irq_handler,
+                                0,
+                                dev_name(&dpio_dev->dev),
+                                &dpio_dev->dev);
+       if (error < 0) {
+               dev_err(&dpio_dev->dev,
+                       "devm_request_irq() failed: %d\n",
+                       error);
+               return error;
+       }
+
+       /* set the affinity hint */
+       cpumask_clear(&mask);
+       cpumask_set_cpu(cpu, &mask);
+       if (irq_set_affinity_hint(irq->msi_desc->irq, &mask))
+               dev_err(&dpio_dev->dev,
+                       "irq_set_affinity failed irq %d cpu %d\n",
+                       irq->msi_desc->irq, cpu);
+
+       return 0;
+}
+
+static int dpaa2_dpio_probe(struct fsl_mc_device *dpio_dev)
+{
+       struct dpio_attr dpio_attrs;
+       struct dpaa2_io_desc desc;
+       struct dpio_priv *priv;
+       int err = -ENOMEM;
+       struct device *dev = &dpio_dev->dev;
+       static int next_cpu = -1;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               goto err_priv_alloc;
+
+       dev_set_drvdata(dev, priv);
+
+       err = fsl_mc_portal_allocate(dpio_dev, 0, &dpio_dev->mc_io);
+       if (err) {
+               dev_dbg(dev, "MC portal allocation failed\n");
+               err = -EPROBE_DEFER;
+               goto err_priv_alloc;
+       }
+
+       err = dpio_open(dpio_dev->mc_io, 0, dpio_dev->obj_desc.id,
+                       &dpio_dev->mc_handle);
+       if (err) {
+               dev_err(dev, "dpio_open() failed\n");
+               goto err_open;
+       }
+
+       err = dpio_get_attributes(dpio_dev->mc_io, 0, dpio_dev->mc_handle,
+                                 &dpio_attrs);
+       if (err) {
+               dev_err(dev, "dpio_get_attributes() failed %d\n", err);
+               goto err_get_attr;
+       }
+       desc.qman_version = dpio_attrs.qbman_version;
+
+       err = dpio_enable(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
+       if (err) {
+               dev_err(dev, "dpio_enable() failed %d\n", err);
+               goto err_get_attr;
+       }
+
+       /* initialize DPIO descriptor */
+       desc.receives_notifications = dpio_attrs.num_priorities ? 1 : 0;
+       desc.has_8prio = dpio_attrs.num_priorities == 8 ? 1 : 0;
+       desc.dpio_id = dpio_dev->obj_desc.id;
+
+       /* get the cpu to use for the affinity hint */
+       if (next_cpu == -1)
+               next_cpu = cpumask_first(cpu_online_mask);
+       else
+               next_cpu = cpumask_next(next_cpu, cpu_online_mask);
+
+       if (!cpu_possible(next_cpu)) {
+               dev_err(dev, "probe failed. Number of DPIOs exceeds NR_CPUS.\n");
+               err = -ERANGE;
+               goto err_allocate_irqs;
+       }
+       desc.cpu = next_cpu;
+
+       /*
+        * Set the CENA regs to be the cache inhibited area of the portal to
+        * avoid coherency issues if a user migrates to another core.
+        */
+       desc.regs_cena = devm_memremap(dev, dpio_dev->regions[1].start,
+                                      resource_size(&dpio_dev->regions[1]),
+                                      MEMREMAP_WC);
+       if (IS_ERR(desc.regs_cena)) {
+               dev_err(dev, "devm_memremap failed\n");
+               err = PTR_ERR(desc.regs_cena);
+               goto err_allocate_irqs;
+       }
+
+       desc.regs_cinh = devm_ioremap(dev, dpio_dev->regions[1].start,
+                                     resource_size(&dpio_dev->regions[1]));
+       if (!desc.regs_cinh) {
+               err = -ENOMEM;
+               dev_err(dev, "devm_ioremap failed\n");
+               goto err_allocate_irqs;
+       }
+
+       err = fsl_mc_allocate_irqs(dpio_dev);
+       if (err) {
+               dev_err(dev, "fsl_mc_allocate_irqs failed. err=%d\n", err);
+               goto err_allocate_irqs;
+       }
+
+       err = register_dpio_irq_handlers(dpio_dev, desc.cpu);
+       if (err)
+               goto err_register_dpio_irq;
+
+       priv->io = dpaa2_io_create(&desc);
+       if (!priv->io) {
+               dev_err(dev, "dpaa2_io_create failed\n");
+               err = -ENOMEM;
+               goto err_dpaa2_io_create;
+       }
+
+       dev_info(dev, "probed\n");
+       dev_dbg(dev, "   receives_notifications = %d\n",
+               desc.receives_notifications);
+       dpio_close(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
+       fsl_mc_portal_free(dpio_dev->mc_io);
+
+       return 0;
+
+err_dpaa2_io_create:
+       unregister_dpio_irq_handlers(dpio_dev);
+err_register_dpio_irq:
+       fsl_mc_free_irqs(dpio_dev);
+err_allocate_irqs:
+       dpio_disable(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
+err_get_attr:
+       dpio_close(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
+err_open:
+       fsl_mc_portal_free(dpio_dev->mc_io);
+err_priv_alloc:
+       return err;
+}
+
+/* Tear down interrupts for a given DPIO object */
+static void dpio_teardown_irqs(struct fsl_mc_device *dpio_dev)
+{
+       unregister_dpio_irq_handlers(dpio_dev);
+       fsl_mc_free_irqs(dpio_dev);
+}
+
+static int dpaa2_dpio_remove(struct fsl_mc_device *dpio_dev)
+{
+       struct device *dev;
+       struct dpio_priv *priv;
+       int err;
+
+       dev = &dpio_dev->dev;
+       priv = dev_get_drvdata(dev);
+
+       dpaa2_io_down(priv->io);
+
+       dpio_teardown_irqs(dpio_dev);
+
+       err = fsl_mc_portal_allocate(dpio_dev, 0, &dpio_dev->mc_io);
+       if (err) {
+               dev_err(dev, "MC portal allocation failed\n");
+               goto err_mcportal;
+       }
+
+       err = dpio_open(dpio_dev->mc_io, 0, dpio_dev->obj_desc.id,
+                       &dpio_dev->mc_handle);
+       if (err) {
+               dev_err(dev, "dpio_open() failed\n");
+               goto err_open;
+       }
+
+       dpio_disable(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
+
+       dpio_close(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
+
+       fsl_mc_portal_free(dpio_dev->mc_io);
+
+       return 0;
+
+err_open:
+       fsl_mc_portal_free(dpio_dev->mc_io);
+err_mcportal:
+       return err;
+}
+
+static const struct fsl_mc_device_id dpaa2_dpio_match_id_table[] = {
+       {
+               .vendor = FSL_MC_VENDOR_FREESCALE,
+               .obj_type = "dpio",
+       },
+       { .vendor = 0x0 }
+};
+
+static struct fsl_mc_driver dpaa2_dpio_driver = {
+       .driver = {
+               .name           = KBUILD_MODNAME,
+               .owner          = THIS_MODULE,
+       },
+       .probe          = dpaa2_dpio_probe,
+       .remove         = dpaa2_dpio_remove,
+       .match_id_table = dpaa2_dpio_match_id_table
+};
+
+static int dpio_driver_init(void)
+{
+       return fsl_mc_driver_register(&dpaa2_dpio_driver);
+}
+
+static void dpio_driver_exit(void)
+{
+       fsl_mc_driver_unregister(&dpaa2_dpio_driver);
+}
+module_init(dpio_driver_init);
+module_exit(dpio_driver_exit);
diff --git a/drivers/soc/fsl/dpio/dpio-service.c b/drivers/soc/fsl/dpio/dpio-service.c
new file mode 100644 (file)
index 0000000..9b17f72
--- /dev/null
@@ -0,0 +1,545 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright 2014-2016 Freescale Semiconductor Inc.
+ * Copyright 2016 NXP
+ *
+ */
+#include <linux/types.h>
+#include <linux/fsl/mc.h>
+#include <soc/fsl/dpaa2-io.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+#include "dpio.h"
+#include "qbman-portal.h"
+
+struct dpaa2_io {
+       struct dpaa2_io_desc dpio_desc;
+       struct qbman_swp_desc swp_desc;
+       struct qbman_swp *swp;
+       struct list_head node;
+       /* protect against multiple management commands */
+       spinlock_t lock_mgmt_cmd;
+       /* protect notifications list */
+       spinlock_t lock_notifications;
+       struct list_head notifications;
+};
+
+struct dpaa2_io_store {
+       unsigned int max;
+       dma_addr_t paddr;
+       struct dpaa2_dq *vaddr;
+       void *alloced_addr;    /* unaligned value from kmalloc() */
+       unsigned int idx;      /* position of the next-to-be-returned entry */
+       struct qbman_swp *swp; /* portal used to issue VDQCR */
+       struct device *dev;    /* device used for DMA mapping */
+};
+
+/* keep a per cpu array of DPIOs for fast access */
+static struct dpaa2_io *dpio_by_cpu[NR_CPUS];
+static struct list_head dpio_list = LIST_HEAD_INIT(dpio_list);
+static DEFINE_SPINLOCK(dpio_list_lock);
+
+static inline struct dpaa2_io *service_select_by_cpu(struct dpaa2_io *d,
+                                                    int cpu)
+{
+       if (d)
+               return d;
+
+       if (cpu != DPAA2_IO_ANY_CPU && cpu >= num_possible_cpus())
+               return NULL;
+
+       /*
+        * If cpu == -1, choose the current cpu, with no guarantees about
+        * potentially being migrated away.
+        */
+       if (unlikely(cpu < 0))
+               cpu = smp_processor_id();
+
+       /* If a specific cpu was requested, pick it up immediately */
+       return dpio_by_cpu[cpu];
+}
+
+static inline struct dpaa2_io *service_select(struct dpaa2_io *d)
+{
+       if (d)
+               return d;
+
+       spin_lock(&dpio_list_lock);
+       d = list_entry(dpio_list.next, struct dpaa2_io, node);
+       list_del(&d->node);
+       list_add_tail(&d->node, &dpio_list);
+       spin_unlock(&dpio_list_lock);
+
+       return d;
+}
+
+/**
+ * dpaa2_io_service_select() - return a dpaa2_io service affined to this cpu
+ * @cpu: the cpu id
+ *
+ * Return the affine dpaa2_io service, or NULL if there is no service affined
+ * to the specified cpu. If DPAA2_IO_ANY_CPU is used, return the next available
+ * service.
+ */
+struct dpaa2_io *dpaa2_io_service_select(int cpu)
+{
+       if (cpu == DPAA2_IO_ANY_CPU)
+               return service_select(NULL);
+
+       return service_select_by_cpu(NULL, cpu);
+}
+EXPORT_SYMBOL_GPL(dpaa2_io_service_select);
+
+/**
+ * dpaa2_io_create() - create a dpaa2_io object.
+ * @desc: the dpaa2_io descriptor
+ *
+ * Activates a "struct dpaa2_io" corresponding to the given config of an actual
+ * DPIO object.
+ *
+ * Return a valid dpaa2_io object for success, or NULL for failure.
+ */
+struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc)
+{
+       struct dpaa2_io *obj = kmalloc(sizeof(*obj), GFP_KERNEL);
+
+       if (!obj)
+               return NULL;
+
+       /* check if CPU is out of range (-1 means any cpu) */
+       if (desc->cpu != DPAA2_IO_ANY_CPU && desc->cpu >= num_possible_cpus()) {
+               kfree(obj);
+               return NULL;
+       }
+
+       obj->dpio_desc = *desc;
+       obj->swp_desc.cena_bar = obj->dpio_desc.regs_cena;
+       obj->swp_desc.cinh_bar = obj->dpio_desc.regs_cinh;
+       obj->swp_desc.qman_version = obj->dpio_desc.qman_version;
+       obj->swp = qbman_swp_init(&obj->swp_desc);
+
+       if (!obj->swp) {
+               kfree(obj);
+               return NULL;
+       }
+
+       INIT_LIST_HEAD(&obj->node);
+       spin_lock_init(&obj->lock_mgmt_cmd);
+       spin_lock_init(&obj->lock_notifications);
+       INIT_LIST_HEAD(&obj->notifications);
+
+       /* For now only enable DQRR interrupts */
+       qbman_swp_interrupt_set_trigger(obj->swp,
+                                       QBMAN_SWP_INTERRUPT_DQRI);
+       qbman_swp_interrupt_clear_status(obj->swp, 0xffffffff);
+       if (obj->dpio_desc.receives_notifications)
+               qbman_swp_push_set(obj->swp, 0, 1);
+
+       spin_lock(&dpio_list_lock);
+       list_add_tail(&obj->node, &dpio_list);
+       if (desc->cpu >= 0 && !dpio_by_cpu[desc->cpu])
+               dpio_by_cpu[desc->cpu] = obj;
+       spin_unlock(&dpio_list_lock);
+
+       return obj;
+}
+
+/**
+ * dpaa2_io_down() - release the dpaa2_io object.
+ * @d: the dpaa2_io object to be released.
+ *
+ * The "struct dpaa2_io" type can represent an individual DPIO object (as
+ * described by "struct dpaa2_io_desc") or an instance of a "DPIO service",
+ * which can be used to group/encapsulate multiple DPIO objects. In all cases,
+ * each handle obtained should be released using this function.
+ */
+void dpaa2_io_down(struct dpaa2_io *d)
+{
+       kfree(d);
+}
+
+#define DPAA_POLL_MAX 32
+
+/**
+ * dpaa2_io_irq() - ISR for DPIO interrupts
+ *
+ * @obj: the given DPIO object.
+ *
+ * Return IRQ_HANDLED for success or IRQ_NONE if there
+ * were no pending interrupts.
+ */
+irqreturn_t dpaa2_io_irq(struct dpaa2_io *obj)
+{
+       const struct dpaa2_dq *dq;
+       int max = 0;
+       struct qbman_swp *swp;
+       u32 status;
+
+       swp = obj->swp;
+       status = qbman_swp_interrupt_read_status(swp);
+       if (!status)
+               return IRQ_NONE;
+
+       dq = qbman_swp_dqrr_next(swp);
+       while (dq) {
+               if (qbman_result_is_SCN(dq)) {
+                       struct dpaa2_io_notification_ctx *ctx;
+                       u64 q64;
+
+                       q64 = qbman_result_SCN_ctx(dq);
+                       ctx = (void *)(uintptr_t)q64;
+                       ctx->cb(ctx);
+               } else {
+                       pr_crit("fsl-mc-dpio: Unrecognised/ignored DQRR entry\n");
+               }
+               qbman_swp_dqrr_consume(swp, dq);
+               ++max;
+               if (max > DPAA_POLL_MAX)
+                       goto done;
+               dq = qbman_swp_dqrr_next(swp);
+       }
+done:
+       qbman_swp_interrupt_clear_status(swp, status);
+       qbman_swp_interrupt_set_inhibit(swp, 0);
+       return IRQ_HANDLED;
+}
+
+/**
+ * dpaa2_io_service_register() - Prepare for servicing of FQDAN or CDAN
+ *                               notifications on the given DPIO service.
+ * @d:   the given DPIO service.
+ * @ctx: the notification context.
+ *
+ * The caller should make the MC command to attach a DPAA2 object to
+ * a DPIO after this function completes successfully.  In that way:
+ *    (a) The DPIO service is "ready" to handle a notification arrival
+ *        (which might happen before the "attach" command to MC has
+ *        returned control of execution back to the caller)
+ *    (b) The DPIO service can provide back to the caller the 'dpio_id' and
+ *        'qman64' parameters that it should pass along in the MC command
+ *        in order for the object to be configured to produce the right
+ *        notification fields to the DPIO service.
+ *
+ * Return 0 for success, or -ENODEV for failure.
+ */
+int dpaa2_io_service_register(struct dpaa2_io *d,
+                             struct dpaa2_io_notification_ctx *ctx)
+{
+       unsigned long irqflags;
+
+       d = service_select_by_cpu(d, ctx->desired_cpu);
+       if (!d)
+               return -ENODEV;
+
+       ctx->dpio_id = d->dpio_desc.dpio_id;
+       ctx->qman64 = (u64)(uintptr_t)ctx;
+       ctx->dpio_private = d;
+       spin_lock_irqsave(&d->lock_notifications, irqflags);
+       list_add(&ctx->node, &d->notifications);
+       spin_unlock_irqrestore(&d->lock_notifications, irqflags);
+
+       /* Enable the generation of CDAN notifications */
+       if (ctx->is_cdan)
+               return qbman_swp_CDAN_set_context_enable(d->swp,
+                                                        (u16)ctx->id,
+                                                        ctx->qman64);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(dpaa2_io_service_register);
+
+/**
+ * dpaa2_io_service_deregister - The opposite of 'register'.
+ * @service: the given DPIO service.
+ * @ctx: the notification context.
+ *
+ * This function should be called only after sending the MC command to
+ * to detach the notification-producing device from the DPIO.
+ */
+void dpaa2_io_service_deregister(struct dpaa2_io *service,
+                                struct dpaa2_io_notification_ctx *ctx)
+{
+       struct dpaa2_io *d = ctx->dpio_private;
+       unsigned long irqflags;
+
+       if (ctx->is_cdan)
+               qbman_swp_CDAN_disable(d->swp, (u16)ctx->id);
+
+       spin_lock_irqsave(&d->lock_notifications, irqflags);
+       list_del(&ctx->node);
+       spin_unlock_irqrestore(&d->lock_notifications, irqflags);
+}
+EXPORT_SYMBOL_GPL(dpaa2_io_service_deregister);
+
+/**
+ * dpaa2_io_service_rearm() - Rearm the notification for the given DPIO service.
+ * @d: the given DPIO service.
+ * @ctx: the notification context.
+ *
+ * Once a FQDAN/CDAN has been produced, the corresponding FQ/channel is
+ * considered "disarmed". Ie. the user can issue pull dequeue operations on that
+ * traffic source for as long as it likes. Eventually it may wish to "rearm"
+ * that source to allow it to produce another FQDAN/CDAN, that's what this
+ * function achieves.
+ *
+ * Return 0 for success.
+ */
+int dpaa2_io_service_rearm(struct dpaa2_io *d,
+                          struct dpaa2_io_notification_ctx *ctx)
+{
+       unsigned long irqflags;
+       int err;
+
+       d = service_select_by_cpu(d, ctx->desired_cpu);
+       if (!unlikely(d))
+               return -ENODEV;
+
+       spin_lock_irqsave(&d->lock_mgmt_cmd, irqflags);
+       if (ctx->is_cdan)
+               err = qbman_swp_CDAN_enable(d->swp, (u16)ctx->id);
+       else
+               err = qbman_swp_fq_schedule(d->swp, ctx->id);
+       spin_unlock_irqrestore(&d->lock_mgmt_cmd, irqflags);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(dpaa2_io_service_rearm);
+
+/**
+ * dpaa2_io_service_pull_channel() - pull dequeue functions from a channel.
+ * @d: the given DPIO service.
+ * @channelid: the given channel id.
+ * @s: the dpaa2_io_store object for the result.
+ *
+ * Return 0 for success, or error code for failure.
+ */
+int dpaa2_io_service_pull_channel(struct dpaa2_io *d, u32 channelid,
+                                 struct dpaa2_io_store *s)
+{
+       struct qbman_pull_desc pd;
+       int err;
+
+       qbman_pull_desc_clear(&pd);
+       qbman_pull_desc_set_storage(&pd, s->vaddr, s->paddr, 1);
+       qbman_pull_desc_set_numframes(&pd, (u8)s->max);
+       qbman_pull_desc_set_channel(&pd, channelid, qbman_pull_type_prio);
+
+       d = service_select(d);
+       if (!d)
+               return -ENODEV;
+
+       s->swp = d->swp;
+       err = qbman_swp_pull(d->swp, &pd);
+       if (err)
+               s->swp = NULL;
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(dpaa2_io_service_pull_channel);
+
+/**
+ * dpaa2_io_service_enqueue_qd() - Enqueue a frame to a QD.
+ * @d: the given DPIO service.
+ * @qdid: the given queuing destination id.
+ * @prio: the given queuing priority.
+ * @qdbin: the given queuing destination bin.
+ * @fd: the frame descriptor which is enqueued.
+ *
+ * Return 0 for successful enqueue, or -EBUSY if the enqueue ring is not ready,
+ * or -ENODEV if there is no dpio service.
+ */
+int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d,
+                               u32 qdid, u8 prio, u16 qdbin,
+                               const struct dpaa2_fd *fd)
+{
+       struct qbman_eq_desc ed;
+
+       d = service_select(d);
+       if (!d)
+               return -ENODEV;
+
+       qbman_eq_desc_clear(&ed);
+       qbman_eq_desc_set_no_orp(&ed, 0);
+       qbman_eq_desc_set_qd(&ed, qdid, qdbin, prio);
+
+       return qbman_swp_enqueue(d->swp, &ed, fd);
+}
+EXPORT_SYMBOL_GPL(dpaa2_io_service_enqueue_qd);
+
+/**
+ * dpaa2_io_service_release() - Release buffers to a buffer pool.
+ * @d: the given DPIO object.
+ * @bpid: the buffer pool id.
+ * @buffers: the buffers to be released.
+ * @num_buffers: the number of the buffers to be released.
+ *
+ * Return 0 for success, and negative error code for failure.
+ */
+int dpaa2_io_service_release(struct dpaa2_io *d,
+                            u32 bpid,
+                            const u64 *buffers,
+                            unsigned int num_buffers)
+{
+       struct qbman_release_desc rd;
+
+       d = service_select(d);
+       if (!d)
+               return -ENODEV;
+
+       qbman_release_desc_clear(&rd);
+       qbman_release_desc_set_bpid(&rd, bpid);
+
+       return qbman_swp_release(d->swp, &rd, buffers, num_buffers);
+}
+EXPORT_SYMBOL_GPL(dpaa2_io_service_release);
+
+/**
+ * dpaa2_io_service_acquire() - Acquire buffers from a buffer pool.
+ * @d: the given DPIO object.
+ * @bpid: the buffer pool id.
+ * @buffers: the buffer addresses for acquired buffers.
+ * @num_buffers: the expected number of the buffers to acquire.
+ *
+ * Return a negative error code if the command failed, otherwise it returns
+ * the number of buffers acquired, which may be less than the number requested.
+ * Eg. if the buffer pool is empty, this will return zero.
+ */
+int dpaa2_io_service_acquire(struct dpaa2_io *d,
+                            u32 bpid,
+                            u64 *buffers,
+                            unsigned int num_buffers)
+{
+       unsigned long irqflags;
+       int err;
+
+       d = service_select(d);
+       if (!d)
+               return -ENODEV;
+
+       spin_lock_irqsave(&d->lock_mgmt_cmd, irqflags);
+       err = qbman_swp_acquire(d->swp, bpid, buffers, num_buffers);
+       spin_unlock_irqrestore(&d->lock_mgmt_cmd, irqflags);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(dpaa2_io_service_acquire);
+
+/*
+ * 'Stores' are reusable memory blocks for holding dequeue results, and to
+ * assist with parsing those results.
+ */
+
+/**
+ * dpaa2_io_store_create() - Create the dma memory storage for dequeue result.
+ * @max_frames: the maximum number of dequeued result for frames, must be <= 16.
+ * @dev:        the device to allow mapping/unmapping the DMAable region.
+ *
+ * The size of the storage is "max_frames*sizeof(struct dpaa2_dq)".
+ * The 'dpaa2_io_store' returned is a DPIO service managed object.
+ *
+ * Return pointer to dpaa2_io_store struct for successfully created storage
+ * memory, or NULL on error.
+ */
+struct dpaa2_io_store *dpaa2_io_store_create(unsigned int max_frames,
+                                            struct device *dev)
+{
+       struct dpaa2_io_store *ret;
+       size_t size;
+
+       if (!max_frames || (max_frames > 16))
+               return NULL;
+
+       ret = kmalloc(sizeof(*ret), GFP_KERNEL);
+       if (!ret)
+               return NULL;
+
+       ret->max = max_frames;
+       size = max_frames * sizeof(struct dpaa2_dq) + 64;
+       ret->alloced_addr = kzalloc(size, GFP_KERNEL);
+       if (!ret->alloced_addr) {
+               kfree(ret);
+               return NULL;
+       }
+
+       ret->vaddr = PTR_ALIGN(ret->alloced_addr, 64);
+       ret->paddr = dma_map_single(dev, ret->vaddr,
+                                   sizeof(struct dpaa2_dq) * max_frames,
+                                   DMA_FROM_DEVICE);
+       if (dma_mapping_error(dev, ret->paddr)) {
+               kfree(ret->alloced_addr);
+               kfree(ret);
+               return NULL;
+       }
+
+       ret->idx = 0;
+       ret->dev = dev;
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(dpaa2_io_store_create);
+
+/**
+ * dpaa2_io_store_destroy() - Frees the dma memory storage for dequeue
+ *                            result.
+ * @s: the storage memory to be destroyed.
+ */
+void dpaa2_io_store_destroy(struct dpaa2_io_store *s)
+{
+       dma_unmap_single(s->dev, s->paddr, sizeof(struct dpaa2_dq) * s->max,
+                        DMA_FROM_DEVICE);
+       kfree(s->alloced_addr);
+       kfree(s);
+}
+EXPORT_SYMBOL_GPL(dpaa2_io_store_destroy);
+
+/**
+ * dpaa2_io_store_next() - Determine when the next dequeue result is available.
+ * @s: the dpaa2_io_store object.
+ * @is_last: indicate whether this is the last frame in the pull command.
+ *
+ * When an object driver performs dequeues to a dpaa2_io_store, this function
+ * can be used to determine when the next frame result is available. Once
+ * this function returns non-NULL, a subsequent call to it will try to find
+ * the next dequeue result.
+ *
+ * Note that if a pull-dequeue has a NULL result because the target FQ/channel
+ * was empty, then this function will also return NULL (rather than expecting
+ * the caller to always check for this. As such, "is_last" can be used to
+ * differentiate between "end-of-empty-dequeue" and "still-waiting".
+ *
+ * Return dequeue result for a valid dequeue result, or NULL for empty dequeue.
+ */
+struct dpaa2_dq *dpaa2_io_store_next(struct dpaa2_io_store *s, int *is_last)
+{
+       int match;
+       struct dpaa2_dq *ret = &s->vaddr[s->idx];
+
+       match = qbman_result_has_new_result(s->swp, ret);
+       if (!match) {
+               *is_last = 0;
+               return NULL;
+       }
+
+       s->idx++;
+
+       if (dpaa2_dq_is_pull_complete(ret)) {
+               *is_last = 1;
+               s->idx = 0;
+               /*
+                * If we get an empty dequeue result to terminate a zero-results
+                * vdqcr, return NULL to the caller rather than expecting him to
+                * check non-NULL results every time.
+                */
+               if (!(dpaa2_dq_flags(ret) & DPAA2_DQ_STAT_VALIDFRAME))
+                       ret = NULL;
+       } else {
+               *is_last = 0;
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(dpaa2_io_store_next);
diff --git a/drivers/soc/fsl/dpio/dpio.c b/drivers/soc/fsl/dpio/dpio.c
new file mode 100644 (file)
index 0000000..ff37c80
--- /dev/null
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright 2016 NXP
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/fsl/mc.h>
+
+#include "dpio.h"
+#include "dpio-cmd.h"
+
+/*
+ * Data Path I/O Portal API
+ * Contains initialization APIs and runtime control APIs for DPIO
+ */
+
+/**
+ * dpio_open() - Open a control session for the specified object
+ * @mc_io:     Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @dpio_id:   DPIO unique ID
+ * @token:     Returned token; use in subsequent API calls
+ *
+ * This function can be used to open a control session for an
+ * already created object; an object may have been declared in
+ * the DPL or by calling the dpio_create() function.
+ * This function returns a unique authentication token,
+ * associated with the specific object ID and the specific MC
+ * portal; this token must be used in all subsequent commands for
+ * this specific object.
+ *
+ * Return:     '0' on Success; Error code otherwise.
+ */
+int dpio_open(struct fsl_mc_io *mc_io,
+             u32 cmd_flags,
+             int dpio_id,
+             u16 *token)
+{
+       struct fsl_mc_command cmd = { 0 };
+       struct dpio_cmd_open *dpio_cmd;
+       int err;
+
+       /* prepare command */
+       cmd.header = mc_encode_cmd_header(DPIO_CMDID_OPEN,
+                                         cmd_flags,
+                                         0);
+       dpio_cmd = (struct dpio_cmd_open *)cmd.params;
+       dpio_cmd->dpio_id = cpu_to_le32(dpio_id);
+
+       err = mc_send_command(mc_io, &cmd);
+       if (err)
+               return err;
+
+       /* retrieve response parameters */
+       *token = mc_cmd_hdr_read_token(&cmd);
+
+       return 0;
+}
+
+/**
+ * dpio_close() - Close the control session of the object
+ * @mc_io:     Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token:     Token of DPIO object
+ *
+ * Return:     '0' on Success; Error code otherwise.
+ */
+int dpio_close(struct fsl_mc_io *mc_io,
+              u32 cmd_flags,
+              u16 token)
+{
+       struct fsl_mc_command cmd = { 0 };
+
+       /* prepare command */
+       cmd.header = mc_encode_cmd_header(DPIO_CMDID_CLOSE,
+                                         cmd_flags,
+                                         token);
+
+       return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpio_enable() - Enable the DPIO, allow I/O portal operations.
+ * @mc_io:     Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token:     Token of DPIO object
+ *
+ * Return:     '0' on Success; Error code otherwise
+ */
+int dpio_enable(struct fsl_mc_io *mc_io,
+               u32 cmd_flags,
+               u16 token)
+{
+       struct fsl_mc_command cmd = { 0 };
+
+       /* prepare command */
+       cmd.header = mc_encode_cmd_header(DPIO_CMDID_ENABLE,
+                                         cmd_flags,
+                                         token);
+
+       return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpio_disable() - Disable the DPIO, stop any I/O portal operation.
+ * @mc_io:     Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token:     Token of DPIO object
+ *
+ * Return:     '0' on Success; Error code otherwise
+ */
+int dpio_disable(struct fsl_mc_io *mc_io,
+                u32 cmd_flags,
+                u16 token)
+{
+       struct fsl_mc_command cmd = { 0 };
+
+       /* prepare command */
+       cmd.header = mc_encode_cmd_header(DPIO_CMDID_DISABLE,
+                                         cmd_flags,
+                                         token);
+
+       return mc_send_command(mc_io, &cmd);
+}
+
+/**
+ * dpio_get_attributes() - Retrieve DPIO attributes
+ * @mc_io:     Pointer to MC portal's I/O object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token:     Token of DPIO object
+ * @attr:      Returned object's attributes
+ *
+ * Return:     '0' on Success; Error code otherwise
+ */
+int dpio_get_attributes(struct fsl_mc_io *mc_io,
+                       u32 cmd_flags,
+                       u16 token,
+                       struct dpio_attr *attr)
+{
+       struct fsl_mc_command cmd = { 0 };
+       struct dpio_rsp_get_attr *dpio_rsp;
+       int err;
+
+       /* prepare command */
+       cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_ATTR,
+                                         cmd_flags,
+                                         token);
+
+       err = mc_send_command(mc_io, &cmd);
+       if (err)
+               return err;
+
+       /* retrieve response parameters */
+       dpio_rsp = (struct dpio_rsp_get_attr *)cmd.params;
+       attr->id = le32_to_cpu(dpio_rsp->id);
+       attr->qbman_portal_id = le16_to_cpu(dpio_rsp->qbman_portal_id);
+       attr->num_priorities = dpio_rsp->num_priorities;
+       attr->channel_mode = dpio_rsp->channel_mode & DPIO_CHANNEL_MODE_MASK;
+       attr->qbman_portal_ce_offset =
+               le64_to_cpu(dpio_rsp->qbman_portal_ce_addr);
+       attr->qbman_portal_ci_offset =
+               le64_to_cpu(dpio_rsp->qbman_portal_ci_addr);
+       attr->qbman_version = le32_to_cpu(dpio_rsp->qbman_version);
+
+       return 0;
+}
+
+/**
+ * dpio_get_api_version - Get Data Path I/O API version
+ * @mc_io:     Pointer to MC portal's DPIO object
+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver: Major version of DPIO API
+ * @minor_ver: Minor version of DPIO API
+ *
+ * Return:     '0' on Success; Error code otherwise
+ */
+int dpio_get_api_version(struct fsl_mc_io *mc_io,
+                        u32 cmd_flags,
+                        u16 *major_ver,
+                        u16 *minor_ver)
+{
+       struct fsl_mc_command cmd = { 0 };
+       int err;
+
+       /* prepare command */
+       cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_API_VERSION,
+                                         cmd_flags, 0);
+
+       err = mc_send_command(mc_io, &cmd);
+       if (err)
+               return err;
+
+       /* retrieve response parameters */
+       mc_cmd_read_api_version(&cmd, major_ver, minor_ver);
+
+       return 0;
+}
diff --git a/drivers/soc/fsl/dpio/dpio.h b/drivers/soc/fsl/dpio/dpio.h
new file mode 100644 (file)
index 0000000..49194c8
--- /dev/null
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/*
+ * Copyright 2013-2016 Freescale Semiconductor Inc.
+ * Copyright 2016 NXP
+ *
+ */
+#ifndef __FSL_DPIO_H
+#define __FSL_DPIO_H
+
+struct fsl_mc_io;
+
+int dpio_open(struct fsl_mc_io *mc_io,
+             u32               cmd_flags,
+             int               dpio_id,
+             u16               *token);
+
+int dpio_close(struct fsl_mc_io        *mc_io,
+              u32              cmd_flags,
+              u16              token);
+
+/**
+ * enum dpio_channel_mode - DPIO notification channel mode
+ * @DPIO_NO_CHANNEL: No support for notification channel
+ * @DPIO_LOCAL_CHANNEL: Notifications on data availability can be received by a
+ *     dedicated channel in the DPIO; user should point the queue's
+ *     destination in the relevant interface to this DPIO
+ */
+enum dpio_channel_mode {
+       DPIO_NO_CHANNEL = 0,
+       DPIO_LOCAL_CHANNEL = 1,
+};
+
+/**
+ * struct dpio_cfg - Structure representing DPIO configuration
+ * @channel_mode: Notification channel mode
+ * @num_priorities: Number of priorities for the notification channel (1-8);
+ *                     relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
+ */
+struct dpio_cfg {
+       enum dpio_channel_mode  channel_mode;
+       u8              num_priorities;
+};
+
+int dpio_enable(struct fsl_mc_io       *mc_io,
+               u32             cmd_flags,
+               u16             token);
+
+int dpio_disable(struct fsl_mc_io      *mc_io,
+                u32            cmd_flags,
+                u16            token);
+
+/**
+ * struct dpio_attr - Structure representing DPIO attributes
+ * @id: DPIO object ID
+ * @qbman_portal_ce_offset: offset of the software portal cache-enabled area
+ * @qbman_portal_ci_offset: offset of the software portal cache-inhibited area
+ * @qbman_portal_id: Software portal ID
+ * @channel_mode: Notification channel mode
+ * @num_priorities: Number of priorities for the notification channel (1-8);
+ *                     relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
+ * @qbman_version: QBMAN version
+ */
+struct dpio_attr {
+       int                     id;
+       u64             qbman_portal_ce_offset;
+       u64             qbman_portal_ci_offset;
+       u16             qbman_portal_id;
+       enum dpio_channel_mode  channel_mode;
+       u8                      num_priorities;
+       u32             qbman_version;
+};
+
+int dpio_get_attributes(struct fsl_mc_io       *mc_io,
+                       u32             cmd_flags,
+                       u16             token,
+                       struct dpio_attr        *attr);
+
+int dpio_get_api_version(struct fsl_mc_io *mc_io,
+                        u32 cmd_flags,
+                        u16 *major_ver,
+                        u16 *minor_ver);
+
+#endif /* __FSL_DPIO_H */
diff --git a/drivers/soc/fsl/dpio/qbman-portal.c b/drivers/soc/fsl/dpio/qbman-portal.c
new file mode 100644 (file)
index 0000000..cf1d448
--- /dev/null
@@ -0,0 +1,1005 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright 2016 NXP
+ *
+ */
+
+#include <asm/cacheflush.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <soc/fsl/dpaa2-global.h>
+
+#include "qbman-portal.h"
+
+#define QMAN_REV_4000   0x04000000
+#define QMAN_REV_4100   0x04010000
+#define QMAN_REV_4101   0x04010001
+#define QMAN_REV_MASK   0xffff0000
+
+/* All QBMan command and result structures use this "valid bit" encoding */
+#define QB_VALID_BIT ((u32)0x80)
+
+/* QBMan portal management command codes */
+#define QBMAN_MC_ACQUIRE       0x30
+#define QBMAN_WQCHAN_CONFIGURE 0x46
+
+/* CINH register offsets */
+#define QBMAN_CINH_SWP_EQAR    0x8c0
+#define QBMAN_CINH_SWP_DQPI    0xa00
+#define QBMAN_CINH_SWP_DCAP    0xac0
+#define QBMAN_CINH_SWP_SDQCR   0xb00
+#define QBMAN_CINH_SWP_RAR     0xcc0
+#define QBMAN_CINH_SWP_ISR     0xe00
+#define QBMAN_CINH_SWP_IER     0xe40
+#define QBMAN_CINH_SWP_ISDR    0xe80
+#define QBMAN_CINH_SWP_IIR     0xec0
+
+/* CENA register offsets */
+#define QBMAN_CENA_SWP_EQCR(n) (0x000 + ((u32)(n) << 6))
+#define QBMAN_CENA_SWP_DQRR(n) (0x200 + ((u32)(n) << 6))
+#define QBMAN_CENA_SWP_RCR(n)  (0x400 + ((u32)(n) << 6))
+#define QBMAN_CENA_SWP_CR      0x600
+#define QBMAN_CENA_SWP_RR(vb)  (0x700 + ((u32)(vb) >> 1))
+#define QBMAN_CENA_SWP_VDQCR   0x780
+
+/* Reverse mapping of QBMAN_CENA_SWP_DQRR() */
+#define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)(p) & 0x1ff) >> 6)
+
+/* Define token used to determine if response written to memory is valid */
+#define QMAN_DQ_TOKEN_VALID 1
+
+/* SDQCR attribute codes */
+#define QB_SDQCR_FC_SHIFT   29
+#define QB_SDQCR_FC_MASK    0x1
+#define QB_SDQCR_DCT_SHIFT  24
+#define QB_SDQCR_DCT_MASK   0x3
+#define QB_SDQCR_TOK_SHIFT  16
+#define QB_SDQCR_TOK_MASK   0xff
+#define QB_SDQCR_SRC_SHIFT  0
+#define QB_SDQCR_SRC_MASK   0xffff
+
+/* opaque token for static dequeues */
+#define QMAN_SDQCR_TOKEN    0xbb
+
+enum qbman_sdqcr_dct {
+       qbman_sdqcr_dct_null = 0,
+       qbman_sdqcr_dct_prio_ics,
+       qbman_sdqcr_dct_active_ics,
+       qbman_sdqcr_dct_active
+};
+
+enum qbman_sdqcr_fc {
+       qbman_sdqcr_fc_one = 0,
+       qbman_sdqcr_fc_up_to_3 = 1
+};
+
+/* Portal Access */
+
+static inline u32 qbman_read_register(struct qbman_swp *p, u32 offset)
+{
+       return readl_relaxed(p->addr_cinh + offset);
+}
+
+static inline void qbman_write_register(struct qbman_swp *p, u32 offset,
+                                       u32 value)
+{
+       writel_relaxed(value, p->addr_cinh + offset);
+}
+
+static inline void *qbman_get_cmd(struct qbman_swp *p, u32 offset)
+{
+       return p->addr_cena + offset;
+}
+
+#define QBMAN_CINH_SWP_CFG   0xd00
+
+#define SWP_CFG_DQRR_MF_SHIFT 20
+#define SWP_CFG_EST_SHIFT     16
+#define SWP_CFG_WN_SHIFT      14
+#define SWP_CFG_RPM_SHIFT     12
+#define SWP_CFG_DCM_SHIFT     10
+#define SWP_CFG_EPM_SHIFT     8
+#define SWP_CFG_SD_SHIFT      5
+#define SWP_CFG_SP_SHIFT      4
+#define SWP_CFG_SE_SHIFT      3
+#define SWP_CFG_DP_SHIFT      2
+#define SWP_CFG_DE_SHIFT      1
+#define SWP_CFG_EP_SHIFT      0
+
+static inline u32 qbman_set_swp_cfg(u8 max_fill, u8 wn,        u8 est, u8 rpm, u8 dcm,
+                                   u8 epm, int sd, int sp, int se,
+                                   int dp, int de, int ep)
+{
+       return (max_fill << SWP_CFG_DQRR_MF_SHIFT |
+               est << SWP_CFG_EST_SHIFT |
+               wn << SWP_CFG_WN_SHIFT |
+               rpm << SWP_CFG_RPM_SHIFT |
+               dcm << SWP_CFG_DCM_SHIFT |
+               epm << SWP_CFG_EPM_SHIFT |
+               sd << SWP_CFG_SD_SHIFT |
+               sp << SWP_CFG_SP_SHIFT |
+               se << SWP_CFG_SE_SHIFT |
+               dp << SWP_CFG_DP_SHIFT |
+               de << SWP_CFG_DE_SHIFT |
+               ep << SWP_CFG_EP_SHIFT);
+}
+
+/**
+ * qbman_swp_init() - Create a functional object representing the given
+ *                    QBMan portal descriptor.
+ * @d: the given qbman swp descriptor
+ *
+ * Return qbman_swp portal for success, NULL if the object cannot
+ * be created.
+ */
+struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
+{
+       struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
+       u32 reg;
+
+       if (!p)
+               return NULL;
+       p->desc = d;
+       p->mc.valid_bit = QB_VALID_BIT;
+       p->sdq = 0;
+       p->sdq |= qbman_sdqcr_dct_prio_ics << QB_SDQCR_DCT_SHIFT;
+       p->sdq |= qbman_sdqcr_fc_up_to_3 << QB_SDQCR_FC_SHIFT;
+       p->sdq |= QMAN_SDQCR_TOKEN << QB_SDQCR_TOK_SHIFT;
+
+       atomic_set(&p->vdq.available, 1);
+       p->vdq.valid_bit = QB_VALID_BIT;
+       p->dqrr.next_idx = 0;
+       p->dqrr.valid_bit = QB_VALID_BIT;
+
+       if ((p->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_4100) {
+               p->dqrr.dqrr_size = 4;
+               p->dqrr.reset_bug = 1;
+       } else {
+               p->dqrr.dqrr_size = 8;
+               p->dqrr.reset_bug = 0;
+       }
+
+       p->addr_cena = d->cena_bar;
+       p->addr_cinh = d->cinh_bar;
+
+       reg = qbman_set_swp_cfg(p->dqrr.dqrr_size,
+                               1, /* Writes Non-cacheable */
+                               0, /* EQCR_CI stashing threshold */
+                               3, /* RPM: Valid bit mode, RCR in array mode */
+                               2, /* DCM: Discrete consumption ack mode */
+                               3, /* EPM: Valid bit mode, EQCR in array mode */
+                               0, /* mem stashing drop enable == FALSE */
+                               1, /* mem stashing priority == TRUE */
+                               0, /* mem stashing enable == FALSE */
+                               1, /* dequeue stashing priority == TRUE */
+                               0, /* dequeue stashing enable == FALSE */
+                               0); /* EQCR_CI stashing priority == FALSE */
+
+       qbman_write_register(p, QBMAN_CINH_SWP_CFG, reg);
+       reg = qbman_read_register(p, QBMAN_CINH_SWP_CFG);
+       if (!reg) {
+               pr_err("qbman: the portal is not enabled!\n");
+               return NULL;
+       }
+
+       /*
+        * SDQCR needs to be initialized to 0 when no channels are
+        * being dequeued from or else the QMan HW will indicate an
+        * error.  The values that were calculated above will be
+        * applied when dequeues from a specific channel are enabled.
+        */
+       qbman_write_register(p, QBMAN_CINH_SWP_SDQCR, 0);
+       return p;
+}
+
+/**
+ * qbman_swp_finish() - Create and destroy a functional object representing
+ *                      the given QBMan portal descriptor.
+ * @p: the qbman_swp object to be destroyed
+ */
+void qbman_swp_finish(struct qbman_swp *p)
+{
+       kfree(p);
+}
+
+/**
+ * qbman_swp_interrupt_read_status()
+ * @p: the given software portal
+ *
+ * Return the value in the SWP_ISR register.
+ */
+u32 qbman_swp_interrupt_read_status(struct qbman_swp *p)
+{
+       return qbman_read_register(p, QBMAN_CINH_SWP_ISR);
+}
+
+/**
+ * qbman_swp_interrupt_clear_status()
+ * @p: the given software portal
+ * @mask: The mask to clear in SWP_ISR register
+ */
+void qbman_swp_interrupt_clear_status(struct qbman_swp *p, u32 mask)
+{
+       qbman_write_register(p, QBMAN_CINH_SWP_ISR, mask);
+}
+
+/**
+ * qbman_swp_interrupt_get_trigger() - read interrupt enable register
+ * @p: the given software portal
+ *
+ * Return the value in the SWP_IER register.
+ */
+u32 qbman_swp_interrupt_get_trigger(struct qbman_swp *p)
+{
+       return qbman_read_register(p, QBMAN_CINH_SWP_IER);
+}
+
+/**
+ * qbman_swp_interrupt_set_trigger() - enable interrupts for a swp
+ * @p: the given software portal
+ * @mask: The mask of bits to enable in SWP_IER
+ */
+void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, u32 mask)
+{
+       qbman_write_register(p, QBMAN_CINH_SWP_IER, mask);
+}
+
+/**
+ * qbman_swp_interrupt_get_inhibit() - read interrupt mask register
+ * @p: the given software portal object
+ *
+ * Return the value in the SWP_IIR register.
+ */
+int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p)
+{
+       return qbman_read_register(p, QBMAN_CINH_SWP_IIR);
+}
+
+/**
+ * qbman_swp_interrupt_set_inhibit() - write interrupt mask register
+ * @p: the given software portal object
+ * @mask: The mask to set in SWP_IIR register
+ */
+void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit)
+{
+       qbman_write_register(p, QBMAN_CINH_SWP_IIR, inhibit ? 0xffffffff : 0);
+}
+
+/*
+ * Different management commands all use this common base layer of code to issue
+ * commands and poll for results.
+ */
+
+/*
+ * Returns a pointer to where the caller should fill in their management command
+ * (caller should ignore the verb byte)
+ */
+void *qbman_swp_mc_start(struct qbman_swp *p)
+{
+       return qbman_get_cmd(p, QBMAN_CENA_SWP_CR);
+}
+
+/*
+ * Commits merges in the caller-supplied command verb (which should not include
+ * the valid-bit) and submits the command to hardware
+ */
+void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, u8 cmd_verb)
+{
+       u8 *v = cmd;
+
+       dma_wmb();
+       *v = cmd_verb | p->mc.valid_bit;
+}
+
+/*
+ * Checks for a completed response (returns non-NULL if only if the response
+ * is complete).
+ */
+void *qbman_swp_mc_result(struct qbman_swp *p)
+{
+       u32 *ret, verb;
+
+       ret = qbman_get_cmd(p, QBMAN_CENA_SWP_RR(p->mc.valid_bit));
+
+       /* Remove the valid-bit - command completed if the rest is non-zero */
+       verb = ret[0] & ~QB_VALID_BIT;
+       if (!verb)
+               return NULL;
+       p->mc.valid_bit ^= QB_VALID_BIT;
+       return ret;
+}
+
+#define QB_ENQUEUE_CMD_OPTIONS_SHIFT    0
+enum qb_enqueue_commands {
+       enqueue_empty = 0,
+       enqueue_response_always = 1,
+       enqueue_rejects_to_fq = 2
+};
+
+#define QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT      2
+#define QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT 3
+#define QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT     4
+
+/**
+ * qbman_eq_desc_clear() - Clear the contents of a descriptor to
+ *                         default/starting state.
+ */
+void qbman_eq_desc_clear(struct qbman_eq_desc *d)
+{
+       memset(d, 0, sizeof(*d));
+}
+
+/**
+ * qbman_eq_desc_set_no_orp() - Set enqueue descriptor without orp
+ * @d:                the enqueue descriptor.
+ * @response_success: 1 = enqueue with response always; 0 = enqueue with
+ *                    rejections returned on a FQ.
+ */
+void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success)
+{
+       d->verb &= ~(1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT);
+       if (respond_success)
+               d->verb |= enqueue_response_always;
+       else
+               d->verb |= enqueue_rejects_to_fq;
+}
+
+/*
+ * Exactly one of the following descriptor "targets" should be set. (Calling any
+ * one of these will replace the effect of any prior call to one of these.)
+ *   -enqueue to a frame queue
+ *   -enqueue to a queuing destination
+ */
+
+/**
+ * qbman_eq_desc_set_fq() - set the FQ for the enqueue command
+ * @d:    the enqueue descriptor
+ * @fqid: the id of the frame queue to be enqueued
+ */
+void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, u32 fqid)
+{
+       d->verb &= ~(1 << QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT);
+       d->tgtid = cpu_to_le32(fqid);
+}
+
+/**
+ * qbman_eq_desc_set_qd() - Set Queuing Destination for the enqueue command
+ * @d:       the enqueue descriptor
+ * @qdid:    the id of the queuing destination to be enqueued
+ * @qd_bin:  the queuing destination bin
+ * @qd_prio: the queuing destination priority
+ */
+void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, u32 qdid,
+                         u32 qd_bin, u32 qd_prio)
+{
+       d->verb |= 1 << QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT;
+       d->tgtid = cpu_to_le32(qdid);
+       d->qdbin = cpu_to_le16(qd_bin);
+       d->qpri = qd_prio;
+}
+
+#define EQAR_IDX(eqar)     ((eqar) & 0x7)
+#define EQAR_VB(eqar)      ((eqar) & 0x80)
+#define EQAR_SUCCESS(eqar) ((eqar) & 0x100)
+
+/**
+ * qbman_swp_enqueue() - Issue an enqueue command
+ * @s:  the software portal used for enqueue
+ * @d:  the enqueue descriptor
+ * @fd: the frame descriptor to be enqueued
+ *
+ * Please note that 'fd' should only be NULL if the "action" of the
+ * descriptor is "orp_hole" or "orp_nesn".
+ *
+ * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready.
+ */
+int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
+                     const struct dpaa2_fd *fd)
+{
+       struct qbman_eq_desc *p;
+       u32 eqar = qbman_read_register(s, QBMAN_CINH_SWP_EQAR);
+
+       if (!EQAR_SUCCESS(eqar))
+               return -EBUSY;
+
+       p = qbman_get_cmd(s, QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
+       memcpy(&p->dca, &d->dca, 31);
+       memcpy(&p->fd, fd, sizeof(*fd));
+
+       /* Set the verb byte, have to substitute in the valid-bit */
+       dma_wmb();
+       p->verb = d->verb | EQAR_VB(eqar);
+
+       return 0;
+}
+
+/* Static (push) dequeue */
+
+/**
+ * qbman_swp_push_get() - Get the push dequeue setup
+ * @p:           the software portal object
+ * @channel_idx: the channel index to query
+ * @enabled:     returned boolean to show whether the push dequeue is enabled
+ *               for the given channel
+ */
+void qbman_swp_push_get(struct qbman_swp *s, u8 channel_idx, int *enabled)
+{
+       u16 src = (s->sdq >> QB_SDQCR_SRC_SHIFT) & QB_SDQCR_SRC_MASK;
+
+       WARN_ON(channel_idx > 15);
+       *enabled = src | (1 << channel_idx);
+}
+
+/**
+ * qbman_swp_push_set() - Enable or disable push dequeue
+ * @p:           the software portal object
+ * @channel_idx: the channel index (0 to 15)
+ * @enable:      enable or disable push dequeue
+ */
+void qbman_swp_push_set(struct qbman_swp *s, u8 channel_idx, int enable)
+{
+       u16 dqsrc;
+
+       WARN_ON(channel_idx > 15);
+       if (enable)
+               s->sdq |= 1 << channel_idx;
+       else
+               s->sdq &= ~(1 << channel_idx);
+
+       /* Read make the complete src map.  If no channels are enabled
+        * the SDQCR must be 0 or else QMan will assert errors
+        */
+       dqsrc = (s->sdq >> QB_SDQCR_SRC_SHIFT) & QB_SDQCR_SRC_MASK;
+       if (dqsrc != 0)
+               qbman_write_register(s, QBMAN_CINH_SWP_SDQCR, s->sdq);
+       else
+               qbman_write_register(s, QBMAN_CINH_SWP_SDQCR, 0);
+}
+
+#define QB_VDQCR_VERB_DCT_SHIFT    0
+#define QB_VDQCR_VERB_DT_SHIFT     2
+#define QB_VDQCR_VERB_RLS_SHIFT    4
+#define QB_VDQCR_VERB_WAE_SHIFT    5
+
+enum qb_pull_dt_e {
+       qb_pull_dt_channel,
+       qb_pull_dt_workqueue,
+       qb_pull_dt_framequeue
+};
+
+/**
+ * qbman_pull_desc_clear() - Clear the contents of a descriptor to
+ *                           default/starting state
+ * @d: the pull dequeue descriptor to be cleared
+ */
+void qbman_pull_desc_clear(struct qbman_pull_desc *d)
+{
+       memset(d, 0, sizeof(*d));
+}
+
+/**
+ * qbman_pull_desc_set_storage()- Set the pull dequeue storage
+ * @d:            the pull dequeue descriptor to be set
+ * @storage:      the pointer of the memory to store the dequeue result
+ * @storage_phys: the physical address of the storage memory
+ * @stash:        to indicate whether write allocate is enabled
+ *
+ * If not called, or if called with 'storage' as NULL, the result pull dequeues
+ * will produce results to DQRR. If 'storage' is non-NULL, then results are
+ * produced to the given memory location (using the DMA address which
+ * the caller provides in 'storage_phys'), and 'stash' controls whether or not
+ * those writes to main-memory express a cache-warming attribute.
+ */
+void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
+                                struct dpaa2_dq *storage,
+                                dma_addr_t storage_phys,
+                                int stash)
+{
+       /* save the virtual address */
+       d->rsp_addr_virt = (u64)(uintptr_t)storage;
+
+       if (!storage) {
+               d->verb &= ~(1 << QB_VDQCR_VERB_RLS_SHIFT);
+               return;
+       }
+       d->verb |= 1 << QB_VDQCR_VERB_RLS_SHIFT;
+       if (stash)
+               d->verb |= 1 << QB_VDQCR_VERB_WAE_SHIFT;
+       else
+               d->verb &= ~(1 << QB_VDQCR_VERB_WAE_SHIFT);
+
+       d->rsp_addr = cpu_to_le64(storage_phys);
+}
+
+/**
+ * qbman_pull_desc_set_numframes() - Set the number of frames to be dequeued
+ * @d:         the pull dequeue descriptor to be set
+ * @numframes: number of frames to be set, must be between 1 and 16, inclusive
+ */
+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, u8 numframes)
+{
+       d->numf = numframes - 1;
+}
+
+/*
+ * Exactly one of the following descriptor "actions" should be set. (Calling any
+ * one of these will replace the effect of any prior call to one of these.)
+ * - pull dequeue from the given frame queue (FQ)
+ * - pull dequeue from any FQ in the given work queue (WQ)
+ * - pull dequeue from any FQ in any WQ in the given channel
+ */
+
+/**
+ * qbman_pull_desc_set_fq() - Set fqid from which the dequeue command dequeues
+ * @fqid: the frame queue index of the given FQ
+ */
+void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, u32 fqid)
+{
+       d->verb |= 1 << QB_VDQCR_VERB_DCT_SHIFT;
+       d->verb |= qb_pull_dt_framequeue << QB_VDQCR_VERB_DT_SHIFT;
+       d->dq_src = cpu_to_le32(fqid);
+}
+
+/**
+ * qbman_pull_desc_set_wq() - Set wqid from which the dequeue command dequeues
+ * @wqid: composed of channel id and wqid within the channel
+ * @dct:  the dequeue command type
+ */
+void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, u32 wqid,
+                           enum qbman_pull_type_e dct)
+{
+       d->verb |= dct << QB_VDQCR_VERB_DCT_SHIFT;
+       d->verb |= qb_pull_dt_workqueue << QB_VDQCR_VERB_DT_SHIFT;
+       d->dq_src = cpu_to_le32(wqid);
+}
+
+/**
+ * qbman_pull_desc_set_channel() - Set channelid from which the dequeue command
+ *                                 dequeues
+ * @chid: the channel id to be dequeued
+ * @dct:  the dequeue command type
+ */
+void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, u32 chid,
+                                enum qbman_pull_type_e dct)
+{
+       d->verb |= dct << QB_VDQCR_VERB_DCT_SHIFT;
+       d->verb |= qb_pull_dt_channel << QB_VDQCR_VERB_DT_SHIFT;
+       d->dq_src = cpu_to_le32(chid);
+}
+
+/**
+ * qbman_swp_pull() - Issue the pull dequeue command
+ * @s: the software portal object
+ * @d: the software portal descriptor which has been configured with
+ *     the set of qbman_pull_desc_set_*() calls
+ *
+ * Return 0 for success, and -EBUSY if the software portal is not ready
+ * to do pull dequeue.
+ */
+int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
+{
+       struct qbman_pull_desc *p;
+
+       if (!atomic_dec_and_test(&s->vdq.available)) {
+               atomic_inc(&s->vdq.available);
+               return -EBUSY;
+       }
+       s->vdq.storage = (void *)(uintptr_t)d->rsp_addr_virt;
+       p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR);
+       p->numf = d->numf;
+       p->tok = QMAN_DQ_TOKEN_VALID;
+       p->dq_src = d->dq_src;
+       p->rsp_addr = d->rsp_addr;
+       p->rsp_addr_virt = d->rsp_addr_virt;
+       dma_wmb();
+
+       /* Set the verb byte, have to substitute in the valid-bit */
+       p->verb = d->verb | s->vdq.valid_bit;
+       s->vdq.valid_bit ^= QB_VALID_BIT;
+
+       return 0;
+}
+
+#define QMAN_DQRR_PI_MASK   0xf
+
+/**
+ * qbman_swp_dqrr_next() - Get an valid DQRR entry
+ * @s: the software portal object
+ *
+ * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry
+ * only once, so repeated calls can return a sequence of DQRR entries, without
+ * requiring they be consumed immediately or in any particular order.
+ */
+const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s)
+{
+       u32 verb;
+       u32 response_verb;
+       u32 flags;
+       struct dpaa2_dq *p;
+
+       /* Before using valid-bit to detect if something is there, we have to
+        * handle the case of the DQRR reset bug...
+        */
+       if (unlikely(s->dqrr.reset_bug)) {
+               /*
+                * We pick up new entries by cache-inhibited producer index,
+                * which means that a non-coherent mapping would require us to
+                * invalidate and read *only* once that PI has indicated that
+                * there's an entry here. The first trip around the DQRR ring
+                * will be much less efficient than all subsequent trips around
+                * it...
+                */
+               u8 pi = qbman_read_register(s, QBMAN_CINH_SWP_DQPI) &
+                       QMAN_DQRR_PI_MASK;
+
+               /* there are new entries if pi != next_idx */
+               if (pi == s->dqrr.next_idx)
+                       return NULL;
+
+               /*
+                * if next_idx is/was the last ring index, and 'pi' is
+                * different, we can disable the workaround as all the ring
+                * entries have now been DMA'd to so valid-bit checking is
+                * repaired. Note: this logic needs to be based on next_idx
+                * (which increments one at a time), rather than on pi (which
+                * can burst and wrap-around between our snapshots of it).
+                */
+               if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1)) {
+                       pr_debug("next_idx=%d, pi=%d, clear reset bug\n",
+                                s->dqrr.next_idx, pi);
+                       s->dqrr.reset_bug = 0;
+               }
+               prefetch(qbman_get_cmd(s,
+                                      QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)));
+       }
+
+       p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
+       verb = p->dq.verb;
+
+       /*
+        * If the valid-bit isn't of the expected polarity, nothing there. Note,
+        * in the DQRR reset bug workaround, we shouldn't need to skip these
+        * check, because we've already determined that a new entry is available
+        * and we've invalidated the cacheline before reading it, so the
+        * valid-bit behaviour is repaired and should tell us what we already
+        * knew from reading PI.
+        */
+       if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) {
+               prefetch(qbman_get_cmd(s,
+                                      QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)));
+               return NULL;
+       }
+       /*
+        * There's something there. Move "next_idx" attention to the next ring
+        * entry (and prefetch it) before returning what we found.
+        */
+       s->dqrr.next_idx++;
+       s->dqrr.next_idx &= s->dqrr.dqrr_size - 1; /* Wrap around */
+       if (!s->dqrr.next_idx)
+               s->dqrr.valid_bit ^= QB_VALID_BIT;
+
+       /*
+        * If this is the final response to a volatile dequeue command
+        * indicate that the vdq is available
+        */
+       flags = p->dq.stat;
+       response_verb = verb & QBMAN_RESULT_MASK;
+       if ((response_verb == QBMAN_RESULT_DQ) &&
+           (flags & DPAA2_DQ_STAT_VOLATILE) &&
+           (flags & DPAA2_DQ_STAT_EXPIRED))
+               atomic_inc(&s->vdq.available);
+
+       prefetch(qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)));
+
+       return p;
+}
+
+/**
+ * qbman_swp_dqrr_consume() -  Consume DQRR entries previously returned from
+ *                             qbman_swp_dqrr_next().
+ * @s: the software portal object
+ * @dq: the DQRR entry to be consumed
+ */
+void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct dpaa2_dq *dq)
+{
+       qbman_write_register(s, QBMAN_CINH_SWP_DCAP, QBMAN_IDX_FROM_DQRR(dq));
+}
+
+/**
+ * qbman_result_has_new_result() - Check and get the dequeue response from the
+ *                                 dq storage memory set in pull dequeue command
+ * @s: the software portal object
+ * @dq: the dequeue result read from the memory
+ *
+ * Return 1 for getting a valid dequeue result, or 0 for not getting a valid
+ * dequeue result.
+ *
+ * Only used for user-provided storage of dequeue results, not DQRR. For
+ * efficiency purposes, the driver will perform any required endianness
+ * conversion to ensure that the user's dequeue result storage is in host-endian
+ * format. As such, once the user has called qbman_result_has_new_result() and
+ * been returned a valid dequeue result, they should not call it again on
+ * the same memory location (except of course if another dequeue command has
+ * been executed to produce a new result to that location).
+ */
+int qbman_result_has_new_result(struct qbman_swp *s, const struct dpaa2_dq *dq)
+{
+       if (dq->dq.tok != QMAN_DQ_TOKEN_VALID)
+               return 0;
+
+       /*
+        * Set token to be 0 so we will detect change back to 1
+        * next time the looping is traversed. Const is cast away here
+        * as we want users to treat the dequeue responses as read only.
+        */
+       ((struct dpaa2_dq *)dq)->dq.tok = 0;
+
+       /*
+        * Determine whether VDQCR is available based on whether the
+        * current result is sitting in the first storage location of
+        * the busy command.
+        */
+       if (s->vdq.storage == dq) {
+               s->vdq.storage = NULL;
+               atomic_inc(&s->vdq.available);
+       }
+
+       return 1;
+}
+
+/**
+ * qbman_release_desc_clear() - Clear the contents of a descriptor to
+ *                              default/starting state.
+ */
+void qbman_release_desc_clear(struct qbman_release_desc *d)
+{
+       memset(d, 0, sizeof(*d));
+       d->verb = 1 << 5; /* Release Command Valid */
+}
+
+/**
+ * qbman_release_desc_set_bpid() - Set the ID of the buffer pool to release to
+ */
+void qbman_release_desc_set_bpid(struct qbman_release_desc *d, u16 bpid)
+{
+       d->bpid = cpu_to_le16(bpid);
+}
+
+/**
+ * qbman_release_desc_set_rcdi() - Determines whether or not the portal's RCDI
+ * interrupt source should be asserted after the release command is completed.
+ */
+void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable)
+{
+       if (enable)
+               d->verb |= 1 << 6;
+       else
+               d->verb &= ~(1 << 6);
+}
+
+#define RAR_IDX(rar)     ((rar) & 0x7)
+#define RAR_VB(rar)      ((rar) & 0x80)
+#define RAR_SUCCESS(rar) ((rar) & 0x100)
+
+/**
+ * qbman_swp_release() - Issue a buffer release command
+ * @s:           the software portal object
+ * @d:           the release descriptor
+ * @buffers:     a pointer pointing to the buffer address to be released
+ * @num_buffers: number of buffers to be released,  must be less than 8
+ *
+ * Return 0 for success, -EBUSY if the release command ring is not ready.
+ */
+int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
+                     const u64 *buffers, unsigned int num_buffers)
+{
+       int i;
+       struct qbman_release_desc *p;
+       u32 rar;
+
+       if (!num_buffers || (num_buffers > 7))
+               return -EINVAL;
+
+       rar = qbman_read_register(s, QBMAN_CINH_SWP_RAR);
+       if (!RAR_SUCCESS(rar))
+               return -EBUSY;
+
+       /* Start the release command */
+       p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
+       /* Copy the caller's buffer pointers to the command */
+       for (i = 0; i < num_buffers; i++)
+               p->buf[i] = cpu_to_le64(buffers[i]);
+       p->bpid = d->bpid;
+
+       /*
+        * Set the verb byte, have to substitute in the valid-bit and the number
+        * of buffers.
+        */
+       dma_wmb();
+       p->verb = d->verb | RAR_VB(rar) | num_buffers;
+
+       return 0;
+}
+
+struct qbman_acquire_desc {
+       u8 verb;
+       u8 reserved;
+       __le16 bpid;
+       u8 num;
+       u8 reserved2[59];
+};
+
+struct qbman_acquire_rslt {
+       u8 verb;
+       u8 rslt;
+       __le16 reserved;
+       u8 num;
+       u8 reserved2[3];
+       __le64 buf[7];
+};
+
+/**
+ * qbman_swp_acquire() - Issue a buffer acquire command
+ * @s:           the software portal object
+ * @bpid:        the buffer pool index
+ * @buffers:     a pointer pointing to the acquired buffer addresses
+ * @num_buffers: number of buffers to be acquired, must be less than 8
+ *
+ * Return 0 for success, or negative error code if the acquire command
+ * fails.
+ */
+int qbman_swp_acquire(struct qbman_swp *s, u16 bpid, u64 *buffers,
+                     unsigned int num_buffers)
+{
+       struct qbman_acquire_desc *p;
+       struct qbman_acquire_rslt *r;
+       int i;
+
+       if (!num_buffers || (num_buffers > 7))
+               return -EINVAL;
+
+       /* Start the management command */
+       p = qbman_swp_mc_start(s);
+
+       if (!p)
+               return -EBUSY;
+
+       /* Encode the caller-provided attributes */
+       p->bpid = cpu_to_le16(bpid);
+       p->num = num_buffers;
+
+       /* Complete the management command */
+       r = qbman_swp_mc_complete(s, p, QBMAN_MC_ACQUIRE);
+       if (unlikely(!r)) {
+               pr_err("qbman: acquire from BPID %d failed, no response\n",
+                      bpid);
+               return -EIO;
+       }
+
+       /* Decode the outcome */
+       WARN_ON((r->verb & 0x7f) != QBMAN_MC_ACQUIRE);
+
+       /* Determine success or failure */
+       if (unlikely(r->rslt != QBMAN_MC_RSLT_OK)) {
+               pr_err("qbman: acquire from BPID 0x%x failed, code=0x%02x\n",
+                      bpid, r->rslt);
+               return -EIO;
+       }
+
+       WARN_ON(r->num > num_buffers);
+
+       /* Copy the acquired buffers to the caller's array */
+       for (i = 0; i < r->num; i++)
+               buffers[i] = le64_to_cpu(r->buf[i]);
+
+       return (int)r->num;
+}
+
+struct qbman_alt_fq_state_desc {
+       u8 verb;
+       u8 reserved[3];
+       __le32 fqid;
+       u8 reserved2[56];
+};
+
+struct qbman_alt_fq_state_rslt {
+       u8 verb;
+       u8 rslt;
+       u8 reserved[62];
+};
+
+#define ALT_FQ_FQID_MASK 0x00FFFFFF
+
+int qbman_swp_alt_fq_state(struct qbman_swp *s, u32 fqid,
+                          u8 alt_fq_verb)
+{
+       struct qbman_alt_fq_state_desc *p;
+       struct qbman_alt_fq_state_rslt *r;
+
+       /* Start the management command */
+       p = qbman_swp_mc_start(s);
+       if (!p)
+               return -EBUSY;
+
+       p->fqid = cpu_to_le32(fqid & ALT_FQ_FQID_MASK);
+
+       /* Complete the management command */
+       r = qbman_swp_mc_complete(s, p, alt_fq_verb);
+       if (unlikely(!r)) {
+               pr_err("qbman: mgmt cmd failed, no response (verb=0x%x)\n",
+                      alt_fq_verb);
+               return -EIO;
+       }
+
+       /* Decode the outcome */
+       WARN_ON((r->verb & QBMAN_RESULT_MASK) != alt_fq_verb);
+
+       /* Determine success or failure */
+       if (unlikely(r->rslt != QBMAN_MC_RSLT_OK)) {
+               pr_err("qbman: ALT FQID %d failed: verb = 0x%08x code = 0x%02x\n",
+                      fqid, r->verb, r->rslt);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+struct qbman_cdan_ctrl_desc {
+       u8 verb;
+       u8 reserved;
+       __le16 ch;
+       u8 we;
+       u8 ctrl;
+       __le16 reserved2;
+       __le64 cdan_ctx;
+       u8 reserved3[48];
+
+};
+
+struct qbman_cdan_ctrl_rslt {
+       u8 verb;
+       u8 rslt;
+       __le16 ch;
+       u8 reserved[60];
+};
+
+int qbman_swp_CDAN_set(struct qbman_swp *s, u16 channelid,
+                      u8 we_mask, u8 cdan_en,
+                      u64 ctx)
+{
+       struct qbman_cdan_ctrl_desc *p = NULL;
+       struct qbman_cdan_ctrl_rslt *r = NULL;
+
+       /* Start the management command */
+       p = qbman_swp_mc_start(s);
+       if (!p)
+               return -EBUSY;
+
+       /* Encode the caller-provided attributes */
+       p->ch = cpu_to_le16(channelid);
+       p->we = we_mask;
+       if (cdan_en)
+               p->ctrl = 1;
+       else
+               p->ctrl = 0;
+       p->cdan_ctx = cpu_to_le64(ctx);
+
+       /* Complete the management command */
+       r = qbman_swp_mc_complete(s, p, QBMAN_WQCHAN_CONFIGURE);
+       if (unlikely(!r)) {
+               pr_err("qbman: wqchan config failed, no response\n");
+               return -EIO;
+       }
+
+       WARN_ON((r->verb & 0x7f) != QBMAN_WQCHAN_CONFIGURE);
+
+       /* Determine success or failure */
+       if (unlikely(r->rslt != QBMAN_MC_RSLT_OK)) {
+               pr_err("qbman: CDAN cQID %d failed: code = 0x%02x\n",
+                      channelid, r->rslt);
+               return -EIO;
+       }
+
+       return 0;
+}
diff --git a/drivers/soc/fsl/dpio/qbman-portal.h b/drivers/soc/fsl/dpio/qbman-portal.h
new file mode 100644 (file)
index 0000000..89d1dd9
--- /dev/null
@@ -0,0 +1,444 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/*
+ * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright 2016 NXP
+ *
+ */
+#ifndef __FSL_QBMAN_PORTAL_H
+#define __FSL_QBMAN_PORTAL_H
+
+#include <soc/fsl/dpaa2-fd.h>
+
+struct dpaa2_dq;
+struct qbman_swp;
+
+/* qbman software portal descriptor structure */
+struct qbman_swp_desc {
+       void *cena_bar; /* Cache-enabled portal base address */
+       void __iomem *cinh_bar; /* Cache-inhibited portal base address */
+       u32 qman_version;
+};
+
+#define QBMAN_SWP_INTERRUPT_EQRI 0x01
+#define QBMAN_SWP_INTERRUPT_EQDI 0x02
+#define QBMAN_SWP_INTERRUPT_DQRI 0x04
+#define QBMAN_SWP_INTERRUPT_RCRI 0x08
+#define QBMAN_SWP_INTERRUPT_RCDI 0x10
+#define QBMAN_SWP_INTERRUPT_VDCI 0x20
+
+/* the structure for pull dequeue descriptor */
+struct qbman_pull_desc {
+       u8 verb;
+       u8 numf;
+       u8 tok;
+       u8 reserved;
+       __le32 dq_src;
+       __le64 rsp_addr;
+       u64 rsp_addr_virt;
+       u8 padding[40];
+};
+
+enum qbman_pull_type_e {
+       /* dequeue with priority precedence, respect intra-class scheduling */
+       qbman_pull_type_prio = 1,
+       /* dequeue with active FQ precedence, respect ICS */
+       qbman_pull_type_active,
+       /* dequeue with active FQ precedence, no ICS */
+       qbman_pull_type_active_noics
+};
+
+/* Definitions for parsing dequeue entries */
+#define QBMAN_RESULT_MASK      0x7f
+#define QBMAN_RESULT_DQ        0x60
+#define QBMAN_RESULT_FQRN      0x21
+#define QBMAN_RESULT_FQRNI     0x22
+#define QBMAN_RESULT_FQPN      0x24
+#define QBMAN_RESULT_FQDAN     0x25
+#define QBMAN_RESULT_CDAN      0x26
+#define QBMAN_RESULT_CSCN_MEM  0x27
+#define QBMAN_RESULT_CGCU      0x28
+#define QBMAN_RESULT_BPSCN     0x29
+#define QBMAN_RESULT_CSCN_WQ   0x2a
+
+/* QBMan FQ management command codes */
+#define QBMAN_FQ_SCHEDULE      0x48
+#define QBMAN_FQ_FORCE         0x49
+#define QBMAN_FQ_XON           0x4d
+#define QBMAN_FQ_XOFF          0x4e
+
+/* structure of enqueue descriptor */
+struct qbman_eq_desc {
+       u8 verb;
+       u8 dca;
+       __le16 seqnum;
+       __le16 orpid;
+       __le16 reserved1;
+       __le32 tgtid;
+       __le32 tag;
+       __le16 qdbin;
+       u8 qpri;
+       u8 reserved[3];
+       u8 wae;
+       u8 rspid;
+       __le64 rsp_addr;
+       u8 fd[32];
+};
+
+/* buffer release descriptor */
+struct qbman_release_desc {
+       u8 verb;
+       u8 reserved;
+       __le16 bpid;
+       __le32 reserved2;
+       __le64 buf[7];
+};
+
+/* Management command result codes */
+#define QBMAN_MC_RSLT_OK      0xf0
+
+#define CODE_CDAN_WE_EN    0x1
+#define CODE_CDAN_WE_CTX   0x4
+
+/* portal data structure */
+struct qbman_swp {
+       const struct qbman_swp_desc *desc;
+       void *addr_cena;
+       void __iomem *addr_cinh;
+
+       /* Management commands */
+       struct {
+               u32 valid_bit; /* 0x00 or 0x80 */
+       } mc;
+
+       /* Push dequeues */
+       u32 sdq;
+
+       /* Volatile dequeues */
+       struct {
+               atomic_t available; /* indicates if a command can be sent */
+               u32 valid_bit; /* 0x00 or 0x80 */
+               struct dpaa2_dq *storage; /* NULL if DQRR */
+       } vdq;
+
+       /* DQRR */
+       struct {
+               u32 next_idx;
+               u32 valid_bit;
+               u8 dqrr_size;
+               int reset_bug; /* indicates dqrr reset workaround is needed */
+       } dqrr;
+};
+
+struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d);
+void qbman_swp_finish(struct qbman_swp *p);
+u32 qbman_swp_interrupt_read_status(struct qbman_swp *p);
+void qbman_swp_interrupt_clear_status(struct qbman_swp *p, u32 mask);
+u32 qbman_swp_interrupt_get_trigger(struct qbman_swp *p);
+void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, u32 mask);
+int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p);
+void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit);
+
+void qbman_swp_push_get(struct qbman_swp *p, u8 channel_idx, int *enabled);
+void qbman_swp_push_set(struct qbman_swp *p, u8 channel_idx, int enable);
+
+void qbman_pull_desc_clear(struct qbman_pull_desc *d);
+void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
+                                struct dpaa2_dq *storage,
+                                dma_addr_t storage_phys,
+                                int stash);
+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, u8 numframes);
+void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, u32 fqid);
+void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, u32 wqid,
+                           enum qbman_pull_type_e dct);
+void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, u32 chid,
+                                enum qbman_pull_type_e dct);
+
+int qbman_swp_pull(struct qbman_swp *p, struct qbman_pull_desc *d);
+
+const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s);
+void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct dpaa2_dq *dq);
+
+int qbman_result_has_new_result(struct qbman_swp *p, const struct dpaa2_dq *dq);
+
+void qbman_eq_desc_clear(struct qbman_eq_desc *d);
+void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success);
+void qbman_eq_desc_set_token(struct qbman_eq_desc *d, u8 token);
+void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, u32 fqid);
+void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, u32 qdid,
+                         u32 qd_bin, u32 qd_prio);
+
+int qbman_swp_enqueue(struct qbman_swp *p, const struct qbman_eq_desc *d,
+                     const struct dpaa2_fd *fd);
+
+void qbman_release_desc_clear(struct qbman_release_desc *d);
+void qbman_release_desc_set_bpid(struct qbman_release_desc *d, u16 bpid);
+void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable);
+
+int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
+                     const u64 *buffers, unsigned int num_buffers);
+int qbman_swp_acquire(struct qbman_swp *s, u16 bpid, u64 *buffers,
+                     unsigned int num_buffers);
+int qbman_swp_alt_fq_state(struct qbman_swp *s, u32 fqid,
+                          u8 alt_fq_verb);
+int qbman_swp_CDAN_set(struct qbman_swp *s, u16 channelid,
+                      u8 we_mask, u8 cdan_en,
+                      u64 ctx);
+
+void *qbman_swp_mc_start(struct qbman_swp *p);
+void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, u8 cmd_verb);
+void *qbman_swp_mc_result(struct qbman_swp *p);
+
+/**
+ * qbman_result_is_DQ() - check if the dequeue result is a dequeue response
+ * @dq: the dequeue result to be checked
+ *
+ * DQRR entries may contain non-dequeue results, ie. notifications
+ */
+static inline int qbman_result_is_DQ(const struct dpaa2_dq *dq)
+{
+       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_DQ);
+}
+
+/**
+ * qbman_result_is_SCN() - Check the dequeue result is notification or not
+ * @dq: the dequeue result to be checked
+ *
+ */
+static inline int qbman_result_is_SCN(const struct dpaa2_dq *dq)
+{
+       return !qbman_result_is_DQ(dq);
+}
+
+/* FQ Data Availability */
+static inline int qbman_result_is_FQDAN(const struct dpaa2_dq *dq)
+{
+       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_FQDAN);
+}
+
+/* Channel Data Availability */
+static inline int qbman_result_is_CDAN(const struct dpaa2_dq *dq)
+{
+       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_CDAN);
+}
+
+/* Congestion State Change */
+static inline int qbman_result_is_CSCN(const struct dpaa2_dq *dq)
+{
+       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_CSCN_WQ);
+}
+
+/* Buffer Pool State Change */
+static inline int qbman_result_is_BPSCN(const struct dpaa2_dq *dq)
+{
+       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_BPSCN);
+}
+
+/* Congestion Group Count Update */
+static inline int qbman_result_is_CGCU(const struct dpaa2_dq *dq)
+{
+       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_CGCU);
+}
+
+/* Retirement */
+static inline int qbman_result_is_FQRN(const struct dpaa2_dq *dq)
+{
+       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_FQRN);
+}
+
+/* Retirement Immediate */
+static inline int qbman_result_is_FQRNI(const struct dpaa2_dq *dq)
+{
+       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_FQRNI);
+}
+
+ /* Park */
+static inline int qbman_result_is_FQPN(const struct dpaa2_dq *dq)
+{
+       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_FQPN);
+}
+
+/**
+ * qbman_result_SCN_state() - Get the state field in State-change notification
+ */
+static inline u8 qbman_result_SCN_state(const struct dpaa2_dq *scn)
+{
+       return scn->scn.state;
+}
+
+#define SCN_RID_MASK 0x00FFFFFF
+
+/**
+ * qbman_result_SCN_rid() - Get the resource id in State-change notification
+ */
+static inline u32 qbman_result_SCN_rid(const struct dpaa2_dq *scn)
+{
+       return le32_to_cpu(scn->scn.rid_tok) & SCN_RID_MASK;
+}
+
+/**
+ * qbman_result_SCN_ctx() - Get the context data in State-change notification
+ */
+static inline u64 qbman_result_SCN_ctx(const struct dpaa2_dq *scn)
+{
+       return le64_to_cpu(scn->scn.ctx);
+}
+
+/**
+ * qbman_swp_fq_schedule() - Move the fq to the scheduled state
+ * @s:    the software portal object
+ * @fqid: the index of frame queue to be scheduled
+ *
+ * There are a couple of different ways that a FQ can end up parked state,
+ * This schedules it.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+static inline int qbman_swp_fq_schedule(struct qbman_swp *s, u32 fqid)
+{
+       return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_SCHEDULE);
+}
+
+/**
+ * qbman_swp_fq_force() - Force the FQ to fully scheduled state
+ * @s:    the software portal object
+ * @fqid: the index of frame queue to be forced
+ *
+ * Force eligible will force a tentatively-scheduled FQ to be fully-scheduled
+ * and thus be available for selection by any channel-dequeuing behaviour (push
+ * or pull). If the FQ is subsequently "dequeued" from the channel and is still
+ * empty at the time this happens, the resulting dq_entry will have no FD.
+ * (qbman_result_DQ_fd() will return NULL.)
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+static inline int qbman_swp_fq_force(struct qbman_swp *s, u32 fqid)
+{
+       return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_FORCE);
+}
+
+/**
+ * qbman_swp_fq_xon() - sets FQ flow-control to XON
+ * @s:    the software portal object
+ * @fqid: the index of frame queue
+ *
+ * This setting doesn't affect enqueues to the FQ, just dequeues.
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+static inline int qbman_swp_fq_xon(struct qbman_swp *s, u32 fqid)
+{
+       return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XON);
+}
+
+/**
+ * qbman_swp_fq_xoff() - sets FQ flow-control to XOFF
+ * @s:    the software portal object
+ * @fqid: the index of frame queue
+ *
+ * This setting doesn't affect enqueues to the FQ, just dequeues.
+ * XOFF FQs will remain in the tenatively-scheduled state, even when
+ * non-empty, meaning they won't be selected for scheduled dequeuing.
+ * If a FQ is changed to XOFF after it had already become truly-scheduled
+ * to a channel, and a pull dequeue of that channel occurs that selects
+ * that FQ for dequeuing, then the resulting dq_entry will have no FD.
+ * (qbman_result_DQ_fd() will return NULL.)
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+static inline int qbman_swp_fq_xoff(struct qbman_swp *s, u32 fqid)
+{
+       return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XOFF);
+}
+
+/* If the user has been allocated a channel object that is going to generate
+ * CDANs to another channel, then the qbman_swp_CDAN* functions will be
+ * necessary.
+ *
+ * CDAN-enabled channels only generate a single CDAN notification, after which
+ * they need to be reenabled before they'll generate another. The idea is
+ * that pull dequeuing will occur in reaction to the CDAN, followed by a
+ * reenable step. Each function generates a distinct command to hardware, so a
+ * combination function is provided if the user wishes to modify the "context"
+ * (which shows up in each CDAN message) each time they reenable, as a single
+ * command to hardware.
+ */
+
+/**
+ * qbman_swp_CDAN_set_context() - Set CDAN context
+ * @s:         the software portal object
+ * @channelid: the channel index
+ * @ctx:       the context to be set in CDAN
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+static inline int qbman_swp_CDAN_set_context(struct qbman_swp *s, u16 channelid,
+                                            u64 ctx)
+{
+       return qbman_swp_CDAN_set(s, channelid,
+                                 CODE_CDAN_WE_CTX,
+                                 0, ctx);
+}
+
+/**
+ * qbman_swp_CDAN_enable() - Enable CDAN for the channel
+ * @s:         the software portal object
+ * @channelid: the index of the channel to generate CDAN
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+static inline int qbman_swp_CDAN_enable(struct qbman_swp *s, u16 channelid)
+{
+       return qbman_swp_CDAN_set(s, channelid,
+                                 CODE_CDAN_WE_EN,
+                                 1, 0);
+}
+
+/**
+ * qbman_swp_CDAN_disable() - disable CDAN for the channel
+ * @s:         the software portal object
+ * @channelid: the index of the channel to generate CDAN
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+static inline int qbman_swp_CDAN_disable(struct qbman_swp *s, u16 channelid)
+{
+       return qbman_swp_CDAN_set(s, channelid,
+                                 CODE_CDAN_WE_EN,
+                                 0, 0);
+}
+
+/**
+ * qbman_swp_CDAN_set_context_enable() - Set CDAN contest and enable CDAN
+ * @s:         the software portal object
+ * @channelid: the index of the channel to generate CDAN
+ * @ctx:i      the context set in CDAN
+ *
+ * Return 0 for success, or negative error code for failure.
+ */
+static inline int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s,
+                                                   u16 channelid,
+                                                   u64 ctx)
+{
+       return qbman_swp_CDAN_set(s, channelid,
+                                 CODE_CDAN_WE_EN | CODE_CDAN_WE_CTX,
+                                 1, ctx);
+}
+
+/* Wraps up submit + poll-for-result */
+static inline void *qbman_swp_mc_complete(struct qbman_swp *swp, void *cmd,
+                                         u8 cmd_verb)
+{
+       int loopvar = 1000;
+
+       qbman_swp_mc_submit(swp, cmd, cmd_verb);
+
+       do {
+               cmd = qbman_swp_mc_result(swp);
+       } while (!cmd && loopvar--);
+
+       WARN_ON(!loopvar);
+
+       return cmd;
+}
+
+#endif /* __FSL_QBMAN_PORTAL_H */
index fb4e6bf0a0c43383e36f0605c083f84a5ed602b1..d570cb5fd381964176611eff2dc144295e469354 100644 (file)
@@ -1,5 +1,5 @@
 menuconfig FSL_DPAA
-       bool "Freescale DPAA 1.x support"
+       bool "QorIQ DPAA1 framework support"
        depends on (FSL_SOC_BOOKE || ARCH_LAYERSCAPE)
        select GENERIC_ALLOCATOR
        help
index 73a2e08b47ef97a76fb7e5bd187acfdc5762f973..fabba17e9d65b6976c1ad17de08406288d4e5df2 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 config QUICC_ENGINE
-       bool "Freescale QUICC Engine (QE) Support"
+       bool "QUICC Engine (QE) framework support"
        depends on FSL_SOC && PPC32
        select GENERIC_ALLOCATOR
        select CRC32
index 3b27075c21a7f41e6fdd2cdd591cac2da8713600..819bed0f566799db5e34988282ae85032a8742ad 100644 (file)
@@ -83,6 +83,33 @@ static void qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
        spin_unlock_irqrestore(&qe_gc->lock, flags);
 }
 
+static void qe_gpio_set_multiple(struct gpio_chip *gc,
+                                unsigned long *mask, unsigned long *bits)
+{
+       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+       struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);
+       struct qe_pio_regs __iomem *regs = mm_gc->regs;
+       unsigned long flags;
+       int i;
+
+       spin_lock_irqsave(&qe_gc->lock, flags);
+
+       for (i = 0; i < gc->ngpio; i++) {
+               if (*mask == 0)
+                       break;
+               if (__test_and_clear_bit(i, mask)) {
+                       if (test_bit(i, bits))
+                               qe_gc->cpdata |= (1U << (QE_PIO_PINS - 1 - i));
+                       else
+                               qe_gc->cpdata &= ~(1U << (QE_PIO_PINS - 1 - i));
+               }
+       }
+
+       out_be32(&regs->cpdata, qe_gc->cpdata);
+
+       spin_unlock_irqrestore(&qe_gc->lock, flags);
+}
+
 static int qe_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 {
        struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
@@ -298,6 +325,7 @@ static int __init qe_add_gpiochips(void)
                gc->direction_output = qe_gpio_dir_out;
                gc->get = qe_gpio_get;
                gc->set = qe_gpio_set;
+               gc->set_multiple = qe_gpio_set_multiple;
 
                ret = of_mm_gpiochip_add_data(np, mm_gc, qe_gc);
                if (ret)
index 546960a18d60093ea5051228938533ee187254fa..b3da635970ea70f56d98a4db94d234178cfa9a82 100644 (file)
@@ -54,7 +54,6 @@ struct imx_pm_domain {
        unsigned int reg_offs;
        signed char cntr_pdn_bit;
        unsigned int ipg_rate_mhz;
-       unsigned int flags;
 };
 
 static inline struct imx_pm_domain *
@@ -69,9 +68,6 @@ static int imx6_pm_domain_power_off(struct generic_pm_domain *genpd)
        int iso, iso2sw;
        u32 val;
 
-       if (pd->flags & PGC_DOMAIN_FLAG_NO_PD)
-               return -EBUSY;
-
        /* Read ISO and ISO2SW power down delays */
        regmap_read(pd->regmap, pd->reg_offs + GPC_PGC_PUPSCR_OFFS, &val);
        iso = val & 0x3f;
@@ -295,26 +291,31 @@ static struct imx_pm_domain imx_gpc_domains[] = {
 struct imx_gpc_dt_data {
        int num_domains;
        bool err009619_present;
+       bool err006287_present;
 };
 
 static const struct imx_gpc_dt_data imx6q_dt_data = {
        .num_domains = 2,
        .err009619_present = false,
+       .err006287_present = false,
 };
 
 static const struct imx_gpc_dt_data imx6qp_dt_data = {
        .num_domains = 2,
        .err009619_present = true,
+       .err006287_present = false,
 };
 
 static const struct imx_gpc_dt_data imx6sl_dt_data = {
        .num_domains = 3,
        .err009619_present = false,
+       .err006287_present = true,
 };
 
 static const struct imx_gpc_dt_data imx6sx_dt_data = {
        .num_domains = 4,
        .err009619_present = false,
+       .err006287_present = false,
 };
 
 static const struct of_device_id imx_gpc_dt_ids[] = {
@@ -434,8 +435,13 @@ static int imx_gpc_probe(struct platform_device *pdev)
 
        /* Disable PU power down in normal operation if ERR009619 is present */
        if (of_id_data->err009619_present)
-               imx_gpc_domains[GPC_PGC_DOMAIN_PU].flags |=
-                               PGC_DOMAIN_FLAG_NO_PD;
+               imx_gpc_domains[GPC_PGC_DOMAIN_PU].base.flags |=
+                               GENPD_FLAG_ALWAYS_ON;
+
+       /* Keep DISP always on if ERR006287 is present */
+       if (of_id_data->err006287_present)
+               imx_gpc_domains[GPC_PGC_DOMAIN_DISPLAY].base.flags |=
+                               GENPD_FLAG_ALWAYS_ON;
 
        if (!pgc_node) {
                ret = imx_gpc_old_dt_init(&pdev->dev, regmap,
index 2afae64061d85c939ea61a8285f1c33b894ac8a4..4e931fdf4d0918aa59368390ed7d8dc8c194b26c 100644 (file)
@@ -146,6 +146,21 @@ static const u32 mt6397_regs[] = {
        [PWRAP_DEW_CIPHER_SWRST] =      0xbc24,
 };
 
+static const u32 mt6351_regs[] = {
+       [PWRAP_DEW_DIO_EN] =            0x02F2,
+       [PWRAP_DEW_READ_TEST] =         0x02F4,
+       [PWRAP_DEW_WRITE_TEST] =        0x02F6,
+       [PWRAP_DEW_CRC_EN] =            0x02FA,
+       [PWRAP_DEW_CRC_VAL] =           0x02FC,
+       [PWRAP_DEW_CIPHER_KEY_SEL] =    0x0300,
+       [PWRAP_DEW_CIPHER_IV_SEL] =     0x0302,
+       [PWRAP_DEW_CIPHER_EN] =         0x0304,
+       [PWRAP_DEW_CIPHER_RDY] =        0x0306,
+       [PWRAP_DEW_CIPHER_MODE] =       0x0308,
+       [PWRAP_DEW_CIPHER_SWRST] =      0x030A,
+       [PWRAP_DEW_RDDMY_NO] =          0x030C,
+};
+
 enum pwrap_regs {
        PWRAP_MUX_SEL,
        PWRAP_WRAP_EN,
@@ -366,6 +381,39 @@ static int mt2701_regs[] = {
        [PWRAP_ADC_RDATA_ADDR2] =       0x154,
 };
 
+static int mt6797_regs[] = {
+       [PWRAP_MUX_SEL] =               0x0,
+       [PWRAP_WRAP_EN] =               0x4,
+       [PWRAP_DIO_EN] =                0x8,
+       [PWRAP_SIDLY] =                 0xC,
+       [PWRAP_RDDMY] =                 0x10,
+       [PWRAP_CSHEXT_WRITE] =          0x18,
+       [PWRAP_CSHEXT_READ] =           0x1C,
+       [PWRAP_CSLEXT_START] =          0x20,
+       [PWRAP_CSLEXT_END] =            0x24,
+       [PWRAP_STAUPD_PRD] =            0x28,
+       [PWRAP_HARB_HPRIO] =            0x50,
+       [PWRAP_HIPRIO_ARB_EN] =         0x54,
+       [PWRAP_MAN_EN] =                0x60,
+       [PWRAP_MAN_CMD] =               0x64,
+       [PWRAP_WACS0_EN] =              0x70,
+       [PWRAP_WACS1_EN] =              0x84,
+       [PWRAP_WACS2_EN] =              0x98,
+       [PWRAP_INIT_DONE2] =            0x9C,
+       [PWRAP_WACS2_CMD] =             0xA0,
+       [PWRAP_WACS2_RDATA] =           0xA4,
+       [PWRAP_WACS2_VLDCLR] =          0xA8,
+       [PWRAP_INT_EN] =                0xC0,
+       [PWRAP_INT_FLG_RAW] =           0xC4,
+       [PWRAP_INT_FLG] =               0xC8,
+       [PWRAP_INT_CLR] =               0xCC,
+       [PWRAP_TIMER_EN] =              0xF4,
+       [PWRAP_WDT_UNIT] =              0xFC,
+       [PWRAP_WDT_SRC_EN] =            0x100,
+       [PWRAP_DCM_EN] =                0x1CC,
+       [PWRAP_DCM_DBC_PRD] =           0x1D4,
+};
+
 static int mt7622_regs[] = {
        [PWRAP_MUX_SEL] =               0x0,
        [PWRAP_WRAP_EN] =               0x4,
@@ -635,12 +683,14 @@ static int mt8135_regs[] = {
 
 enum pmic_type {
        PMIC_MT6323,
+       PMIC_MT6351,
        PMIC_MT6380,
        PMIC_MT6397,
 };
 
 enum pwrap_type {
        PWRAP_MT2701,
+       PWRAP_MT6797,
        PWRAP_MT7622,
        PWRAP_MT8135,
        PWRAP_MT8173,
@@ -1067,6 +1117,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
                pwrap_writel(wrp, 1, PWRAP_CIPHER_START);
                break;
        case PWRAP_MT2701:
+       case PWRAP_MT6797:
        case PWRAP_MT8173:
                pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);
                break;
@@ -1080,8 +1131,6 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
        pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x0);
        pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_KEY_SEL], 0x1);
        pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_IV_SEL], 0x2);
-       pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_LOAD], 0x1);
-       pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_START], 0x1);
 
        switch (wrp->slave->type) {
        case PMIC_MT6397:
@@ -1091,6 +1140,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
                            0x1);
                break;
        case PMIC_MT6323:
+       case PMIC_MT6351:
                pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_EN],
                            0x1);
                break;
@@ -1367,6 +1417,15 @@ static const struct pwrap_slv_type pmic_mt6397 = {
        .pwrap_write = pwrap_write16,
 };
 
+static const struct pwrap_slv_type pmic_mt6351 = {
+       .dew_regs = mt6351_regs,
+       .type = PMIC_MT6351,
+       .regmap = &pwrap_regmap_config16,
+       .caps = 0,
+       .pwrap_read = pwrap_read16,
+       .pwrap_write = pwrap_write16,
+};
+
 static const struct of_device_id of_slave_match_tbl[] = {
        {
                .compatible = "mediatek,mt6323",
@@ -1380,6 +1439,9 @@ static const struct of_device_id of_slave_match_tbl[] = {
        }, {
                .compatible = "mediatek,mt6397",
                .data = &pmic_mt6397,
+       }, {
+               .compatible = "mediatek,mt6351",
+               .data = &pmic_mt6351,
        }, {
                /* sentinel */
        }
@@ -1398,6 +1460,18 @@ static const struct pmic_wrapper_type pwrap_mt2701 = {
        .init_soc_specific = pwrap_mt2701_init_soc_specific,
 };
 
+static const struct pmic_wrapper_type pwrap_mt6797 = {
+       .regs = mt6797_regs,
+       .type = PWRAP_MT6797,
+       .arb_en_all = 0x01fff,
+       .int_en_all = 0xffffffc6,
+       .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
+       .wdt_src = PWRAP_WDT_SRC_MASK_ALL,
+       .has_bridge = 0,
+       .init_reg_clock = pwrap_common_init_reg_clock,
+       .init_soc_specific = NULL,
+};
+
 static const struct pmic_wrapper_type pwrap_mt7622 = {
        .regs = mt7622_regs,
        .type = PWRAP_MT7622,
@@ -1438,6 +1512,9 @@ static const struct of_device_id of_pwrap_match_tbl[] = {
        {
                .compatible = "mediatek,mt2701-pwrap",
                .data = &pwrap_mt2701,
+       }, {
+               .compatible = "mediatek,mt6797-pwrap",
+               .data = &pwrap_mt6797,
        }, {
                .compatible = "mediatek,mt7622-pwrap",
                .data = &pwrap_mt7622,
index 7dc0f20d79079be51ca7e07ff278b7650360c0ab..c37b0803c1b60d9f0d385c76dd2be05a136dd35e 100644 (file)
@@ -18,6 +18,9 @@ obj-$(CONFIG_SYSC_R8A77970)   += r8a77970-sysc.o
 obj-$(CONFIG_SYSC_R8A77980)    += r8a77980-sysc.o
 obj-$(CONFIG_SYSC_R8A77990)    += r8a77990-sysc.o
 obj-$(CONFIG_SYSC_R8A77995)    += r8a77995-sysc.o
+ifdef CONFIG_SMP
+obj-$(CONFIG_ARCH_R9A06G032)   += r9a06g032-smp.o
+endif
 
 # Family
 obj-$(CONFIG_RST_RCAR)         += rcar-rst.o
diff --git a/drivers/soc/renesas/r9a06g032-smp.c b/drivers/soc/renesas/r9a06g032-smp.c
new file mode 100644 (file)
index 0000000..a1926e8
--- /dev/null
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * R9A06G032 Second CA7 enabler.
+ *
+ * Copyright (C) 2018 Renesas Electronics Europe Limited
+ *
+ * Michel Pollet <michel.pollet@bp.renesas.com>, <buserror@gmail.com>
+ * Derived from actions,s500-smp
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/smp.h>
+
+/*
+ * The second CPU is parked in ROM at boot time. It requires waking it after
+ * writing an address into the BOOTADDR register of sysctrl.
+ *
+ * So the default value of the "cpu-release-addr" corresponds to BOOTADDR...
+ *
+ * *However* the BOOTADDR register is not available when the kernel
+ * starts in NONSEC mode.
+ *
+ * So for NONSEC mode, the bootloader re-parks the second CPU into a pen
+ * in SRAM, and changes the "cpu-release-addr" of linux's DT to a SRAM address,
+ * which is not restricted.
+ */
+
+static void __iomem *cpu_bootaddr;
+
+static DEFINE_SPINLOCK(cpu_lock);
+
+static int
+r9a06g032_smp_boot_secondary(unsigned int cpu,
+                            struct task_struct *idle)
+{
+       if (!cpu_bootaddr)
+               return -ENODEV;
+
+       spin_lock(&cpu_lock);
+
+       writel(__pa_symbol(secondary_startup), cpu_bootaddr);
+       arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+       spin_unlock(&cpu_lock);
+
+       return 0;
+}
+
+static void __init r9a06g032_smp_prepare_cpus(unsigned int max_cpus)
+{
+       struct device_node *dn;
+       int ret = -EINVAL, dns;
+       u32 bootaddr;
+
+       dn = of_get_cpu_node(1, NULL);
+       if (!dn) {
+               pr_err("CPU#1: missing device tree node\n");
+               return;
+       }
+       /*
+        * Determine the address from which the CPU is polling.
+        * The bootloader *does* change this property.
+        * Note: The property can be either 64 or 32 bits, so handle both cases
+        */
+       if (of_find_property(dn, "cpu-release-addr", &dns)) {
+               if (dns == sizeof(u64)) {
+                       u64 temp;
+
+                       ret = of_property_read_u64(dn,
+                                                  "cpu-release-addr", &temp);
+                       bootaddr = temp;
+               } else {
+                       ret = of_property_read_u32(dn,
+                                                  "cpu-release-addr",
+                                                  &bootaddr);
+               }
+       }
+       of_node_put(dn);
+       if (ret) {
+               pr_err("CPU#1: invalid cpu-release-addr property\n");
+               return;
+       }
+       pr_info("CPU#1: cpu-release-addr %08x\n", bootaddr);
+
+       cpu_bootaddr = ioremap(bootaddr, sizeof(bootaddr));
+}
+
+static const struct smp_operations r9a06g032_smp_ops __initconst = {
+       .smp_prepare_cpus = r9a06g032_smp_prepare_cpus,
+       .smp_boot_secondary = r9a06g032_smp_boot_secondary,
+};
+
+CPU_METHOD_OF_DECLARE(r9a06g032_smp,
+                     "renesas,r9a06g032-smp", &r9a06g032_smp_ops);
index 50d03d8b4f9a55f50d52f328039afe0c27991740..029188e8be6e95f2b86d30dc6963a94ce01fc3c9 100644 (file)
 
 #define RCAR_PD_ALWAYS_ON      32      /* Always-on power area */
 
+struct rcar_sysc_ch {
+       u16 chan_offs;
+       u8 chan_bit;
+       u8 isr_bit;
+};
+
 static void __iomem *rcar_sysc_base;
 static DEFINE_SPINLOCK(rcar_sysc_lock); /* SMP CPUs + I/O devices */
 
@@ -143,12 +149,12 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
        return ret;
 }
 
-int rcar_sysc_power_down(const struct rcar_sysc_ch *sysc_ch)
+static int rcar_sysc_power_down(const struct rcar_sysc_ch *sysc_ch)
 {
        return rcar_sysc_power(sysc_ch, false);
 }
 
-int rcar_sysc_power_up(const struct rcar_sysc_ch *sysc_ch)
+static int rcar_sysc_power_up(const struct rcar_sysc_ch *sysc_ch)
 {
        return rcar_sysc_power(sysc_ch, true);
 }
@@ -315,6 +321,8 @@ struct rcar_pm_domains {
        struct generic_pm_domain *domains[RCAR_PD_ALWAYS_ON + 1];
 };
 
+static struct genpd_onecell_data *rcar_sysc_onecell_data;
+
 static int __init rcar_sysc_pd_init(void)
 {
        const struct rcar_sysc_info *info;
@@ -326,9 +334,6 @@ static int __init rcar_sysc_pd_init(void)
        unsigned int i;
        int error;
 
-       if (rcar_sysc_base)
-               return 0;
-
        np = of_find_matching_node_and_match(NULL, rcar_sysc_matches, &match);
        if (!np)
                return -ENODEV;
@@ -361,6 +366,7 @@ static int __init rcar_sysc_pd_init(void)
 
        domains->onecell_data.domains = domains->domains;
        domains->onecell_data.num_domains = ARRAY_SIZE(domains->domains);
+       rcar_sysc_onecell_data = &domains->onecell_data;
 
        for (i = 0, syscier = 0; i < info->num_areas; i++)
                syscier |= BIT(info->areas[i].isr_bit);
@@ -448,27 +454,39 @@ void __init rcar_sysc_nullify(struct rcar_sysc_area *areas,
                }
 }
 
-void __init rcar_sysc_init(phys_addr_t base, u32 syscier)
+#ifdef CONFIG_ARCH_R8A7779
+static int rcar_sysc_power_cpu(unsigned int idx, bool on)
 {
-       u32 syscimr;
+       struct generic_pm_domain *genpd;
+       struct rcar_sysc_pd *pd;
+       unsigned int i;
 
-       if (!rcar_sysc_pd_init())
-               return;
+       if (!rcar_sysc_onecell_data)
+               return -ENODEV;
 
-       rcar_sysc_base = ioremap_nocache(base, PAGE_SIZE);
+       for (i = 0; i < rcar_sysc_onecell_data->num_domains; i++) {
+               genpd = rcar_sysc_onecell_data->domains[i];
+               if (!genpd)
+                       continue;
 
-       /*
-        * Mask all interrupt sources to prevent the CPU from receiving them.
-        * Make sure not to clear reserved bits that were set before.
-        */
-       syscimr = ioread32(rcar_sysc_base + SYSCIMR);
-       syscimr |= syscier;
-       pr_debug("%s: syscimr = 0x%08x\n", __func__, syscimr);
-       iowrite32(syscimr, rcar_sysc_base + SYSCIMR);
+               pd = to_rcar_pd(genpd);
+               if (!(pd->flags & PD_CPU) || pd->ch.chan_bit != idx)
+                       continue;
 
-       /*
-        * SYSC needs all interrupt sources enabled to control power.
-        */
-       pr_debug("%s: syscier = 0x%08x\n", __func__, syscier);
-       iowrite32(syscier, rcar_sysc_base + SYSCIER);
+               return on ? rcar_sysc_power_up(&pd->ch)
+                         : rcar_sysc_power_down(&pd->ch);
+       }
+
+       return -ENOENT;
+}
+
+int rcar_sysc_power_down_cpu(unsigned int cpu)
+{
+       return rcar_sysc_power_cpu(cpu, false);
+}
+
+int rcar_sysc_power_up_cpu(unsigned int cpu)
+{
+       return rcar_sysc_power_cpu(cpu, true);
 }
+#endif /* CONFIG_ARCH_R8A7779 */
index 882be5ed7e84fea1b160da834fe51c3247dbb4ba..b4b0f3480bd36f4ee9662ef10628a4f12b5c52c3 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 
 #include <linux/soc/sunxi/sunxi_sram.h>
 
@@ -63,6 +64,12 @@ static struct sunxi_sram_desc sun4i_a10_sram_a3_a4 = {
                                  SUNXI_SRAM_MAP(1, 1, "emac")),
 };
 
+static struct sunxi_sram_desc sun4i_a10_sram_c1 = {
+       .data   = SUNXI_SRAM_DATA("C1", 0x0, 0x0, 31,
+                                 SUNXI_SRAM_MAP(0, 0, "cpu"),
+                                 SUNXI_SRAM_MAP(0x7fffffff, 1, "ve")),
+};
+
 static struct sunxi_sram_desc sun4i_a10_sram_d = {
        .data   = SUNXI_SRAM_DATA("D", 0x4, 0x0, 1,
                                  SUNXI_SRAM_MAP(0, 0, "cpu"),
@@ -80,6 +87,10 @@ static const struct of_device_id sunxi_sram_dt_ids[] = {
                .compatible     = "allwinner,sun4i-a10-sram-a3-a4",
                .data           = &sun4i_a10_sram_a3_a4.data,
        },
+       {
+               .compatible     = "allwinner,sun4i-a10-sram-c1",
+               .data           = &sun4i_a10_sram_c1.data,
+       },
        {
                .compatible     = "allwinner,sun4i-a10-sram-d",
                .data           = &sun4i_a10_sram_d.data,
@@ -281,13 +292,51 @@ int sunxi_sram_release(struct device *dev)
 }
 EXPORT_SYMBOL(sunxi_sram_release);
 
+struct sunxi_sramc_variant {
+       bool has_emac_clock;
+};
+
+static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = {
+       /* Nothing special */
+};
+
+static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = {
+       .has_emac_clock = true,
+};
+
+#define SUNXI_SRAM_EMAC_CLOCK_REG      0x30
+static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
+                                            unsigned int reg)
+{
+       if (reg == SUNXI_SRAM_EMAC_CLOCK_REG)
+               return true;
+       return false;
+}
+
+static struct regmap_config sunxi_sram_emac_clock_regmap = {
+       .reg_bits       = 32,
+       .val_bits       = 32,
+       .reg_stride     = 4,
+       /* last defined register */
+       .max_register   = SUNXI_SRAM_EMAC_CLOCK_REG,
+       /* other devices have no business accessing other registers */
+       .readable_reg   = sunxi_sram_regmap_accessible_reg,
+       .writeable_reg  = sunxi_sram_regmap_accessible_reg,
+};
+
 static int sunxi_sram_probe(struct platform_device *pdev)
 {
        struct resource *res;
        struct dentry *d;
+       struct regmap *emac_clock;
+       const struct sunxi_sramc_variant *variant;
 
        sram_dev = &pdev->dev;
 
+       variant = of_device_get_match_data(&pdev->dev);
+       if (!variant)
+               return -EINVAL;
+
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(base))
@@ -300,12 +349,46 @@ static int sunxi_sram_probe(struct platform_device *pdev)
        if (!d)
                return -ENOMEM;
 
+       if (variant->has_emac_clock) {
+               emac_clock = devm_regmap_init_mmio(&pdev->dev, base,
+                                                  &sunxi_sram_emac_clock_regmap);
+
+               if (IS_ERR(emac_clock))
+                       return PTR_ERR(emac_clock);
+       }
+
        return 0;
 }
 
 static const struct of_device_id sunxi_sram_dt_match[] = {
-       { .compatible = "allwinner,sun4i-a10-sram-controller" },
-       { .compatible = "allwinner,sun50i-a64-sram-controller" },
+       {
+               .compatible = "allwinner,sun4i-a10-sram-controller",
+               .data = &sun4i_a10_sramc_variant,
+       },
+       {
+               .compatible = "allwinner,sun4i-a10-system-control",
+               .data = &sun4i_a10_sramc_variant,
+       },
+       {
+               .compatible = "allwinner,sun5i-a13-system-control",
+               .data = &sun4i_a10_sramc_variant,
+       },
+       {
+               .compatible = "allwinner,sun8i-a23-system-control",
+               .data = &sun4i_a10_sramc_variant,
+       },
+       {
+               .compatible = "allwinner,sun8i-h3-system-control",
+               .data = &sun4i_a10_sramc_variant,
+       },
+       {
+               .compatible = "allwinner,sun50i-a64-sram-controller",
+               .data = &sun50i_a64_sramc_variant,
+       },
+       {
+               .compatible = "allwinner,sun50i-a64-system-control",
+               .data = &sun50i_a64_sramc_variant,
+       },
        { },
 };
 MODULE_DEVICE_TABLE(of, sunxi_sram_dt_match);
index 92770d84a2885844b98bf7ec015c06c2b62c1553..be4570baad96c0c1a1bd5c1d9eb1d0d70e4da97d 100644 (file)
@@ -1,3 +1,17 @@
+# 64-bit ARM SoCs from TI
+if ARM64
+
+if ARCH_K3
+
+config ARCH_K3_AM6_SOC
+       bool "K3 AM6 SoC"
+       help
+         Enable support for TI's AM6 SoC Family support
+
+endif
+
+endif
+
 #
 # TI SOC drivers
 #
index 652739c7f71845b86a331189570604dd66b5f43c..d0dab323651fc3b6c4741898669318b54a32e588 100644 (file)
@@ -41,6 +41,8 @@ static struct am33xx_pm_sram_addr *pm_sram;
 static struct device *pm33xx_dev;
 static struct wkup_m3_ipc *m3_ipc;
 
+static unsigned long suspend_wfi_flags;
+
 static u32 sram_suspend_address(unsigned long addr)
 {
        return ((unsigned long)am33xx_do_wfi_sram +
@@ -53,7 +55,7 @@ static int am33xx_pm_suspend(suspend_state_t suspend_state)
        int i, ret = 0;
 
        ret = pm_ops->soc_suspend((unsigned long)suspend_state,
-                                 am33xx_do_wfi_sram);
+                                 am33xx_do_wfi_sram, suspend_wfi_flags);
 
        if (ret) {
                dev_err(pm33xx_dev, "PM: Kernel suspend failure\n");
@@ -227,6 +229,7 @@ static int am33xx_push_sram_idle(void)
        ro_sram_data.amx3_pm_sram_data_virt = ocmcram_location_data;
        ro_sram_data.amx3_pm_sram_data_phys =
                gen_pool_virt_to_phys(sram_pool_data, ocmcram_location_data);
+       ro_sram_data.rtc_base_virt = pm_ops->get_rtc_base_addr();
 
        /* Save physical address to calculate resume offset during pm init */
        am33xx_do_wfi_sram_phys = gen_pool_virt_to_phys(sram_pool,
@@ -310,6 +313,17 @@ static int am33xx_pm_probe(struct platform_device *pdev)
        suspend_set_ops(&am33xx_pm_ops);
 #endif /* CONFIG_SUSPEND */
 
+       /*
+        * For a system suspend we must flush the caches, we want
+        * the DDR in self-refresh, we want to save the context
+        * of the EMIF, and we want the wkup_m3 to handle low-power
+        * transition.
+        */
+       suspend_wfi_flags |= WFI_FLAG_FLUSH_CACHE;
+       suspend_wfi_flags |= WFI_FLAG_SELF_REFRESH;
+       suspend_wfi_flags |= WFI_FLAG_SAVE_EMIF;
+       suspend_wfi_flags |= WFI_FLAG_WAKE_M3;
+
        ret = pm_ops->init();
        if (ret) {
                dev_err(dev, "Unable to call core pm init!\n");
index 369aef5e7228e959883c58d0870737d860fbf8a4..f5cb8c0af09f3ab8ade4443ada270bf1f1eefa92 100644 (file)
@@ -46,6 +46,7 @@
 #define M3_BASELINE_VERSION            0x191
 #define M3_STATUS_RESP_MASK            (0xffff << 16)
 #define M3_FW_VERSION_MASK             0xffff
+#define M3_WAKE_SRC_MASK               0xff
 
 #define M3_STATE_UNKNOWN               0
 #define M3_STATE_RESET                 1
 
 static struct wkup_m3_ipc *m3_ipc_state;
 
+static const struct wkup_m3_wakeup_src wakeups[] = {
+       {.irq_nr = 35,  .src = "USB0_PHY"},
+       {.irq_nr = 36,  .src = "USB1_PHY"},
+       {.irq_nr = 40,  .src = "I2C0"},
+       {.irq_nr = 41,  .src = "RTC Timer"},
+       {.irq_nr = 42,  .src = "RTC Alarm"},
+       {.irq_nr = 43,  .src = "Timer0"},
+       {.irq_nr = 44,  .src = "Timer1"},
+       {.irq_nr = 45,  .src = "UART"},
+       {.irq_nr = 46,  .src = "GPIO0"},
+       {.irq_nr = 48,  .src = "MPU_WAKE"},
+       {.irq_nr = 49,  .src = "WDT0"},
+       {.irq_nr = 50,  .src = "WDT1"},
+       {.irq_nr = 51,  .src = "ADC_TSC"},
+       {.irq_nr = 0,   .src = "Unknown"},
+};
+
 static void am33xx_txev_eoi(struct wkup_m3_ipc *m3_ipc)
 {
        writel(AM33XX_M3_TXEV_ACK,
@@ -329,12 +347,45 @@ static int wkup_m3_finish_low_power(struct wkup_m3_ipc *m3_ipc)
        return 0;
 }
 
+/**
+ * wkup_m3_request_wake_src - Get the wakeup source info passed from wkup_m3
+ * @m3_ipc: Pointer to wkup_m3_ipc context
+ */
+static const char *wkup_m3_request_wake_src(struct wkup_m3_ipc *m3_ipc)
+{
+       unsigned int wakeup_src_idx;
+       int j, val;
+
+       val = wkup_m3_ctrl_ipc_read(m3_ipc, 6);
+
+       wakeup_src_idx = val & M3_WAKE_SRC_MASK;
+
+       for (j = 0; j < ARRAY_SIZE(wakeups) - 1; j++) {
+               if (wakeups[j].irq_nr == wakeup_src_idx)
+                       return wakeups[j].src;
+       }
+       return wakeups[j].src;
+}
+
+/**
+ * wkup_m3_set_rtc_only - Set the rtc_only flag
+ * @wkup_m3_wakeup: struct wkup_m3_wakeup_src * gets assigned the
+ *                  wakeup src value
+ */
+static void wkup_m3_set_rtc_only(struct wkup_m3_ipc *m3_ipc)
+{
+       if (m3_ipc_state)
+               m3_ipc_state->is_rtc_only = true;
+}
+
 static struct wkup_m3_ipc_ops ipc_ops = {
        .set_mem_type = wkup_m3_set_mem_type,
        .set_resume_address = wkup_m3_set_resume_address,
        .prepare_low_power = wkup_m3_prepare_low_power,
        .finish_low_power = wkup_m3_finish_low_power,
        .request_pm_status = wkup_m3_request_pm_status,
+       .request_wake_src = wkup_m3_request_wake_src,
+       .set_rtc_only = wkup_m3_set_rtc_only,
 };
 
 /**
@@ -484,6 +535,30 @@ static int wkup_m3_ipc_remove(struct platform_device *pdev)
        return 0;
 }
 
+static int __maybe_unused wkup_m3_ipc_suspend(struct device *dev)
+{
+       /*
+        * Nothing needs to be done on suspend even with rtc_only flag set
+        */
+       return 0;
+}
+
+static int __maybe_unused wkup_m3_ipc_resume(struct device *dev)
+{
+       if (m3_ipc_state->is_rtc_only) {
+               rproc_shutdown(m3_ipc_state->rproc);
+               rproc_boot(m3_ipc_state->rproc);
+       }
+
+       m3_ipc_state->is_rtc_only = false;
+
+       return 0;
+}
+
+static const struct dev_pm_ops wkup_m3_ipc_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(wkup_m3_ipc_suspend, wkup_m3_ipc_resume)
+};
+
 static const struct of_device_id wkup_m3_ipc_of_match[] = {
        { .compatible = "ti,am3352-wkup-m3-ipc", },
        { .compatible = "ti,am4372-wkup-m3-ipc", },
@@ -497,6 +572,7 @@ static struct platform_driver wkup_m3_ipc_driver = {
        .driver = {
                .name = "wkup_m3_ipc",
                .of_match_table = wkup_m3_ipc_of_match,
+               .pm = &wkup_m3_ipc_pm_ops,
        },
 };
 
index 396fb3d563983930918bea54f820a7340d6a6984..1abf76be2aa8c7c49f867bc09dbbf68ca374a4d3 100644 (file)
@@ -90,8 +90,6 @@ source "drivers/staging/clocking-wizard/Kconfig"
 
 source "drivers/staging/fbtft/Kconfig"
 
-source "drivers/staging/fsl-mc/Kconfig"
-
 source "drivers/staging/fsl-dpaa2/Kconfig"
 
 source "drivers/staging/wilc1000/Kconfig"
index ad7b4ca412ef12c42407a58f5989186fbff78700..ab0cbe8815b1c1b6112c2dfd93c06bd508dd92e9 100644 (file)
@@ -35,7 +35,6 @@ obj-$(CONFIG_GS_FPGABOOT)     += gs_fpgaboot/
 obj-$(CONFIG_UNISYSSPAR)       += unisys/
 obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)  += clocking-wizard/
 obj-$(CONFIG_FB_TFT)           += fbtft/
-obj-$(CONFIG_FSL_MC_BUS)       += fsl-mc/
 obj-$(CONFIG_FSL_DPAA2)                += fsl-dpaa2/
 obj-$(CONFIG_WILC1000)         += wilc1000/
 obj-$(CONFIG_MOST)             += most/
index e2dac44eccbeb71fa6baa05775c224c66ccabaf6..9329fcad95acd336535662bc32e0ed5fce39ca39 100644 (file)
@@ -426,7 +426,7 @@ static int build_sg_fd(struct dpaa2_eth_priv *priv,
        dpaa2_fd_set_format(fd, dpaa2_fd_sg);
        dpaa2_fd_set_addr(fd, addr);
        dpaa2_fd_set_len(fd, skb->len);
-       dpaa2_fd_set_ctrl(fd, DPAA2_FD_CTRL_PTA | DPAA2_FD_CTRL_PTV1);
+       dpaa2_fd_set_ctrl(fd, FD_CTRL_PTA | FD_CTRL_PTV1);
 
        if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
                enable_tx_tstamp(fd, sgt_buf);
@@ -479,7 +479,7 @@ static int build_single_fd(struct dpaa2_eth_priv *priv,
        dpaa2_fd_set_offset(fd, (u16)(skb->data - buffer_start));
        dpaa2_fd_set_len(fd, skb->len);
        dpaa2_fd_set_format(fd, dpaa2_fd_single);
-       dpaa2_fd_set_ctrl(fd, DPAA2_FD_CTRL_PTA | DPAA2_FD_CTRL_PTV1);
+       dpaa2_fd_set_ctrl(fd, FD_CTRL_PTA | FD_CTRL_PTV1);
 
        if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
                enable_tx_tstamp(fd, buffer_start);
index 506466778b2cbd9eb6c936963569c74afecebe9b..d54cb0b99d08794cbdffcaf2382d2029c0ee789c 100644 (file)
@@ -10,8 +10,8 @@
 #include <linux/if_vlan.h>
 #include <linux/fsl/mc.h>
 
-#include "../../fsl-mc/include/dpaa2-io.h"
-#include "../../fsl-mc/include/dpaa2-fd.h"
+#include <soc/fsl/dpaa2-io.h>
+#include <soc/fsl/dpaa2-fd.h>
 #include "dpni.h"
 #include "dpni-cmd.h"
 
@@ -97,21 +97,13 @@ struct dpaa2_eth_swa {
 #define DPAA2_FD_FRC_FAICFDV           0x0400
 
 /* Error bits in FD CTRL */
-#define DPAA2_FD_CTRL_UFD              0x00000004
-#define DPAA2_FD_CTRL_SBE              0x00000008
-#define DPAA2_FD_CTRL_FSE              0x00000020
-#define DPAA2_FD_CTRL_FAERR            0x00000040
-
-#define DPAA2_FD_RX_ERR_MASK           (DPAA2_FD_CTRL_SBE      | \
-                                        DPAA2_FD_CTRL_FAERR)
-#define DPAA2_FD_TX_ERR_MASK           (DPAA2_FD_CTRL_UFD      | \
-                                        DPAA2_FD_CTRL_SBE      | \
-                                        DPAA2_FD_CTRL_FSE      | \
-                                        DPAA2_FD_CTRL_FAERR)
+#define DPAA2_FD_RX_ERR_MASK           (FD_CTRL_SBE | FD_CTRL_FAERR)
+#define DPAA2_FD_TX_ERR_MASK           (FD_CTRL_UFD    | \
+                                        FD_CTRL_SBE    | \
+                                        FD_CTRL_FSE    | \
+                                        FD_CTRL_FAERR)
 
 /* Annotation bits in FD CTRL */
-#define DPAA2_FD_CTRL_PTA              0x00800000
-#define DPAA2_FD_CTRL_PTV1             0x00400000
 #define DPAA2_FD_CTRL_ASAL             0x00020000      /* ASAL = 128B */
 
 /* Frame annotation status */
diff --git a/drivers/staging/fsl-mc/Kconfig b/drivers/staging/fsl-mc/Kconfig
deleted file mode 100644 (file)
index 3002229..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-source "drivers/staging/fsl-mc/bus/Kconfig"
diff --git a/drivers/staging/fsl-mc/Makefile b/drivers/staging/fsl-mc/Makefile
deleted file mode 100644 (file)
index 1468388..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# Freescale Management Complex (MC) bus drivers
-obj-$(CONFIG_FSL_MC_BUS)       += bus/
diff --git a/drivers/staging/fsl-mc/bus/Kconfig b/drivers/staging/fsl-mc/bus/Kconfig
deleted file mode 100644 (file)
index 3424530..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# DPAA2 fsl-mc bus
-#
-# Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
-#
-
-config FSL_MC_DPIO
-        tristate "QorIQ DPAA2 DPIO driver"
-        depends on FSL_MC_BUS
-        help
-         Driver for the DPAA2 DPIO object.  A DPIO provides queue and
-         buffer management facilities for software to interact with
-         other DPAA2 objects. This driver does not expose the DPIO
-         objects individually, but groups them under a service layer
-         API.
diff --git a/drivers/staging/fsl-mc/bus/Makefile b/drivers/staging/fsl-mc/bus/Makefile
deleted file mode 100644 (file)
index 21d8ebc..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Freescale Management Complex (MC) bus drivers
-#
-# Copyright (C) 2014 Freescale Semiconductor, Inc.
-#
-
-# MC DPIO driver
-obj-$(CONFIG_FSL_MC_DPIO) += dpio/
diff --git a/drivers/staging/fsl-mc/bus/dpio/Makefile b/drivers/staging/fsl-mc/bus/dpio/Makefile
deleted file mode 100644 (file)
index b9ff24c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# QorIQ DPAA2 DPIO driver
-#
-
-obj-$(CONFIG_FSL_MC_DPIO) += fsl-mc-dpio.o
-
-fsl-mc-dpio-objs := dpio.o qbman-portal.o dpio-service.o dpio-driver.o
diff --git a/drivers/staging/fsl-mc/bus/dpio/dpio-cmd.h b/drivers/staging/fsl-mc/bus/dpio/dpio-cmd.h
deleted file mode 100644 (file)
index ab8f82e..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
-/*
- * Copyright 2013-2016 Freescale Semiconductor Inc.
- * Copyright 2016 NXP
- *
- */
-#ifndef _FSL_DPIO_CMD_H
-#define _FSL_DPIO_CMD_H
-
-/* DPIO Version */
-#define DPIO_VER_MAJOR                 4
-#define DPIO_VER_MINOR                 2
-
-/* Command Versioning */
-
-#define DPIO_CMD_ID_OFFSET             4
-#define DPIO_CMD_BASE_VERSION          1
-
-#define DPIO_CMD(id)   (((id) << DPIO_CMD_ID_OFFSET) | DPIO_CMD_BASE_VERSION)
-
-/* Command IDs */
-#define DPIO_CMDID_CLOSE                               DPIO_CMD(0x800)
-#define DPIO_CMDID_OPEN                                        DPIO_CMD(0x803)
-#define DPIO_CMDID_GET_API_VERSION                     DPIO_CMD(0xa03)
-#define DPIO_CMDID_ENABLE                              DPIO_CMD(0x002)
-#define DPIO_CMDID_DISABLE                             DPIO_CMD(0x003)
-#define DPIO_CMDID_GET_ATTR                            DPIO_CMD(0x004)
-
-struct dpio_cmd_open {
-       __le32 dpio_id;
-};
-
-#define DPIO_CHANNEL_MODE_MASK         0x3
-
-struct dpio_rsp_get_attr {
-       /* cmd word 0 */
-       __le32 id;
-       __le16 qbman_portal_id;
-       u8 num_priorities;
-       u8 channel_mode;
-       /* cmd word 1 */
-       __le64 qbman_portal_ce_addr;
-       /* cmd word 2 */
-       __le64 qbman_portal_ci_addr;
-       /* cmd word 3 */
-       __le32 qbman_version;
-};
-
-#endif /* _FSL_DPIO_CMD_H */
diff --git a/drivers/staging/fsl-mc/bus/dpio/dpio-driver.c b/drivers/staging/fsl-mc/bus/dpio/dpio-driver.c
deleted file mode 100644 (file)
index 11a90a9..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
-/*
- * Copyright 2014-2016 Freescale Semiconductor Inc.
- * Copyright NXP 2016
- *
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/msi.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-
-#include <linux/fsl/mc.h>
-#include "../../include/dpaa2-io.h"
-
-#include "qbman-portal.h"
-#include "dpio.h"
-#include "dpio-cmd.h"
-
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_AUTHOR("Freescale Semiconductor, Inc");
-MODULE_DESCRIPTION("DPIO Driver");
-
-struct dpio_priv {
-       struct dpaa2_io *io;
-};
-
-static irqreturn_t dpio_irq_handler(int irq_num, void *arg)
-{
-       struct device *dev = (struct device *)arg;
-       struct dpio_priv *priv = dev_get_drvdata(dev);
-
-       return dpaa2_io_irq(priv->io);
-}
-
-static void unregister_dpio_irq_handlers(struct fsl_mc_device *dpio_dev)
-{
-       struct fsl_mc_device_irq *irq;
-
-       irq = dpio_dev->irqs[0];
-
-       /* clear the affinity hint */
-       irq_set_affinity_hint(irq->msi_desc->irq, NULL);
-}
-
-static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int cpu)
-{
-       struct dpio_priv *priv;
-       int error;
-       struct fsl_mc_device_irq *irq;
-       cpumask_t mask;
-
-       priv = dev_get_drvdata(&dpio_dev->dev);
-
-       irq = dpio_dev->irqs[0];
-       error = devm_request_irq(&dpio_dev->dev,
-                                irq->msi_desc->irq,
-                                dpio_irq_handler,
-                                0,
-                                dev_name(&dpio_dev->dev),
-                                &dpio_dev->dev);
-       if (error < 0) {
-               dev_err(&dpio_dev->dev,
-                       "devm_request_irq() failed: %d\n",
-                       error);
-               return error;
-       }
-
-       /* set the affinity hint */
-       cpumask_clear(&mask);
-       cpumask_set_cpu(cpu, &mask);
-       if (irq_set_affinity_hint(irq->msi_desc->irq, &mask))
-               dev_err(&dpio_dev->dev,
-                       "irq_set_affinity failed irq %d cpu %d\n",
-                       irq->msi_desc->irq, cpu);
-
-       return 0;
-}
-
-static int dpaa2_dpio_probe(struct fsl_mc_device *dpio_dev)
-{
-       struct dpio_attr dpio_attrs;
-       struct dpaa2_io_desc desc;
-       struct dpio_priv *priv;
-       int err = -ENOMEM;
-       struct device *dev = &dpio_dev->dev;
-       static int next_cpu = -1;
-
-       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               goto err_priv_alloc;
-
-       dev_set_drvdata(dev, priv);
-
-       err = fsl_mc_portal_allocate(dpio_dev, 0, &dpio_dev->mc_io);
-       if (err) {
-               dev_dbg(dev, "MC portal allocation failed\n");
-               err = -EPROBE_DEFER;
-               goto err_priv_alloc;
-       }
-
-       err = dpio_open(dpio_dev->mc_io, 0, dpio_dev->obj_desc.id,
-                       &dpio_dev->mc_handle);
-       if (err) {
-               dev_err(dev, "dpio_open() failed\n");
-               goto err_open;
-       }
-
-       err = dpio_get_attributes(dpio_dev->mc_io, 0, dpio_dev->mc_handle,
-                                 &dpio_attrs);
-       if (err) {
-               dev_err(dev, "dpio_get_attributes() failed %d\n", err);
-               goto err_get_attr;
-       }
-       desc.qman_version = dpio_attrs.qbman_version;
-
-       err = dpio_enable(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
-       if (err) {
-               dev_err(dev, "dpio_enable() failed %d\n", err);
-               goto err_get_attr;
-       }
-
-       /* initialize DPIO descriptor */
-       desc.receives_notifications = dpio_attrs.num_priorities ? 1 : 0;
-       desc.has_8prio = dpio_attrs.num_priorities == 8 ? 1 : 0;
-       desc.dpio_id = dpio_dev->obj_desc.id;
-
-       /* get the cpu to use for the affinity hint */
-       if (next_cpu == -1)
-               next_cpu = cpumask_first(cpu_online_mask);
-       else
-               next_cpu = cpumask_next(next_cpu, cpu_online_mask);
-
-       if (!cpu_possible(next_cpu)) {
-               dev_err(dev, "probe failed. Number of DPIOs exceeds NR_CPUS.\n");
-               err = -ERANGE;
-               goto err_allocate_irqs;
-       }
-       desc.cpu = next_cpu;
-
-       /*
-        * Set the CENA regs to be the cache inhibited area of the portal to
-        * avoid coherency issues if a user migrates to another core.
-        */
-       desc.regs_cena = devm_memremap(dev, dpio_dev->regions[1].start,
-                                      resource_size(&dpio_dev->regions[1]),
-                                      MEMREMAP_WC);
-       if (IS_ERR(desc.regs_cena)) {
-               dev_err(dev, "devm_memremap failed\n");
-               err = PTR_ERR(desc.regs_cena);
-               goto err_allocate_irqs;
-       }
-
-       desc.regs_cinh = devm_ioremap(dev, dpio_dev->regions[1].start,
-                                     resource_size(&dpio_dev->regions[1]));
-       if (!desc.regs_cinh) {
-               err = -ENOMEM;
-               dev_err(dev, "devm_ioremap failed\n");
-               goto err_allocate_irqs;
-       }
-
-       err = fsl_mc_allocate_irqs(dpio_dev);
-       if (err) {
-               dev_err(dev, "fsl_mc_allocate_irqs failed. err=%d\n", err);
-               goto err_allocate_irqs;
-       }
-
-       err = register_dpio_irq_handlers(dpio_dev, desc.cpu);
-       if (err)
-               goto err_register_dpio_irq;
-
-       priv->io = dpaa2_io_create(&desc);
-       if (!priv->io) {
-               dev_err(dev, "dpaa2_io_create failed\n");
-               err = -ENOMEM;
-               goto err_dpaa2_io_create;
-       }
-
-       dev_info(dev, "probed\n");
-       dev_dbg(dev, "   receives_notifications = %d\n",
-               desc.receives_notifications);
-       dpio_close(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
-       fsl_mc_portal_free(dpio_dev->mc_io);
-
-       return 0;
-
-err_dpaa2_io_create:
-       unregister_dpio_irq_handlers(dpio_dev);
-err_register_dpio_irq:
-       fsl_mc_free_irqs(dpio_dev);
-err_allocate_irqs:
-       dpio_disable(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
-err_get_attr:
-       dpio_close(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
-err_open:
-       fsl_mc_portal_free(dpio_dev->mc_io);
-err_priv_alloc:
-       return err;
-}
-
-/* Tear down interrupts for a given DPIO object */
-static void dpio_teardown_irqs(struct fsl_mc_device *dpio_dev)
-{
-       unregister_dpio_irq_handlers(dpio_dev);
-       fsl_mc_free_irqs(dpio_dev);
-}
-
-static int dpaa2_dpio_remove(struct fsl_mc_device *dpio_dev)
-{
-       struct device *dev;
-       struct dpio_priv *priv;
-       int err;
-
-       dev = &dpio_dev->dev;
-       priv = dev_get_drvdata(dev);
-
-       dpaa2_io_down(priv->io);
-
-       dpio_teardown_irqs(dpio_dev);
-
-       err = fsl_mc_portal_allocate(dpio_dev, 0, &dpio_dev->mc_io);
-       if (err) {
-               dev_err(dev, "MC portal allocation failed\n");
-               goto err_mcportal;
-       }
-
-       err = dpio_open(dpio_dev->mc_io, 0, dpio_dev->obj_desc.id,
-                       &dpio_dev->mc_handle);
-       if (err) {
-               dev_err(dev, "dpio_open() failed\n");
-               goto err_open;
-       }
-
-       dpio_disable(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
-
-       dpio_close(dpio_dev->mc_io, 0, dpio_dev->mc_handle);
-
-       fsl_mc_portal_free(dpio_dev->mc_io);
-
-       return 0;
-
-err_open:
-       fsl_mc_portal_free(dpio_dev->mc_io);
-err_mcportal:
-       return err;
-}
-
-static const struct fsl_mc_device_id dpaa2_dpio_match_id_table[] = {
-       {
-               .vendor = FSL_MC_VENDOR_FREESCALE,
-               .obj_type = "dpio",
-       },
-       { .vendor = 0x0 }
-};
-
-static struct fsl_mc_driver dpaa2_dpio_driver = {
-       .driver = {
-               .name           = KBUILD_MODNAME,
-               .owner          = THIS_MODULE,
-       },
-       .probe          = dpaa2_dpio_probe,
-       .remove         = dpaa2_dpio_remove,
-       .match_id_table = dpaa2_dpio_match_id_table
-};
-
-static int dpio_driver_init(void)
-{
-       return fsl_mc_driver_register(&dpaa2_dpio_driver);
-}
-
-static void dpio_driver_exit(void)
-{
-       fsl_mc_driver_unregister(&dpaa2_dpio_driver);
-}
-module_init(dpio_driver_init);
-module_exit(dpio_driver_exit);
diff --git a/drivers/staging/fsl-mc/bus/dpio/dpio-driver.txt b/drivers/staging/fsl-mc/bus/dpio/dpio-driver.txt
deleted file mode 100644 (file)
index 72ba9da..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-Copyright 2016 NXP
-
-Introduction
-------------
-
-A DPAA2 DPIO (Data Path I/O) is a hardware object that provides
-interfaces to enqueue and dequeue frames to/from network interfaces
-and other accelerators.  A DPIO also provides hardware buffer
-pool management for network interfaces.
-
-This document provides an overview the Linux DPIO driver, its
-subcomponents, and its APIs.
-
-See Documentation/networking/dpaa2/overview.rst for a general overview of DPAA2
-and the general DPAA2 driver architecture in Linux.
-
-Driver Overview
----------------
-
-The DPIO driver is bound to DPIO objects discovered on the fsl-mc bus and
-provides services that:
-  A) allow other drivers, such as the Ethernet driver, to enqueue and dequeue
-     frames for their respective objects
-  B) allow drivers to register callbacks for data availability notifications
-     when data becomes available on a queue or channel
-  C) allow drivers to manage hardware buffer pools
-
-The Linux DPIO driver consists of 3 primary components--
-   DPIO object driver-- fsl-mc driver that manages the DPIO object
-   DPIO service-- provides APIs to other Linux drivers for services
-   QBman portal interface-- sends portal commands, gets responses
-
-          fsl-mc          other
-           bus           drivers
-            |               |
-        +---+----+   +------+-----+
-        |DPIO obj|   |DPIO service|
-        | driver |---|  (DPIO)    |
-        +--------+   +------+-----+
-                            |
-                     +------+-----+
-                     |    QBman   |
-                     | portal i/f |
-                     +------------+
-                            |
-                         hardware
-
-The diagram below shows how the DPIO driver components fit with the other
-DPAA2 Linux driver components:
-                                                   +------------+
-                                                   | OS Network |
-                                                   |   Stack    |
-                 +------------+                    +------------+
-                 | Allocator  |. . . . . . .       |  Ethernet  |
-                 |(DPMCP,DPBP)|                    |   (DPNI)   |
-                 +-.----------+                    +---+---+----+
-                  .          .                         ^   |
-                 .            .           <data avail, |   |<enqueue,
-                .              .           tx confirm> |   | dequeue>
-    +-------------+             .                      |   |
-    | DPRC driver |              .    +--------+ +------------+
-    |   (DPRC)    |               . . |DPIO obj| |DPIO service|
-    +----------+--+                   | driver |-|  (DPIO)    |
-               |                      +--------+ +------+-----+
-               |<dev add/remove>                 +------|-----+
-               |                                 |   QBman    |
-          +----+--------------+                  | portal i/f |
-          |   MC-bus driver   |                  +------------+
-          |                   |                     |
-          | /soc/fsl-mc       |                     |
-          +-------------------+                     |
-                                                    |
- =========================================|=========|========================
-                                        +-+--DPIO---|-----------+
-                                        |           |           |
-                                        |        QBman Portal   |
-                                        +-----------------------+
-
- ============================================================================
-
-
-DPIO Object Driver (dpio-driver.c)
-----------------------------------
-
-   The dpio-driver component registers with the fsl-mc bus to handle objects of
-   type "dpio".  The implementation of probe() handles basic initialization
-   of the DPIO including mapping of the DPIO regions (the QBman SW portal)
-   and initializing interrupts and registering irq handlers.  The dpio-driver
-   registers the probed DPIO with dpio-service.
-
-DPIO service  (dpio-service.c, dpaa2-io.h)
-------------------------------------------
-
-   The dpio service component provides queuing, notification, and buffers
-   management services to DPAA2 drivers, such as the Ethernet driver.  A system
-   will typically allocate 1 DPIO object per CPU to allow queuing operations
-   to happen simultaneously across all CPUs.
-
-   Notification handling
-      dpaa2_io_service_register()
-      dpaa2_io_service_deregister()
-      dpaa2_io_service_rearm()
-
-   Queuing
-      dpaa2_io_service_pull_fq()
-      dpaa2_io_service_pull_channel()
-      dpaa2_io_service_enqueue_fq()
-      dpaa2_io_service_enqueue_qd()
-      dpaa2_io_store_create()
-      dpaa2_io_store_destroy()
-      dpaa2_io_store_next()
-
-   Buffer pool management
-      dpaa2_io_service_release()
-      dpaa2_io_service_acquire()
-
-QBman portal interface (qbman-portal.c)
----------------------------------------
-
-   The qbman-portal component provides APIs to do the low level hardware
-   bit twiddling for operations such as:
-      -initializing Qman software portals
-      -building and sending portal commands
-      -portal interrupt configuration and processing
-
-   The qbman-portal APIs are not public to other drivers, and are
-   only used by dpio-service.
-
-Other (dpaa2-fd.h, dpaa2-global.h)
-----------------------------------
-
-   Frame descriptor and scatter-gather definitions and the APIs used to
-   manipulate them are defined in dpaa2-fd.h.
-
-   Dequeue result struct and parsing APIs are defined in dpaa2-global.h.
diff --git a/drivers/staging/fsl-mc/bus/dpio/dpio-service.c b/drivers/staging/fsl-mc/bus/dpio/dpio-service.c
deleted file mode 100644 (file)
index 14ed2be..0000000
+++ /dev/null
@@ -1,545 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
-/*
- * Copyright 2014-2016 Freescale Semiconductor Inc.
- * Copyright 2016 NXP
- *
- */
-#include <linux/types.h>
-#include <linux/fsl/mc.h>
-#include "../../include/dpaa2-io.h"
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-
-#include "dpio.h"
-#include "qbman-portal.h"
-
-struct dpaa2_io {
-       struct dpaa2_io_desc dpio_desc;
-       struct qbman_swp_desc swp_desc;
-       struct qbman_swp *swp;
-       struct list_head node;
-       /* protect against multiple management commands */
-       spinlock_t lock_mgmt_cmd;
-       /* protect notifications list */
-       spinlock_t lock_notifications;
-       struct list_head notifications;
-};
-
-struct dpaa2_io_store {
-       unsigned int max;
-       dma_addr_t paddr;
-       struct dpaa2_dq *vaddr;
-       void *alloced_addr;    /* unaligned value from kmalloc() */
-       unsigned int idx;      /* position of the next-to-be-returned entry */
-       struct qbman_swp *swp; /* portal used to issue VDQCR */
-       struct device *dev;    /* device used for DMA mapping */
-};
-
-/* keep a per cpu array of DPIOs for fast access */
-static struct dpaa2_io *dpio_by_cpu[NR_CPUS];
-static struct list_head dpio_list = LIST_HEAD_INIT(dpio_list);
-static DEFINE_SPINLOCK(dpio_list_lock);
-
-static inline struct dpaa2_io *service_select_by_cpu(struct dpaa2_io *d,
-                                                    int cpu)
-{
-       if (d)
-               return d;
-
-       if (cpu != DPAA2_IO_ANY_CPU && cpu >= num_possible_cpus())
-               return NULL;
-
-       /*
-        * If cpu == -1, choose the current cpu, with no guarantees about
-        * potentially being migrated away.
-        */
-       if (unlikely(cpu < 0))
-               cpu = smp_processor_id();
-
-       /* If a specific cpu was requested, pick it up immediately */
-       return dpio_by_cpu[cpu];
-}
-
-static inline struct dpaa2_io *service_select(struct dpaa2_io *d)
-{
-       if (d)
-               return d;
-
-       spin_lock(&dpio_list_lock);
-       d = list_entry(dpio_list.next, struct dpaa2_io, node);
-       list_del(&d->node);
-       list_add_tail(&d->node, &dpio_list);
-       spin_unlock(&dpio_list_lock);
-
-       return d;
-}
-
-/**
- * dpaa2_io_service_select() - return a dpaa2_io service affined to this cpu
- * @cpu: the cpu id
- *
- * Return the affine dpaa2_io service, or NULL if there is no service affined
- * to the specified cpu. If DPAA2_IO_ANY_CPU is used, return the next available
- * service.
- */
-struct dpaa2_io *dpaa2_io_service_select(int cpu)
-{
-       if (cpu == DPAA2_IO_ANY_CPU)
-               return service_select(NULL);
-
-       return service_select_by_cpu(NULL, cpu);
-}
-EXPORT_SYMBOL_GPL(dpaa2_io_service_select);
-
-/**
- * dpaa2_io_create() - create a dpaa2_io object.
- * @desc: the dpaa2_io descriptor
- *
- * Activates a "struct dpaa2_io" corresponding to the given config of an actual
- * DPIO object.
- *
- * Return a valid dpaa2_io object for success, or NULL for failure.
- */
-struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc)
-{
-       struct dpaa2_io *obj = kmalloc(sizeof(*obj), GFP_KERNEL);
-
-       if (!obj)
-               return NULL;
-
-       /* check if CPU is out of range (-1 means any cpu) */
-       if (desc->cpu != DPAA2_IO_ANY_CPU && desc->cpu >= num_possible_cpus()) {
-               kfree(obj);
-               return NULL;
-       }
-
-       obj->dpio_desc = *desc;
-       obj->swp_desc.cena_bar = obj->dpio_desc.regs_cena;
-       obj->swp_desc.cinh_bar = obj->dpio_desc.regs_cinh;
-       obj->swp_desc.qman_version = obj->dpio_desc.qman_version;
-       obj->swp = qbman_swp_init(&obj->swp_desc);
-
-       if (!obj->swp) {
-               kfree(obj);
-               return NULL;
-       }
-
-       INIT_LIST_HEAD(&obj->node);
-       spin_lock_init(&obj->lock_mgmt_cmd);
-       spin_lock_init(&obj->lock_notifications);
-       INIT_LIST_HEAD(&obj->notifications);
-
-       /* For now only enable DQRR interrupts */
-       qbman_swp_interrupt_set_trigger(obj->swp,
-                                       QBMAN_SWP_INTERRUPT_DQRI);
-       qbman_swp_interrupt_clear_status(obj->swp, 0xffffffff);
-       if (obj->dpio_desc.receives_notifications)
-               qbman_swp_push_set(obj->swp, 0, 1);
-
-       spin_lock(&dpio_list_lock);
-       list_add_tail(&obj->node, &dpio_list);
-       if (desc->cpu >= 0 && !dpio_by_cpu[desc->cpu])
-               dpio_by_cpu[desc->cpu] = obj;
-       spin_unlock(&dpio_list_lock);
-
-       return obj;
-}
-
-/**
- * dpaa2_io_down() - release the dpaa2_io object.
- * @d: the dpaa2_io object to be released.
- *
- * The "struct dpaa2_io" type can represent an individual DPIO object (as
- * described by "struct dpaa2_io_desc") or an instance of a "DPIO service",
- * which can be used to group/encapsulate multiple DPIO objects. In all cases,
- * each handle obtained should be released using this function.
- */
-void dpaa2_io_down(struct dpaa2_io *d)
-{
-       kfree(d);
-}
-
-#define DPAA_POLL_MAX 32
-
-/**
- * dpaa2_io_irq() - ISR for DPIO interrupts
- *
- * @obj: the given DPIO object.
- *
- * Return IRQ_HANDLED for success or IRQ_NONE if there
- * were no pending interrupts.
- */
-irqreturn_t dpaa2_io_irq(struct dpaa2_io *obj)
-{
-       const struct dpaa2_dq *dq;
-       int max = 0;
-       struct qbman_swp *swp;
-       u32 status;
-
-       swp = obj->swp;
-       status = qbman_swp_interrupt_read_status(swp);
-       if (!status)
-               return IRQ_NONE;
-
-       dq = qbman_swp_dqrr_next(swp);
-       while (dq) {
-               if (qbman_result_is_SCN(dq)) {
-                       struct dpaa2_io_notification_ctx *ctx;
-                       u64 q64;
-
-                       q64 = qbman_result_SCN_ctx(dq);
-                       ctx = (void *)(uintptr_t)q64;
-                       ctx->cb(ctx);
-               } else {
-                       pr_crit("fsl-mc-dpio: Unrecognised/ignored DQRR entry\n");
-               }
-               qbman_swp_dqrr_consume(swp, dq);
-               ++max;
-               if (max > DPAA_POLL_MAX)
-                       goto done;
-               dq = qbman_swp_dqrr_next(swp);
-       }
-done:
-       qbman_swp_interrupt_clear_status(swp, status);
-       qbman_swp_interrupt_set_inhibit(swp, 0);
-       return IRQ_HANDLED;
-}
-
-/**
- * dpaa2_io_service_register() - Prepare for servicing of FQDAN or CDAN
- *                               notifications on the given DPIO service.
- * @d:   the given DPIO service.
- * @ctx: the notification context.
- *
- * The caller should make the MC command to attach a DPAA2 object to
- * a DPIO after this function completes successfully.  In that way:
- *    (a) The DPIO service is "ready" to handle a notification arrival
- *        (which might happen before the "attach" command to MC has
- *        returned control of execution back to the caller)
- *    (b) The DPIO service can provide back to the caller the 'dpio_id' and
- *        'qman64' parameters that it should pass along in the MC command
- *        in order for the object to be configured to produce the right
- *        notification fields to the DPIO service.
- *
- * Return 0 for success, or -ENODEV for failure.
- */
-int dpaa2_io_service_register(struct dpaa2_io *d,
-                             struct dpaa2_io_notification_ctx *ctx)
-{
-       unsigned long irqflags;
-
-       d = service_select_by_cpu(d, ctx->desired_cpu);
-       if (!d)
-               return -ENODEV;
-
-       ctx->dpio_id = d->dpio_desc.dpio_id;
-       ctx->qman64 = (u64)(uintptr_t)ctx;
-       ctx->dpio_private = d;
-       spin_lock_irqsave(&d->lock_notifications, irqflags);
-       list_add(&ctx->node, &d->notifications);
-       spin_unlock_irqrestore(&d->lock_notifications, irqflags);
-
-       /* Enable the generation of CDAN notifications */
-       if (ctx->is_cdan)
-               return qbman_swp_CDAN_set_context_enable(d->swp,
-                                                        (u16)ctx->id,
-                                                        ctx->qman64);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(dpaa2_io_service_register);
-
-/**
- * dpaa2_io_service_deregister - The opposite of 'register'.
- * @service: the given DPIO service.
- * @ctx: the notification context.
- *
- * This function should be called only after sending the MC command to
- * to detach the notification-producing device from the DPIO.
- */
-void dpaa2_io_service_deregister(struct dpaa2_io *service,
-                                struct dpaa2_io_notification_ctx *ctx)
-{
-       struct dpaa2_io *d = ctx->dpio_private;
-       unsigned long irqflags;
-
-       if (ctx->is_cdan)
-               qbman_swp_CDAN_disable(d->swp, (u16)ctx->id);
-
-       spin_lock_irqsave(&d->lock_notifications, irqflags);
-       list_del(&ctx->node);
-       spin_unlock_irqrestore(&d->lock_notifications, irqflags);
-}
-EXPORT_SYMBOL_GPL(dpaa2_io_service_deregister);
-
-/**
- * dpaa2_io_service_rearm() - Rearm the notification for the given DPIO service.
- * @d: the given DPIO service.
- * @ctx: the notification context.
- *
- * Once a FQDAN/CDAN has been produced, the corresponding FQ/channel is
- * considered "disarmed". Ie. the user can issue pull dequeue operations on that
- * traffic source for as long as it likes. Eventually it may wish to "rearm"
- * that source to allow it to produce another FQDAN/CDAN, that's what this
- * function achieves.
- *
- * Return 0 for success.
- */
-int dpaa2_io_service_rearm(struct dpaa2_io *d,
-                          struct dpaa2_io_notification_ctx *ctx)
-{
-       unsigned long irqflags;
-       int err;
-
-       d = service_select_by_cpu(d, ctx->desired_cpu);
-       if (!unlikely(d))
-               return -ENODEV;
-
-       spin_lock_irqsave(&d->lock_mgmt_cmd, irqflags);
-       if (ctx->is_cdan)
-               err = qbman_swp_CDAN_enable(d->swp, (u16)ctx->id);
-       else
-               err = qbman_swp_fq_schedule(d->swp, ctx->id);
-       spin_unlock_irqrestore(&d->lock_mgmt_cmd, irqflags);
-
-       return err;
-}
-EXPORT_SYMBOL_GPL(dpaa2_io_service_rearm);
-
-/**
- * dpaa2_io_service_pull_channel() - pull dequeue functions from a channel.
- * @d: the given DPIO service.
- * @channelid: the given channel id.
- * @s: the dpaa2_io_store object for the result.
- *
- * Return 0 for success, or error code for failure.
- */
-int dpaa2_io_service_pull_channel(struct dpaa2_io *d, u32 channelid,
-                                 struct dpaa2_io_store *s)
-{
-       struct qbman_pull_desc pd;
-       int err;
-
-       qbman_pull_desc_clear(&pd);
-       qbman_pull_desc_set_storage(&pd, s->vaddr, s->paddr, 1);
-       qbman_pull_desc_set_numframes(&pd, (u8)s->max);
-       qbman_pull_desc_set_channel(&pd, channelid, qbman_pull_type_prio);
-
-       d = service_select(d);
-       if (!d)
-               return -ENODEV;
-
-       s->swp = d->swp;
-       err = qbman_swp_pull(d->swp, &pd);
-       if (err)
-               s->swp = NULL;
-
-       return err;
-}
-EXPORT_SYMBOL_GPL(dpaa2_io_service_pull_channel);
-
-/**
- * dpaa2_io_service_enqueue_qd() - Enqueue a frame to a QD.
- * @d: the given DPIO service.
- * @qdid: the given queuing destination id.
- * @prio: the given queuing priority.
- * @qdbin: the given queuing destination bin.
- * @fd: the frame descriptor which is enqueued.
- *
- * Return 0 for successful enqueue, or -EBUSY if the enqueue ring is not ready,
- * or -ENODEV if there is no dpio service.
- */
-int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d,
-                               u32 qdid, u8 prio, u16 qdbin,
-                               const struct dpaa2_fd *fd)
-{
-       struct qbman_eq_desc ed;
-
-       d = service_select(d);
-       if (!d)
-               return -ENODEV;
-
-       qbman_eq_desc_clear(&ed);
-       qbman_eq_desc_set_no_orp(&ed, 0);
-       qbman_eq_desc_set_qd(&ed, qdid, qdbin, prio);
-
-       return qbman_swp_enqueue(d->swp, &ed, fd);
-}
-EXPORT_SYMBOL_GPL(dpaa2_io_service_enqueue_qd);
-
-/**
- * dpaa2_io_service_release() - Release buffers to a buffer pool.
- * @d: the given DPIO object.
- * @bpid: the buffer pool id.
- * @buffers: the buffers to be released.
- * @num_buffers: the number of the buffers to be released.
- *
- * Return 0 for success, and negative error code for failure.
- */
-int dpaa2_io_service_release(struct dpaa2_io *d,
-                            u32 bpid,
-                            const u64 *buffers,
-                            unsigned int num_buffers)
-{
-       struct qbman_release_desc rd;
-
-       d = service_select(d);
-       if (!d)
-               return -ENODEV;
-
-       qbman_release_desc_clear(&rd);
-       qbman_release_desc_set_bpid(&rd, bpid);
-
-       return qbman_swp_release(d->swp, &rd, buffers, num_buffers);
-}
-EXPORT_SYMBOL_GPL(dpaa2_io_service_release);
-
-/**
- * dpaa2_io_service_acquire() - Acquire buffers from a buffer pool.
- * @d: the given DPIO object.
- * @bpid: the buffer pool id.
- * @buffers: the buffer addresses for acquired buffers.
- * @num_buffers: the expected number of the buffers to acquire.
- *
- * Return a negative error code if the command failed, otherwise it returns
- * the number of buffers acquired, which may be less than the number requested.
- * Eg. if the buffer pool is empty, this will return zero.
- */
-int dpaa2_io_service_acquire(struct dpaa2_io *d,
-                            u32 bpid,
-                            u64 *buffers,
-                            unsigned int num_buffers)
-{
-       unsigned long irqflags;
-       int err;
-
-       d = service_select(d);
-       if (!d)
-               return -ENODEV;
-
-       spin_lock_irqsave(&d->lock_mgmt_cmd, irqflags);
-       err = qbman_swp_acquire(d->swp, bpid, buffers, num_buffers);
-       spin_unlock_irqrestore(&d->lock_mgmt_cmd, irqflags);
-
-       return err;
-}
-EXPORT_SYMBOL_GPL(dpaa2_io_service_acquire);
-
-/*
- * 'Stores' are reusable memory blocks for holding dequeue results, and to
- * assist with parsing those results.
- */
-
-/**
- * dpaa2_io_store_create() - Create the dma memory storage for dequeue result.
- * @max_frames: the maximum number of dequeued result for frames, must be <= 16.
- * @dev:        the device to allow mapping/unmapping the DMAable region.
- *
- * The size of the storage is "max_frames*sizeof(struct dpaa2_dq)".
- * The 'dpaa2_io_store' returned is a DPIO service managed object.
- *
- * Return pointer to dpaa2_io_store struct for successfully created storage
- * memory, or NULL on error.
- */
-struct dpaa2_io_store *dpaa2_io_store_create(unsigned int max_frames,
-                                            struct device *dev)
-{
-       struct dpaa2_io_store *ret;
-       size_t size;
-
-       if (!max_frames || (max_frames > 16))
-               return NULL;
-
-       ret = kmalloc(sizeof(*ret), GFP_KERNEL);
-       if (!ret)
-               return NULL;
-
-       ret->max = max_frames;
-       size = max_frames * sizeof(struct dpaa2_dq) + 64;
-       ret->alloced_addr = kzalloc(size, GFP_KERNEL);
-       if (!ret->alloced_addr) {
-               kfree(ret);
-               return NULL;
-       }
-
-       ret->vaddr = PTR_ALIGN(ret->alloced_addr, 64);
-       ret->paddr = dma_map_single(dev, ret->vaddr,
-                                   sizeof(struct dpaa2_dq) * max_frames,
-                                   DMA_FROM_DEVICE);
-       if (dma_mapping_error(dev, ret->paddr)) {
-               kfree(ret->alloced_addr);
-               kfree(ret);
-               return NULL;
-       }
-
-       ret->idx = 0;
-       ret->dev = dev;
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(dpaa2_io_store_create);
-
-/**
- * dpaa2_io_store_destroy() - Frees the dma memory storage for dequeue
- *                            result.
- * @s: the storage memory to be destroyed.
- */
-void dpaa2_io_store_destroy(struct dpaa2_io_store *s)
-{
-       dma_unmap_single(s->dev, s->paddr, sizeof(struct dpaa2_dq) * s->max,
-                        DMA_FROM_DEVICE);
-       kfree(s->alloced_addr);
-       kfree(s);
-}
-EXPORT_SYMBOL_GPL(dpaa2_io_store_destroy);
-
-/**
- * dpaa2_io_store_next() - Determine when the next dequeue result is available.
- * @s: the dpaa2_io_store object.
- * @is_last: indicate whether this is the last frame in the pull command.
- *
- * When an object driver performs dequeues to a dpaa2_io_store, this function
- * can be used to determine when the next frame result is available. Once
- * this function returns non-NULL, a subsequent call to it will try to find
- * the next dequeue result.
- *
- * Note that if a pull-dequeue has a NULL result because the target FQ/channel
- * was empty, then this function will also return NULL (rather than expecting
- * the caller to always check for this. As such, "is_last" can be used to
- * differentiate between "end-of-empty-dequeue" and "still-waiting".
- *
- * Return dequeue result for a valid dequeue result, or NULL for empty dequeue.
- */
-struct dpaa2_dq *dpaa2_io_store_next(struct dpaa2_io_store *s, int *is_last)
-{
-       int match;
-       struct dpaa2_dq *ret = &s->vaddr[s->idx];
-
-       match = qbman_result_has_new_result(s->swp, ret);
-       if (!match) {
-               *is_last = 0;
-               return NULL;
-       }
-
-       s->idx++;
-
-       if (dpaa2_dq_is_pull_complete(ret)) {
-               *is_last = 1;
-               s->idx = 0;
-               /*
-                * If we get an empty dequeue result to terminate a zero-results
-                * vdqcr, return NULL to the caller rather than expecting him to
-                * check non-NULL results every time.
-                */
-               if (!(dpaa2_dq_flags(ret) & DPAA2_DQ_STAT_VALIDFRAME))
-                       ret = NULL;
-       } else {
-               *is_last = 0;
-       }
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(dpaa2_io_store_next);
diff --git a/drivers/staging/fsl-mc/bus/dpio/dpio.c b/drivers/staging/fsl-mc/bus/dpio/dpio.c
deleted file mode 100644 (file)
index ff37c80..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
-/*
- * Copyright 2013-2016 Freescale Semiconductor Inc.
- * Copyright 2016 NXP
- *
- */
-#include <linux/kernel.h>
-#include <linux/fsl/mc.h>
-
-#include "dpio.h"
-#include "dpio-cmd.h"
-
-/*
- * Data Path I/O Portal API
- * Contains initialization APIs and runtime control APIs for DPIO
- */
-
-/**
- * dpio_open() - Open a control session for the specified object
- * @mc_io:     Pointer to MC portal's I/O object
- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- * @dpio_id:   DPIO unique ID
- * @token:     Returned token; use in subsequent API calls
- *
- * This function can be used to open a control session for an
- * already created object; an object may have been declared in
- * the DPL or by calling the dpio_create() function.
- * This function returns a unique authentication token,
- * associated with the specific object ID and the specific MC
- * portal; this token must be used in all subsequent commands for
- * this specific object.
- *
- * Return:     '0' on Success; Error code otherwise.
- */
-int dpio_open(struct fsl_mc_io *mc_io,
-             u32 cmd_flags,
-             int dpio_id,
-             u16 *token)
-{
-       struct fsl_mc_command cmd = { 0 };
-       struct dpio_cmd_open *dpio_cmd;
-       int err;
-
-       /* prepare command */
-       cmd.header = mc_encode_cmd_header(DPIO_CMDID_OPEN,
-                                         cmd_flags,
-                                         0);
-       dpio_cmd = (struct dpio_cmd_open *)cmd.params;
-       dpio_cmd->dpio_id = cpu_to_le32(dpio_id);
-
-       err = mc_send_command(mc_io, &cmd);
-       if (err)
-               return err;
-
-       /* retrieve response parameters */
-       *token = mc_cmd_hdr_read_token(&cmd);
-
-       return 0;
-}
-
-/**
- * dpio_close() - Close the control session of the object
- * @mc_io:     Pointer to MC portal's I/O object
- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- * @token:     Token of DPIO object
- *
- * Return:     '0' on Success; Error code otherwise.
- */
-int dpio_close(struct fsl_mc_io *mc_io,
-              u32 cmd_flags,
-              u16 token)
-{
-       struct fsl_mc_command cmd = { 0 };
-
-       /* prepare command */
-       cmd.header = mc_encode_cmd_header(DPIO_CMDID_CLOSE,
-                                         cmd_flags,
-                                         token);
-
-       return mc_send_command(mc_io, &cmd);
-}
-
-/**
- * dpio_enable() - Enable the DPIO, allow I/O portal operations.
- * @mc_io:     Pointer to MC portal's I/O object
- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- * @token:     Token of DPIO object
- *
- * Return:     '0' on Success; Error code otherwise
- */
-int dpio_enable(struct fsl_mc_io *mc_io,
-               u32 cmd_flags,
-               u16 token)
-{
-       struct fsl_mc_command cmd = { 0 };
-
-       /* prepare command */
-       cmd.header = mc_encode_cmd_header(DPIO_CMDID_ENABLE,
-                                         cmd_flags,
-                                         token);
-
-       return mc_send_command(mc_io, &cmd);
-}
-
-/**
- * dpio_disable() - Disable the DPIO, stop any I/O portal operation.
- * @mc_io:     Pointer to MC portal's I/O object
- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- * @token:     Token of DPIO object
- *
- * Return:     '0' on Success; Error code otherwise
- */
-int dpio_disable(struct fsl_mc_io *mc_io,
-                u32 cmd_flags,
-                u16 token)
-{
-       struct fsl_mc_command cmd = { 0 };
-
-       /* prepare command */
-       cmd.header = mc_encode_cmd_header(DPIO_CMDID_DISABLE,
-                                         cmd_flags,
-                                         token);
-
-       return mc_send_command(mc_io, &cmd);
-}
-
-/**
- * dpio_get_attributes() - Retrieve DPIO attributes
- * @mc_io:     Pointer to MC portal's I/O object
- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- * @token:     Token of DPIO object
- * @attr:      Returned object's attributes
- *
- * Return:     '0' on Success; Error code otherwise
- */
-int dpio_get_attributes(struct fsl_mc_io *mc_io,
-                       u32 cmd_flags,
-                       u16 token,
-                       struct dpio_attr *attr)
-{
-       struct fsl_mc_command cmd = { 0 };
-       struct dpio_rsp_get_attr *dpio_rsp;
-       int err;
-
-       /* prepare command */
-       cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_ATTR,
-                                         cmd_flags,
-                                         token);
-
-       err = mc_send_command(mc_io, &cmd);
-       if (err)
-               return err;
-
-       /* retrieve response parameters */
-       dpio_rsp = (struct dpio_rsp_get_attr *)cmd.params;
-       attr->id = le32_to_cpu(dpio_rsp->id);
-       attr->qbman_portal_id = le16_to_cpu(dpio_rsp->qbman_portal_id);
-       attr->num_priorities = dpio_rsp->num_priorities;
-       attr->channel_mode = dpio_rsp->channel_mode & DPIO_CHANNEL_MODE_MASK;
-       attr->qbman_portal_ce_offset =
-               le64_to_cpu(dpio_rsp->qbman_portal_ce_addr);
-       attr->qbman_portal_ci_offset =
-               le64_to_cpu(dpio_rsp->qbman_portal_ci_addr);
-       attr->qbman_version = le32_to_cpu(dpio_rsp->qbman_version);
-
-       return 0;
-}
-
-/**
- * dpio_get_api_version - Get Data Path I/O API version
- * @mc_io:     Pointer to MC portal's DPIO object
- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
- * @major_ver: Major version of DPIO API
- * @minor_ver: Minor version of DPIO API
- *
- * Return:     '0' on Success; Error code otherwise
- */
-int dpio_get_api_version(struct fsl_mc_io *mc_io,
-                        u32 cmd_flags,
-                        u16 *major_ver,
-                        u16 *minor_ver)
-{
-       struct fsl_mc_command cmd = { 0 };
-       int err;
-
-       /* prepare command */
-       cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_API_VERSION,
-                                         cmd_flags, 0);
-
-       err = mc_send_command(mc_io, &cmd);
-       if (err)
-               return err;
-
-       /* retrieve response parameters */
-       mc_cmd_read_api_version(&cmd, major_ver, minor_ver);
-
-       return 0;
-}
diff --git a/drivers/staging/fsl-mc/bus/dpio/dpio.h b/drivers/staging/fsl-mc/bus/dpio/dpio.h
deleted file mode 100644 (file)
index 49194c8..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
-/*
- * Copyright 2013-2016 Freescale Semiconductor Inc.
- * Copyright 2016 NXP
- *
- */
-#ifndef __FSL_DPIO_H
-#define __FSL_DPIO_H
-
-struct fsl_mc_io;
-
-int dpio_open(struct fsl_mc_io *mc_io,
-             u32               cmd_flags,
-             int               dpio_id,
-             u16               *token);
-
-int dpio_close(struct fsl_mc_io        *mc_io,
-              u32              cmd_flags,
-              u16              token);
-
-/**
- * enum dpio_channel_mode - DPIO notification channel mode
- * @DPIO_NO_CHANNEL: No support for notification channel
- * @DPIO_LOCAL_CHANNEL: Notifications on data availability can be received by a
- *     dedicated channel in the DPIO; user should point the queue's
- *     destination in the relevant interface to this DPIO
- */
-enum dpio_channel_mode {
-       DPIO_NO_CHANNEL = 0,
-       DPIO_LOCAL_CHANNEL = 1,
-};
-
-/**
- * struct dpio_cfg - Structure representing DPIO configuration
- * @channel_mode: Notification channel mode
- * @num_priorities: Number of priorities for the notification channel (1-8);
- *                     relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
- */
-struct dpio_cfg {
-       enum dpio_channel_mode  channel_mode;
-       u8              num_priorities;
-};
-
-int dpio_enable(struct fsl_mc_io       *mc_io,
-               u32             cmd_flags,
-               u16             token);
-
-int dpio_disable(struct fsl_mc_io      *mc_io,
-                u32            cmd_flags,
-                u16            token);
-
-/**
- * struct dpio_attr - Structure representing DPIO attributes
- * @id: DPIO object ID
- * @qbman_portal_ce_offset: offset of the software portal cache-enabled area
- * @qbman_portal_ci_offset: offset of the software portal cache-inhibited area
- * @qbman_portal_id: Software portal ID
- * @channel_mode: Notification channel mode
- * @num_priorities: Number of priorities for the notification channel (1-8);
- *                     relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
- * @qbman_version: QBMAN version
- */
-struct dpio_attr {
-       int                     id;
-       u64             qbman_portal_ce_offset;
-       u64             qbman_portal_ci_offset;
-       u16             qbman_portal_id;
-       enum dpio_channel_mode  channel_mode;
-       u8                      num_priorities;
-       u32             qbman_version;
-};
-
-int dpio_get_attributes(struct fsl_mc_io       *mc_io,
-                       u32             cmd_flags,
-                       u16             token,
-                       struct dpio_attr        *attr);
-
-int dpio_get_api_version(struct fsl_mc_io *mc_io,
-                        u32 cmd_flags,
-                        u16 *major_ver,
-                        u16 *minor_ver);
-
-#endif /* __FSL_DPIO_H */
diff --git a/drivers/staging/fsl-mc/bus/dpio/qbman-portal.c b/drivers/staging/fsl-mc/bus/dpio/qbman-portal.c
deleted file mode 100644 (file)
index 116fafb..0000000
+++ /dev/null
@@ -1,1005 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
-/*
- * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
- * Copyright 2016 NXP
- *
- */
-
-#include <asm/cacheflush.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include "../../include/dpaa2-global.h"
-
-#include "qbman-portal.h"
-
-#define QMAN_REV_4000   0x04000000
-#define QMAN_REV_4100   0x04010000
-#define QMAN_REV_4101   0x04010001
-#define QMAN_REV_MASK   0xffff0000
-
-/* All QBMan command and result structures use this "valid bit" encoding */
-#define QB_VALID_BIT ((u32)0x80)
-
-/* QBMan portal management command codes */
-#define QBMAN_MC_ACQUIRE       0x30
-#define QBMAN_WQCHAN_CONFIGURE 0x46
-
-/* CINH register offsets */
-#define QBMAN_CINH_SWP_EQAR    0x8c0
-#define QBMAN_CINH_SWP_DQPI    0xa00
-#define QBMAN_CINH_SWP_DCAP    0xac0
-#define QBMAN_CINH_SWP_SDQCR   0xb00
-#define QBMAN_CINH_SWP_RAR     0xcc0
-#define QBMAN_CINH_SWP_ISR     0xe00
-#define QBMAN_CINH_SWP_IER     0xe40
-#define QBMAN_CINH_SWP_ISDR    0xe80
-#define QBMAN_CINH_SWP_IIR     0xec0
-
-/* CENA register offsets */
-#define QBMAN_CENA_SWP_EQCR(n) (0x000 + ((u32)(n) << 6))
-#define QBMAN_CENA_SWP_DQRR(n) (0x200 + ((u32)(n) << 6))
-#define QBMAN_CENA_SWP_RCR(n)  (0x400 + ((u32)(n) << 6))
-#define QBMAN_CENA_SWP_CR      0x600
-#define QBMAN_CENA_SWP_RR(vb)  (0x700 + ((u32)(vb) >> 1))
-#define QBMAN_CENA_SWP_VDQCR   0x780
-
-/* Reverse mapping of QBMAN_CENA_SWP_DQRR() */
-#define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)(p) & 0x1ff) >> 6)
-
-/* Define token used to determine if response written to memory is valid */
-#define QMAN_DQ_TOKEN_VALID 1
-
-/* SDQCR attribute codes */
-#define QB_SDQCR_FC_SHIFT   29
-#define QB_SDQCR_FC_MASK    0x1
-#define QB_SDQCR_DCT_SHIFT  24
-#define QB_SDQCR_DCT_MASK   0x3
-#define QB_SDQCR_TOK_SHIFT  16
-#define QB_SDQCR_TOK_MASK   0xff
-#define QB_SDQCR_SRC_SHIFT  0
-#define QB_SDQCR_SRC_MASK   0xffff
-
-/* opaque token for static dequeues */
-#define QMAN_SDQCR_TOKEN    0xbb
-
-enum qbman_sdqcr_dct {
-       qbman_sdqcr_dct_null = 0,
-       qbman_sdqcr_dct_prio_ics,
-       qbman_sdqcr_dct_active_ics,
-       qbman_sdqcr_dct_active
-};
-
-enum qbman_sdqcr_fc {
-       qbman_sdqcr_fc_one = 0,
-       qbman_sdqcr_fc_up_to_3 = 1
-};
-
-/* Portal Access */
-
-static inline u32 qbman_read_register(struct qbman_swp *p, u32 offset)
-{
-       return readl_relaxed(p->addr_cinh + offset);
-}
-
-static inline void qbman_write_register(struct qbman_swp *p, u32 offset,
-                                       u32 value)
-{
-       writel_relaxed(value, p->addr_cinh + offset);
-}
-
-static inline void *qbman_get_cmd(struct qbman_swp *p, u32 offset)
-{
-       return p->addr_cena + offset;
-}
-
-#define QBMAN_CINH_SWP_CFG   0xd00
-
-#define SWP_CFG_DQRR_MF_SHIFT 20
-#define SWP_CFG_EST_SHIFT     16
-#define SWP_CFG_WN_SHIFT      14
-#define SWP_CFG_RPM_SHIFT     12
-#define SWP_CFG_DCM_SHIFT     10
-#define SWP_CFG_EPM_SHIFT     8
-#define SWP_CFG_SD_SHIFT      5
-#define SWP_CFG_SP_SHIFT      4
-#define SWP_CFG_SE_SHIFT      3
-#define SWP_CFG_DP_SHIFT      2
-#define SWP_CFG_DE_SHIFT      1
-#define SWP_CFG_EP_SHIFT      0
-
-static inline u32 qbman_set_swp_cfg(u8 max_fill, u8 wn,        u8 est, u8 rpm, u8 dcm,
-                                   u8 epm, int sd, int sp, int se,
-                                   int dp, int de, int ep)
-{
-       return (max_fill << SWP_CFG_DQRR_MF_SHIFT |
-               est << SWP_CFG_EST_SHIFT |
-               wn << SWP_CFG_WN_SHIFT |
-               rpm << SWP_CFG_RPM_SHIFT |
-               dcm << SWP_CFG_DCM_SHIFT |
-               epm << SWP_CFG_EPM_SHIFT |
-               sd << SWP_CFG_SD_SHIFT |
-               sp << SWP_CFG_SP_SHIFT |
-               se << SWP_CFG_SE_SHIFT |
-               dp << SWP_CFG_DP_SHIFT |
-               de << SWP_CFG_DE_SHIFT |
-               ep << SWP_CFG_EP_SHIFT);
-}
-
-/**
- * qbman_swp_init() - Create a functional object representing the given
- *                    QBMan portal descriptor.
- * @d: the given qbman swp descriptor
- *
- * Return qbman_swp portal for success, NULL if the object cannot
- * be created.
- */
-struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
-{
-       struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
-       u32 reg;
-
-       if (!p)
-               return NULL;
-       p->desc = d;
-       p->mc.valid_bit = QB_VALID_BIT;
-       p->sdq = 0;
-       p->sdq |= qbman_sdqcr_dct_prio_ics << QB_SDQCR_DCT_SHIFT;
-       p->sdq |= qbman_sdqcr_fc_up_to_3 << QB_SDQCR_FC_SHIFT;
-       p->sdq |= QMAN_SDQCR_TOKEN << QB_SDQCR_TOK_SHIFT;
-
-       atomic_set(&p->vdq.available, 1);
-       p->vdq.valid_bit = QB_VALID_BIT;
-       p->dqrr.next_idx = 0;
-       p->dqrr.valid_bit = QB_VALID_BIT;
-
-       if ((p->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_4100) {
-               p->dqrr.dqrr_size = 4;
-               p->dqrr.reset_bug = 1;
-       } else {
-               p->dqrr.dqrr_size = 8;
-               p->dqrr.reset_bug = 0;
-       }
-
-       p->addr_cena = d->cena_bar;
-       p->addr_cinh = d->cinh_bar;
-
-       reg = qbman_set_swp_cfg(p->dqrr.dqrr_size,
-                               1, /* Writes Non-cacheable */
-                               0, /* EQCR_CI stashing threshold */
-                               3, /* RPM: Valid bit mode, RCR in array mode */
-                               2, /* DCM: Discrete consumption ack mode */
-                               3, /* EPM: Valid bit mode, EQCR in array mode */
-                               0, /* mem stashing drop enable == FALSE */
-                               1, /* mem stashing priority == TRUE */
-                               0, /* mem stashing enable == FALSE */
-                               1, /* dequeue stashing priority == TRUE */
-                               0, /* dequeue stashing enable == FALSE */
-                               0); /* EQCR_CI stashing priority == FALSE */
-
-       qbman_write_register(p, QBMAN_CINH_SWP_CFG, reg);
-       reg = qbman_read_register(p, QBMAN_CINH_SWP_CFG);
-       if (!reg) {
-               pr_err("qbman: the portal is not enabled!\n");
-               return NULL;
-       }
-
-       /*
-        * SDQCR needs to be initialized to 0 when no channels are
-        * being dequeued from or else the QMan HW will indicate an
-        * error.  The values that were calculated above will be
-        * applied when dequeues from a specific channel are enabled.
-        */
-       qbman_write_register(p, QBMAN_CINH_SWP_SDQCR, 0);
-       return p;
-}
-
-/**
- * qbman_swp_finish() - Create and destroy a functional object representing
- *                      the given QBMan portal descriptor.
- * @p: the qbman_swp object to be destroyed
- */
-void qbman_swp_finish(struct qbman_swp *p)
-{
-       kfree(p);
-}
-
-/**
- * qbman_swp_interrupt_read_status()
- * @p: the given software portal
- *
- * Return the value in the SWP_ISR register.
- */
-u32 qbman_swp_interrupt_read_status(struct qbman_swp *p)
-{
-       return qbman_read_register(p, QBMAN_CINH_SWP_ISR);
-}
-
-/**
- * qbman_swp_interrupt_clear_status()
- * @p: the given software portal
- * @mask: The mask to clear in SWP_ISR register
- */
-void qbman_swp_interrupt_clear_status(struct qbman_swp *p, u32 mask)
-{
-       qbman_write_register(p, QBMAN_CINH_SWP_ISR, mask);
-}
-
-/**
- * qbman_swp_interrupt_get_trigger() - read interrupt enable register
- * @p: the given software portal
- *
- * Return the value in the SWP_IER register.
- */
-u32 qbman_swp_interrupt_get_trigger(struct qbman_swp *p)
-{
-       return qbman_read_register(p, QBMAN_CINH_SWP_IER);
-}
-
-/**
- * qbman_swp_interrupt_set_trigger() - enable interrupts for a swp
- * @p: the given software portal
- * @mask: The mask of bits to enable in SWP_IER
- */
-void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, u32 mask)
-{
-       qbman_write_register(p, QBMAN_CINH_SWP_IER, mask);
-}
-
-/**
- * qbman_swp_interrupt_get_inhibit() - read interrupt mask register
- * @p: the given software portal object
- *
- * Return the value in the SWP_IIR register.
- */
-int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p)
-{
-       return qbman_read_register(p, QBMAN_CINH_SWP_IIR);
-}
-
-/**
- * qbman_swp_interrupt_set_inhibit() - write interrupt mask register
- * @p: the given software portal object
- * @mask: The mask to set in SWP_IIR register
- */
-void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit)
-{
-       qbman_write_register(p, QBMAN_CINH_SWP_IIR, inhibit ? 0xffffffff : 0);
-}
-
-/*
- * Different management commands all use this common base layer of code to issue
- * commands and poll for results.
- */
-
-/*
- * Returns a pointer to where the caller should fill in their management command
- * (caller should ignore the verb byte)
- */
-void *qbman_swp_mc_start(struct qbman_swp *p)
-{
-       return qbman_get_cmd(p, QBMAN_CENA_SWP_CR);
-}
-
-/*
- * Commits merges in the caller-supplied command verb (which should not include
- * the valid-bit) and submits the command to hardware
- */
-void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, u8 cmd_verb)
-{
-       u8 *v = cmd;
-
-       dma_wmb();
-       *v = cmd_verb | p->mc.valid_bit;
-}
-
-/*
- * Checks for a completed response (returns non-NULL if only if the response
- * is complete).
- */
-void *qbman_swp_mc_result(struct qbman_swp *p)
-{
-       u32 *ret, verb;
-
-       ret = qbman_get_cmd(p, QBMAN_CENA_SWP_RR(p->mc.valid_bit));
-
-       /* Remove the valid-bit - command completed if the rest is non-zero */
-       verb = ret[0] & ~QB_VALID_BIT;
-       if (!verb)
-               return NULL;
-       p->mc.valid_bit ^= QB_VALID_BIT;
-       return ret;
-}
-
-#define QB_ENQUEUE_CMD_OPTIONS_SHIFT    0
-enum qb_enqueue_commands {
-       enqueue_empty = 0,
-       enqueue_response_always = 1,
-       enqueue_rejects_to_fq = 2
-};
-
-#define QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT      2
-#define QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT 3
-#define QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT     4
-
-/**
- * qbman_eq_desc_clear() - Clear the contents of a descriptor to
- *                         default/starting state.
- */
-void qbman_eq_desc_clear(struct qbman_eq_desc *d)
-{
-       memset(d, 0, sizeof(*d));
-}
-
-/**
- * qbman_eq_desc_set_no_orp() - Set enqueue descriptor without orp
- * @d:                the enqueue descriptor.
- * @response_success: 1 = enqueue with response always; 0 = enqueue with
- *                    rejections returned on a FQ.
- */
-void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success)
-{
-       d->verb &= ~(1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT);
-       if (respond_success)
-               d->verb |= enqueue_response_always;
-       else
-               d->verb |= enqueue_rejects_to_fq;
-}
-
-/*
- * Exactly one of the following descriptor "targets" should be set. (Calling any
- * one of these will replace the effect of any prior call to one of these.)
- *   -enqueue to a frame queue
- *   -enqueue to a queuing destination
- */
-
-/**
- * qbman_eq_desc_set_fq() - set the FQ for the enqueue command
- * @d:    the enqueue descriptor
- * @fqid: the id of the frame queue to be enqueued
- */
-void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, u32 fqid)
-{
-       d->verb &= ~(1 << QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT);
-       d->tgtid = cpu_to_le32(fqid);
-}
-
-/**
- * qbman_eq_desc_set_qd() - Set Queuing Destination for the enqueue command
- * @d:       the enqueue descriptor
- * @qdid:    the id of the queuing destination to be enqueued
- * @qd_bin:  the queuing destination bin
- * @qd_prio: the queuing destination priority
- */
-void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, u32 qdid,
-                         u32 qd_bin, u32 qd_prio)
-{
-       d->verb |= 1 << QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT;
-       d->tgtid = cpu_to_le32(qdid);
-       d->qdbin = cpu_to_le16(qd_bin);
-       d->qpri = qd_prio;
-}
-
-#define EQAR_IDX(eqar)     ((eqar) & 0x7)
-#define EQAR_VB(eqar)      ((eqar) & 0x80)
-#define EQAR_SUCCESS(eqar) ((eqar) & 0x100)
-
-/**
- * qbman_swp_enqueue() - Issue an enqueue command
- * @s:  the software portal used for enqueue
- * @d:  the enqueue descriptor
- * @fd: the frame descriptor to be enqueued
- *
- * Please note that 'fd' should only be NULL if the "action" of the
- * descriptor is "orp_hole" or "orp_nesn".
- *
- * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready.
- */
-int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
-                     const struct dpaa2_fd *fd)
-{
-       struct qbman_eq_desc *p;
-       u32 eqar = qbman_read_register(s, QBMAN_CINH_SWP_EQAR);
-
-       if (!EQAR_SUCCESS(eqar))
-               return -EBUSY;
-
-       p = qbman_get_cmd(s, QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
-       memcpy(&p->dca, &d->dca, 31);
-       memcpy(&p->fd, fd, sizeof(*fd));
-
-       /* Set the verb byte, have to substitute in the valid-bit */
-       dma_wmb();
-       p->verb = d->verb | EQAR_VB(eqar);
-
-       return 0;
-}
-
-/* Static (push) dequeue */
-
-/**
- * qbman_swp_push_get() - Get the push dequeue setup
- * @p:           the software portal object
- * @channel_idx: the channel index to query
- * @enabled:     returned boolean to show whether the push dequeue is enabled
- *               for the given channel
- */
-void qbman_swp_push_get(struct qbman_swp *s, u8 channel_idx, int *enabled)
-{
-       u16 src = (s->sdq >> QB_SDQCR_SRC_SHIFT) & QB_SDQCR_SRC_MASK;
-
-       WARN_ON(channel_idx > 15);
-       *enabled = src | (1 << channel_idx);
-}
-
-/**
- * qbman_swp_push_set() - Enable or disable push dequeue
- * @p:           the software portal object
- * @channel_idx: the channel index (0 to 15)
- * @enable:      enable or disable push dequeue
- */
-void qbman_swp_push_set(struct qbman_swp *s, u8 channel_idx, int enable)
-{
-       u16 dqsrc;
-
-       WARN_ON(channel_idx > 15);
-       if (enable)
-               s->sdq |= 1 << channel_idx;
-       else
-               s->sdq &= ~(1 << channel_idx);
-
-       /* Read make the complete src map.  If no channels are enabled
-        * the SDQCR must be 0 or else QMan will assert errors
-        */
-       dqsrc = (s->sdq >> QB_SDQCR_SRC_SHIFT) & QB_SDQCR_SRC_MASK;
-       if (dqsrc != 0)
-               qbman_write_register(s, QBMAN_CINH_SWP_SDQCR, s->sdq);
-       else
-               qbman_write_register(s, QBMAN_CINH_SWP_SDQCR, 0);
-}
-
-#define QB_VDQCR_VERB_DCT_SHIFT    0
-#define QB_VDQCR_VERB_DT_SHIFT     2
-#define QB_VDQCR_VERB_RLS_SHIFT    4
-#define QB_VDQCR_VERB_WAE_SHIFT    5
-
-enum qb_pull_dt_e {
-       qb_pull_dt_channel,
-       qb_pull_dt_workqueue,
-       qb_pull_dt_framequeue
-};
-
-/**
- * qbman_pull_desc_clear() - Clear the contents of a descriptor to
- *                           default/starting state
- * @d: the pull dequeue descriptor to be cleared
- */
-void qbman_pull_desc_clear(struct qbman_pull_desc *d)
-{
-       memset(d, 0, sizeof(*d));
-}
-
-/**
- * qbman_pull_desc_set_storage()- Set the pull dequeue storage
- * @d:            the pull dequeue descriptor to be set
- * @storage:      the pointer of the memory to store the dequeue result
- * @storage_phys: the physical address of the storage memory
- * @stash:        to indicate whether write allocate is enabled
- *
- * If not called, or if called with 'storage' as NULL, the result pull dequeues
- * will produce results to DQRR. If 'storage' is non-NULL, then results are
- * produced to the given memory location (using the DMA address which
- * the caller provides in 'storage_phys'), and 'stash' controls whether or not
- * those writes to main-memory express a cache-warming attribute.
- */
-void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
-                                struct dpaa2_dq *storage,
-                                dma_addr_t storage_phys,
-                                int stash)
-{
-       /* save the virtual address */
-       d->rsp_addr_virt = (u64)(uintptr_t)storage;
-
-       if (!storage) {
-               d->verb &= ~(1 << QB_VDQCR_VERB_RLS_SHIFT);
-               return;
-       }
-       d->verb |= 1 << QB_VDQCR_VERB_RLS_SHIFT;
-       if (stash)
-               d->verb |= 1 << QB_VDQCR_VERB_WAE_SHIFT;
-       else
-               d->verb &= ~(1 << QB_VDQCR_VERB_WAE_SHIFT);
-
-       d->rsp_addr = cpu_to_le64(storage_phys);
-}
-
-/**
- * qbman_pull_desc_set_numframes() - Set the number of frames to be dequeued
- * @d:         the pull dequeue descriptor to be set
- * @numframes: number of frames to be set, must be between 1 and 16, inclusive
- */
-void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, u8 numframes)
-{
-       d->numf = numframes - 1;
-}
-
-/*
- * Exactly one of the following descriptor "actions" should be set. (Calling any
- * one of these will replace the effect of any prior call to one of these.)
- * - pull dequeue from the given frame queue (FQ)
- * - pull dequeue from any FQ in the given work queue (WQ)
- * - pull dequeue from any FQ in any WQ in the given channel
- */
-
-/**
- * qbman_pull_desc_set_fq() - Set fqid from which the dequeue command dequeues
- * @fqid: the frame queue index of the given FQ
- */
-void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, u32 fqid)
-{
-       d->verb |= 1 << QB_VDQCR_VERB_DCT_SHIFT;
-       d->verb |= qb_pull_dt_framequeue << QB_VDQCR_VERB_DT_SHIFT;
-       d->dq_src = cpu_to_le32(fqid);
-}
-
-/**
- * qbman_pull_desc_set_wq() - Set wqid from which the dequeue command dequeues
- * @wqid: composed of channel id and wqid within the channel
- * @dct:  the dequeue command type
- */
-void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, u32 wqid,
-                           enum qbman_pull_type_e dct)
-{
-       d->verb |= dct << QB_VDQCR_VERB_DCT_SHIFT;
-       d->verb |= qb_pull_dt_workqueue << QB_VDQCR_VERB_DT_SHIFT;
-       d->dq_src = cpu_to_le32(wqid);
-}
-
-/**
- * qbman_pull_desc_set_channel() - Set channelid from which the dequeue command
- *                                 dequeues
- * @chid: the channel id to be dequeued
- * @dct:  the dequeue command type
- */
-void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, u32 chid,
-                                enum qbman_pull_type_e dct)
-{
-       d->verb |= dct << QB_VDQCR_VERB_DCT_SHIFT;
-       d->verb |= qb_pull_dt_channel << QB_VDQCR_VERB_DT_SHIFT;
-       d->dq_src = cpu_to_le32(chid);
-}
-
-/**
- * qbman_swp_pull() - Issue the pull dequeue command
- * @s: the software portal object
- * @d: the software portal descriptor which has been configured with
- *     the set of qbman_pull_desc_set_*() calls
- *
- * Return 0 for success, and -EBUSY if the software portal is not ready
- * to do pull dequeue.
- */
-int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
-{
-       struct qbman_pull_desc *p;
-
-       if (!atomic_dec_and_test(&s->vdq.available)) {
-               atomic_inc(&s->vdq.available);
-               return -EBUSY;
-       }
-       s->vdq.storage = (void *)(uintptr_t)d->rsp_addr_virt;
-       p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR);
-       p->numf = d->numf;
-       p->tok = QMAN_DQ_TOKEN_VALID;
-       p->dq_src = d->dq_src;
-       p->rsp_addr = d->rsp_addr;
-       p->rsp_addr_virt = d->rsp_addr_virt;
-       dma_wmb();
-
-       /* Set the verb byte, have to substitute in the valid-bit */
-       p->verb = d->verb | s->vdq.valid_bit;
-       s->vdq.valid_bit ^= QB_VALID_BIT;
-
-       return 0;
-}
-
-#define QMAN_DQRR_PI_MASK   0xf
-
-/**
- * qbman_swp_dqrr_next() - Get an valid DQRR entry
- * @s: the software portal object
- *
- * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry
- * only once, so repeated calls can return a sequence of DQRR entries, without
- * requiring they be consumed immediately or in any particular order.
- */
-const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s)
-{
-       u32 verb;
-       u32 response_verb;
-       u32 flags;
-       struct dpaa2_dq *p;
-
-       /* Before using valid-bit to detect if something is there, we have to
-        * handle the case of the DQRR reset bug...
-        */
-       if (unlikely(s->dqrr.reset_bug)) {
-               /*
-                * We pick up new entries by cache-inhibited producer index,
-                * which means that a non-coherent mapping would require us to
-                * invalidate and read *only* once that PI has indicated that
-                * there's an entry here. The first trip around the DQRR ring
-                * will be much less efficient than all subsequent trips around
-                * it...
-                */
-               u8 pi = qbman_read_register(s, QBMAN_CINH_SWP_DQPI) &
-                       QMAN_DQRR_PI_MASK;
-
-               /* there are new entries if pi != next_idx */
-               if (pi == s->dqrr.next_idx)
-                       return NULL;
-
-               /*
-                * if next_idx is/was the last ring index, and 'pi' is
-                * different, we can disable the workaround as all the ring
-                * entries have now been DMA'd to so valid-bit checking is
-                * repaired. Note: this logic needs to be based on next_idx
-                * (which increments one at a time), rather than on pi (which
-                * can burst and wrap-around between our snapshots of it).
-                */
-               if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1)) {
-                       pr_debug("next_idx=%d, pi=%d, clear reset bug\n",
-                                s->dqrr.next_idx, pi);
-                       s->dqrr.reset_bug = 0;
-               }
-               prefetch(qbman_get_cmd(s,
-                                      QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)));
-       }
-
-       p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
-       verb = p->dq.verb;
-
-       /*
-        * If the valid-bit isn't of the expected polarity, nothing there. Note,
-        * in the DQRR reset bug workaround, we shouldn't need to skip these
-        * check, because we've already determined that a new entry is available
-        * and we've invalidated the cacheline before reading it, so the
-        * valid-bit behaviour is repaired and should tell us what we already
-        * knew from reading PI.
-        */
-       if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) {
-               prefetch(qbman_get_cmd(s,
-                                      QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)));
-               return NULL;
-       }
-       /*
-        * There's something there. Move "next_idx" attention to the next ring
-        * entry (and prefetch it) before returning what we found.
-        */
-       s->dqrr.next_idx++;
-       s->dqrr.next_idx &= s->dqrr.dqrr_size - 1; /* Wrap around */
-       if (!s->dqrr.next_idx)
-               s->dqrr.valid_bit ^= QB_VALID_BIT;
-
-       /*
-        * If this is the final response to a volatile dequeue command
-        * indicate that the vdq is available
-        */
-       flags = p->dq.stat;
-       response_verb = verb & QBMAN_RESULT_MASK;
-       if ((response_verb == QBMAN_RESULT_DQ) &&
-           (flags & DPAA2_DQ_STAT_VOLATILE) &&
-           (flags & DPAA2_DQ_STAT_EXPIRED))
-               atomic_inc(&s->vdq.available);
-
-       prefetch(qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)));
-
-       return p;
-}
-
-/**
- * qbman_swp_dqrr_consume() -  Consume DQRR entries previously returned from
- *                             qbman_swp_dqrr_next().
- * @s: the software portal object
- * @dq: the DQRR entry to be consumed
- */
-void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct dpaa2_dq *dq)
-{
-       qbman_write_register(s, QBMAN_CINH_SWP_DCAP, QBMAN_IDX_FROM_DQRR(dq));
-}
-
-/**
- * qbman_result_has_new_result() - Check and get the dequeue response from the
- *                                 dq storage memory set in pull dequeue command
- * @s: the software portal object
- * @dq: the dequeue result read from the memory
- *
- * Return 1 for getting a valid dequeue result, or 0 for not getting a valid
- * dequeue result.
- *
- * Only used for user-provided storage of dequeue results, not DQRR. For
- * efficiency purposes, the driver will perform any required endianness
- * conversion to ensure that the user's dequeue result storage is in host-endian
- * format. As such, once the user has called qbman_result_has_new_result() and
- * been returned a valid dequeue result, they should not call it again on
- * the same memory location (except of course if another dequeue command has
- * been executed to produce a new result to that location).
- */
-int qbman_result_has_new_result(struct qbman_swp *s, const struct dpaa2_dq *dq)
-{
-       if (dq->dq.tok != QMAN_DQ_TOKEN_VALID)
-               return 0;
-
-       /*
-        * Set token to be 0 so we will detect change back to 1
-        * next time the looping is traversed. Const is cast away here
-        * as we want users to treat the dequeue responses as read only.
-        */
-       ((struct dpaa2_dq *)dq)->dq.tok = 0;
-
-       /*
-        * Determine whether VDQCR is available based on whether the
-        * current result is sitting in the first storage location of
-        * the busy command.
-        */
-       if (s->vdq.storage == dq) {
-               s->vdq.storage = NULL;
-               atomic_inc(&s->vdq.available);
-       }
-
-       return 1;
-}
-
-/**
- * qbman_release_desc_clear() - Clear the contents of a descriptor to
- *                              default/starting state.
- */
-void qbman_release_desc_clear(struct qbman_release_desc *d)
-{
-       memset(d, 0, sizeof(*d));
-       d->verb = 1 << 5; /* Release Command Valid */
-}
-
-/**
- * qbman_release_desc_set_bpid() - Set the ID of the buffer pool to release to
- */
-void qbman_release_desc_set_bpid(struct qbman_release_desc *d, u16 bpid)
-{
-       d->bpid = cpu_to_le16(bpid);
-}
-
-/**
- * qbman_release_desc_set_rcdi() - Determines whether or not the portal's RCDI
- * interrupt source should be asserted after the release command is completed.
- */
-void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable)
-{
-       if (enable)
-               d->verb |= 1 << 6;
-       else
-               d->verb &= ~(1 << 6);
-}
-
-#define RAR_IDX(rar)     ((rar) & 0x7)
-#define RAR_VB(rar)      ((rar) & 0x80)
-#define RAR_SUCCESS(rar) ((rar) & 0x100)
-
-/**
- * qbman_swp_release() - Issue a buffer release command
- * @s:           the software portal object
- * @d:           the release descriptor
- * @buffers:     a pointer pointing to the buffer address to be released
- * @num_buffers: number of buffers to be released,  must be less than 8
- *
- * Return 0 for success, -EBUSY if the release command ring is not ready.
- */
-int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
-                     const u64 *buffers, unsigned int num_buffers)
-{
-       int i;
-       struct qbman_release_desc *p;
-       u32 rar;
-
-       if (!num_buffers || (num_buffers > 7))
-               return -EINVAL;
-
-       rar = qbman_read_register(s, QBMAN_CINH_SWP_RAR);
-       if (!RAR_SUCCESS(rar))
-               return -EBUSY;
-
-       /* Start the release command */
-       p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
-       /* Copy the caller's buffer pointers to the command */
-       for (i = 0; i < num_buffers; i++)
-               p->buf[i] = cpu_to_le64(buffers[i]);
-       p->bpid = d->bpid;
-
-       /*
-        * Set the verb byte, have to substitute in the valid-bit and the number
-        * of buffers.
-        */
-       dma_wmb();
-       p->verb = d->verb | RAR_VB(rar) | num_buffers;
-
-       return 0;
-}
-
-struct qbman_acquire_desc {
-       u8 verb;
-       u8 reserved;
-       __le16 bpid;
-       u8 num;
-       u8 reserved2[59];
-};
-
-struct qbman_acquire_rslt {
-       u8 verb;
-       u8 rslt;
-       __le16 reserved;
-       u8 num;
-       u8 reserved2[3];
-       __le64 buf[7];
-};
-
-/**
- * qbman_swp_acquire() - Issue a buffer acquire command
- * @s:           the software portal object
- * @bpid:        the buffer pool index
- * @buffers:     a pointer pointing to the acquired buffer addresses
- * @num_buffers: number of buffers to be acquired, must be less than 8
- *
- * Return 0 for success, or negative error code if the acquire command
- * fails.
- */
-int qbman_swp_acquire(struct qbman_swp *s, u16 bpid, u64 *buffers,
-                     unsigned int num_buffers)
-{
-       struct qbman_acquire_desc *p;
-       struct qbman_acquire_rslt *r;
-       int i;
-
-       if (!num_buffers || (num_buffers > 7))
-               return -EINVAL;
-
-       /* Start the management command */
-       p = qbman_swp_mc_start(s);
-
-       if (!p)
-               return -EBUSY;
-
-       /* Encode the caller-provided attributes */
-       p->bpid = cpu_to_le16(bpid);
-       p->num = num_buffers;
-
-       /* Complete the management command */
-       r = qbman_swp_mc_complete(s, p, QBMAN_MC_ACQUIRE);
-       if (unlikely(!r)) {
-               pr_err("qbman: acquire from BPID %d failed, no response\n",
-                      bpid);
-               return -EIO;
-       }
-
-       /* Decode the outcome */
-       WARN_ON((r->verb & 0x7f) != QBMAN_MC_ACQUIRE);
-
-       /* Determine success or failure */
-       if (unlikely(r->rslt != QBMAN_MC_RSLT_OK)) {
-               pr_err("qbman: acquire from BPID 0x%x failed, code=0x%02x\n",
-                      bpid, r->rslt);
-               return -EIO;
-       }
-
-       WARN_ON(r->num > num_buffers);
-
-       /* Copy the acquired buffers to the caller's array */
-       for (i = 0; i < r->num; i++)
-               buffers[i] = le64_to_cpu(r->buf[i]);
-
-       return (int)r->num;
-}
-
-struct qbman_alt_fq_state_desc {
-       u8 verb;
-       u8 reserved[3];
-       __le32 fqid;
-       u8 reserved2[56];
-};
-
-struct qbman_alt_fq_state_rslt {
-       u8 verb;
-       u8 rslt;
-       u8 reserved[62];
-};
-
-#define ALT_FQ_FQID_MASK 0x00FFFFFF
-
-int qbman_swp_alt_fq_state(struct qbman_swp *s, u32 fqid,
-                          u8 alt_fq_verb)
-{
-       struct qbman_alt_fq_state_desc *p;
-       struct qbman_alt_fq_state_rslt *r;
-
-       /* Start the management command */
-       p = qbman_swp_mc_start(s);
-       if (!p)
-               return -EBUSY;
-
-       p->fqid = cpu_to_le32(fqid & ALT_FQ_FQID_MASK);
-
-       /* Complete the management command */
-       r = qbman_swp_mc_complete(s, p, alt_fq_verb);
-       if (unlikely(!r)) {
-               pr_err("qbman: mgmt cmd failed, no response (verb=0x%x)\n",
-                      alt_fq_verb);
-               return -EIO;
-       }
-
-       /* Decode the outcome */
-       WARN_ON((r->verb & QBMAN_RESULT_MASK) != alt_fq_verb);
-
-       /* Determine success or failure */
-       if (unlikely(r->rslt != QBMAN_MC_RSLT_OK)) {
-               pr_err("qbman: ALT FQID %d failed: verb = 0x%08x code = 0x%02x\n",
-                      fqid, r->verb, r->rslt);
-               return -EIO;
-       }
-
-       return 0;
-}
-
-struct qbman_cdan_ctrl_desc {
-       u8 verb;
-       u8 reserved;
-       __le16 ch;
-       u8 we;
-       u8 ctrl;
-       __le16 reserved2;
-       __le64 cdan_ctx;
-       u8 reserved3[48];
-
-};
-
-struct qbman_cdan_ctrl_rslt {
-       u8 verb;
-       u8 rslt;
-       __le16 ch;
-       u8 reserved[60];
-};
-
-int qbman_swp_CDAN_set(struct qbman_swp *s, u16 channelid,
-                      u8 we_mask, u8 cdan_en,
-                      u64 ctx)
-{
-       struct qbman_cdan_ctrl_desc *p = NULL;
-       struct qbman_cdan_ctrl_rslt *r = NULL;
-
-       /* Start the management command */
-       p = qbman_swp_mc_start(s);
-       if (!p)
-               return -EBUSY;
-
-       /* Encode the caller-provided attributes */
-       p->ch = cpu_to_le16(channelid);
-       p->we = we_mask;
-       if (cdan_en)
-               p->ctrl = 1;
-       else
-               p->ctrl = 0;
-       p->cdan_ctx = cpu_to_le64(ctx);
-
-       /* Complete the management command */
-       r = qbman_swp_mc_complete(s, p, QBMAN_WQCHAN_CONFIGURE);
-       if (unlikely(!r)) {
-               pr_err("qbman: wqchan config failed, no response\n");
-               return -EIO;
-       }
-
-       WARN_ON((r->verb & 0x7f) != QBMAN_WQCHAN_CONFIGURE);
-
-       /* Determine success or failure */
-       if (unlikely(r->rslt != QBMAN_MC_RSLT_OK)) {
-               pr_err("qbman: CDAN cQID %d failed: code = 0x%02x\n",
-                      channelid, r->rslt);
-               return -EIO;
-       }
-
-       return 0;
-}
diff --git a/drivers/staging/fsl-mc/bus/dpio/qbman-portal.h b/drivers/staging/fsl-mc/bus/dpio/qbman-portal.h
deleted file mode 100644 (file)
index 69db3c8..0000000
+++ /dev/null
@@ -1,444 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
-/*
- * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
- * Copyright 2016 NXP
- *
- */
-#ifndef __FSL_QBMAN_PORTAL_H
-#define __FSL_QBMAN_PORTAL_H
-
-#include "../../include/dpaa2-fd.h"
-
-struct dpaa2_dq;
-struct qbman_swp;
-
-/* qbman software portal descriptor structure */
-struct qbman_swp_desc {
-       void *cena_bar; /* Cache-enabled portal base address */
-       void __iomem *cinh_bar; /* Cache-inhibited portal base address */
-       u32 qman_version;
-};
-
-#define QBMAN_SWP_INTERRUPT_EQRI 0x01
-#define QBMAN_SWP_INTERRUPT_EQDI 0x02
-#define QBMAN_SWP_INTERRUPT_DQRI 0x04
-#define QBMAN_SWP_INTERRUPT_RCRI 0x08
-#define QBMAN_SWP_INTERRUPT_RCDI 0x10
-#define QBMAN_SWP_INTERRUPT_VDCI 0x20
-
-/* the structure for pull dequeue descriptor */
-struct qbman_pull_desc {
-       u8 verb;
-       u8 numf;
-       u8 tok;
-       u8 reserved;
-       __le32 dq_src;
-       __le64 rsp_addr;
-       u64 rsp_addr_virt;
-       u8 padding[40];
-};
-
-enum qbman_pull_type_e {
-       /* dequeue with priority precedence, respect intra-class scheduling */
-       qbman_pull_type_prio = 1,
-       /* dequeue with active FQ precedence, respect ICS */
-       qbman_pull_type_active,
-       /* dequeue with active FQ precedence, no ICS */
-       qbman_pull_type_active_noics
-};
-
-/* Definitions for parsing dequeue entries */
-#define QBMAN_RESULT_MASK      0x7f
-#define QBMAN_RESULT_DQ        0x60
-#define QBMAN_RESULT_FQRN      0x21
-#define QBMAN_RESULT_FQRNI     0x22
-#define QBMAN_RESULT_FQPN      0x24
-#define QBMAN_RESULT_FQDAN     0x25
-#define QBMAN_RESULT_CDAN      0x26
-#define QBMAN_RESULT_CSCN_MEM  0x27
-#define QBMAN_RESULT_CGCU      0x28
-#define QBMAN_RESULT_BPSCN     0x29
-#define QBMAN_RESULT_CSCN_WQ   0x2a
-
-/* QBMan FQ management command codes */
-#define QBMAN_FQ_SCHEDULE      0x48
-#define QBMAN_FQ_FORCE         0x49
-#define QBMAN_FQ_XON           0x4d
-#define QBMAN_FQ_XOFF          0x4e
-
-/* structure of enqueue descriptor */
-struct qbman_eq_desc {
-       u8 verb;
-       u8 dca;
-       __le16 seqnum;
-       __le16 orpid;
-       __le16 reserved1;
-       __le32 tgtid;
-       __le32 tag;
-       __le16 qdbin;
-       u8 qpri;
-       u8 reserved[3];
-       u8 wae;
-       u8 rspid;
-       __le64 rsp_addr;
-       u8 fd[32];
-};
-
-/* buffer release descriptor */
-struct qbman_release_desc {
-       u8 verb;
-       u8 reserved;
-       __le16 bpid;
-       __le32 reserved2;
-       __le64 buf[7];
-};
-
-/* Management command result codes */
-#define QBMAN_MC_RSLT_OK      0xf0
-
-#define CODE_CDAN_WE_EN    0x1
-#define CODE_CDAN_WE_CTX   0x4
-
-/* portal data structure */
-struct qbman_swp {
-       const struct qbman_swp_desc *desc;
-       void *addr_cena;
-       void __iomem *addr_cinh;
-
-       /* Management commands */
-       struct {
-               u32 valid_bit; /* 0x00 or 0x80 */
-       } mc;
-
-       /* Push dequeues */
-       u32 sdq;
-
-       /* Volatile dequeues */
-       struct {
-               atomic_t available; /* indicates if a command can be sent */
-               u32 valid_bit; /* 0x00 or 0x80 */
-               struct dpaa2_dq *storage; /* NULL if DQRR */
-       } vdq;
-
-       /* DQRR */
-       struct {
-               u32 next_idx;
-               u32 valid_bit;
-               u8 dqrr_size;
-               int reset_bug; /* indicates dqrr reset workaround is needed */
-       } dqrr;
-};
-
-struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d);
-void qbman_swp_finish(struct qbman_swp *p);
-u32 qbman_swp_interrupt_read_status(struct qbman_swp *p);
-void qbman_swp_interrupt_clear_status(struct qbman_swp *p, u32 mask);
-u32 qbman_swp_interrupt_get_trigger(struct qbman_swp *p);
-void qbman_swp_interrupt_set_trigger(struct qbman_swp *p, u32 mask);
-int qbman_swp_interrupt_get_inhibit(struct qbman_swp *p);
-void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit);
-
-void qbman_swp_push_get(struct qbman_swp *p, u8 channel_idx, int *enabled);
-void qbman_swp_push_set(struct qbman_swp *p, u8 channel_idx, int enable);
-
-void qbman_pull_desc_clear(struct qbman_pull_desc *d);
-void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
-                                struct dpaa2_dq *storage,
-                                dma_addr_t storage_phys,
-                                int stash);
-void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, u8 numframes);
-void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, u32 fqid);
-void qbman_pull_desc_set_wq(struct qbman_pull_desc *d, u32 wqid,
-                           enum qbman_pull_type_e dct);
-void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, u32 chid,
-                                enum qbman_pull_type_e dct);
-
-int qbman_swp_pull(struct qbman_swp *p, struct qbman_pull_desc *d);
-
-const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s);
-void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct dpaa2_dq *dq);
-
-int qbman_result_has_new_result(struct qbman_swp *p, const struct dpaa2_dq *dq);
-
-void qbman_eq_desc_clear(struct qbman_eq_desc *d);
-void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success);
-void qbman_eq_desc_set_token(struct qbman_eq_desc *d, u8 token);
-void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, u32 fqid);
-void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, u32 qdid,
-                         u32 qd_bin, u32 qd_prio);
-
-int qbman_swp_enqueue(struct qbman_swp *p, const struct qbman_eq_desc *d,
-                     const struct dpaa2_fd *fd);
-
-void qbman_release_desc_clear(struct qbman_release_desc *d);
-void qbman_release_desc_set_bpid(struct qbman_release_desc *d, u16 bpid);
-void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable);
-
-int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
-                     const u64 *buffers, unsigned int num_buffers);
-int qbman_swp_acquire(struct qbman_swp *s, u16 bpid, u64 *buffers,
-                     unsigned int num_buffers);
-int qbman_swp_alt_fq_state(struct qbman_swp *s, u32 fqid,
-                          u8 alt_fq_verb);
-int qbman_swp_CDAN_set(struct qbman_swp *s, u16 channelid,
-                      u8 we_mask, u8 cdan_en,
-                      u64 ctx);
-
-void *qbman_swp_mc_start(struct qbman_swp *p);
-void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, u8 cmd_verb);
-void *qbman_swp_mc_result(struct qbman_swp *p);
-
-/**
- * qbman_result_is_DQ() - check if the dequeue result is a dequeue response
- * @dq: the dequeue result to be checked
- *
- * DQRR entries may contain non-dequeue results, ie. notifications
- */
-static inline int qbman_result_is_DQ(const struct dpaa2_dq *dq)
-{
-       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_DQ);
-}
-
-/**
- * qbman_result_is_SCN() - Check the dequeue result is notification or not
- * @dq: the dequeue result to be checked
- *
- */
-static inline int qbman_result_is_SCN(const struct dpaa2_dq *dq)
-{
-       return !qbman_result_is_DQ(dq);
-}
-
-/* FQ Data Availability */
-static inline int qbman_result_is_FQDAN(const struct dpaa2_dq *dq)
-{
-       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_FQDAN);
-}
-
-/* Channel Data Availability */
-static inline int qbman_result_is_CDAN(const struct dpaa2_dq *dq)
-{
-       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_CDAN);
-}
-
-/* Congestion State Change */
-static inline int qbman_result_is_CSCN(const struct dpaa2_dq *dq)
-{
-       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_CSCN_WQ);
-}
-
-/* Buffer Pool State Change */
-static inline int qbman_result_is_BPSCN(const struct dpaa2_dq *dq)
-{
-       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_BPSCN);
-}
-
-/* Congestion Group Count Update */
-static inline int qbman_result_is_CGCU(const struct dpaa2_dq *dq)
-{
-       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_CGCU);
-}
-
-/* Retirement */
-static inline int qbman_result_is_FQRN(const struct dpaa2_dq *dq)
-{
-       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_FQRN);
-}
-
-/* Retirement Immediate */
-static inline int qbman_result_is_FQRNI(const struct dpaa2_dq *dq)
-{
-       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_FQRNI);
-}
-
- /* Park */
-static inline int qbman_result_is_FQPN(const struct dpaa2_dq *dq)
-{
-       return ((dq->dq.verb & QBMAN_RESULT_MASK) == QBMAN_RESULT_FQPN);
-}
-
-/**
- * qbman_result_SCN_state() - Get the state field in State-change notification
- */
-static inline u8 qbman_result_SCN_state(const struct dpaa2_dq *scn)
-{
-       return scn->scn.state;
-}
-
-#define SCN_RID_MASK 0x00FFFFFF
-
-/**
- * qbman_result_SCN_rid() - Get the resource id in State-change notification
- */
-static inline u32 qbman_result_SCN_rid(const struct dpaa2_dq *scn)
-{
-       return le32_to_cpu(scn->scn.rid_tok) & SCN_RID_MASK;
-}
-
-/**
- * qbman_result_SCN_ctx() - Get the context data in State-change notification
- */
-static inline u64 qbman_result_SCN_ctx(const struct dpaa2_dq *scn)
-{
-       return le64_to_cpu(scn->scn.ctx);
-}
-
-/**
- * qbman_swp_fq_schedule() - Move the fq to the scheduled state
- * @s:    the software portal object
- * @fqid: the index of frame queue to be scheduled
- *
- * There are a couple of different ways that a FQ can end up parked state,
- * This schedules it.
- *
- * Return 0 for success, or negative error code for failure.
- */
-static inline int qbman_swp_fq_schedule(struct qbman_swp *s, u32 fqid)
-{
-       return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_SCHEDULE);
-}
-
-/**
- * qbman_swp_fq_force() - Force the FQ to fully scheduled state
- * @s:    the software portal object
- * @fqid: the index of frame queue to be forced
- *
- * Force eligible will force a tentatively-scheduled FQ to be fully-scheduled
- * and thus be available for selection by any channel-dequeuing behaviour (push
- * or pull). If the FQ is subsequently "dequeued" from the channel and is still
- * empty at the time this happens, the resulting dq_entry will have no FD.
- * (qbman_result_DQ_fd() will return NULL.)
- *
- * Return 0 for success, or negative error code for failure.
- */
-static inline int qbman_swp_fq_force(struct qbman_swp *s, u32 fqid)
-{
-       return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_FORCE);
-}
-
-/**
- * qbman_swp_fq_xon() - sets FQ flow-control to XON
- * @s:    the software portal object
- * @fqid: the index of frame queue
- *
- * This setting doesn't affect enqueues to the FQ, just dequeues.
- *
- * Return 0 for success, or negative error code for failure.
- */
-static inline int qbman_swp_fq_xon(struct qbman_swp *s, u32 fqid)
-{
-       return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XON);
-}
-
-/**
- * qbman_swp_fq_xoff() - sets FQ flow-control to XOFF
- * @s:    the software portal object
- * @fqid: the index of frame queue
- *
- * This setting doesn't affect enqueues to the FQ, just dequeues.
- * XOFF FQs will remain in the tenatively-scheduled state, even when
- * non-empty, meaning they won't be selected for scheduled dequeuing.
- * If a FQ is changed to XOFF after it had already become truly-scheduled
- * to a channel, and a pull dequeue of that channel occurs that selects
- * that FQ for dequeuing, then the resulting dq_entry will have no FD.
- * (qbman_result_DQ_fd() will return NULL.)
- *
- * Return 0 for success, or negative error code for failure.
- */
-static inline int qbman_swp_fq_xoff(struct qbman_swp *s, u32 fqid)
-{
-       return qbman_swp_alt_fq_state(s, fqid, QBMAN_FQ_XOFF);
-}
-
-/* If the user has been allocated a channel object that is going to generate
- * CDANs to another channel, then the qbman_swp_CDAN* functions will be
- * necessary.
- *
- * CDAN-enabled channels only generate a single CDAN notification, after which
- * they need to be reenabled before they'll generate another. The idea is
- * that pull dequeuing will occur in reaction to the CDAN, followed by a
- * reenable step. Each function generates a distinct command to hardware, so a
- * combination function is provided if the user wishes to modify the "context"
- * (which shows up in each CDAN message) each time they reenable, as a single
- * command to hardware.
- */
-
-/**
- * qbman_swp_CDAN_set_context() - Set CDAN context
- * @s:         the software portal object
- * @channelid: the channel index
- * @ctx:       the context to be set in CDAN
- *
- * Return 0 for success, or negative error code for failure.
- */
-static inline int qbman_swp_CDAN_set_context(struct qbman_swp *s, u16 channelid,
-                                            u64 ctx)
-{
-       return qbman_swp_CDAN_set(s, channelid,
-                                 CODE_CDAN_WE_CTX,
-                                 0, ctx);
-}
-
-/**
- * qbman_swp_CDAN_enable() - Enable CDAN for the channel
- * @s:         the software portal object
- * @channelid: the index of the channel to generate CDAN
- *
- * Return 0 for success, or negative error code for failure.
- */
-static inline int qbman_swp_CDAN_enable(struct qbman_swp *s, u16 channelid)
-{
-       return qbman_swp_CDAN_set(s, channelid,
-                                 CODE_CDAN_WE_EN,
-                                 1, 0);
-}
-
-/**
- * qbman_swp_CDAN_disable() - disable CDAN for the channel
- * @s:         the software portal object
- * @channelid: the index of the channel to generate CDAN
- *
- * Return 0 for success, or negative error code for failure.
- */
-static inline int qbman_swp_CDAN_disable(struct qbman_swp *s, u16 channelid)
-{
-       return qbman_swp_CDAN_set(s, channelid,
-                                 CODE_CDAN_WE_EN,
-                                 0, 0);
-}
-
-/**
- * qbman_swp_CDAN_set_context_enable() - Set CDAN contest and enable CDAN
- * @s:         the software portal object
- * @channelid: the index of the channel to generate CDAN
- * @ctx:i      the context set in CDAN
- *
- * Return 0 for success, or negative error code for failure.
- */
-static inline int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s,
-                                                   u16 channelid,
-                                                   u64 ctx)
-{
-       return qbman_swp_CDAN_set(s, channelid,
-                                 CODE_CDAN_WE_EN | CODE_CDAN_WE_CTX,
-                                 1, ctx);
-}
-
-/* Wraps up submit + poll-for-result */
-static inline void *qbman_swp_mc_complete(struct qbman_swp *swp, void *cmd,
-                                         u8 cmd_verb)
-{
-       int loopvar = 1000;
-
-       qbman_swp_mc_submit(swp, cmd, cmd_verb);
-
-       do {
-               cmd = qbman_swp_mc_result(swp);
-       } while (!cmd && loopvar--);
-
-       WARN_ON(!loopvar);
-
-       return cmd;
-}
-
-#endif /* __FSL_QBMAN_PORTAL_H */
diff --git a/drivers/staging/fsl-mc/include/dpaa2-fd.h b/drivers/staging/fsl-mc/include/dpaa2-fd.h
deleted file mode 100644 (file)
index b55b89b..0000000
+++ /dev/null
@@ -1,426 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
-/*
- * Copyright 2014-2016 Freescale Semiconductor Inc.
- * Copyright 2016 NXP
- *
- */
-#ifndef __FSL_DPAA2_FD_H
-#define __FSL_DPAA2_FD_H
-
-#include <linux/kernel.h>
-
-/**
- * DOC: DPAA2 FD - Frame Descriptor APIs for DPAA2
- *
- * Frame Descriptors (FDs) are used to describe frame data in the DPAA2.
- * Frames can be enqueued and dequeued to Frame Queues (FQs) which are consumed
- * by the various DPAA accelerators (WRIOP, SEC, PME, DCE)
- *
- * There are three types of frames: single, scatter gather, and frame lists.
- *
- * The set of APIs in this file must be used to create, manipulate and
- * query Frame Descriptors.
- */
-
-/**
- * struct dpaa2_fd - Struct describing FDs
- * @words:         for easier/faster copying the whole FD structure
- * @addr:          address in the FD
- * @len:           length in the FD
- * @bpid:          buffer pool ID
- * @format_offset: format, offset, and short-length fields
- * @frc:           frame context
- * @ctrl:          control bits...including dd, sc, va, err, etc
- * @flc:           flow context address
- *
- * This structure represents the basic Frame Descriptor used in the system.
- */
-struct dpaa2_fd {
-       union {
-               u32 words[8];
-               struct dpaa2_fd_simple {
-                       __le64 addr;
-                       __le32 len;
-                       __le16 bpid;
-                       __le16 format_offset;
-                       __le32 frc;
-                       __le32 ctrl;
-                       __le64 flc;
-               } simple;
-       };
-};
-
-#define FD_SHORT_LEN_FLAG_MASK 0x1
-#define FD_SHORT_LEN_FLAG_SHIFT        14
-#define FD_SHORT_LEN_MASK      0x3FFFF
-#define FD_OFFSET_MASK         0x0FFF
-#define FD_FORMAT_MASK         0x3
-#define FD_FORMAT_SHIFT                12
-#define FD_BPID_MASK           0x3FFF
-#define SG_SHORT_LEN_FLAG_MASK 0x1
-#define SG_SHORT_LEN_FLAG_SHIFT        14
-#define SG_SHORT_LEN_MASK      0x1FFFF
-#define SG_OFFSET_MASK         0x0FFF
-#define SG_FORMAT_MASK         0x3
-#define SG_FORMAT_SHIFT                12
-#define SG_BPID_MASK           0x3FFF
-#define SG_FINAL_FLAG_MASK     0x1
-#define SG_FINAL_FLAG_SHIFT    15
-
-enum dpaa2_fd_format {
-       dpaa2_fd_single = 0,
-       dpaa2_fd_list,
-       dpaa2_fd_sg
-};
-
-/**
- * dpaa2_fd_get_addr() - get the addr field of frame descriptor
- * @fd: the given frame descriptor
- *
- * Return the address in the frame descriptor.
- */
-static inline dma_addr_t dpaa2_fd_get_addr(const struct dpaa2_fd *fd)
-{
-       return (dma_addr_t)le64_to_cpu(fd->simple.addr);
-}
-
-/**
- * dpaa2_fd_set_addr() - Set the addr field of frame descriptor
- * @fd: the given frame descriptor
- * @addr: the address needs to be set in frame descriptor
- */
-static inline void dpaa2_fd_set_addr(struct dpaa2_fd *fd, dma_addr_t addr)
-{
-       fd->simple.addr = cpu_to_le64(addr);
-}
-
-/**
- * dpaa2_fd_get_frc() - Get the frame context in the frame descriptor
- * @fd: the given frame descriptor
- *
- * Return the frame context field in the frame descriptor.
- */
-static inline u32 dpaa2_fd_get_frc(const struct dpaa2_fd *fd)
-{
-       return le32_to_cpu(fd->simple.frc);
-}
-
-/**
- * dpaa2_fd_set_frc() - Set the frame context in the frame descriptor
- * @fd: the given frame descriptor
- * @frc: the frame context needs to be set in frame descriptor
- */
-static inline void dpaa2_fd_set_frc(struct dpaa2_fd *fd, u32 frc)
-{
-       fd->simple.frc = cpu_to_le32(frc);
-}
-
-/**
- * dpaa2_fd_get_ctrl() - Get the control bits in the frame descriptor
- * @fd: the given frame descriptor
- *
- * Return the control bits field in the frame descriptor.
- */
-static inline u32 dpaa2_fd_get_ctrl(const struct dpaa2_fd *fd)
-{
-       return le32_to_cpu(fd->simple.ctrl);
-}
-
-/**
- * dpaa2_fd_set_ctrl() - Set the control bits in the frame descriptor
- * @fd: the given frame descriptor
- * @ctrl: the control bits to be set in the frame descriptor
- */
-static inline void dpaa2_fd_set_ctrl(struct dpaa2_fd *fd, u32 ctrl)
-{
-       fd->simple.ctrl = cpu_to_le32(ctrl);
-}
-
-/**
- * dpaa2_fd_get_flc() - Get the flow context in the frame descriptor
- * @fd: the given frame descriptor
- *
- * Return the flow context in the frame descriptor.
- */
-static inline dma_addr_t dpaa2_fd_get_flc(const struct dpaa2_fd *fd)
-{
-       return (dma_addr_t)le64_to_cpu(fd->simple.flc);
-}
-
-/**
- * dpaa2_fd_set_flc() - Set the flow context field of frame descriptor
- * @fd: the given frame descriptor
- * @flc_addr: the flow context needs to be set in frame descriptor
- */
-static inline void dpaa2_fd_set_flc(struct dpaa2_fd *fd,  dma_addr_t flc_addr)
-{
-       fd->simple.flc = cpu_to_le64(flc_addr);
-}
-
-static inline bool dpaa2_fd_short_len(const struct dpaa2_fd *fd)
-{
-       return !!((le16_to_cpu(fd->simple.format_offset) >>
-                 FD_SHORT_LEN_FLAG_SHIFT) & FD_SHORT_LEN_FLAG_MASK);
-}
-
-/**
- * dpaa2_fd_get_len() - Get the length in the frame descriptor
- * @fd: the given frame descriptor
- *
- * Return the length field in the frame descriptor.
- */
-static inline u32 dpaa2_fd_get_len(const struct dpaa2_fd *fd)
-{
-       if (dpaa2_fd_short_len(fd))
-               return le32_to_cpu(fd->simple.len) & FD_SHORT_LEN_MASK;
-
-       return le32_to_cpu(fd->simple.len);
-}
-
-/**
- * dpaa2_fd_set_len() - Set the length field of frame descriptor
- * @fd: the given frame descriptor
- * @len: the length needs to be set in frame descriptor
- */
-static inline void dpaa2_fd_set_len(struct dpaa2_fd *fd, u32 len)
-{
-       fd->simple.len = cpu_to_le32(len);
-}
-
-/**
- * dpaa2_fd_get_offset() - Get the offset field in the frame descriptor
- * @fd: the given frame descriptor
- *
- * Return the offset.
- */
-static inline uint16_t dpaa2_fd_get_offset(const struct dpaa2_fd *fd)
-{
-       return le16_to_cpu(fd->simple.format_offset) & FD_OFFSET_MASK;
-}
-
-/**
- * dpaa2_fd_set_offset() - Set the offset field of frame descriptor
- * @fd: the given frame descriptor
- * @offset: the offset needs to be set in frame descriptor
- */
-static inline void dpaa2_fd_set_offset(struct dpaa2_fd *fd, uint16_t offset)
-{
-       fd->simple.format_offset &= cpu_to_le16(~FD_OFFSET_MASK);
-       fd->simple.format_offset |= cpu_to_le16(offset);
-}
-
-/**
- * dpaa2_fd_get_format() - Get the format field in the frame descriptor
- * @fd: the given frame descriptor
- *
- * Return the format.
- */
-static inline enum dpaa2_fd_format dpaa2_fd_get_format(
-                                               const struct dpaa2_fd *fd)
-{
-       return (enum dpaa2_fd_format)((le16_to_cpu(fd->simple.format_offset)
-                                     >> FD_FORMAT_SHIFT) & FD_FORMAT_MASK);
-}
-
-/**
- * dpaa2_fd_set_format() - Set the format field of frame descriptor
- * @fd: the given frame descriptor
- * @format: the format needs to be set in frame descriptor
- */
-static inline void dpaa2_fd_set_format(struct dpaa2_fd *fd,
-                                      enum dpaa2_fd_format format)
-{
-       fd->simple.format_offset &=
-               cpu_to_le16(~(FD_FORMAT_MASK << FD_FORMAT_SHIFT));
-       fd->simple.format_offset |= cpu_to_le16(format << FD_FORMAT_SHIFT);
-}
-
-/**
- * dpaa2_fd_get_bpid() - Get the bpid field in the frame descriptor
- * @fd: the given frame descriptor
- *
- * Return the buffer pool id.
- */
-static inline uint16_t dpaa2_fd_get_bpid(const struct dpaa2_fd *fd)
-{
-       return le16_to_cpu(fd->simple.bpid) & FD_BPID_MASK;
-}
-
-/**
- * dpaa2_fd_set_bpid() - Set the bpid field of frame descriptor
- * @fd: the given frame descriptor
- * @bpid: buffer pool id to be set
- */
-static inline void dpaa2_fd_set_bpid(struct dpaa2_fd *fd, uint16_t bpid)
-{
-       fd->simple.bpid &= cpu_to_le16(~(FD_BPID_MASK));
-       fd->simple.bpid |= cpu_to_le16(bpid);
-}
-
-/**
- * struct dpaa2_sg_entry - the scatter-gathering structure
- * @addr: address of the sg entry
- * @len: length in this sg entry
- * @bpid: buffer pool id
- * @format_offset: format and offset fields
- */
-struct dpaa2_sg_entry {
-       __le64 addr;
-       __le32 len;
-       __le16 bpid;
-       __le16 format_offset;
-};
-
-enum dpaa2_sg_format {
-       dpaa2_sg_single = 0,
-       dpaa2_sg_frame_data,
-       dpaa2_sg_sgt_ext
-};
-
-/* Accessors for SG entry fields */
-
-/**
- * dpaa2_sg_get_addr() - Get the address from SG entry
- * @sg: the given scatter-gathering object
- *
- * Return the address.
- */
-static inline dma_addr_t dpaa2_sg_get_addr(const struct dpaa2_sg_entry *sg)
-{
-       return (dma_addr_t)le64_to_cpu(sg->addr);
-}
-
-/**
- * dpaa2_sg_set_addr() - Set the address in SG entry
- * @sg: the given scatter-gathering object
- * @addr: the address to be set
- */
-static inline void dpaa2_sg_set_addr(struct dpaa2_sg_entry *sg, dma_addr_t addr)
-{
-       sg->addr = cpu_to_le64(addr);
-}
-
-static inline bool dpaa2_sg_short_len(const struct dpaa2_sg_entry *sg)
-{
-       return !!((le16_to_cpu(sg->format_offset) >> SG_SHORT_LEN_FLAG_SHIFT)
-               & SG_SHORT_LEN_FLAG_MASK);
-}
-
-/**
- * dpaa2_sg_get_len() - Get the length in SG entry
- * @sg: the given scatter-gathering object
- *
- * Return the length.
- */
-static inline u32 dpaa2_sg_get_len(const struct dpaa2_sg_entry *sg)
-{
-       if (dpaa2_sg_short_len(sg))
-               return le32_to_cpu(sg->len) & SG_SHORT_LEN_MASK;
-
-       return le32_to_cpu(sg->len);
-}
-
-/**
- * dpaa2_sg_set_len() - Set the length in SG entry
- * @sg: the given scatter-gathering object
- * @len: the length to be set
- */
-static inline void dpaa2_sg_set_len(struct dpaa2_sg_entry *sg, u32 len)
-{
-       sg->len = cpu_to_le32(len);
-}
-
-/**
- * dpaa2_sg_get_offset() - Get the offset in SG entry
- * @sg: the given scatter-gathering object
- *
- * Return the offset.
- */
-static inline u16 dpaa2_sg_get_offset(const struct dpaa2_sg_entry *sg)
-{
-       return le16_to_cpu(sg->format_offset) & SG_OFFSET_MASK;
-}
-
-/**
- * dpaa2_sg_set_offset() - Set the offset in SG entry
- * @sg: the given scatter-gathering object
- * @offset: the offset to be set
- */
-static inline void dpaa2_sg_set_offset(struct dpaa2_sg_entry *sg,
-                                      u16 offset)
-{
-       sg->format_offset &= cpu_to_le16(~SG_OFFSET_MASK);
-       sg->format_offset |= cpu_to_le16(offset);
-}
-
-/**
- * dpaa2_sg_get_format() - Get the SG format in SG entry
- * @sg: the given scatter-gathering object
- *
- * Return the format.
- */
-static inline enum dpaa2_sg_format
-       dpaa2_sg_get_format(const struct dpaa2_sg_entry *sg)
-{
-       return (enum dpaa2_sg_format)((le16_to_cpu(sg->format_offset)
-                                      >> SG_FORMAT_SHIFT) & SG_FORMAT_MASK);
-}
-
-/**
- * dpaa2_sg_set_format() - Set the SG format in SG entry
- * @sg: the given scatter-gathering object
- * @format: the format to be set
- */
-static inline void dpaa2_sg_set_format(struct dpaa2_sg_entry *sg,
-                                      enum dpaa2_sg_format format)
-{
-       sg->format_offset &= cpu_to_le16(~(SG_FORMAT_MASK << SG_FORMAT_SHIFT));
-       sg->format_offset |= cpu_to_le16(format << SG_FORMAT_SHIFT);
-}
-
-/**
- * dpaa2_sg_get_bpid() - Get the buffer pool id in SG entry
- * @sg: the given scatter-gathering object
- *
- * Return the bpid.
- */
-static inline u16 dpaa2_sg_get_bpid(const struct dpaa2_sg_entry *sg)
-{
-       return le16_to_cpu(sg->bpid) & SG_BPID_MASK;
-}
-
-/**
- * dpaa2_sg_set_bpid() - Set the buffer pool id in SG entry
- * @sg: the given scatter-gathering object
- * @bpid: the bpid to be set
- */
-static inline void dpaa2_sg_set_bpid(struct dpaa2_sg_entry *sg, u16 bpid)
-{
-       sg->bpid &= cpu_to_le16(~(SG_BPID_MASK));
-       sg->bpid |= cpu_to_le16(bpid);
-}
-
-/**
- * dpaa2_sg_is_final() - Check final bit in SG entry
- * @sg: the given scatter-gathering object
- *
- * Return bool.
- */
-static inline bool dpaa2_sg_is_final(const struct dpaa2_sg_entry *sg)
-{
-       return !!(le16_to_cpu(sg->format_offset) >> SG_FINAL_FLAG_SHIFT);
-}
-
-/**
- * dpaa2_sg_set_final() - Set the final bit in SG entry
- * @sg: the given scatter-gathering object
- * @final: the final boolean to be set
- */
-static inline void dpaa2_sg_set_final(struct dpaa2_sg_entry *sg, bool final)
-{
-       sg->format_offset &= cpu_to_le16((~(SG_FINAL_FLAG_MASK
-                                        << SG_FINAL_FLAG_SHIFT)) & 0xFFFF);
-       sg->format_offset |= cpu_to_le16(final << SG_FINAL_FLAG_SHIFT);
-}
-
-#endif /* __FSL_DPAA2_FD_H */
diff --git a/drivers/staging/fsl-mc/include/dpaa2-global.h b/drivers/staging/fsl-mc/include/dpaa2-global.h
deleted file mode 100644 (file)
index 9bc0713..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
-/*
- * Copyright 2014-2016 Freescale Semiconductor Inc.
- * Copyright 2016 NXP
- *
- */
-#ifndef __FSL_DPAA2_GLOBAL_H
-#define __FSL_DPAA2_GLOBAL_H
-
-#include <linux/types.h>
-#include <linux/cpumask.h>
-#include "dpaa2-fd.h"
-
-struct dpaa2_dq {
-       union {
-               struct common {
-                       u8 verb;
-                       u8 reserved[63];
-               } common;
-               struct dq {
-                       u8 verb;
-                       u8 stat;
-                       __le16 seqnum;
-                       __le16 oprid;
-                       u8 reserved;
-                       u8 tok;
-                       __le32 fqid;
-                       u32 reserved2;
-                       __le32 fq_byte_cnt;
-                       __le32 fq_frm_cnt;
-                       __le64 fqd_ctx;
-                       u8 fd[32];
-               } dq;
-               struct scn {
-                       u8 verb;
-                       u8 stat;
-                       u8 state;
-                       u8 reserved;
-                       __le32 rid_tok;
-                       __le64 ctx;
-               } scn;
-       };
-};
-
-/* Parsing frame dequeue results */
-/* FQ empty */
-#define DPAA2_DQ_STAT_FQEMPTY       0x80
-/* FQ held active */
-#define DPAA2_DQ_STAT_HELDACTIVE    0x40
-/* FQ force eligible */
-#define DPAA2_DQ_STAT_FORCEELIGIBLE 0x20
-/* valid frame */
-#define DPAA2_DQ_STAT_VALIDFRAME    0x10
-/* FQ ODP enable */
-#define DPAA2_DQ_STAT_ODPVALID      0x04
-/* volatile dequeue */
-#define DPAA2_DQ_STAT_VOLATILE      0x02
-/* volatile dequeue command is expired */
-#define DPAA2_DQ_STAT_EXPIRED       0x01
-
-#define DQ_FQID_MASK           0x00FFFFFF
-#define DQ_FRAME_COUNT_MASK    0x00FFFFFF
-
-/**
- * dpaa2_dq_flags() - Get the stat field of dequeue response
- * @dq: the dequeue result.
- */
-static inline u32 dpaa2_dq_flags(const struct dpaa2_dq *dq)
-{
-       return dq->dq.stat;
-}
-
-/**
- * dpaa2_dq_is_pull() - Check whether the dq response is from a pull
- *                      command.
- * @dq: the dequeue result
- *
- * Return 1 for volatile(pull) dequeue, 0 for static dequeue.
- */
-static inline int dpaa2_dq_is_pull(const struct dpaa2_dq *dq)
-{
-       return (int)(dpaa2_dq_flags(dq) & DPAA2_DQ_STAT_VOLATILE);
-}
-
-/**
- * dpaa2_dq_is_pull_complete() - Check whether the pull command is completed.
- * @dq: the dequeue result
- *
- * Return boolean.
- */
-static inline bool dpaa2_dq_is_pull_complete(const struct dpaa2_dq *dq)
-{
-       return !!(dpaa2_dq_flags(dq) & DPAA2_DQ_STAT_EXPIRED);
-}
-
-/**
- * dpaa2_dq_seqnum() - Get the seqnum field in dequeue response
- * @dq: the dequeue result
- *
- * seqnum is valid only if VALIDFRAME flag is TRUE
- *
- * Return seqnum.
- */
-static inline u16 dpaa2_dq_seqnum(const struct dpaa2_dq *dq)
-{
-       return le16_to_cpu(dq->dq.seqnum);
-}
-
-/**
- * dpaa2_dq_odpid() - Get the odpid field in dequeue response
- * @dq: the dequeue result
- *
- * odpid is valid only if ODPVALID flag is TRUE.
- *
- * Return odpid.
- */
-static inline u16 dpaa2_dq_odpid(const struct dpaa2_dq *dq)
-{
-       return le16_to_cpu(dq->dq.oprid);
-}
-
-/**
- * dpaa2_dq_fqid() - Get the fqid in dequeue response
- * @dq: the dequeue result
- *
- * Return fqid.
- */
-static inline u32 dpaa2_dq_fqid(const struct dpaa2_dq *dq)
-{
-       return le32_to_cpu(dq->dq.fqid) & DQ_FQID_MASK;
-}
-
-/**
- * dpaa2_dq_byte_count() - Get the byte count in dequeue response
- * @dq: the dequeue result
- *
- * Return the byte count remaining in the FQ.
- */
-static inline u32 dpaa2_dq_byte_count(const struct dpaa2_dq *dq)
-{
-       return le32_to_cpu(dq->dq.fq_byte_cnt);
-}
-
-/**
- * dpaa2_dq_frame_count() - Get the frame count in dequeue response
- * @dq: the dequeue result
- *
- * Return the frame count remaining in the FQ.
- */
-static inline u32 dpaa2_dq_frame_count(const struct dpaa2_dq *dq)
-{
-       return le32_to_cpu(dq->dq.fq_frm_cnt) & DQ_FRAME_COUNT_MASK;
-}
-
-/**
- * dpaa2_dq_fd_ctx() - Get the frame queue context in dequeue response
- * @dq: the dequeue result
- *
- * Return the frame queue context.
- */
-static inline u64 dpaa2_dq_fqd_ctx(const struct dpaa2_dq *dq)
-{
-       return le64_to_cpu(dq->dq.fqd_ctx);
-}
-
-/**
- * dpaa2_dq_fd() - Get the frame descriptor in dequeue response
- * @dq: the dequeue result
- *
- * Return the frame descriptor.
- */
-static inline const struct dpaa2_fd *dpaa2_dq_fd(const struct dpaa2_dq *dq)
-{
-       return (const struct dpaa2_fd *)&dq->dq.fd[0];
-}
-
-#endif /* __FSL_DPAA2_GLOBAL_H */
diff --git a/drivers/staging/fsl-mc/include/dpaa2-io.h b/drivers/staging/fsl-mc/include/dpaa2-io.h
deleted file mode 100644 (file)
index ab51e40..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
-/*
- * Copyright 2014-2016 Freescale Semiconductor Inc.
- * Copyright NXP
- *
- */
-#ifndef __FSL_DPAA2_IO_H
-#define __FSL_DPAA2_IO_H
-
-#include <linux/types.h>
-#include <linux/cpumask.h>
-#include <linux/irqreturn.h>
-
-#include "dpaa2-fd.h"
-#include "dpaa2-global.h"
-
-struct dpaa2_io;
-struct dpaa2_io_store;
-struct device;
-
-/**
- * DOC: DPIO Service
- *
- * The DPIO service provides APIs for users to interact with the datapath
- * by enqueueing and dequeing frame descriptors.
- *
- * The following set of APIs can be used to enqueue and dequeue frames
- * as well as producing notification callbacks when data is available
- * for dequeue.
- */
-
-#define DPAA2_IO_ANY_CPU       -1
-
-/**
- * struct dpaa2_io_desc - The DPIO descriptor
- * @receives_notifications: Use notificaton mode. Non-zero if the DPIO
- *                  has a channel.
- * @has_8prio:      Set to non-zero for channel with 8 priority WQs.  Ignored
- *                  unless receives_notification is TRUE.
- * @cpu:            The cpu index that at least interrupt handlers will
- *                  execute on.
- * @stash_affinity: The stash affinity for this portal favour 'cpu'
- * @regs_cena:      The cache enabled regs.
- * @regs_cinh:      The cache inhibited regs
- * @dpio_id:        The dpio index
- * @qman_version:   The qman version
- *
- * Describes the attributes and features of the DPIO object.
- */
-struct dpaa2_io_desc {
-       int receives_notifications;
-       int has_8prio;
-       int cpu;
-       void *regs_cena;
-       void __iomem *regs_cinh;
-       int dpio_id;
-       u32 qman_version;
-};
-
-struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc);
-
-void dpaa2_io_down(struct dpaa2_io *d);
-
-irqreturn_t dpaa2_io_irq(struct dpaa2_io *obj);
-
-struct dpaa2_io *dpaa2_io_service_select(int cpu);
-
-/**
- * struct dpaa2_io_notification_ctx - The DPIO notification context structure
- * @cb:           The callback to be invoked when the notification arrives
- * @is_cdan:      Zero for FQDAN, non-zero for CDAN
- * @id:           FQID or channel ID, needed for rearm
- * @desired_cpu:  The cpu on which the notifications will show up. Use
- *                DPAA2_IO_ANY_CPU if don't care
- * @dpio_id:      The dpio index
- * @qman64:       The 64-bit context value shows up in the FQDAN/CDAN.
- * @node:         The list node
- * @dpio_private: The dpio object internal to dpio_service
- *
- * Used when a FQDAN/CDAN registration is made by drivers.
- */
-struct dpaa2_io_notification_ctx {
-       void (*cb)(struct dpaa2_io_notification_ctx *ctx);
-       int is_cdan;
-       u32 id;
-       int desired_cpu;
-       int dpio_id;
-       u64 qman64;
-       struct list_head node;
-       void *dpio_private;
-};
-
-int dpaa2_io_service_register(struct dpaa2_io *service,
-                             struct dpaa2_io_notification_ctx *ctx);
-void dpaa2_io_service_deregister(struct dpaa2_io *service,
-                                struct dpaa2_io_notification_ctx *ctx);
-int dpaa2_io_service_rearm(struct dpaa2_io *service,
-                          struct dpaa2_io_notification_ctx *ctx);
-
-int dpaa2_io_service_pull_channel(struct dpaa2_io *d, u32 channelid,
-                                 struct dpaa2_io_store *s);
-
-int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d, u32 qdid, u8 prio,
-                               u16 qdbin, const struct dpaa2_fd *fd);
-int dpaa2_io_service_release(struct dpaa2_io *d, u32 bpid,
-                            const u64 *buffers, unsigned int num_buffers);
-int dpaa2_io_service_acquire(struct dpaa2_io *d, u32 bpid,
-                            u64 *buffers, unsigned int num_buffers);
-
-struct dpaa2_io_store *dpaa2_io_store_create(unsigned int max_frames,
-                                            struct device *dev);
-void dpaa2_io_store_destroy(struct dpaa2_io_store *s);
-struct dpaa2_dq *dpaa2_io_store_next(struct dpaa2_io_store *s, int *is_last);
-
-#endif /* __FSL_DPAA2_IO_H */
index 768cce0ccb807518f32b3d72d875915e9391fdfd..76a262674c8dc7c4563fba8f6b570b6155d2d182 100644 (file)
@@ -207,8 +207,8 @@ cxgbit_ddp_reserve(struct cxgbit_sock *csk, struct cxgbi_task_tag_info *ttinfo,
        ret = dma_map_sg(&ppm->pdev->dev, sgl, sgcnt, DMA_FROM_DEVICE);
        sgl->offset = sg_offset;
        if (!ret) {
-               pr_info("%s: 0x%x, xfer %u, sgl %u dma mapping err.\n",
-                       __func__, 0, xferlen, sgcnt);
+               pr_debug("%s: 0x%x, xfer %u, sgl %u dma mapping err.\n",
+                        __func__, 0, xferlen, sgcnt);
                goto rel_ppods;
        }
 
@@ -250,8 +250,8 @@ cxgbit_get_r2t_ttt(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
 
        ret = cxgbit_ddp_reserve(csk, ttinfo, cmd->se_cmd.data_length);
        if (ret < 0) {
-               pr_info("csk 0x%p, cmd 0x%p, xfer len %u, sgcnt %u no ddp.\n",
-                       csk, cmd, cmd->se_cmd.data_length, ttinfo->nents);
+               pr_debug("csk 0x%p, cmd 0x%p, xfer len %u, sgcnt %u no ddp.\n",
+                        csk, cmd, cmd->se_cmd.data_length, ttinfo->nents);
 
                ttinfo->sgl = NULL;
                ttinfo->nents = 0;
index 8e223799347a1dd78d5abcd8d8616717e93802ba..94bad43c41ffc2c7c33c1d3b48b0f0773fd87aa6 100644 (file)
@@ -57,9 +57,8 @@ static DEFINE_SPINLOCK(tiqn_lock);
 static DEFINE_MUTEX(np_lock);
 
 static struct idr tiqn_idr;
-struct idr sess_idr;
+DEFINE_IDA(sess_ida);
 struct mutex auth_id_lock;
-spinlock_t sess_idr_lock;
 
 struct iscsit_global *iscsit_global;
 
@@ -700,9 +699,7 @@ static int __init iscsi_target_init_module(void)
 
        spin_lock_init(&iscsit_global->ts_bitmap_lock);
        mutex_init(&auth_id_lock);
-       spin_lock_init(&sess_idr_lock);
        idr_init(&tiqn_idr);
-       idr_init(&sess_idr);
 
        ret = target_register_template(&iscsi_ops);
        if (ret)
@@ -4375,10 +4372,7 @@ int iscsit_close_session(struct iscsi_session *sess)
        pr_debug("Decremented number of active iSCSI Sessions on"
                " iSCSI TPG: %hu to %u\n", tpg->tpgt, tpg->nsessions);
 
-       spin_lock(&sess_idr_lock);
-       idr_remove(&sess_idr, sess->session_index);
-       spin_unlock(&sess_idr_lock);
-
+       ida_free(&sess_ida, sess->session_index);
        kfree(sess->sess_ops);
        sess->sess_ops = NULL;
        spin_unlock_bh(&se_tpg->session_lock);
index 42de1843aa40d06f9967693ab5dbf20852e84629..48bac0acf8c76e055c022bc2b74423cca50b04bf 100644 (file)
@@ -55,9 +55,7 @@ extern struct kmem_cache *lio_ooo_cache;
 extern struct kmem_cache *lio_qr_cache;
 extern struct kmem_cache *lio_r2t_cache;
 
-extern struct idr sess_idr;
+extern struct ida sess_ida;
 extern struct mutex auth_id_lock;
-extern spinlock_t sess_idr_lock;
-
 
 #endif   /*** ISCSI_TARGET_H ***/
index 923b1a9fc3dcd95f71de3d2eb78e7e8064b81b01..9e74f8bc29636aef1855ff43e1c340aa062d8453 100644 (file)
@@ -336,22 +336,15 @@ static int iscsi_login_zero_tsih_s1(
        timer_setup(&sess->time2retain_timer,
                    iscsit_handle_time2retain_timeout, 0);
 
-       idr_preload(GFP_KERNEL);
-       spin_lock_bh(&sess_idr_lock);
-       ret = idr_alloc(&sess_idr, NULL, 0, 0, GFP_NOWAIT);
-       if (ret >= 0)
-               sess->session_index = ret;
-       spin_unlock_bh(&sess_idr_lock);
-       idr_preload_end();
-
+       ret = ida_alloc(&sess_ida, GFP_KERNEL);
        if (ret < 0) {
-               pr_err("idr_alloc() for sess_idr failed\n");
+               pr_err("Session ID allocation failed %d\n", ret);
                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
                                ISCSI_LOGIN_STATUS_NO_RESOURCES);
-               kfree(sess);
-               return -ENOMEM;
+               goto free_sess;
        }
 
+       sess->session_index = ret;
        sess->creation_time = get_jiffies_64();
        /*
         * The FFP CmdSN window values will be allocated from the TPG's
@@ -365,20 +358,26 @@ static int iscsi_login_zero_tsih_s1(
                                ISCSI_LOGIN_STATUS_NO_RESOURCES);
                pr_err("Unable to allocate memory for"
                                " struct iscsi_sess_ops.\n");
-               kfree(sess);
-               return -ENOMEM;
+               goto free_id;
        }
 
        sess->se_sess = transport_alloc_session(TARGET_PROT_NORMAL);
        if (IS_ERR(sess->se_sess)) {
                iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
                                ISCSI_LOGIN_STATUS_NO_RESOURCES);
-               kfree(sess->sess_ops);
-               kfree(sess);
-               return -ENOMEM;
+               goto free_ops;
        }
 
        return 0;
+
+free_ops:
+       kfree(sess->sess_ops);
+free_id:
+       ida_free(&sess_ida, sess->session_index);
+free_sess:
+       kfree(sess);
+       conn->sess = NULL;
+       return -ENOMEM;
 }
 
 static int iscsi_login_zero_tsih_s2(
@@ -1161,13 +1160,9 @@ void iscsi_target_login_sess_out(struct iscsi_conn *conn,
                                   ISCSI_LOGIN_STATUS_INIT_ERR);
        if (!zero_tsih || !conn->sess)
                goto old_sess_out;
-       if (conn->sess->se_sess)
-               transport_free_session(conn->sess->se_sess);
-       if (conn->sess->session_index != 0) {
-               spin_lock_bh(&sess_idr_lock);
-               idr_remove(&sess_idr, conn->sess->session_index);
-               spin_unlock_bh(&sess_idr_lock);
-       }
+
+       transport_free_session(conn->sess->se_sess);
+       ida_free(&sess_ida, conn->sess->session_index);
        kfree(conn->sess->sess_ops);
        kfree(conn->sess);
        conn->sess = NULL;
index 0126de898036cdb6eacb51cc672232b7de9060d7..3c59e19029befd7ad0070db571de0b4b8271dfdb 100644 (file)
@@ -5,3 +5,11 @@ config OPTEE
        help
          This implements the OP-TEE Trusted Execution Environment (TEE)
          driver.
+
+config OPTEE_SHM_NUM_PRIV_PAGES
+       int "Private Shared Memory Pages"
+       default 1
+       depends on OPTEE
+       help
+         This sets the number of private shared memory pages to be
+         used by OP-TEE TEE driver.
index e5fd5ed217dac9562bb7ccf10c2ac96053d7a991..e1aafe842d660bb11b1146133105f37bff24873e 100644 (file)
@@ -32,7 +32,7 @@
 
 #define DRIVER_NAME "optee"
 
-#define OPTEE_SHM_NUM_PRIV_PAGES       1
+#define OPTEE_SHM_NUM_PRIV_PAGES       CONFIG_OPTEE_SHM_NUM_PRIV_PAGES
 
 /**
  * optee_from_msg_param() - convert from OPTEE_MSG parameters to
index 41aea12e2bccd9f4ab55b3f77706753330850667..b45c73dd37a54831c867d7ccb94a2a14cbc3939c 100644 (file)
@@ -48,7 +48,7 @@ static void handle_rpc_func_cmd_get_time(struct optee_msg_arg *arg)
                        OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT)
                goto bad;
 
-       getnstimeofday64(&ts);
+       ktime_get_real_ts64(&ts);
        arg->params[0].u.value.a = ts.tv_sec;
        arg->params[0].u.value.b = ts.tv_nsec;
 
index 82979880f9853e2d2455d1e55adc2c5b9f4d8495..0e69edc77d184d436f2220caf90895438e36fc70 100644 (file)
@@ -360,7 +360,7 @@ config INTEL_SOC_DTS_IOSF_CORE
 
 config INTEL_SOC_DTS_THERMAL
        tristate "Intel SoCs DTS thermal driver"
-       depends on X86 && PCI
+       depends on X86 && PCI && ACPI
        select INTEL_SOC_DTS_IOSF_CORE
        select THERMAL_WRITABLE_TRIPS
        help
index 4540e892b61d300d9d735c862d8528f258ae81c4..cde891c54cde0dcbc1965fcd7fec6a8f434a9bae 100644 (file)
@@ -28,7 +28,7 @@
  *              case of external interrupts without need for ack, clamping down
  *              cpu in non-irq context does not reduce irq. for majority of the
  *              cases, clamping down cpu does help reduce irq as well, we should
- *              be able to differenciate the two cases and give a quantitative
+ *              be able to differentiate the two cases and give a quantitative
  *              solution for the irqs that we can control. perhaps based on
  *              get_cpu_iowait_time_us()
  *
index c27868b2c6afc5f438754f370961fee1c3eaac8e..1e47511a6bd5baa0e0db1846d858b8fd2757fb19 100644 (file)
@@ -15,6 +15,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/acpi.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <asm/cpu_device_id.h>
@@ -31,6 +32,7 @@ MODULE_PARM_DESC(crit_offset,
 /* IRQ 86 is a fixed APIC interrupt for BYT DTS Aux threshold notifications */
 #define BYT_SOC_DTS_APIC_IRQ   86
 
+static int soc_dts_thres_gsi;
 static int soc_dts_thres_irq;
 static struct intel_soc_dts_sensors *soc_dts;
 
@@ -65,7 +67,21 @@ static int __init intel_soc_thermal_init(void)
                return err;
        }
 
-       soc_dts_thres_irq = (int)match_cpu->driver_data;
+       soc_dts_thres_gsi = (int)match_cpu->driver_data;
+       if (soc_dts_thres_gsi) {
+               /*
+                * Note the flags here MUST match the firmware defaults, rather
+                * then the request_irq flags, otherwise we get an EBUSY error.
+                */
+               soc_dts_thres_irq = acpi_register_gsi(NULL, soc_dts_thres_gsi,
+                                                     ACPI_LEVEL_SENSITIVE,
+                                                     ACPI_ACTIVE_LOW);
+               if (soc_dts_thres_irq < 0) {
+                       pr_warn("intel_soc_dts: Could not get IRQ for GSI %d, err %d\n",
+                               soc_dts_thres_gsi, soc_dts_thres_irq);
+                       soc_dts_thres_irq = 0;
+               }
+       }
 
        if (soc_dts_thres_irq) {
                err = request_threaded_irq(soc_dts_thres_irq, NULL,
@@ -90,8 +106,10 @@ static int __init intel_soc_thermal_init(void)
        return 0;
 
 error_trips:
-       if (soc_dts_thres_irq)
+       if (soc_dts_thres_irq) {
                free_irq(soc_dts_thres_irq, soc_dts);
+               acpi_unregister_gsi(soc_dts_thres_gsi);
+       }
        intel_soc_dts_iosf_exit(soc_dts);
 
        return err;
@@ -99,8 +117,10 @@ error_trips:
 
 static void __exit intel_soc_thermal_exit(void)
 {
-       if (soc_dts_thres_irq)
+       if (soc_dts_thres_irq) {
                free_irq(soc_dts_thres_irq, soc_dts);
+               acpi_unregister_gsi(soc_dts_thres_gsi);
+       }
        intel_soc_dts_iosf_exit(soc_dts);
 }
 
index 977a8307fbb1a4e0d66cb1c619834472bfe0d1ea..4f28165592056d5ec90309c5bff737f5ba66ea0b 100644 (file)
@@ -260,10 +260,13 @@ static int of_thermal_set_mode(struct thermal_zone_device *tz,
 
        mutex_lock(&tz->lock);
 
-       if (mode == THERMAL_DEVICE_ENABLED)
+       if (mode == THERMAL_DEVICE_ENABLED) {
                tz->polling_delay = data->polling_delay;
-       else
+               tz->passive_delay = data->passive_delay;
+       } else {
                tz->polling_delay = 0;
+               tz->passive_delay = 0;
+       }
 
        mutex_unlock(&tz->lock);
 
index c866cc1659606726584e47b6e74ff59fe2d6aa51..450ed66edf582b4c6c77e3a376a17173cfdf57b9 100644 (file)
@@ -1,16 +1,6 @@
-/*
- * Copyright 2016 Freescale Semiconductor, Inc.
- *
- * 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.
- *
- */
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright 2016 Freescale Semiconductor, Inc.
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -197,7 +187,7 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
        int ret;
        struct qoriq_tmu_data *data;
        struct device_node *np = pdev->dev.of_node;
-       u32 site = 0;
+       u32 site;
 
        if (!np) {
                dev_err(&pdev->dev, "Device OF-Node is NULL");
@@ -233,8 +223,9 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
        if (ret < 0)
                goto err_tmu;
 
-       data->tz = thermal_zone_of_sensor_register(&pdev->dev, data->sensor_id,
-                               data, &tmu_tz_ops);
+       data->tz = devm_thermal_zone_of_sensor_register(&pdev->dev,
+                                                       data->sensor_id,
+                                                       data, &tmu_tz_ops);
        if (IS_ERR(data->tz)) {
                ret = PTR_ERR(data->tz);
                dev_err(&pdev->dev,
@@ -243,7 +234,7 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
        }
 
        /* Enable monitoring */
-       site |= 0x1 << (15 - data->sensor_id);
+       site = 0x1 << (15 - data->sensor_id);
        tmu_write(data, site | TMR_ME | TMR_ALPF, &data->regs->tmr);
 
        return 0;
@@ -261,8 +252,6 @@ static int qoriq_tmu_remove(struct platform_device *pdev)
 {
        struct qoriq_tmu_data *data = platform_get_drvdata(pdev);
 
-       thermal_zone_of_sensor_unregister(&pdev->dev, data->tz);
-
        /* Disable monitoring */
        tmu_write(data, TMR_DISABLE, &data->regs->tmr);
 
index 766521eb70715a1ff6c9a6b93434ec47d8716c49..7aed5337bdd35b3b3214372e7d5f9a01cf26789c 100644 (file)
@@ -1,19 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  *  R-Car Gen3 THS thermal sensor driver
  *  Based on rcar_thermal.c and work from Hien Dang and Khiem Nguyen.
  *
  * Copyright (C) 2016 Renesas Electronics Corporation.
  * Copyright (C) 2016 Sang Engineering
- *
- *  This program is free software; 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/delay.h>
 #include <linux/err.h>
index e77e63070e998e1d997537ca88da1e7dd4ea533c..78f932822d381c9dbc013aee618be56e533baaab 100644 (file)
@@ -1,21 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  *  R-Car THS/TSC thermal sensor driver
  *
  * Copyright (C) 2012 Renesas Solutions Corp.
  * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 #include <linux/delay.h>
 #include <linux/err.h>
@@ -660,6 +648,6 @@ static struct platform_driver rcar_thermal_driver = {
 };
 module_platform_driver(rcar_thermal_driver);
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("R-Car THS/TSC thermal sensor driver");
 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
index f631f8bee308846d1cab8fe73ac89e4d8953d7f7..77baf895108fac45252ed6f3ea1b8b5557cbee91 100644 (file)
@@ -52,6 +52,7 @@ static u32 hvc_opal_boot_termno;
 static const struct hv_ops hvc_opal_raw_ops = {
        .get_chars = opal_get_chars,
        .put_chars = opal_put_chars,
+       .flush = opal_flush_chars,
        .notifier_add = notifier_add_irq,
        .notifier_del = notifier_del_irq,
        .notifier_hangup = notifier_hangup_irq,
@@ -141,6 +142,7 @@ static int hvc_opal_hvsi_tiocmset(struct hvc_struct *hp, unsigned int set,
 static const struct hv_ops hvc_opal_hvsi_ops = {
        .get_chars = hvc_opal_hvsi_get_chars,
        .put_chars = hvc_opal_hvsi_put_chars,
+       .flush = opal_flush_chars,
        .notifier_add = hvc_opal_hvsi_open,
        .notifier_del = hvc_opal_hvsi_close,
        .notifier_hangup = hvc_opal_hvsi_hangup,
index 6364890575ec03a54b70e24bdb3dce37285a938c..06ed20dd01ba6f9cc443c690f04c131f09790cba 100644 (file)
@@ -348,7 +348,7 @@ static void send_sig_all(int sig)
                if (is_global_init(p))
                        continue;
 
-               do_send_sig_info(sig, SEND_SIG_FORCED, p, true);
+               do_send_sig_info(sig, SEND_SIG_FORCED, p, PIDTYPE_MAX);
        }
        read_unlock(&tasklist_lock);
 }
index 11c2df904ac93acf78067a7b205daaf6b5c50210..32bc3e3fe4d30bcea455fb7dc13657b63b111cd9 100644 (file)
@@ -2113,7 +2113,7 @@ static int __tty_fasync(int fd, struct file *filp, int on)
                        type = PIDTYPE_PGID;
                } else {
                        pid = task_pid(current);
-                       type = PIDTYPE_PID;
+                       type = PIDTYPE_TGID;
                }
                get_pid(pid);
                spin_unlock_irqrestore(&tty->ctrl_lock, flags);
index d9145a8f35d2e5515ee8f16ef9d7b5d237158ca8..8e3bab1e0c1f693394c849528b6eb9e2d01a3c26 100644 (file)
@@ -161,16 +161,10 @@ static int exynos_ehci_probe(struct platform_device *pdev)
        }
        exynos_ehci = to_exynos_ehci(hcd);
 
-       if (of_device_is_compatible(pdev->dev.of_node,
-                                       "samsung,exynos5440-ehci"))
-               goto skip_phy;
-
        err = exynos_ehci_get_phy(&pdev->dev, exynos_ehci);
        if (err)
                goto fail_clk;
 
-skip_phy:
-
        exynos_ehci->clk = devm_clk_get(&pdev->dev, "usbhost");
 
        if (IS_ERR(exynos_ehci->clk)) {
@@ -304,7 +298,6 @@ static const struct dev_pm_ops exynos_ehci_pm_ops = {
 #ifdef CONFIG_OF
 static const struct of_device_id exynos_ehci_match[] = {
        { .compatible = "samsung,exynos4210-ehci" },
-       { .compatible = "samsung,exynos5440-ehci" },
        {},
 };
 MODULE_DEVICE_TABLE(of, exynos_ehci_match);
index a39fae41bc70015eaacfeb28002bf3cc1088afec..c0c4dcca6f3cbb12a607325b4ef8773704ce6ff3 100644 (file)
@@ -130,15 +130,10 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 
        exynos_ohci = to_exynos_ohci(hcd);
 
-       if (of_device_is_compatible(pdev->dev.of_node,
-                                       "samsung,exynos5440-ohci"))
-               goto skip_phy;
-
        err = exynos_ohci_get_phy(&pdev->dev, exynos_ohci);
        if (err)
                goto fail_clk;
 
-skip_phy:
        exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost");
 
        if (IS_ERR(exynos_ohci->clk)) {
@@ -270,7 +265,6 @@ static const struct dev_pm_ops exynos_ohci_pm_ops = {
 #ifdef CONFIG_OF
 static const struct of_device_id exynos_ohci_match[] = {
        { .compatible = "samsung,exynos4210-ohci" },
-       { .compatible = "samsung,exynos5440-ohci" },
        {},
 };
 MODULE_DEVICE_TABLE(of, exynos_ohci_match);
index cfdecea5078f4095546adcee397213cd0f2b67b1..b580885243f7e091975174e06bb03d7514ff9ec7 100644 (file)
@@ -12,7 +12,7 @@ config VHOST_NET
 
 config VHOST_SCSI
        tristate "VHOST_SCSI TCM fabric driver"
-       depends on TARGET_CORE && EVENTFD && m
+       depends on TARGET_CORE && EVENTFD
        select VHOST
        default n
        ---help---
index 76f8d649147b53af26ab8fc0a696efc3907bd647..c24bb690680b4104d6621c5b984d869f51af2cd3 100644 (file)
@@ -55,7 +55,7 @@
 #define VHOST_SCSI_DEFAULT_TAGS 256
 #define VHOST_SCSI_PREALLOC_SGLS 2048
 #define VHOST_SCSI_PREALLOC_UPAGES 2048
-#define VHOST_SCSI_PREALLOC_PROT_SGLS 512
+#define VHOST_SCSI_PREALLOC_PROT_SGLS 2048
 
 struct vhost_scsi_inflight {
        /* Wait for the flush operation to finish */
index 96c1d8400822a3d852553e5baddaaed9907d7f71..b13c6b4b2c665a332a40aeada1eaa1e421d9a4aa 100644 (file)
@@ -952,7 +952,7 @@ static void vhost_iotlb_notify_vq(struct vhost_dev *d,
        list_for_each_entry_safe(node, n, &d->pending_list, node) {
                struct vhost_iotlb_msg *vq_msg = &node->msg.iotlb;
                if (msg->iova <= vq_msg->iova &&
-                   msg->iova + msg->size - 1 > vq_msg->iova &&
+                   msg->iova + msg->size - 1 >= vq_msg->iova &&
                    vq_msg->type == VHOST_IOTLB_MISS) {
                        vhost_poll_queue(&node->vq->poll);
                        list_del(&node->node);
index e91edef98633e9d624ca50f171c13d0978510eca..787792c3d08d66b93012c27deed878e820c06e12 100644 (file)
@@ -152,7 +152,7 @@ config FRAMEBUFFER_CONSOLE_ROTATION
 
 config FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
        bool "Framebuffer Console Deferred Takeover"
-       depends on FRAMEBUFFER_CONSOLE=y && DUMMY_CONSOLE=y
+       depends on FB=y && FRAMEBUFFER_CONSOLE && DUMMY_CONSOLE
        help
          If enabled this defers the framebuffer console taking over the
          console from the dummy console until the first text is displayed on
index 0254251fdd79a745e77a46793915e55425b4770f..45ad925ad5f8fbb203a137c0ab114f4fb71d62f2 100644 (file)
@@ -38,13 +38,11 @@ void dummycon_register_output_notifier(struct notifier_block *nb)
        if (dummycon_putc_called)
                nb->notifier_call(nb, 0, NULL);
 }
-EXPORT_SYMBOL_GPL(dummycon_register_output_notifier);
 
 void dummycon_unregister_output_notifier(struct notifier_block *nb)
 {
        raw_notifier_chain_unregister(&dummycon_output_nh, nb);
 }
-EXPORT_SYMBOL_GPL(dummycon_unregister_output_notifier);
 
 static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos)
 {
index f09e17b60e45ef611f51e2e21528432731fac8f0..09731b2f6815f98651acba84cf9cc8d679f34f7a 100644 (file)
@@ -112,6 +112,11 @@ EXPORT_SYMBOL(vgacon_text_force);
 static int __init text_mode(char *str)
 {
        vgacon_text_mode_force = true;
+
+       pr_warning("You have booted with nomodeset. This means your GPU drivers are DISABLED\n");
+       pr_warning("Any video related functionality will be severely degraded, and you may not even be able to suspend the system properly\n");
+       pr_warning("Unless you actually understand what nomodeset does, you should reboot without enabling it\n");
+
        return 1;
 }
 
index cc11c60612980208d8bb26bd4c92b8892d792bfe..0777aff211e5cddad3c216e0f58f6c9576e9ac7f 100644 (file)
@@ -2303,7 +2303,7 @@ static void ami_build_copper(struct fb_info *info)
        ami_rebuild_copper(info->par);
 }
 
-
+#ifndef MODULE
 static void __init amifb_setup_mcap(char *spec)
 {
        char *p;
@@ -2368,7 +2368,7 @@ static int __init amifb_setup(char *options)
 
        return 0;
 }
-
+#endif
 
 static int amifb_check_var(struct fb_var_screeninfo *var,
                           struct fb_info *info)
index 5fb156bdcf4e5450f0d8e0348010dadee09bd05f..75ebbbf0a1fbb5b4e3d633ced517967d94d02e6b 100644 (file)
@@ -2234,8 +2234,8 @@ static int fbcon_switch(struct vc_data *vc)
         *
         * info->currcon = vc->vc_num;
         */
-       for (i = 0; i < FB_MAX; i++) {
-               if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) {
+       for_each_registered_fb(i) {
+               if (registered_fb[i]->fbcon_par) {
                        struct fbcon_ops *o = registered_fb[i]->fbcon_par;
 
                        o->currcon = vc->vc_num;
@@ -3124,11 +3124,9 @@ static int fbcon_fb_unregistered(struct fb_info *info)
        if (idx == info_idx) {
                info_idx = -1;
 
-               for (i = 0; i < FB_MAX; i++) {
-                       if (registered_fb[i] != NULL) {
-                               info_idx = i;
-                               break;
-                       }
+               for_each_registered_fb(i) {
+                       info_idx = i;
+                       break;
                }
        }
 
@@ -3594,13 +3592,24 @@ static int fbcon_init_device(void)
 }
 
 #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
+static void fbcon_register_existing_fbs(struct work_struct *work)
+{
+       int i;
+
+       console_lock();
+
+       for_each_registered_fb(i)
+               fbcon_fb_registered(registered_fb[i]);
+
+       console_unlock();
+}
+
 static struct notifier_block fbcon_output_nb;
+static DECLARE_WORK(fbcon_deferred_takeover_work, fbcon_register_existing_fbs);
 
 static int fbcon_output_notifier(struct notifier_block *nb,
                                 unsigned long action, void *data)
 {
-       int i;
-
        WARN_CONSOLE_UNLOCKED();
 
        pr_info("fbcon: Taking over console\n");
@@ -3609,45 +3618,37 @@ static int fbcon_output_notifier(struct notifier_block *nb,
        deferred_takeover = false;
        logo_shown = FBCON_LOGO_DONTSHOW;
 
-       for (i = 0; i < FB_MAX; i++) {
-               if (registered_fb[i])
-                       fbcon_fb_registered(registered_fb[i]);
-       }
+       /* We may get called in atomic context */
+       schedule_work(&fbcon_deferred_takeover_work);
 
        return NOTIFY_OK;
 }
-
-static void fbcon_register_output_notifier(void)
-{
-       fbcon_output_nb.notifier_call = fbcon_output_notifier;
-       dummycon_register_output_notifier(&fbcon_output_nb);
-}
-#else
-static inline void fbcon_register_output_notifier(void) {}
 #endif
 
 static void fbcon_start(void)
 {
+       WARN_CONSOLE_UNLOCKED();
+
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
+       if (conswitchp != &dummy_con)
+               deferred_takeover = false;
+
        if (deferred_takeover) {
-               fbcon_register_output_notifier();
+               fbcon_output_nb.notifier_call = fbcon_output_notifier;
+               dummycon_register_output_notifier(&fbcon_output_nb);
                return;
        }
+#endif
 
        if (num_registered_fb) {
                int i;
 
-               console_lock();
-
-               for (i = 0; i < FB_MAX; i++) {
-                       if (registered_fb[i] != NULL) {
-                               info_idx = i;
-                               break;
-                       }
+               for_each_registered_fb(i) {
+                       info_idx = i;
+                       break;
                }
 
                do_fbcon_takeover(0);
-               console_unlock();
-
        }
 }
 
@@ -3669,15 +3670,12 @@ static void fbcon_exit(void)
        kfree((void *)softback_buf);
        softback_buf = 0UL;
 
-       for (i = 0; i < FB_MAX; i++) {
+       for_each_registered_fb(i) {
                int pending = 0;
 
                mapped = 0;
                info = registered_fb[i];
 
-               if (info == NULL)
-                       continue;
-
                if (info->queue.func)
                        pending = cancel_work_sync(&info->queue);
                DPRINTK("fbcon: %s pending work\n", (pending ? "canceled" :
@@ -3733,8 +3731,8 @@ void __init fb_console_init(void)
        for (i = 0; i < MAX_NR_CONSOLES; i++)
                con2fb_map[i] = -1;
 
-       console_unlock();
        fbcon_start();
+       console_unlock();
 }
 
 #ifdef MODULE
index 609438d2465b288f831eb086b9d0ef982bb5ddef..20405421a5ed07c398036fbf3110eea18f61e2e6 100644 (file)
@@ -1347,6 +1347,7 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd,
        case FBIOGET_CON2FBMAP:
        case FBIOPUT_CON2FBMAP:
                arg = (unsigned long) compat_ptr(arg);
+               /* fall through */
        case FBIOBLANK:
                ret = do_fb_ioctl(info, cmd, arg);
                break;
@@ -1593,10 +1594,8 @@ static int do_remove_conflicting_framebuffers(struct apertures_struct *a,
        int i, ret;
 
        /* check all firmware fbs and kick off if the base addr overlaps */
-       for (i = 0 ; i < FB_MAX; i++) {
+       for_each_registered_fb(i) {
                struct apertures_struct *gen_aper;
-               if (!registered_fb[i])
-                       continue;
 
                if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE))
                        continue;
@@ -1691,25 +1690,30 @@ static int do_register_framebuffer(struct fb_info *fb_info)
        event.info = fb_info;
        if (!lockless_register_fb)
                console_lock();
+       else
+               atomic_inc(&ignore_console_lock_warning);
        if (!lock_fb_info(fb_info)) {
-               if (!lockless_register_fb)
-                       console_unlock();
-               return -ENODEV;
+               ret = -ENODEV;
+               goto unlock_console;
        }
+       ret = 0;
 
        fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
        unlock_fb_info(fb_info);
+unlock_console:
        if (!lockless_register_fb)
                console_unlock();
-       return 0;
+       else
+               atomic_dec(&ignore_console_lock_warning);
+       return ret;
 }
 
-static int do_unregister_framebuffer(struct fb_info *fb_info)
+static int unbind_console(struct fb_info *fb_info)
 {
        struct fb_event event;
-       int i, ret = 0;
+       int ret;
+       int i = fb_info->node;
 
-       i = fb_info->node;
        if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
                return -EINVAL;
 
@@ -1724,17 +1728,29 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
        unlock_fb_info(fb_info);
        console_unlock();
 
+       return ret;
+}
+
+static int __unlink_framebuffer(struct fb_info *fb_info);
+
+static int do_unregister_framebuffer(struct fb_info *fb_info)
+{
+       struct fb_event event;
+       int ret;
+
+       ret = unbind_console(fb_info);
+
        if (ret)
                return -EINVAL;
 
        pm_vt_switch_unregister(fb_info->dev);
 
-       unlink_framebuffer(fb_info);
+       __unlink_framebuffer(fb_info);
        if (fb_info->pixmap.addr &&
            (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
                kfree(fb_info->pixmap.addr);
        fb_destroy_modelist(&fb_info->modelist);
-       registered_fb[i] = NULL;
+       registered_fb[fb_info->node] = NULL;
        num_registered_fb--;
        fb_cleanup_device(fb_info);
        event.info = fb_info;
@@ -1747,7 +1763,7 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
        return 0;
 }
 
-int unlink_framebuffer(struct fb_info *fb_info)
+static int __unlink_framebuffer(struct fb_info *fb_info)
 {
        int i;
 
@@ -1759,6 +1775,20 @@ int unlink_framebuffer(struct fb_info *fb_info)
                device_destroy(fb_class, MKDEV(FB_MAJOR, i));
                fb_info->dev = NULL;
        }
+
+       return 0;
+}
+
+int unlink_framebuffer(struct fb_info *fb_info)
+{
+       int ret;
+
+       ret = __unlink_framebuffer(fb_info);
+       if (ret)
+               return ret;
+
+       unbind_console(fb_info);
+
        return 0;
 }
 EXPORT_SYMBOL(unlink_framebuffer);
index 2510fa728d77160326781219ec554ae50c99be4a..283d9307df21c2d9b46d609080f078e591943b65 100644 (file)
@@ -628,45 +628,47 @@ static int fb_try_mode(struct fb_var_screeninfo *var, struct fb_info *info,
 }
 
 /**
- *     fb_find_mode - finds a valid video mode
- *     @var: frame buffer user defined part of display
- *     @info: frame buffer info structure
- *     @mode_option: string video mode to find
- *     @db: video mode database
- *     @dbsize: size of @db
- *     @default_mode: default video mode to fall back to
- *     @default_bpp: default color depth in bits per pixel
+ * fb_find_mode - finds a valid video mode
+ * @var: frame buffer user defined part of display
+ * @info: frame buffer info structure
+ * @mode_option: string video mode to find
+ * @db: video mode database
+ * @dbsize: size of @db
+ * @default_mode: default video mode to fall back to
+ * @default_bpp: default color depth in bits per pixel
  *
- *     Finds a suitable video mode, starting with the specified mode
- *     in @mode_option with fallback to @default_mode.  If
- *     @default_mode fails, all modes in the video mode database will
- *     be tried.
+ * Finds a suitable video mode, starting with the specified mode
+ * in @mode_option with fallback to @default_mode.  If
+ * @default_mode fails, all modes in the video mode database will
+ * be tried.
  *
- *     Valid mode specifiers for @mode_option:
+ * Valid mode specifiers for @mode_option::
  *
- *     <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m] or
- *     <name>[-<bpp>][@<refresh>]
+ *     <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][p][m]
+ *
+ * or ::
  *
- *     with <xres>, <yres>, <bpp> and <refresh> decimal numbers and
- *     <name> a string.
+ *     <name>[-<bpp>][@<refresh>]
  *
- *      If 'M' is present after yres (and before refresh/bpp if present),
- *      the function will compute the timings using VESA(tm) Coordinated
- *      Video Timings (CVT).  If 'R' is present after 'M', will compute with
- *      reduced blanking (for flatpanels).  If 'i' is present, compute
- *      interlaced mode.  If 'm' is present, add margins equal to 1.8%
- *      of xres rounded down to 8 pixels, and 1.8% of yres. The char
- *      'i' and 'm' must be after 'M' and 'R'. Example:
+ * with <xres>, <yres>, <bpp> and <refresh> decimal numbers and
+ * <name> a string.
  *
- *      1024x768MR-8@60m - Reduced blank with margins at 60Hz.
+ * If 'M' is present after yres (and before refresh/bpp if present),
+ * the function will compute the timings using VESA(tm) Coordinated
+ * Video Timings (CVT).  If 'R' is present after 'M', will compute with
+ * reduced blanking (for flatpanels).  If 'i' or 'p' are present, compute
+ * interlaced or progressive mode.  If 'm' is present, add margins equal
+ * to 1.8% of xres rounded down to 8 pixels, and 1.8% of yres. The char
+ * 'i', 'p' and 'm' must be after 'M' and 'R'. Example::
  *
- *     NOTE: The passed struct @var is _not_ cleared!  This allows you
- *     to supply values for e.g. the grayscale and accel_flags fields.
+ *     1024x768MR-8@60m - Reduced blank with margins at 60Hz.
  *
- *     Returns zero for failure, 1 if using specified @mode_option,
- *     2 if using specified @mode_option with an ignored refresh rate,
- *     3 if default mode is used, 4 if fall back to any valid mode.
+ * NOTE: The passed struct @var is _not_ cleared!  This allows you
+ * to supply values for e.g. the grayscale and accel_flags fields.
  *
+ * Returns zero for failure, 1 if using specified @mode_option,
+ * 2 if using specified @mode_option with an ignored refresh rate,
+ * 3 if default mode is used, 4 if fall back to any valid mode.
  */
 
 int fb_find_mode(struct fb_var_screeninfo *var,
@@ -697,7 +699,8 @@ int fb_find_mode(struct fb_var_screeninfo *var,
                unsigned int namelen = strlen(name);
                int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
                unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0;
-               int yres_specified = 0, cvt = 0, rb = 0, interlace = 0;
+               int yres_specified = 0, cvt = 0, rb = 0;
+               int interlace_specified = 0, interlace = 0;
                int margins = 0;
                u32 best, diff, tdiff;
 
@@ -748,9 +751,17 @@ int fb_find_mode(struct fb_var_screeninfo *var,
                                if (!cvt)
                                        margins = 1;
                                break;
+                       case 'p':
+                               if (!cvt) {
+                                       interlace = 0;
+                                       interlace_specified = 1;
+                               }
+                               break;
                        case 'i':
-                               if (!cvt)
+                               if (!cvt) {
                                        interlace = 1;
+                                       interlace_specified = 1;
+                               }
                                break;
                        default:
                                goto done;
@@ -819,11 +830,21 @@ done:
                        if ((name_matches(db[i], name, namelen) ||
                             (res_specified && res_matches(db[i], xres, yres))) &&
                            !fb_try_mode(var, info, &db[i], bpp)) {
-                               if (refresh_specified && db[i].refresh == refresh)
-                                       return 1;
+                               const int db_interlace = (db[i].vmode &
+                                       FB_VMODE_INTERLACED ? 1 : 0);
+                               int score = abs(db[i].refresh - refresh);
+
+                               if (interlace_specified)
+                                       score += abs(db_interlace - interlace);
+
+                               if (!interlace_specified ||
+                                   db_interlace == interlace)
+                                       if (refresh_specified &&
+                                           db[i].refresh == refresh)
+                                               return 1;
 
-                               if (abs(db[i].refresh - refresh) < diff) {
-                                       diff = abs(db[i].refresh - refresh);
+                               if (score < diff) {
+                                       diff = score;
                                        best = i;
                                }
                        }
index c6f78d27947b9dae5f00b148c325198956910095..3946649b85c8908f4e9874b837ccdad274af8499 100644 (file)
@@ -9,16 +9,39 @@
 
 #include <linux/kernel.h>
 #include <linux/efi.h>
+#include <linux/efi-bgrt.h>
 #include <linux/errno.h>
 #include <linux/fb.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
+#include <linux/printk.h>
 #include <linux/screen_info.h>
 #include <video/vga.h>
 #include <asm/efi.h>
 #include <drm/drm_utils.h> /* For drm_get_panel_orientation_quirk */
 #include <drm/drm_connector.h>  /* For DRM_MODE_PANEL_ORIENTATION_* */
 
+struct bmp_file_header {
+       u16 id;
+       u32 file_size;
+       u32 reserved;
+       u32 bitmap_offset;
+} __packed;
+
+struct bmp_dib_header {
+       u32 dib_header_size;
+       s32 width;
+       s32 height;
+       u16 planes;
+       u16 bpp;
+       u32 compression;
+       u32 bitmap_size;
+       u32 horz_resolution;
+       u32 vert_resolution;
+       u32 colors_used;
+       u32 colors_important;
+} __packed;
+
 static bool request_mem_succeeded = false;
 static u64 mem_flags = EFI_MEMORY_WC | EFI_MEMORY_UC;
 
@@ -66,6 +89,164 @@ static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green,
        return 0;
 }
 
+/*
+ * If fbcon deffered console takeover is configured, the intent is for the
+ * framebuffer to show the boot graphics (e.g. vendor logo) until there is some
+ * (error) message to display. But the boot graphics may have been destroyed by
+ * e.g. option ROM output, detect this and restore the boot graphics.
+ */
+#if defined CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER && \
+    defined CONFIG_ACPI_BGRT
+static void efifb_copy_bmp(u8 *src, u32 *dst, int width, struct screen_info *si)
+{
+       u8 r, g, b;
+
+       while (width--) {
+               b = *src++;
+               g = *src++;
+               r = *src++;
+               *dst++ = (r << si->red_pos)   |
+                        (g << si->green_pos) |
+                        (b << si->blue_pos);
+       }
+}
+
+#ifdef CONFIG_X86
+/*
+ * On x86 some firmwares use a low non native resolution for the display when
+ * they have shown some text messages. While keeping the bgrt filled with info
+ * for the native resolution. If the bgrt image intended for the native
+ * resolution still fits, it will be displayed very close to the right edge of
+ * the display looking quite bad. This function checks for this.
+ */
+static bool efifb_bgrt_sanity_check(struct screen_info *si, u32 bmp_width)
+{
+       static const int default_resolutions[][2] = {
+               {  800,  600 },
+               { 1024,  768 },
+               { 1280, 1024 },
+       };
+       u32 i, right_margin;
+
+       for (i = 0; i < ARRAY_SIZE(default_resolutions); i++) {
+               if (default_resolutions[i][0] == si->lfb_width &&
+                   default_resolutions[i][1] == si->lfb_height)
+                       break;
+       }
+       /* If not a default resolution used for textmode, this should be fine */
+       if (i >= ARRAY_SIZE(default_resolutions))
+               return true;
+
+       /* If the right margin is 5 times smaller then the left one, reject */
+       right_margin = si->lfb_width - (bgrt_tab.image_offset_x + bmp_width);
+       if (right_margin < (bgrt_tab.image_offset_x / 5))
+               return false;
+
+       return true;
+}
+#else
+static bool efifb_bgrt_sanity_check(struct screen_info *si, u32 bmp_width)
+{
+       return true;
+}
+#endif
+
+static void efifb_show_boot_graphics(struct fb_info *info)
+{
+       u32 bmp_width, bmp_height, bmp_pitch, screen_pitch, dst_x, y, src_y;
+       struct screen_info *si = &screen_info;
+       struct bmp_file_header *file_header;
+       struct bmp_dib_header *dib_header;
+       void *bgrt_image = NULL;
+       u8 *dst = info->screen_base;
+
+       if (!bgrt_tab.image_address) {
+               pr_info("efifb: No BGRT, not showing boot graphics\n");
+               return;
+       }
+
+       /* Avoid flashing the logo if we're going to print std probe messages */
+       if (console_loglevel > CONSOLE_LOGLEVEL_QUIET)
+               return;
+
+       /* bgrt_tab.status is unreliable, so we don't check it */
+
+       if (si->lfb_depth != 32) {
+               pr_info("efifb: not 32 bits, not showing boot graphics\n");
+               return;
+       }
+
+       bgrt_image = memremap(bgrt_tab.image_address, bgrt_image_size,
+                             MEMREMAP_WB);
+       if (!bgrt_image) {
+               pr_warn("efifb: Ignoring BGRT: failed to map image memory\n");
+               return;
+       }
+
+       if (bgrt_image_size < (sizeof(*file_header) + sizeof(*dib_header)))
+               goto error;
+
+       file_header = bgrt_image;
+       if (file_header->id != 0x4d42 || file_header->reserved != 0)
+               goto error;
+
+       dib_header = bgrt_image + sizeof(*file_header);
+       if (dib_header->dib_header_size != 40 || dib_header->width < 0 ||
+           dib_header->planes != 1 || dib_header->bpp != 24 ||
+           dib_header->compression != 0)
+               goto error;
+
+       bmp_width = dib_header->width;
+       bmp_height = abs(dib_header->height);
+       bmp_pitch = round_up(3 * bmp_width, 4);
+       screen_pitch = si->lfb_linelength;
+
+       if ((file_header->bitmap_offset + bmp_pitch * bmp_height) >
+                               bgrt_image_size)
+               goto error;
+
+       if ((bgrt_tab.image_offset_x + bmp_width) > si->lfb_width ||
+           (bgrt_tab.image_offset_y + bmp_height) > si->lfb_height)
+               goto error;
+
+       if (!efifb_bgrt_sanity_check(si, bmp_width))
+               goto error;
+
+       pr_info("efifb: showing boot graphics\n");
+
+       for (y = 0; y < si->lfb_height; y++, dst += si->lfb_linelength) {
+               /* Only background? */
+               if (y < bgrt_tab.image_offset_y ||
+                   y >= (bgrt_tab.image_offset_y + bmp_height)) {
+                       memset(dst, 0, 4 * si->lfb_width);
+                       continue;
+               }
+
+               src_y = y - bgrt_tab.image_offset_y;
+               /* Positive header height means upside down row order */
+               if (dib_header->height > 0)
+                       src_y = (bmp_height - 1) - src_y;
+
+               memset(dst, 0, bgrt_tab.image_offset_x * 4);
+               dst_x = bgrt_tab.image_offset_x;
+               efifb_copy_bmp(bgrt_image + file_header->bitmap_offset +
+                                           src_y * bmp_pitch,
+                              (u32 *)dst + dst_x, bmp_width, si);
+               dst_x += bmp_width;
+               memset((u32 *)dst + dst_x, 0, (si->lfb_width - dst_x) * 4);
+       }
+
+       memunmap(bgrt_image);
+       return;
+
+error:
+       memunmap(bgrt_image);
+       pr_warn("efifb: Ignoring BGRT: unexpected or invalid BMP data\n");
+}
+#else
+static inline void efifb_show_boot_graphics(struct fb_info *info) {}
+#endif
+
 static void efifb_destroy(struct fb_info *info)
 {
        if (info->screen_base) {
@@ -311,6 +492,8 @@ static int efifb_probe(struct platform_device *dev)
                goto err_release_fb;
        }
 
+       efifb_show_boot_graphics(info);
+
        pr_info("efifb: framebuffer at 0x%lx, using %dk, total %dk\n",
               efifb_fix.smem_start, size_remap/1024, size_total/1024);
        pr_info("efifb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
index 1bfd13cbd4e3e0ef40a23a5f03404c3e54e7f08a..bc9eb8afc3137dbea13728a9d1bff9fc03bff016 100644 (file)
@@ -360,6 +360,10 @@ struct mfb_info {
  * @ad[]: Area Descriptors for each real AOI
  * @gamma: gamma color table
  * @cursor: hardware cursor data
+ * @blank_cursor: blank cursor for hiding cursor
+ * @next_cursor: scratch space to build load cursor
+ * @edid_data: EDID information buffer
+ * @has_edid: whether or not the EDID buffer is valid
  *
  * This data structure must be allocated with 32-byte alignment, so that the
  * internal fields can be aligned properly.
@@ -381,6 +385,8 @@ struct fsl_diu_data {
        __le16 cursor[MAX_CURS * MAX_CURS] __aligned(32);
        /* Blank cursor data -- used to hide the cursor */
        __le16 blank_cursor[MAX_CURS * MAX_CURS] __aligned(32);
+       /* Scratch cursor data -- used to build new cursor */
+       __le16 next_cursor[MAX_CURS * MAX_CURS] __aligned(32);
        uint8_t edid_data[EDID_LENGTH];
        bool has_edid;
 } __aligned(32);
@@ -1056,13 +1062,17 @@ static int fsl_diu_cursor(struct fb_info *info, struct fb_cursor *cursor)
         * FB_CUR_SETSHAPE - the cursor bitmask has changed
         */
        if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETIMAGE)) {
+               /*
+                * Determine the size of the cursor image data.  Normally,
+                * it's 8x16.
+                */
                unsigned int image_size =
-                       DIV_ROUND_UP(cursor->image.width, 8) * cursor->image.height;
+                       DIV_ROUND_UP(cursor->image.width, 8) *
+                       cursor->image.height;
                unsigned int image_words =
                        DIV_ROUND_UP(image_size, sizeof(uint32_t));
                unsigned int bg_idx = cursor->image.bg_color;
                unsigned int fg_idx = cursor->image.fg_color;
-               uint8_t buffer[image_size];
                uint32_t *image, *source, *mask;
                uint16_t fg, bg;
                unsigned int i;
@@ -1070,13 +1080,6 @@ static int fsl_diu_cursor(struct fb_info *info, struct fb_cursor *cursor)
                if (info->state != FBINFO_STATE_RUNNING)
                        return 0;
 
-               /*
-                * Determine the size of the cursor image data.  Normally,
-                * it's 8x16.
-                */
-               image_size = DIV_ROUND_UP(cursor->image.width, 8) *
-                       cursor->image.height;
-
                bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
                     ((info->cmap.green[bg_idx] & 0xf8) << 2) |
                     ((info->cmap.blue[bg_idx] & 0xf8) >> 3) |
@@ -1088,7 +1091,7 @@ static int fsl_diu_cursor(struct fb_info *info, struct fb_cursor *cursor)
                     1 << 15;
 
                /* Use 32-bit operations on the data to improve performance */
-               image = (uint32_t *)buffer;
+               image = (uint32_t *)data->next_cursor;
                source = (uint32_t *)cursor->image.data;
                mask = (uint32_t *)cursor->mask;
 
index 3b70044773b67566b6c7ebf516bc23dde166f95b..4377e344263878e0c907e89f8d70d43e23796744 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
+#include <linux/acpi.h>
 
 enum {
        FB_GET_WIDTH        = 0x00,
@@ -124,6 +125,7 @@ static int goldfish_fb_check_var(struct fb_var_screeninfo *var,
 static int goldfish_fb_set_par(struct fb_info *info)
 {
        struct goldfish_fb *fb = container_of(info, struct goldfish_fb, fb);
+
        if (fb->rotation != fb->fb.var.rotate) {
                info->fix.line_length = info->var.xres * 2;
                fb->rotation = fb->fb.var.rotate;
@@ -148,13 +150,14 @@ static int goldfish_fb_pan_display(struct fb_var_screeninfo *var,
        wait_event_timeout(fb->wait,
                        fb->base_update_count != base_update_count, HZ / 15);
        if (fb->base_update_count == base_update_count)
-               pr_err("goldfish_fb_pan_display: timeout waiting for base update\n");
+               pr_err("%s: timeout waiting for base update\n", __func__);
        return 0;
 }
 
 static int goldfish_fb_blank(int blank, struct fb_info *info)
 {
        struct goldfish_fb *fb = container_of(info, struct goldfish_fb, fb);
+
        switch (blank) {
        case FB_BLANK_NORMAL:
                writel(1, fb->reg_base + FB_SET_BLANK);
@@ -234,7 +237,7 @@ static int goldfish_fb_probe(struct platform_device *pdev)
        fb->fb.var.activate     = FB_ACTIVATE_NOW;
        fb->fb.var.height       = readl(fb->reg_base + FB_GET_PHYS_HEIGHT);
        fb->fb.var.width        = readl(fb->reg_base + FB_GET_PHYS_WIDTH);
-       fb->fb.var.pixclock     = 10000;
+       fb->fb.var.pixclock     = 0;
 
        fb->fb.var.red.offset = 11;
        fb->fb.var.red.length = 5;
@@ -301,6 +304,7 @@ static int goldfish_fb_remove(struct platform_device *pdev)
        dma_free_coherent(&pdev->dev, framesize, (void *)fb->fb.screen_base,
                                                fb->fb.fix.smem_start);
        iounmap(fb->reg_base);
+       kfree(fb);
        return 0;
 }
 
@@ -310,12 +314,19 @@ static const struct of_device_id goldfish_fb_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, goldfish_fb_of_match);
 
+static const struct acpi_device_id goldfish_fb_acpi_match[] = {
+       { "GFSH0004", 0 },
+       { },
+};
+MODULE_DEVICE_TABLE(acpi, goldfish_fb_acpi_match);
+
 static struct platform_driver goldfish_fb_driver = {
        .probe          = goldfish_fb_probe,
        .remove         = goldfish_fb_remove,
        .driver = {
                .name = "goldfish_fb",
                .of_match_table = goldfish_fb_of_match,
+               .acpi_match_table = ACPI_PTR(goldfish_fb_acpi_match),
        }
 };
 
index 7bc5f6056c77df7cd2293ffd5f4514080a6019b7..f6d7b04d6dffaf222c21277c7e0ecdcca5a2de35 100644 (file)
@@ -429,6 +429,7 @@ static int i740fb_decode_var(const struct fb_var_screeninfo *var,
                break;
        case 9 ... 15:
                bpp = 15;
+               /* fall through */
        case 16:
                if ((1000000 / var->pixclock) > DACSPEED16) {
                        dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 15/16bpp)\n",
index 9085e9525341e8c811e6e1432d4138d5194776a3..bb4fee52e501722c7353d2f81c364bdbc9fb84e3 100644 (file)
@@ -233,7 +233,7 @@ static int load_waveform(u8 *mem, size_t size, int m, int t,
 
        /* check temperature range table checksum */
        cksum_idx = sizeof(*wfm_hdr) + wfm_hdr->trc + 1;
-       if (cksum_idx > size)
+       if (cksum_idx >= size)
                return -EINVAL;
        cksum = calc_cksum(sizeof(*wfm_hdr), cksum_idx, mem);
        if (cksum != mem[cksum_idx]) {
@@ -245,7 +245,7 @@ static int load_waveform(u8 *mem, size_t size, int m, int t,
        /* check waveform mode table address checksum */
        wmta = get_unaligned_le32(wfm_hdr->wmta) & 0x00FFFFFF;
        cksum_idx = wmta + m*4 + 3;
-       if (cksum_idx > size)
+       if (cksum_idx >= size)
                return -EINVAL;
        cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem);
        if (cksum != mem[cksum_idx]) {
@@ -257,7 +257,7 @@ static int load_waveform(u8 *mem, size_t size, int m, int t,
        /* check waveform temperature table address checksum */
        tta = get_unaligned_le32(mem + wmta + m * 4) & 0x00FFFFFF;
        cksum_idx = tta + trn*4 + 3;
-       if (cksum_idx > size)
+       if (cksum_idx >= size)
                return -EINVAL;
        cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem);
        if (cksum != mem[cksum_idx]) {
@@ -270,7 +270,7 @@ static int load_waveform(u8 *mem, size_t size, int m, int t,
        metromem buffer. this does runlength decoding of the waveform */
        wfm_idx = get_unaligned_le32(mem + tta + trn * 4) & 0x00FFFFFF;
        owfm_idx = wfm_idx;
-       if (wfm_idx > size)
+       if (wfm_idx >= size)
                return -EINVAL;
        while (wfm_idx < size) {
                unsigned char rl;
@@ -292,7 +292,7 @@ static int load_waveform(u8 *mem, size_t size, int m, int t,
        }
 
        cksum_idx = wfm_idx;
-       if (cksum_idx > size)
+       if (cksum_idx >= size)
                return -EINVAL;
        cksum = calc_cksum(owfm_idx, cksum_idx, mem);
        if (cksum != mem[cksum_idx]) {
index 585f39efcff674715575221ce6a3a6ab43c214eb..1c75f4806ed3bda367b1666e98558d9f6d679f00 100644 (file)
@@ -958,7 +958,7 @@ int omapfb_register_client(struct omapfb_notifier_block *omapfb_nb,
 {
        int r;
 
-       if ((unsigned)omapfb_nb->plane_idx > OMAPFB_PLANE_NUM)
+       if ((unsigned)omapfb_nb->plane_idx >= OMAPFB_PLANE_NUM)
                return -EINVAL;
 
        if (!notifier_inited) {
index 602edfed09dfd85ab6de06a8d5d1214226b98bea..f54c3f56b64137039f8c60d91b1f0ec8036cbda4 100644 (file)
@@ -2,5 +2,5 @@
 obj-$(CONFIG_OMAP2_VRFB) += vrfb.o
 obj-y += dss/
 obj-y += displays/
-obj-$(CONFIG_FB_OMAP2) += omapfb.o
-omapfb-y := omapfb-main.o omapfb-sysfs.o omapfb-ioctl.o
+obj-$(CONFIG_FB_OMAP2) += omap2fb.o
+omap2fb-y := omapfb-main.o omapfb-sysfs.o omapfb-ioctl.o
index 3079a3df8c3756a46d528dc8a147508356aae8b0..47f0459e3551b3a493bd94e7ebb26e8ab6cfc622 100644 (file)
@@ -219,7 +219,7 @@ static int tpd_probe_of(struct platform_device *pdev)
 
 static int tpd_probe(struct platform_device *pdev)
 {
-       struct omap_dss_device *in, *dssdev;
+       struct omap_dss_device *dssdev;
        struct panel_drv_data *ddata;
        int r;
        struct gpio_desc *gpio;
@@ -238,25 +238,30 @@ static int tpd_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-
        gpio = devm_gpiod_get_index_optional(&pdev->dev, NULL, 0,
                GPIOD_OUT_LOW);
-       if (IS_ERR(gpio))
+       if (IS_ERR(gpio)) {
+               r = PTR_ERR(gpio);
                goto err_gpio;
+       }
 
        ddata->ct_cp_hpd_gpio = gpio;
 
        gpio = devm_gpiod_get_index_optional(&pdev->dev, NULL, 1,
                GPIOD_OUT_LOW);
-       if (IS_ERR(gpio))
+       if (IS_ERR(gpio)) {
+               r = PTR_ERR(gpio);
                goto err_gpio;
+       }
 
        ddata->ls_oe_gpio = gpio;
 
        gpio = devm_gpiod_get_index(&pdev->dev, NULL, 2,
                GPIOD_IN);
-       if (IS_ERR(gpio))
+       if (IS_ERR(gpio)) {
+               r = PTR_ERR(gpio);
                goto err_gpio;
+       }
 
        ddata->hpd_gpio = gpio;
 
@@ -268,8 +273,6 @@ static int tpd_probe(struct platform_device *pdev)
        dssdev->owner = THIS_MODULE;
        dssdev->port_num = 1;
 
-       in = ddata->in;
-
        r = omapdss_register_output(dssdev);
        if (r) {
                dev_err(&pdev->dev, "Failed to register output\n");
index fb605aefd9b1e5359d24e0e607911babe57ff831..a06d9c25765c544bc7efa8da382edecf5943a8e1 100644 (file)
@@ -1858,7 +1858,7 @@ static s32 pixinc(int pixels, u8 ps)
                return 1 - (-pixels + 1) * ps;
        else
                BUG();
-               return 0;
+       return 0;
 }
 
 static void calc_vrfb_rotation_offset(u8 rotation, bool mirror,
@@ -1905,6 +1905,7 @@ static void calc_vrfb_rotation_offset(u8 rotation, bool mirror,
                if (color_mode == OMAP_DSS_COLOR_YUV2 ||
                        color_mode == OMAP_DSS_COLOR_UYVY)
                        width = width >> 1;
+               /* fall through */
        case OMAP_DSS_ROT_90:
        case OMAP_DSS_ROT_270:
                *offset1 = 0;
@@ -1927,6 +1928,7 @@ static void calc_vrfb_rotation_offset(u8 rotation, bool mirror,
                if (color_mode == OMAP_DSS_COLOR_YUV2 ||
                        color_mode == OMAP_DSS_COLOR_UYVY)
                        width = width >> 1;
+               /* fall through */
        case OMAP_DSS_ROT_90 + 4:
        case OMAP_DSS_ROT_270 + 4:
                *offset1 = 0;
index 3e7887c53d7c2bdb0a34123d4c81319f3ff1893d..b8b5b4ac0e09cf2195212cda09e4b0f24f27cb5c 100644 (file)
@@ -893,6 +893,7 @@ int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
                                / (var->bits_per_pixel >> 2);
                        break;
                }
+               /* fall through */
        default:
                screen_width = fix->line_length / (var->bits_per_pixel >> 3);
                break;
index bd6c2f5f6095d585b486399dcb19da50fd3c0c7b..1dcf02e12af4f3ee676bd7be8e4f59b71f864c21 100644 (file)
@@ -233,8 +233,10 @@ static u32 to3264(u32 timing, int bpp, int is64)
        switch (bpp) {
        case 24:
                timing *= 3;
+               /* fall through */
        case 8:
                timing >>= 1;
+               /* fall through */
        case 16:
                timing >>= 1;
        case 32:
index 0955622a12270266fd7c82ee1b0ff3d5bf015f43..69cfb337c8577ac1ca8f3eede0eeba7e1ec10087 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/clk.h>
 #include <linux/fs.h>
 #include <linux/io.h>
+#include <linux/of.h>
 
 #include "pxa3xx-gcu.h"
 
@@ -703,11 +704,20 @@ static int pxa3xx_gcu_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id pxa3xx_gcu_of_match[] = {
+       { .compatible = "marvell,pxa300-gcu", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, pxa3xx_gcu_of_match);
+#endif
+
 static struct platform_driver pxa3xx_gcu_driver = {
        .probe    = pxa3xx_gcu_probe,
        .remove  = pxa3xx_gcu_remove,
        .driver  = {
                .name   = DRV_NAME,
+               .of_match_table = of_match_ptr(pxa3xx_gcu_of_match),
        },
 };
 
index 76722a59f55e34c83ec948d77c2c0df5c936fa16..bbed039617a4259b0517cb09e1f88676158ad8eb 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/freezer.h>
 #include <linux/console.h>
 #include <linux/of_graph.h>
+#include <linux/regulator/consumer.h>
 #include <video/of_display_timing.h>
 #include <video/videomode.h>
 
@@ -1423,6 +1424,21 @@ static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int on)
 
        if (fbi->lcd_power)
                fbi->lcd_power(on, &fbi->fb.var);
+
+       if (fbi->lcd_supply && fbi->lcd_supply_enabled != on) {
+               int ret;
+
+               if (on)
+                       ret = regulator_enable(fbi->lcd_supply);
+               else
+                       ret = regulator_disable(fbi->lcd_supply);
+
+               if (ret < 0)
+                       pr_warn("Unable to %s LCD supply regulator: %d\n",
+                               on ? "enable" : "disable", ret);
+               else
+                       fbi->lcd_supply_enabled = on;
+       }
 }
 
 static void pxafb_enable_controller(struct pxafb_info *fbi)
@@ -1799,19 +1815,17 @@ static struct pxafb_info *pxafb_init_fbinfo(struct device *dev,
        void *addr;
 
        /* Alloc the pxafb_info and pseudo_palette in one step */
-       fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL);
+       fbi = devm_kzalloc(dev, sizeof(struct pxafb_info) + sizeof(u32) * 16,
+                          GFP_KERNEL);
        if (!fbi)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
-       memset(fbi, 0, sizeof(struct pxafb_info));
        fbi->dev = dev;
        fbi->inf = inf;
 
-       fbi->clk = clk_get(dev, NULL);
-       if (IS_ERR(fbi->clk)) {
-               kfree(fbi);
-               return NULL;
-       }
+       fbi->clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(fbi->clk))
+               return ERR_CAST(fbi->clk);
 
        strcpy(fbi->fb.fix.id, PXA_NAME);
 
@@ -2128,8 +2142,9 @@ static int of_get_pxafb_display(struct device *dev, struct device_node *disp,
                return -EINVAL;
 
        ret = -ENOMEM;
-       info->modes = kmalloc_array(timings->num_timings,
-                                   sizeof(info->modes[0]), GFP_KERNEL);
+       info->modes = devm_kcalloc(dev, timings->num_timings,
+                                  sizeof(info->modes[0]),
+                                  GFP_KERNEL);
        if (!info->modes)
                goto out;
        info->num_modes = timings->num_timings;
@@ -2288,10 +2303,9 @@ static int pxafb_probe(struct platform_device *dev)
        }
 
        fbi = pxafb_init_fbinfo(&dev->dev, inf);
-       if (!fbi) {
-               /* only reason for pxafb_init_fbinfo to fail is kmalloc */
+       if (IS_ERR(fbi)) {
                dev_err(&dev->dev, "Failed to initialize framebuffer device\n");
-               ret = -ENOMEM;
+               ret = PTR_ERR(fbi);
                goto failed;
        }
 
@@ -2301,25 +2315,26 @@ static int pxafb_probe(struct platform_device *dev)
        fbi->backlight_power = inf->pxafb_backlight_power;
        fbi->lcd_power = inf->pxafb_lcd_power;
 
+       fbi->lcd_supply = devm_regulator_get_optional(&dev->dev, "lcd");
+       if (IS_ERR(fbi->lcd_supply)) {
+               if (PTR_ERR(fbi->lcd_supply) == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+
+               fbi->lcd_supply = NULL;
+       }
+
        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 failed_fbi;
-       }
-
-       r = request_mem_region(r->start, resource_size(r), dev->name);
-       if (r == NULL) {
-               dev_err(&dev->dev, "failed to request I/O memory\n");
-               ret = -EBUSY;
-               goto failed_fbi;
+               goto failed;
        }
 
-       fbi->mmio_base = ioremap(r->start, resource_size(r));
-       if (fbi->mmio_base == NULL) {
-               dev_err(&dev->dev, "failed to map I/O memory\n");
+       fbi->mmio_base = devm_ioremap_resource(&dev->dev, r);
+       if (IS_ERR(fbi->mmio_base)) {
+               dev_err(&dev->dev, "failed to get I/O memory\n");
                ret = -EBUSY;
-               goto failed_free_res;
+               goto failed;
        }
 
        fbi->dma_buff_size = PAGE_ALIGN(sizeof(struct pxafb_dma_buff));
@@ -2328,7 +2343,7 @@ static int pxafb_probe(struct platform_device *dev)
        if (fbi->dma_buff == NULL) {
                dev_err(&dev->dev, "failed to allocate memory for DMA\n");
                ret = -ENOMEM;
-               goto failed_free_io;
+               goto failed;
        }
 
        ret = pxafb_init_video_memory(fbi);
@@ -2345,7 +2360,7 @@ static int pxafb_probe(struct platform_device *dev)
                goto failed_free_mem;
        }
 
-       ret = request_irq(irq, pxafb_handle_irq, 0, "LCD", fbi);
+       ret = devm_request_irq(&dev->dev, irq, pxafb_handle_irq, 0, "LCD", fbi);
        if (ret) {
                dev_err(&dev->dev, "request_irq failed: %d\n", ret);
                ret = -EBUSY;
@@ -2355,7 +2370,7 @@ static int pxafb_probe(struct platform_device *dev)
        ret = pxafb_smart_init(fbi);
        if (ret) {
                dev_err(&dev->dev, "failed to initialize smartpanel\n");
-               goto failed_free_irq;
+               goto failed_free_mem;
        }
 
        /*
@@ -2365,13 +2380,13 @@ static int pxafb_probe(struct platform_device *dev)
        ret = pxafb_check_var(&fbi->fb.var, &fbi->fb);
        if (ret) {
                dev_err(&dev->dev, "failed to get suitable mode\n");
-               goto failed_free_irq;
+               goto failed_free_mem;
        }
 
        ret = pxafb_set_par(&fbi->fb);
        if (ret) {
                dev_err(&dev->dev, "Failed to set parameters\n");
-               goto failed_free_irq;
+               goto failed_free_mem;
        }
 
        platform_set_drvdata(dev, fbi);
@@ -2404,20 +2419,11 @@ static int pxafb_probe(struct platform_device *dev)
 failed_free_cmap:
        if (fbi->fb.cmap.len)
                fb_dealloc_cmap(&fbi->fb.cmap);
-failed_free_irq:
-       free_irq(irq, fbi);
 failed_free_mem:
        free_pages_exact(fbi->video_mem, fbi->video_mem_size);
 failed_free_dma:
        dma_free_coherent(&dev->dev, fbi->dma_buff_size,
                        fbi->dma_buff, fbi->dma_buff_phys);
-failed_free_io:
-       iounmap(fbi->mmio_base);
-failed_free_res:
-       release_mem_region(r->start, resource_size(r));
-failed_fbi:
-       clk_put(fbi->clk);
-       kfree(fbi);
 failed:
        return ret;
 }
@@ -2425,8 +2431,6 @@ failed:
 static int pxafb_remove(struct platform_device *dev)
 {
        struct pxafb_info *fbi = platform_get_drvdata(dev);
-       struct resource *r;
-       int irq;
        struct fb_info *info;
 
        if (!fbi)
@@ -2442,22 +2446,11 @@ static int pxafb_remove(struct platform_device *dev)
        if (fbi->fb.cmap.len)
                fb_dealloc_cmap(&fbi->fb.cmap);
 
-       irq = platform_get_irq(dev, 0);
-       free_irq(irq, fbi);
-
        free_pages_exact(fbi->video_mem, fbi->video_mem_size);
 
        dma_free_wc(&dev->dev, fbi->dma_buff_size, fbi->dma_buff,
                    fbi->dma_buff_phys);
 
-       iounmap(fbi->mmio_base);
-
-       r = platform_get_resource(dev, IORESOURCE_MEM, 0);
-       release_mem_region(r->start, resource_size(r));
-
-       clk_put(fbi->clk);
-       kfree(fbi);
-
        return 0;
 }
 
index 5dc414e26fc84b2e02ba490b911a215c4f2c3694..b641289c8a99133e13bff44be0a540f6261339fc 100644 (file)
@@ -165,6 +165,9 @@ struct pxafb_info {
        struct notifier_block   freq_policy;
 #endif
 
+       struct regulator *lcd_supply;
+       bool lcd_supply_enabled;
+
        void (*lcd_power)(int, struct fb_var_screeninfo *);
        void (*backlight_power)(int);
 
index a3c44ecf4523e8edb6d64c45a89f574924453d7f..9a9d748b07f2777da666a2ecfc8fcd35738f1505 100644 (file)
@@ -27,8 +27,8 @@
 #include <linux/platform_data/simplefb.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
-#include <linux/clk-provider.h>
 #include <linux/of.h>
+#include <linux/of_clk.h>
 #include <linux/of_platform.h>
 #include <linux/parser.h>
 #include <linux/regulator/consumer.h>
index dec1fed9880eaa75b6d3dcf3bb6bbb24bed454f4..fbbf26b170f7857b7b3772346b5255c192c5558c 100644 (file)
@@ -522,6 +522,7 @@ static int tdfxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
        case 32:
                var->transp.offset = 24;
                var->transp.length = 8;
+               /* fall through */
        case 24:
                var->red.offset = 16;
                var->green.offset = 8;
index 284706184b1b67bdd28395fc97213baf844b58c2..f4b74559060087e3e6a1fdf4af88dbcd5e6adaed 100644 (file)
@@ -777,9 +777,6 @@ static int get_nativex(struct tridentfb_par *par)
        case 3:
                x = 800; y = 600;
                break;
-       case 4:
-               x = 1400; y = 1050;
-               break;
        case 1:
        default:
                x = 640;  y = 480;
index f365d4862015321e9ad8f2efdc072877e505a409..afbd6101c78eb4c0b87a4c6a8a4cce47cf474176 100644 (file)
@@ -25,8 +25,8 @@
 #include <linux/fb.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
-#include <linux/prefetch.h>
 #include <linux/delay.h>
+#include <asm/unaligned.h>
 #include <video/udlfb.h>
 #include "edid.h"
 
@@ -72,6 +72,13 @@ static bool fb_defio = 1;  /* Detect mmap writes using page faults */
 static bool shadow = 1; /* Optionally disable shadow framebuffer */
 static int pixel_limit; /* Optionally force a pixel resolution limit */
 
+struct dlfb_deferred_free {
+       struct list_head list;
+       void *mem;
+};
+
+static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info, u32 new_len);
+
 /* dlfb keeps a list of urbs for efficient bulk transfers */
 static void dlfb_urb_completion(struct urb *urb);
 static struct urb *dlfb_get_urb(struct dlfb_data *dlfb);
@@ -367,9 +374,6 @@ static int dlfb_trim_hline(const u8 *bback, const u8 **bfront, int *width_bytes)
        int start = width;
        int end = width;
 
-       prefetch((void *) front);
-       prefetch((void *) back);
-
        for (j = 0; j < width; j++) {
                if (back[j] != front[j]) {
                        start = j;
@@ -423,7 +427,9 @@ static void dlfb_compress_hline(
        const uint16_t *const pixel_end,
        uint32_t *device_address_ptr,
        uint8_t **command_buffer_ptr,
-       const uint8_t *const cmd_buffer_end)
+       const uint8_t *const cmd_buffer_end,
+       unsigned long back_buffer_offset,
+       int *ident_ptr)
 {
        const uint16_t *pixel = *pixel_start_ptr;
        uint32_t dev_addr  = *device_address_ptr;
@@ -436,7 +442,13 @@ static void dlfb_compress_hline(
                const uint16_t *raw_pixel_start = NULL;
                const uint16_t *cmd_pixel_start, *cmd_pixel_end = NULL;
 
-               prefetchw((void *) cmd); /* pull in one cache line at least */
+               if (back_buffer_offset &&
+                   *pixel == *(u16 *)((u8 *)pixel + back_buffer_offset)) {
+                       pixel++;
+                       dev_addr += BPP;
+                       (*ident_ptr)++;
+                       continue;
+               }
 
                *cmd++ = 0xAF;
                *cmd++ = 0x6B;
@@ -450,29 +462,39 @@ static void dlfb_compress_hline(
                raw_pixels_count_byte = cmd++; /*  we'll know this later */
                raw_pixel_start = pixel;
 
-               cmd_pixel_end = pixel + min(MAX_CMD_PIXELS + 1,
-                       min((int)(pixel_end - pixel),
-                           (int)(cmd_buffer_end - cmd) / BPP));
+               cmd_pixel_end = pixel + min3(MAX_CMD_PIXELS + 1UL,
+                                       (unsigned long)(pixel_end - pixel),
+                                       (unsigned long)(cmd_buffer_end - 1 - cmd) / BPP);
 
-               prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * BPP);
+               if (back_buffer_offset) {
+                       /* note: the framebuffer may change under us, so we must test for underflow */
+                       while (cmd_pixel_end - 1 > pixel &&
+                              *(cmd_pixel_end - 1) == *(u16 *)((u8 *)(cmd_pixel_end - 1) + back_buffer_offset))
+                               cmd_pixel_end--;
+               }
 
                while (pixel < cmd_pixel_end) {
                        const uint16_t * const repeating_pixel = pixel;
+                       u16 pixel_value = *pixel;
 
-                       *cmd++ = *pixel >> 8;
-                       *cmd++ = *pixel;
+                       put_unaligned_be16(pixel_value, cmd);
+                       if (back_buffer_offset)
+                               *(u16 *)((u8 *)pixel + back_buffer_offset) = pixel_value;
+                       cmd += 2;
                        pixel++;
 
                        if (unlikely((pixel < cmd_pixel_end) &&
-                                    (*pixel == *repeating_pixel))) {
+                                    (*pixel == pixel_value))) {
                                /* go back and fill in raw pixel count */
                                *raw_pixels_count_byte = ((repeating_pixel -
                                                raw_pixel_start) + 1) & 0xFF;
 
-                               while ((pixel < cmd_pixel_end)
-                                      && (*pixel == *repeating_pixel)) {
+                               do {
+                                       if (back_buffer_offset)
+                                               *(u16 *)((u8 *)pixel + back_buffer_offset) = pixel_value;
                                        pixel++;
-                               }
+                               } while ((pixel < cmd_pixel_end) &&
+                                        (*pixel == pixel_value));
 
                                /* immediately after raw data is repeat byte */
                                *cmd++ = ((pixel - repeating_pixel) - 1) & 0xFF;
@@ -486,13 +508,16 @@ static void dlfb_compress_hline(
                if (pixel > raw_pixel_start) {
                        /* finalize last RAW span */
                        *raw_pixels_count_byte = (pixel-raw_pixel_start) & 0xFF;
+               } else {
+                       /* undo unused byte */
+                       cmd--;
                }
 
                *cmd_pixels_count_byte = (pixel - cmd_pixel_start) & 0xFF;
-               dev_addr += (pixel - cmd_pixel_start) * BPP;
+               dev_addr += (u8 *)pixel - (u8 *)cmd_pixel_start;
        }
 
-       if (cmd_buffer_end <= MIN_RLX_CMD_BYTES + cmd) {
+       if (cmd_buffer_end - MIN_RLX_CMD_BYTES <= cmd) {
                /* Fill leftover bytes with no-ops */
                if (cmd_buffer_end > cmd)
                        memset(cmd, 0xAF, cmd_buffer_end - cmd);
@@ -520,6 +545,7 @@ static int dlfb_render_hline(struct dlfb_data *dlfb, struct urb **urb_ptr,
        struct urb *urb = *urb_ptr;
        u8 *cmd = *urb_buf_ptr;
        u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length;
+       unsigned long back_buffer_offset = 0;
 
        line_start = (u8 *) (front + byte_offset);
        next_pixel = line_start;
@@ -530,6 +556,8 @@ static int dlfb_render_hline(struct dlfb_data *dlfb, struct urb **urb_ptr,
                const u8 *back_start = (u8 *) (dlfb->backing_buffer
                                                + byte_offset);
 
+               back_buffer_offset = (unsigned long)back_start - (unsigned long)line_start;
+
                *ident_ptr += dlfb_trim_hline(back_start, &next_pixel,
                        &byte_width);
 
@@ -538,16 +566,14 @@ static int dlfb_render_hline(struct dlfb_data *dlfb, struct urb **urb_ptr,
                dev_addr += offset;
                back_start += offset;
                line_start += offset;
-
-               memcpy((char *)back_start, (char *) line_start,
-                      byte_width);
        }
 
        while (next_pixel < line_end) {
 
                dlfb_compress_hline((const uint16_t **) &next_pixel,
                             (const uint16_t *) line_end, &dev_addr,
-                       (u8 **) &cmd, (u8 *) cmd_end);
+                       (u8 **) &cmd, (u8 *) cmd_end, back_buffer_offset,
+                       ident_ptr);
 
                if (cmd >= cmd_end) {
                        int len = cmd - (u8 *) urb->transfer_buffer;
@@ -610,8 +636,11 @@ static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y,
        }
 
        if (cmd > (char *) urb->transfer_buffer) {
+               int len;
+               if (cmd < (char *) urb->transfer_buffer + urb->transfer_buffer_length)
+                       *cmd++ = 0xAF;
                /* Send partial buffer remaining before exiting */
-               int len = cmd - (char *) urb->transfer_buffer;
+               len = cmd - (char *) urb->transfer_buffer;
                ret = dlfb_submit_urb(dlfb, urb, len);
                bytes_sent += len;
        } else
@@ -735,8 +764,11 @@ static void dlfb_dpy_deferred_io(struct fb_info *info,
        }
 
        if (cmd > (char *) urb->transfer_buffer) {
+               int len;
+               if (cmd < (char *) urb->transfer_buffer + urb->transfer_buffer_length)
+                       *cmd++ = 0xAF;
                /* Send partial buffer remaining before exiting */
-               int len = cmd - (char *) urb->transfer_buffer;
+               len = cmd - (char *) urb->transfer_buffer;
                dlfb_submit_urb(dlfb, urb, len);
                bytes_sent += len;
        } else
@@ -917,19 +949,17 @@ static void dlfb_free(struct kref *kref)
 {
        struct dlfb_data *dlfb = container_of(kref, struct dlfb_data, kref);
 
+       while (!list_empty(&dlfb->deferred_free)) {
+               struct dlfb_deferred_free *d = list_entry(dlfb->deferred_free.next, struct dlfb_deferred_free, list);
+               list_del(&d->list);
+               vfree(d->mem);
+               kfree(d);
+       }
        vfree(dlfb->backing_buffer);
        kfree(dlfb->edid);
        kfree(dlfb);
 }
 
-static void dlfb_release_urb_work(struct work_struct *work)
-{
-       struct urb_node *unode = container_of(work, struct urb_node,
-                                             release_urb_work.work);
-
-       up(&unode->dlfb->urbs.limit_sem);
-}
-
 static void dlfb_free_framebuffer(struct dlfb_data *dlfb)
 {
        struct fb_info *info = dlfb->info;
@@ -1018,10 +1048,6 @@ static int dlfb_ops_check_var(struct fb_var_screeninfo *var,
        struct fb_videomode mode;
        struct dlfb_data *dlfb = info->par;
 
-       /* TODO: support dynamically changing framebuffer size */
-       if ((var->xres * var->yres * 2) > info->fix.smem_len)
-               return -EINVAL;
-
        /* set device-specific elements of var unrelated to mode */
        dlfb_var_color_format(var);
 
@@ -1039,22 +1065,42 @@ static int dlfb_ops_set_par(struct fb_info *info)
        int result;
        u16 *pix_framebuffer;
        int i;
+       struct fb_var_screeninfo fvs;
+       u32 line_length = info->var.xres * (info->var.bits_per_pixel / 8);
+
+       /* clear the activate field because it causes spurious miscompares */
+       fvs = info->var;
+       fvs.activate = 0;
+       fvs.vmode &= ~FB_VMODE_SMOOTH_XPAN;
+
+       if (!memcmp(&dlfb->current_mode, &fvs, sizeof(struct fb_var_screeninfo)))
+               return 0;
+
+       result = dlfb_realloc_framebuffer(dlfb, info, info->var.yres * line_length);
+       if (result)
+               return result;
 
        result = dlfb_set_video_mode(dlfb, &info->var);
 
-       if ((result == 0) && (dlfb->fb_count == 0)) {
+       if (result)
+               return result;
+
+       dlfb->current_mode = fvs;
+       info->fix.line_length = line_length;
+
+       if (dlfb->fb_count == 0) {
 
                /* paint greenscreen */
 
                pix_framebuffer = (u16 *) info->screen_base;
                for (i = 0; i < info->fix.smem_len / 2; i++)
                        pix_framebuffer[i] = 0x37e6;
-
-               dlfb_handle_damage(dlfb, 0, 0, info->var.xres, info->var.yres,
-                                  info->screen_base);
        }
 
-       return result;
+       dlfb_handle_damage(dlfb, 0, 0, info->var.xres, info->var.yres,
+                          info->screen_base);
+
+       return 0;
 }
 
 /* To fonzi the jukebox (e.g. make blanking changes take effect) */
@@ -1129,21 +1175,29 @@ static struct fb_ops dlfb_ops = {
 };
 
 
+static void dlfb_deferred_vfree(struct dlfb_data *dlfb, void *mem)
+{
+       struct dlfb_deferred_free *d = kmalloc(sizeof(struct dlfb_deferred_free), GFP_KERNEL);
+       if (!d)
+               return;
+       d->mem = mem;
+       list_add(&d->list, &dlfb->deferred_free);
+}
+
 /*
  * Assumes &info->lock held by caller
  * Assumes no active clients have framebuffer open
  */
-static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info)
+static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info, u32 new_len)
 {
-       int old_len = info->fix.smem_len;
-       int new_len;
-       unsigned char *old_fb = info->screen_base;
+       u32 old_len = info->fix.smem_len;
+       const void *old_fb = (const void __force *)info->screen_base;
        unsigned char *new_fb;
        unsigned char *new_back = NULL;
 
-       new_len = info->fix.line_length * info->var.yres;
+       new_len = PAGE_ALIGN(new_len);
 
-       if (PAGE_ALIGN(new_len) > old_len) {
+       if (new_len > old_len) {
                /*
                 * Alloc system memory for virtual framebuffer
                 */
@@ -1152,14 +1206,15 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info
                        dev_err(info->dev, "Virtual framebuffer alloc failed\n");
                        return -ENOMEM;
                }
+               memset(new_fb, 0xff, new_len);
 
                if (info->screen_base) {
                        memcpy(new_fb, old_fb, old_len);
-                       vfree(info->screen_base);
+                       dlfb_deferred_vfree(dlfb, (void __force *)info->screen_base);
                }
 
-               info->screen_base = new_fb;
-               info->fix.smem_len = PAGE_ALIGN(new_len);
+               info->screen_base = (char __iomem *)new_fb;
+               info->fix.smem_len = new_len;
                info->fix.smem_start = (unsigned long) new_fb;
                info->flags = udlfb_info_flags;
 
@@ -1175,7 +1230,7 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info
                        dev_info(info->dev,
                                 "No shadow/backing buffer allocated\n");
                else {
-                       vfree(dlfb->backing_buffer);
+                       dlfb_deferred_vfree(dlfb, dlfb->backing_buffer);
                        dlfb->backing_buffer = new_back;
                }
        }
@@ -1327,11 +1382,6 @@ static int dlfb_setup_modes(struct dlfb_data *dlfb,
                 * with mode size info, we can now alloc our framebuffer.
                 */
                memcpy(&info->fix, &dlfb_fix, sizeof(dlfb_fix));
-               info->fix.line_length = info->var.xres *
-                       (info->var.bits_per_pixel / 8);
-
-               result = dlfb_realloc_framebuffer(dlfb, info);
-
        } else
                result = -EINVAL;
 
@@ -1419,7 +1469,10 @@ static ssize_t edid_store(
        if (!dlfb->edid || memcmp(src, dlfb->edid, src_size))
                return -EINVAL;
 
-       dlfb_ops_set_par(fb_info);
+       ret = dlfb_ops_set_par(fb_info);
+       if (ret)
+               return ret;
+
        return src_size;
 }
 
@@ -1579,6 +1632,7 @@ static int dlfb_usb_probe(struct usb_interface *intf,
        }
 
        kref_init(&dlfb->kref); /* matching kref_put in usb .disconnect fn */
+       INIT_LIST_HEAD(&dlfb->deferred_free);
 
        dlfb->udev = usbdev;
        usb_set_intfdata(intf, dlfb);
@@ -1649,7 +1703,8 @@ static void dlfb_init_framebuffer_work(struct work_struct *work)
        dlfb->info = info;
        info->par = dlfb;
        info->pseudo_palette = dlfb->pseudo_palette;
-       info->fbops = &dlfb_ops;
+       dlfb->ops = dlfb_ops;
+       info->fbops = &dlfb->ops;
 
        retval = fb_alloc_cmap(&info->cmap, 256, 0);
        if (retval < 0) {
@@ -1675,7 +1730,9 @@ static void dlfb_init_framebuffer_work(struct work_struct *work)
        dlfb_select_std_channel(dlfb);
 
        dlfb_ops_check_var(&info->var, info);
-       dlfb_ops_set_par(info);
+       retval = dlfb_ops_set_par(info);
+       if (retval)
+               goto error;
 
        retval = register_framebuffer(info);
        if (retval < 0) {
@@ -1789,14 +1846,7 @@ static void dlfb_urb_completion(struct urb *urb)
        dlfb->urbs.available++;
        spin_unlock_irqrestore(&dlfb->urbs.lock, flags);
 
-       /*
-        * When using fb_defio, we deadlock if up() is called
-        * while another is waiting. So queue to another process.
-        */
-       if (fb_defio)
-               schedule_delayed_work(&unode->release_urb_work, 0);
-       else
-               up(&dlfb->urbs.limit_sem);
+       up(&dlfb->urbs.limit_sem);
 }
 
 static void dlfb_free_urb_list(struct dlfb_data *dlfb)
@@ -1805,23 +1855,17 @@ static void dlfb_free_urb_list(struct dlfb_data *dlfb)
        struct list_head *node;
        struct urb_node *unode;
        struct urb *urb;
-       int ret;
-       unsigned long flags;
 
        /* keep waiting and freeing, until we've got 'em all */
        while (count--) {
+               down(&dlfb->urbs.limit_sem);
 
-               /* Getting interrupted means a leak, but ok at disconnect */
-               ret = down_interruptible(&dlfb->urbs.limit_sem);
-               if (ret)
-                       break;
-
-               spin_lock_irqsave(&dlfb->urbs.lock, flags);
+               spin_lock_irq(&dlfb->urbs.lock);
 
                node = dlfb->urbs.list.next; /* have reserved one with sem */
                list_del_init(node);
 
-               spin_unlock_irqrestore(&dlfb->urbs.lock, flags);
+               spin_unlock_irq(&dlfb->urbs.lock);
 
                unode = list_entry(node, struct urb_node, entry);
                urb = unode->urb;
@@ -1838,25 +1882,27 @@ static void dlfb_free_urb_list(struct dlfb_data *dlfb)
 
 static int dlfb_alloc_urb_list(struct dlfb_data *dlfb, int count, size_t size)
 {
-       int i = 0;
        struct urb *urb;
        struct urb_node *unode;
        char *buf;
+       size_t wanted_size = count * size;
 
        spin_lock_init(&dlfb->urbs.lock);
 
+retry:
        dlfb->urbs.size = size;
        INIT_LIST_HEAD(&dlfb->urbs.list);
 
-       while (i < count) {
+       sema_init(&dlfb->urbs.limit_sem, 0);
+       dlfb->urbs.count = 0;
+       dlfb->urbs.available = 0;
+
+       while (dlfb->urbs.count * size < wanted_size) {
                unode = kzalloc(sizeof(*unode), GFP_KERNEL);
                if (!unode)
                        break;
                unode->dlfb = dlfb;
 
-               INIT_DELAYED_WORK(&unode->release_urb_work,
-                         dlfb_release_urb_work);
-
                urb = usb_alloc_urb(0, GFP_KERNEL);
                if (!urb) {
                        kfree(unode);
@@ -1864,11 +1910,16 @@ static int dlfb_alloc_urb_list(struct dlfb_data *dlfb, int count, size_t size)
                }
                unode->urb = urb;
 
-               buf = usb_alloc_coherent(dlfb->udev, MAX_TRANSFER, GFP_KERNEL,
+               buf = usb_alloc_coherent(dlfb->udev, size, GFP_KERNEL,
                                         &urb->transfer_dma);
                if (!buf) {
                        kfree(unode);
                        usb_free_urb(urb);
+                       if (size > PAGE_SIZE) {
+                               size /= 2;
+                               dlfb_free_urb_list(dlfb);
+                               goto retry;
+                       }
                        break;
                }
 
@@ -1879,14 +1930,12 @@ static int dlfb_alloc_urb_list(struct dlfb_data *dlfb, int count, size_t size)
 
                list_add_tail(&unode->entry, &dlfb->urbs.list);
 
-               i++;
+               up(&dlfb->urbs.limit_sem);
+               dlfb->urbs.count++;
+               dlfb->urbs.available++;
        }
 
-       sema_init(&dlfb->urbs.limit_sem, i);
-       dlfb->urbs.count = i;
-       dlfb->urbs.available = i;
-
-       return i;
+       return dlfb->urbs.count;
 }
 
 static struct urb *dlfb_get_urb(struct dlfb_data *dlfb)
@@ -1894,7 +1943,6 @@ static struct urb *dlfb_get_urb(struct dlfb_data *dlfb)
        int ret;
        struct list_head *entry;
        struct urb_node *unode;
-       unsigned long flags;
 
        /* Wait for an in-flight buffer to complete and get re-queued */
        ret = down_timeout(&dlfb->urbs.limit_sem, GET_URB_TIMEOUT);
@@ -1906,14 +1954,14 @@ static struct urb *dlfb_get_urb(struct dlfb_data *dlfb)
                return NULL;
        }
 
-       spin_lock_irqsave(&dlfb->urbs.lock, flags);
+       spin_lock_irq(&dlfb->urbs.lock);
 
        BUG_ON(list_empty(&dlfb->urbs.list)); /* reserved one with limit_sem */
        entry = dlfb->urbs.list.next;
        list_del_init(entry);
        dlfb->urbs.available--;
 
-       spin_unlock_irqrestore(&dlfb->urbs.lock, flags);
+       spin_unlock_irq(&dlfb->urbs.lock);
 
        unode = list_entry(entry, struct urb_node, entry);
        return unode->urb;
index 5d21ff436ec80a313dc9133a22b1db08ab7006ae..b9305d73a1e5ada2d74d4dda8cde74b6c25a46e6 100644 (file)
@@ -758,6 +758,7 @@ static void set_lcd_output_path(int set_iga, int output_interface)
                    viaparinfo->chip_info->gfx_chip_name))
                        viafb_write_reg_mask(CR97, VIACR, 0x84,
                                       BIT7 + BIT2 + BIT1 + BIT0);
+               /* fall through */
        case INTERFACE_DVP0:
        case INTERFACE_DVP1:
        case INTERFACE_DFP_HIGH:
index d2f785068ef4bb97fbc7228a684eae00d0688280..7bb7e90b8f006f28548da5ed6b4944ee0f9131e6 100644 (file)
@@ -19,6 +19,7 @@
  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#include <linux/compiler.h>
 #include <linux/module.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
@@ -1468,7 +1469,7 @@ static const struct file_operations viafb_vt1636_proc_fops = {
 
 #endif /* CONFIG_FB_VIA_DIRECT_PROCFS */
 
-static int viafb_sup_odev_proc_show(struct seq_file *m, void *v)
+static int __maybe_unused viafb_sup_odev_proc_show(struct seq_file *m, void *v)
 {
        via_odev_to_seq(m, supported_odev_map[
                viaparinfo->shared->chip_info.gfx_chip_name]);
index 3988c0914322134cc1de978d3aedca96475b64ba..d1c1f6283729623d86ebea846a7e506653f997c0 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/balloon_compaction.h>
-#include <linux/oom.h>
 #include <linux/wait.h>
 #include <linux/mm.h>
 #include <linux/mount.h>
  */
 #define VIRTIO_BALLOON_PAGES_PER_PAGE (unsigned)(PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT)
 #define VIRTIO_BALLOON_ARRAY_PFNS_MAX 256
-#define OOM_VBALLOON_DEFAULT_PAGES 256
 #define VIRTBALLOON_OOM_NOTIFY_PRIORITY 80
 
-static int oom_pages = OOM_VBALLOON_DEFAULT_PAGES;
-module_param(oom_pages, int, S_IRUSR | S_IWUSR);
-MODULE_PARM_DESC(oom_pages, "pages to free on OOM");
-
 #ifdef CONFIG_BALLOON_COMPACTION
 static struct vfsmount *balloon_mnt;
 #endif
@@ -86,8 +80,8 @@ struct virtio_balloon {
        /* Memory statistics */
        struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR];
 
-       /* To register callback in oom notifier call chain */
-       struct notifier_block nb;
+       /* To register a shrinker to shrink memory upon memory pressure */
+       struct shrinker shrinker;
 };
 
 static struct virtio_device_id id_table[] = {
@@ -365,38 +359,6 @@ static void update_balloon_size(struct virtio_balloon *vb)
                      &actual);
 }
 
-/*
- * virtballoon_oom_notify - release pages when system is under severe
- *                         memory pressure (called from out_of_memory())
- * @self : notifier block struct
- * @dummy: not used
- * @parm : returned - number of freed pages
- *
- * The balancing of memory by use of the virtio balloon should not cause
- * the termination of processes while there are pages in the balloon.
- * If virtio balloon manages to release some memory, it will make the
- * system return and retry the allocation that forced the OOM killer
- * to run.
- */
-static int virtballoon_oom_notify(struct notifier_block *self,
-                                 unsigned long dummy, void *parm)
-{
-       struct virtio_balloon *vb;
-       unsigned long *freed;
-       unsigned num_freed_pages;
-
-       vb = container_of(self, struct virtio_balloon, nb);
-       if (!virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM))
-               return NOTIFY_OK;
-
-       freed = parm;
-       num_freed_pages = leak_balloon(vb, oom_pages);
-       update_balloon_size(vb);
-       *freed += num_freed_pages;
-
-       return NOTIFY_OK;
-}
-
 static void update_balloon_stats_func(struct work_struct *work)
 {
        struct virtio_balloon *vb;
@@ -455,9 +417,13 @@ static int init_vqs(struct virtio_balloon *vb)
                num_stats = update_balloon_stats(vb);
 
                sg_init_one(&sg, vb->stats, sizeof(vb->stats[0]) * num_stats);
-               if (virtqueue_add_outbuf(vb->stats_vq, &sg, 1, vb, GFP_KERNEL)
-                   < 0)
-                       BUG();
+               err = virtqueue_add_outbuf(vb->stats_vq, &sg, 1, vb,
+                                          GFP_KERNEL);
+               if (err) {
+                       dev_warn(&vb->vdev->dev, "%s: add stat_vq failed\n",
+                                __func__);
+                       return err;
+               }
                virtqueue_kick(vb->stats_vq);
        }
        return 0;
@@ -546,6 +512,52 @@ static struct file_system_type balloon_fs = {
 
 #endif /* CONFIG_BALLOON_COMPACTION */
 
+static unsigned long virtio_balloon_shrinker_scan(struct shrinker *shrinker,
+                                                 struct shrink_control *sc)
+{
+       unsigned long pages_to_free, pages_freed = 0;
+       struct virtio_balloon *vb = container_of(shrinker,
+                                       struct virtio_balloon, shrinker);
+
+       pages_to_free = sc->nr_to_scan * VIRTIO_BALLOON_PAGES_PER_PAGE;
+
+       /*
+        * One invocation of leak_balloon can deflate at most
+        * VIRTIO_BALLOON_ARRAY_PFNS_MAX balloon pages, so we call it
+        * multiple times to deflate pages till reaching pages_to_free.
+        */
+       while (vb->num_pages && pages_to_free) {
+               pages_to_free -= pages_freed;
+               pages_freed += leak_balloon(vb, pages_to_free);
+       }
+       update_balloon_size(vb);
+
+       return pages_freed / VIRTIO_BALLOON_PAGES_PER_PAGE;
+}
+
+static unsigned long virtio_balloon_shrinker_count(struct shrinker *shrinker,
+                                                  struct shrink_control *sc)
+{
+       struct virtio_balloon *vb = container_of(shrinker,
+                                       struct virtio_balloon, shrinker);
+
+       return vb->num_pages / VIRTIO_BALLOON_PAGES_PER_PAGE;
+}
+
+static void virtio_balloon_unregister_shrinker(struct virtio_balloon *vb)
+{
+       unregister_shrinker(&vb->shrinker);
+}
+
+static int virtio_balloon_register_shrinker(struct virtio_balloon *vb)
+{
+       vb->shrinker.scan_objects = virtio_balloon_shrinker_scan;
+       vb->shrinker.count_objects = virtio_balloon_shrinker_count;
+       vb->shrinker.seeks = DEFAULT_SEEKS;
+
+       return register_shrinker(&vb->shrinker);
+}
+
 static int virtballoon_probe(struct virtio_device *vdev)
 {
        struct virtio_balloon *vb;
@@ -557,7 +569,7 @@ static int virtballoon_probe(struct virtio_device *vdev)
                return -EINVAL;
        }
 
-       vdev->priv = vb = kmalloc(sizeof(*vb), GFP_KERNEL);
+       vdev->priv = vb = kzalloc(sizeof(*vb), GFP_KERNEL);
        if (!vb) {
                err = -ENOMEM;
                goto out;
@@ -566,8 +578,6 @@ static int virtballoon_probe(struct virtio_device *vdev)
        INIT_WORK(&vb->update_balloon_stats_work, update_balloon_stats_func);
        INIT_WORK(&vb->update_balloon_size_work, update_balloon_size_func);
        spin_lock_init(&vb->stop_update_lock);
-       vb->stop_update = false;
-       vb->num_pages = 0;
        mutex_init(&vb->balloon_lock);
        init_waitqueue_head(&vb->acked);
        vb->vdev = vdev;
@@ -578,17 +588,10 @@ static int virtballoon_probe(struct virtio_device *vdev)
        if (err)
                goto out_free_vb;
 
-       vb->nb.notifier_call = virtballoon_oom_notify;
-       vb->nb.priority = VIRTBALLOON_OOM_NOTIFY_PRIORITY;
-       err = register_oom_notifier(&vb->nb);
-       if (err < 0)
-               goto out_del_vqs;
-
 #ifdef CONFIG_BALLOON_COMPACTION
        balloon_mnt = kern_mount(&balloon_fs);
        if (IS_ERR(balloon_mnt)) {
                err = PTR_ERR(balloon_mnt);
-               unregister_oom_notifier(&vb->nb);
                goto out_del_vqs;
        }
 
@@ -597,13 +600,19 @@ static int virtballoon_probe(struct virtio_device *vdev)
        if (IS_ERR(vb->vb_dev_info.inode)) {
                err = PTR_ERR(vb->vb_dev_info.inode);
                kern_unmount(balloon_mnt);
-               unregister_oom_notifier(&vb->nb);
-               vb->vb_dev_info.inode = NULL;
                goto out_del_vqs;
        }
        vb->vb_dev_info.inode->i_mapping->a_ops = &balloon_aops;
 #endif
-
+       /*
+        * We continue to use VIRTIO_BALLOON_F_DEFLATE_ON_OOM to decide if a
+        * shrinker needs to be registered to relieve memory pressure.
+        */
+       if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM)) {
+               err = virtio_balloon_register_shrinker(vb);
+               if (err)
+                       goto out_del_vqs;
+       }
        virtio_device_ready(vdev);
 
        if (towards_target(vb))
@@ -635,8 +644,8 @@ static void virtballoon_remove(struct virtio_device *vdev)
 {
        struct virtio_balloon *vb = vdev->priv;
 
-       unregister_oom_notifier(&vb->nb);
-
+       if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM))
+               virtio_balloon_unregister_shrinker(vb);
        spin_lock_irq(&vb->stop_update_lock);
        vb->stop_update = true;
        spin_unlock_irq(&vb->stop_update_lock);
index 67763d3c7abfa7ceb559351798f53bb3a3584401..4cd9ea5c75be728b88a45df1d3d199c3d7801ab6 100644 (file)
@@ -397,9 +397,23 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
        /* Activate the queue */
        writel(virtqueue_get_vring_size(vq), vm_dev->base + VIRTIO_MMIO_QUEUE_NUM);
        if (vm_dev->version == 1) {
+               u64 q_pfn = virtqueue_get_desc_addr(vq) >> PAGE_SHIFT;
+
+               /*
+                * virtio-mmio v1 uses a 32bit QUEUE PFN. If we have something
+                * that doesn't fit in 32bit, fail the setup rather than
+                * pretending to be successful.
+                */
+               if (q_pfn >> 32) {
+                       dev_err(&vdev->dev,
+                               "platform bug: legacy virtio-mmio must not be used with RAM above 0x%llxGB\n",
+                               0x1ULL << (32 + PAGE_SHIFT - 30));
+                       err = -E2BIG;
+                       goto error_bad_pfn;
+               }
+
                writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_QUEUE_ALIGN);
-               writel(virtqueue_get_desc_addr(vq) >> PAGE_SHIFT,
-                               vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
+               writel(q_pfn, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
        } else {
                u64 addr;
 
@@ -430,6 +444,8 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
 
        return vq;
 
+error_bad_pfn:
+       vring_del_virtqueue(vq);
 error_new_virtqueue:
        if (vm_dev->version == 1) {
                writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
index 2780886e8ba3d393ba4847366983c2ab56a7ed3e..de062fb201bc2a4316910419d0495fbb2d0f9601 100644 (file)
@@ -122,6 +122,7 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
        struct virtqueue *vq;
        u16 num;
        int err;
+       u64 q_pfn;
 
        /* Select the queue we're interested in */
        iowrite16(index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL);
@@ -141,9 +142,17 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
        if (!vq)
                return ERR_PTR(-ENOMEM);
 
+       q_pfn = virtqueue_get_desc_addr(vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT;
+       if (q_pfn >> 32) {
+               dev_err(&vp_dev->pci_dev->dev,
+                       "platform bug: legacy virtio-mmio must not be used with RAM above 0x%llxGB\n",
+                       0x1ULL << (32 + PAGE_SHIFT - 30));
+               err = -E2BIG;
+               goto out_del_vq;
+       }
+
        /* activate the queue */
-       iowrite32(virtqueue_get_desc_addr(vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT,
-                 vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN);
+       iowrite32(q_pfn, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN);
 
        vq->priv = (void __force *)vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY;
 
@@ -160,6 +169,7 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
 
 out_deactivate:
        iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN);
+out_del_vq:
        vring_del_virtqueue(vq);
        return ERR_PTR(err);
 }
index 7931231d8e80bdf1b75da7627a0b4cabef3cc0e8..e22fdeddada182131207b51e239e5254c8972432 100644 (file)
@@ -100,18 +100,6 @@ config W1_SLAVE_DS2438
          Say Y here if you want to use a 1-wire
          DS2438 Smart Battery Monitor device support
 
-config W1_SLAVE_DS2760
-       tristate "Dallas 2760 battery monitor chip (HP iPAQ & others)"
-       help
-         If you enable this you will have the DS2760 battery monitor
-         chip support.
-
-         The battery monitor chip is used in many batteries/devices
-         as the one who is responsible for charging/discharging/monitoring
-         Li+ batteries.
-
-         If you are unsure, say N.
-
 config W1_SLAVE_DS2780
        tristate "Dallas 2780 battery monitor chip"
        help
index d5f4f4d5b9e5998f2384e2135d37b9bf1729f0f6..eab29f151413743e21bd23ac23d9348b107df6a0 100644 (file)
@@ -14,7 +14,6 @@ obj-$(CONFIG_W1_SLAVE_DS2431) += w1_ds2431.o
 obj-$(CONFIG_W1_SLAVE_DS2805)  += w1_ds2805.o
 obj-$(CONFIG_W1_SLAVE_DS2433)  += w1_ds2433.o
 obj-$(CONFIG_W1_SLAVE_DS2438)  += w1_ds2438.o
-obj-$(CONFIG_W1_SLAVE_DS2760)  += w1_ds2760.o
 obj-$(CONFIG_W1_SLAVE_DS2780)  += w1_ds2780.o
 obj-$(CONFIG_W1_SLAVE_DS2781)  += w1_ds2781.o
 obj-$(CONFIG_W1_SLAVE_DS28E04) += w1_ds28e04.o
diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c
deleted file mode 100644 (file)
index 26168ab..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 1-Wire implementation for the ds2760 chip
- *
- * Copyright © 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
- *
- * Use consistent with the GNU GPL is permitted,
- * provided that this copyright notice is
- * preserved in its entirety in all copies and derived works.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/types.h>
-#include <linux/platform_device.h>
-#include <linux/mutex.h>
-#include <linux/idr.h>
-#include <linux/gfp.h>
-
-#include <linux/w1.h>
-
-#include "w1_ds2760.h"
-
-#define W1_FAMILY_DS2760       0x30
-
-static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count,
-                       int io)
-{
-       struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
-
-       if (!dev)
-               return 0;
-
-       mutex_lock(&sl->master->bus_mutex);
-
-       if (addr > DS2760_DATA_SIZE || addr < 0) {
-               count = 0;
-               goto out;
-       }
-       if (addr + count > DS2760_DATA_SIZE)
-               count = DS2760_DATA_SIZE - addr;
-
-       if (!w1_reset_select_slave(sl)) {
-               if (!io) {
-                       w1_write_8(sl->master, W1_DS2760_READ_DATA);
-                       w1_write_8(sl->master, addr);
-                       count = w1_read_block(sl->master, buf, count);
-               } else {
-                       w1_write_8(sl->master, W1_DS2760_WRITE_DATA);
-                       w1_write_8(sl->master, addr);
-                       w1_write_block(sl->master, buf, count);
-                       /* XXX w1_write_block returns void, not n_written */
-               }
-       }
-
-out:
-       mutex_unlock(&sl->master->bus_mutex);
-
-       return count;
-}
-
-int w1_ds2760_read(struct device *dev, char *buf, int addr, size_t count)
-{
-       return w1_ds2760_io(dev, buf, addr, count, 0);
-}
-EXPORT_SYMBOL(w1_ds2760_read);
-
-int w1_ds2760_write(struct device *dev, char *buf, int addr, size_t count)
-{
-       return w1_ds2760_io(dev, buf, addr, count, 1);
-}
-EXPORT_SYMBOL(w1_ds2760_write);
-
-static int w1_ds2760_eeprom_cmd(struct device *dev, int addr, int cmd)
-{
-       struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
-
-       if (!dev)
-               return -EINVAL;
-
-       mutex_lock(&sl->master->bus_mutex);
-
-       if (w1_reset_select_slave(sl) == 0) {
-               w1_write_8(sl->master, cmd);
-               w1_write_8(sl->master, addr);
-       }
-
-       mutex_unlock(&sl->master->bus_mutex);
-       return 0;
-}
-
-int w1_ds2760_store_eeprom(struct device *dev, int addr)
-{
-       return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_COPY_DATA);
-}
-EXPORT_SYMBOL(w1_ds2760_store_eeprom);
-
-int w1_ds2760_recall_eeprom(struct device *dev, int addr)
-{
-       return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_RECALL_DATA);
-}
-EXPORT_SYMBOL(w1_ds2760_recall_eeprom);
-
-static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj,
-                            struct bin_attribute *bin_attr, char *buf,
-                            loff_t off, size_t count)
-{
-       struct device *dev = container_of(kobj, struct device, kobj);
-       return w1_ds2760_read(dev, buf, off, count);
-}
-
-static BIN_ATTR_RO(w1_slave, DS2760_DATA_SIZE);
-
-static struct bin_attribute *w1_ds2760_bin_attrs[] = {
-       &bin_attr_w1_slave,
-       NULL,
-};
-
-static const struct attribute_group w1_ds2760_group = {
-       .bin_attrs = w1_ds2760_bin_attrs,
-};
-
-static const struct attribute_group *w1_ds2760_groups[] = {
-       &w1_ds2760_group,
-       NULL,
-};
-
-static int w1_ds2760_add_slave(struct w1_slave *sl)
-{
-       int ret;
-       struct platform_device *pdev;
-
-       pdev = platform_device_alloc("ds2760-battery", PLATFORM_DEVID_AUTO);
-       if (!pdev)
-               return -ENOMEM;
-       pdev->dev.parent = &sl->dev;
-
-       ret = platform_device_add(pdev);
-       if (ret)
-               goto pdev_add_failed;
-
-       dev_set_drvdata(&sl->dev, pdev);
-
-       return 0;
-
-pdev_add_failed:
-       platform_device_put(pdev);
-
-       return ret;
-}
-
-static void w1_ds2760_remove_slave(struct w1_slave *sl)
-{
-       struct platform_device *pdev = dev_get_drvdata(&sl->dev);
-
-       platform_device_unregister(pdev);
-}
-
-static struct w1_family_ops w1_ds2760_fops = {
-       .add_slave    = w1_ds2760_add_slave,
-       .remove_slave = w1_ds2760_remove_slave,
-       .groups       = w1_ds2760_groups,
-};
-
-static struct w1_family w1_ds2760_family = {
-       .fid = W1_FAMILY_DS2760,
-       .fops = &w1_ds2760_fops,
-};
-module_w1_family(w1_ds2760_family);
-
-MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>");
-MODULE_DESCRIPTION("1-wire Driver Dallas 2760 battery monitor chip");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2760));
diff --git a/drivers/w1/slaves/w1_ds2760.h b/drivers/w1/slaves/w1_ds2760.h
deleted file mode 100644 (file)
index 24168c9..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 1-Wire implementation for the ds2760 chip
- *
- * Copyright © 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
- *
- * Use consistent with the GNU GPL is permitted,
- * provided that this copyright notice is
- * preserved in its entirety in all copies and derived works.
- *
- */
-
-#ifndef __w1_ds2760_h__
-#define __w1_ds2760_h__
-
-/* Known commands to the DS2760 chip */
-#define W1_DS2760_SWAP                 0xAA
-#define W1_DS2760_READ_DATA            0x69
-#define W1_DS2760_WRITE_DATA           0x6C
-#define W1_DS2760_COPY_DATA            0x48
-#define W1_DS2760_RECALL_DATA          0xB8
-#define W1_DS2760_LOCK                 0x6A
-
-/* Number of valid register addresses */
-#define DS2760_DATA_SIZE               0x40
-
-#define DS2760_PROTECTION_REG          0x00
-
-#define DS2760_STATUS_REG              0x01
-#define DS2760_STATUS_IE               (1 << 2)
-#define DS2760_STATUS_SWEN             (1 << 3)
-#define DS2760_STATUS_RNAOP            (1 << 4)
-#define DS2760_STATUS_PMOD             (1 << 5)
-
-#define DS2760_EEPROM_REG              0x07
-#define DS2760_SPECIAL_FEATURE_REG     0x08
-#define DS2760_VOLTAGE_MSB             0x0c
-#define DS2760_VOLTAGE_LSB             0x0d
-#define DS2760_CURRENT_MSB             0x0e
-#define DS2760_CURRENT_LSB             0x0f
-#define DS2760_CURRENT_ACCUM_MSB       0x10
-#define DS2760_CURRENT_ACCUM_LSB       0x11
-#define DS2760_TEMP_MSB                        0x18
-#define DS2760_TEMP_LSB                        0x19
-#define DS2760_EEPROM_BLOCK0           0x20
-#define DS2760_ACTIVE_FULL             0x20
-#define DS2760_EEPROM_BLOCK1           0x30
-#define DS2760_STATUS_WRITE_REG                0x31
-#define DS2760_RATED_CAPACITY          0x32
-#define DS2760_CURRENT_OFFSET_BIAS     0x33
-#define DS2760_ACTIVE_EMPTY            0x3b
-
-extern int w1_ds2760_read(struct device *dev, char *buf, int addr,
-                         size_t count);
-extern int w1_ds2760_write(struct device *dev, char *buf, int addr,
-                          size_t count);
-extern int w1_ds2760_store_eeprom(struct device *dev, int addr);
-extern int w1_ds2760_recall_eeprom(struct device *dev, int addr);
-
-#endif /* !__w1_ds2760_h__ */
index caef0e0fd81740585e62e066f6d84c09f25a267e..890c038c25f8717f38d1c901d4ec9662d13905c5 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/hwmon.h>
+#include <linux/of.h>
 
 #include <linux/atomic.h>
 
@@ -686,6 +687,8 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
        sl->dev.bus = &w1_bus_type;
        sl->dev.release = &w1_slave_release;
        sl->dev.groups = w1_slave_groups;
+       sl->dev.of_node = of_find_matching_node(sl->master->dev.of_node,
+                                               sl->family->of_match_table);
 
        dev_set_name(&sl->dev, "%02x-%012llx",
                 (unsigned int) sl->reg_num.family,
index 2f3b049ea3017c9c481e54b64610975830cdf25d..e268add430104bb1d02a4024d0d5b51c0299f0ab 100644 (file)
@@ -146,12 +146,7 @@ static int kempld_wdt_set_stage_timeout(struct kempld_wdt_data *wdt_data,
        u32 remainder;
        u8 stage_cfg;
 
-#if GCC_VERSION < 40400
-       /* work around a bug compiling do_div() */
-       prescaler = READ_ONCE(kempld_prescaler[PRESCALER_21]);
-#else
        prescaler = kempld_prescaler[PRESCALER_21];
-#endif
 
        if (!stage)
                return -EINVAL;
index c866a62f766d4ee4bfd5e5bc57e701ef8766159a..57390c7666e5dd8d44bfe9bdf1e503afb13de189 100644 (file)
@@ -479,18 +479,25 @@ static const struct vm_operations_struct gntdev_vmops = {
 
 /* ------------------------------------------------------------------ */
 
+static bool in_range(struct gntdev_grant_map *map,
+                             unsigned long start, unsigned long end)
+{
+       if (!map->vma)
+               return false;
+       if (map->vma->vm_start >= end)
+               return false;
+       if (map->vma->vm_end <= start)
+               return false;
+
+       return true;
+}
+
 static void unmap_if_in_range(struct gntdev_grant_map *map,
                              unsigned long start, unsigned long end)
 {
        unsigned long mstart, mend;
        int err;
 
-       if (!map->vma)
-               return;
-       if (map->vma->vm_start >= end)
-               return;
-       if (map->vma->vm_end <= start)
-               return;
        mstart = max(start, map->vma->vm_start);
        mend   = min(end,   map->vma->vm_end);
        pr_debug("map %d+%d (%lx %lx), range %lx %lx, mrange %lx %lx\n",
@@ -503,21 +510,40 @@ static void unmap_if_in_range(struct gntdev_grant_map *map,
        WARN_ON(err);
 }
 
-static void mn_invl_range_start(struct mmu_notifier *mn,
+static int mn_invl_range_start(struct mmu_notifier *mn,
                                struct mm_struct *mm,
-                               unsigned long start, unsigned long end)
+                               unsigned long start, unsigned long end,
+                               bool blockable)
 {
        struct gntdev_priv *priv = container_of(mn, struct gntdev_priv, mn);
        struct gntdev_grant_map *map;
+       int ret = 0;
+
+       /* TODO do we really need a mutex here? */
+       if (blockable)
+               mutex_lock(&priv->lock);
+       else if (!mutex_trylock(&priv->lock))
+               return -EAGAIN;
 
-       mutex_lock(&priv->lock);
        list_for_each_entry(map, &priv->maps, next) {
+               if (in_range(map, start, end)) {
+                       ret = -EAGAIN;
+                       goto out_unlock;
+               }
                unmap_if_in_range(map, start, end);
        }
        list_for_each_entry(map, &priv->freeable_maps, next) {
+               if (in_range(map, start, end)) {
+                       ret = -EAGAIN;
+                       goto out_unlock;
+               }
                unmap_if_in_range(map, start, end);
        }
+
+out_unlock:
        mutex_unlock(&priv->lock);
+
+       return ret;
 }
 
 static void mn_release(struct mmu_notifier *mn,
index 262835ace35d42c983bbff50d034316c7a53aade..b8bf61abb65ba8cc45484bf2a65cb7f9d7507b04 100644 (file)
@@ -288,7 +288,6 @@ static int mc_queue_handle(uint32_t flags)
        int ret = 0;
 
        mc_op.cmd = XEN_MC_fetch;
-       mc_op.interface_version = XEN_MCA_INTERFACE_VERSION;
        set_xen_guest_handle(mc_op.u.mc_fetch.data, &g_mi);
        do {
                mc_op.u.mc_fetch.flags = flags;
@@ -358,7 +357,6 @@ static int bind_virq_for_mce(void)
 
        /* Fetch physical CPU Numbers */
        mc_op.cmd = XEN_MC_physcpuinfo;
-       mc_op.interface_version = XEN_MCA_INTERFACE_VERSION;
        set_xen_guest_handle(mc_op.u.mc_physcpuinfo.info, g_physinfo);
        ret = HYPERVISOR_mca(&mc_op);
        if (ret) {
index b29f4e40851f0cab2894450e61352285fd28b9f4..fbb9137c7d0287b652cf9c429db0ca593713032b 100644 (file)
@@ -362,6 +362,12 @@ read_acpi_id(acpi_handle handle, u32 lvl, void *context, void **rv)
        default:
                return AE_OK;
        }
+       if (invalid_phys_cpuid(acpi_get_phys_id(handle,
+                                               acpi_type == ACPI_TYPE_DEVICE,
+                                               acpi_id))) {
+               pr_debug("CPU with ACPI ID %u is unavailable\n", acpi_id);
+               return AE_OK;
+       }
        /* There are more ACPI Processor objects than in x2APIC or MADT.
         * This can happen with incorrect ACPI SSDT declerations. */
        if (acpi_id >= nr_acpi_bits) {
index f2088838f690b218a4f16ee0a56bfa23a08acb73..5b471889d7237c926682392b123db99e7ab6656f 100644 (file)
@@ -402,10 +402,19 @@ static ssize_t modalias_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(modalias);
 
+static ssize_t state_show(struct device *dev,
+                           struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%s\n",
+                       xenbus_strstate(to_xenbus_device(dev)->state));
+}
+static DEVICE_ATTR_RO(state);
+
 static struct attribute *xenbus_dev_attrs[] = {
        &dev_attr_nodename.attr,
        &dev_attr_devtype.attr,
        &dev_attr_modalias.attr,
+       &dev_attr_state.attr,
        NULL,
 };
 
index e91028d4340abf9b7ad32c5cf77f668bf32bfd4b..66621e96f9afe2a8a33bdb35d624353473aa7386 100644 (file)
@@ -167,7 +167,7 @@ adfs_mode2atts(struct super_block *sb, struct inode *inode)
  * of time to convert from RISC OS epoch to Unix epoch.
  */
 static void
-adfs_adfs2unix_time(struct timespec *tv, struct inode *inode)
+adfs_adfs2unix_time(struct timespec64 *tv, struct inode *inode)
 {
        unsigned int high, low;
        /* 01 Jan 1970 00:00:00 (Unix epoch) as nanoseconds since
@@ -195,11 +195,11 @@ adfs_adfs2unix_time(struct timespec *tv, struct inode *inode)
        /* convert from RISC OS to Unix epoch */
        nsec -= nsec_unix_epoch_diff_risc_os_epoch;
 
-       *tv = ns_to_timespec(nsec);
+       *tv = ns_to_timespec64(nsec);
        return;
 
  cur_time:
-       *tv = timespec64_to_timespec(current_time(inode));
+       *tv = current_time(inode);
        return;
 
  too_early:
@@ -242,7 +242,6 @@ adfs_unix2adfs_time(struct inode *inode, unsigned int secs)
 struct inode *
 adfs_iget(struct super_block *sb, struct object_info *obj)
 {
-       struct timespec ts;
        struct inode *inode;
 
        inode = new_inode(sb);
@@ -271,9 +270,7 @@ adfs_iget(struct super_block *sb, struct object_info *obj)
        ADFS_I(inode)->stamped   = ((obj->loadaddr & 0xfff00000) == 0xfff00000);
 
        inode->i_mode    = adfs_atts2mode(sb, inode);
-       ts = timespec64_to_timespec(inode->i_mtime);
-       adfs_adfs2unix_time(&ts, inode);
-       inode->i_mtime = timespec_to_timespec64(ts);
+       adfs_adfs2unix_time(&inode->i_mtime, inode);
        inode->i_atime = inode->i_mtime;
        inode->i_ctime = inode->i_mtime;
 
index 9778df1357179d14238cfa52e7394886206a1f1d..871a228d7f37ce1b0b0d7122b41a8f83f134f391 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/fscache.h>
 #include <linux/backing-dev.h>
 #include <linux/uuid.h>
+#include <linux/mm_types.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 #include <net/sock.h>
@@ -1076,7 +1077,7 @@ extern int afs_writepages(struct address_space *, struct writeback_control *);
 extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *);
 extern ssize_t afs_file_write(struct kiocb *, struct iov_iter *);
 extern int afs_fsync(struct file *, loff_t, loff_t, int);
-extern int afs_page_mkwrite(struct vm_fault *);
+extern vm_fault_t afs_page_mkwrite(struct vm_fault *vmf);
 extern void afs_prune_wb_keys(struct afs_vnode *);
 extern int afs_launder_page(struct page *);
 
index 0c3285c8db95b4ec6457fdfe759e1997c9c69a7f..476dcbb79713d20d12023dfb265a0ef62e48e6fc 100644 (file)
@@ -98,13 +98,13 @@ static int afs_proc_cells_write(struct file *file, char *buf, size_t size)
                goto inval;
 
        args = strchr(name, ' ');
-       if (!args)
-               goto inval;
-       do {
-               *args++ = 0;
-       } while(*args == ' ');
-       if (!*args)
-               goto inval;
+       if (args) {
+               do {
+                       *args++ = 0;
+               } while(*args == ' ');
+               if (!*args)
+                       goto inval;
+       }
 
        /* determine command to perform */
        _debug("cmd=%s name=%s args=%s", buf, name, args);
@@ -120,7 +120,6 @@ static int afs_proc_cells_write(struct file *file, char *buf, size_t size)
 
                if (test_and_set_bit(AFS_CELL_FL_NO_GC, &cell->flags))
                        afs_put_cell(net, cell);
-               printk("kAFS: Added new cell '%s'\n", name);
        } else {
                goto inval;
        }
index 8b39e6ebb40bc17905cf2eca24b1eacadf933584..19c04caf3c012bd777d20e31355357154cc38a83 100644 (file)
@@ -753,7 +753,7 @@ int afs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
  * notification that a previously read-only page is about to become writable
  * - if it returns an error, the caller will deliver a bus error signal
  */
-int afs_page_mkwrite(struct vm_fault *vmf)
+vm_fault_t afs_page_mkwrite(struct vm_fault *vmf)
 {
        struct file *file = vmf->vma->vm_file;
        struct inode *inode = file_inode(file);
index 9400a9f6318a0fab9ac95aeb12e84776a4ae4006..9f9cadbfbd7a34f8005fafb0960b3c60e4848c60 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/string.h>
 #include <linux/wait.h>
 #include <linux/sched.h>
+#include <linux/sched/signal.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/uaccess.h>
@@ -26,6 +27,7 @@
 #include <linux/list.h>
 #include <linux/completion.h>
 #include <linux/file.h>
+#include <linux/magic.h>
 
 /* This is the range of ioctl() numbers we claim as ours */
 #define AUTOFS_IOC_FIRST     AUTOFS_IOC_READY
@@ -124,7 +126,8 @@ struct autofs_sb_info {
 
 static inline struct autofs_sb_info *autofs_sbi(struct super_block *sb)
 {
-       return (struct autofs_sb_info *)(sb->s_fs_info);
+       return sb->s_magic != AUTOFS_SUPER_MAGIC ?
+               NULL : (struct autofs_sb_info *)(sb->s_fs_info);
 }
 
 static inline struct autofs_info *autofs_dentry_ino(struct dentry *dentry)
@@ -151,15 +154,9 @@ int autofs_expire_run(struct super_block *, struct vfsmount *,
                      struct autofs_sb_info *,
                      struct autofs_packet_expire __user *);
 int autofs_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
-                          struct autofs_sb_info *sbi, int when);
+                          struct autofs_sb_info *sbi, unsigned int how);
 int autofs_expire_multi(struct super_block *, struct vfsmount *,
                        struct autofs_sb_info *, int __user *);
-struct dentry *autofs_expire_direct(struct super_block *sb,
-                                   struct vfsmount *mnt,
-                                   struct autofs_sb_info *sbi, int how);
-struct dentry *autofs_expire_indirect(struct super_block *sb,
-                                     struct vfsmount *mnt,
-                                     struct autofs_sb_info *sbi, int how);
 
 /* Device node initialization */
 
index b332d3f6e7306d7c3fe923c64f82126ca95ca4a3..d441244b79df98d23d6e0640466a2db68ffdac6b 100644 (file)
 
 #include "autofs_i.h"
 
-static unsigned long now;
-
 /* Check if a dentry can be expired */
 static inline int autofs_can_expire(struct dentry *dentry,
-                                   unsigned long timeout, int do_now)
+                                   unsigned long timeout, unsigned int how)
 {
        struct autofs_info *ino = autofs_dentry_ino(dentry);
 
@@ -22,16 +20,17 @@ static inline int autofs_can_expire(struct dentry *dentry,
        if (ino == NULL)
                return 0;
 
-       if (!do_now) {
+       if (!(how & AUTOFS_EXP_IMMEDIATE)) {
                /* Too young to die */
-               if (!timeout || time_after(ino->last_used + timeout, now))
+               if (!timeout || time_after(ino->last_used + timeout, jiffies))
                        return 0;
        }
        return 1;
 }
 
 /* Check a mount point for busyness */
-static int autofs_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
+static int autofs_mount_busy(struct vfsmount *mnt,
+                            struct dentry *dentry, unsigned int how)
 {
        struct dentry *top = dentry;
        struct path path = {.mnt = mnt, .dentry = dentry};
@@ -52,6 +51,12 @@ static int autofs_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
                        goto done;
        }
 
+       /* Not a submount, has a forced expire been requested */
+       if (how & AUTOFS_EXP_FORCED) {
+               status = 0;
+               goto done;
+       }
+
        /* Update the expiry counter if fs is busy */
        if (!may_umount_tree(path.mnt)) {
                struct autofs_info *ino;
@@ -187,10 +192,14 @@ again:
 static int autofs_direct_busy(struct vfsmount *mnt,
                              struct dentry *top,
                              unsigned long timeout,
-                             int do_now)
+                             unsigned int how)
 {
        pr_debug("top %p %pd\n", top, top);
 
+       /* Forced expire, user space handles busy mounts */
+       if (how & AUTOFS_EXP_FORCED)
+               return 0;
+
        /* If it's busy update the expiry counters */
        if (!may_umount_tree(mnt)) {
                struct autofs_info *ino;
@@ -202,7 +211,7 @@ static int autofs_direct_busy(struct vfsmount *mnt,
        }
 
        /* Timeout of a direct mount is determined by its top dentry */
-       if (!autofs_can_expire(top, timeout, do_now))
+       if (!autofs_can_expire(top, timeout, how))
                return 1;
 
        return 0;
@@ -215,7 +224,7 @@ static int autofs_direct_busy(struct vfsmount *mnt,
 static int autofs_tree_busy(struct vfsmount *mnt,
                            struct dentry *top,
                            unsigned long timeout,
-                           int do_now)
+                           unsigned int how)
 {
        struct autofs_info *top_ino = autofs_dentry_ino(top);
        struct dentry *p;
@@ -237,7 +246,7 @@ static int autofs_tree_busy(struct vfsmount *mnt,
                 * If the fs is busy update the expiry counter.
                 */
                if (d_mountpoint(p)) {
-                       if (autofs_mount_busy(mnt, p)) {
+                       if (autofs_mount_busy(mnt, p, how)) {
                                top_ino->last_used = jiffies;
                                dput(p);
                                return 1;
@@ -260,8 +269,12 @@ static int autofs_tree_busy(struct vfsmount *mnt,
                }
        }
 
+       /* Forced expire, user space handles busy mounts */
+       if (how & AUTOFS_EXP_FORCED)
+               return 0;
+
        /* Timeout of a tree mount is ultimately determined by its top dentry */
-       if (!autofs_can_expire(top, timeout, do_now))
+       if (!autofs_can_expire(top, timeout, how))
                return 1;
 
        return 0;
@@ -270,7 +283,7 @@ static int autofs_tree_busy(struct vfsmount *mnt,
 static struct dentry *autofs_check_leaves(struct vfsmount *mnt,
                                          struct dentry *parent,
                                          unsigned long timeout,
-                                         int do_now)
+                                         unsigned int how)
 {
        struct dentry *p;
 
@@ -282,11 +295,17 @@ static struct dentry *autofs_check_leaves(struct vfsmount *mnt,
 
                if (d_mountpoint(p)) {
                        /* Can we umount this guy */
-                       if (autofs_mount_busy(mnt, p))
+                       if (autofs_mount_busy(mnt, p, how))
                                continue;
 
+                       /* This isn't a submount so if a forced expire
+                        * has been requested, user space handles busy
+                        * mounts */
+                       if (how & AUTOFS_EXP_FORCED)
+                               return p;
+
                        /* Can we expire this guy */
-                       if (autofs_can_expire(p, timeout, do_now))
+                       if (autofs_can_expire(p, timeout, how))
                                return p;
                }
        }
@@ -294,23 +313,21 @@ static struct dentry *autofs_check_leaves(struct vfsmount *mnt,
 }
 
 /* Check if we can expire a direct mount (possibly a tree) */
-struct dentry *autofs_expire_direct(struct super_block *sb,
-                                   struct vfsmount *mnt,
-                                   struct autofs_sb_info *sbi,
-                                   int how)
+static struct dentry *autofs_expire_direct(struct super_block *sb,
+                                          struct vfsmount *mnt,
+                                          struct autofs_sb_info *sbi,
+                                          unsigned int how)
 {
-       unsigned long timeout;
        struct dentry *root = dget(sb->s_root);
-       int do_now = how & AUTOFS_EXP_IMMEDIATE;
        struct autofs_info *ino;
+       unsigned long timeout;
 
        if (!root)
                return NULL;
 
-       now = jiffies;
        timeout = sbi->exp_timeout;
 
-       if (!autofs_direct_busy(mnt, root, timeout, do_now)) {
+       if (!autofs_direct_busy(mnt, root, timeout, how)) {
                spin_lock(&sbi->fs_lock);
                ino = autofs_dentry_ino(root);
                /* No point expiring a pending mount */
@@ -321,7 +338,7 @@ struct dentry *autofs_expire_direct(struct super_block *sb,
                ino->flags |= AUTOFS_INF_WANT_EXPIRE;
                spin_unlock(&sbi->fs_lock);
                synchronize_rcu();
-               if (!autofs_direct_busy(mnt, root, timeout, do_now)) {
+               if (!autofs_direct_busy(mnt, root, timeout, how)) {
                        spin_lock(&sbi->fs_lock);
                        ino->flags |= AUTOFS_INF_EXPIRING;
                        init_completion(&ino->expire_complete);
@@ -346,10 +363,8 @@ out:
 static struct dentry *should_expire(struct dentry *dentry,
                                    struct vfsmount *mnt,
                                    unsigned long timeout,
-                                   int how)
+                                   unsigned int how)
 {
-       int do_now = how & AUTOFS_EXP_IMMEDIATE;
-       int exp_leaves = how & AUTOFS_EXP_LEAVES;
        struct autofs_info *ino = autofs_dentry_ino(dentry);
        unsigned int ino_count;
 
@@ -367,22 +382,33 @@ static struct dentry *should_expire(struct dentry *dentry,
                pr_debug("checking mountpoint %p %pd\n", dentry, dentry);
 
                /* Can we umount this guy */
-               if (autofs_mount_busy(mnt, dentry))
+               if (autofs_mount_busy(mnt, dentry, how))
                        return NULL;
 
+               /* This isn't a submount so if a forced expire
+                * has been requested, user space handles busy
+                * mounts */
+               if (how & AUTOFS_EXP_FORCED)
+                       return dentry;
+
                /* Can we expire this guy */
-               if (autofs_can_expire(dentry, timeout, do_now))
+               if (autofs_can_expire(dentry, timeout, how))
                        return dentry;
                return NULL;
        }
 
        if (d_really_is_positive(dentry) && d_is_symlink(dentry)) {
                pr_debug("checking symlink %p %pd\n", dentry, dentry);
+
+               /* Forced expire, user space handles busy mounts */
+               if (how & AUTOFS_EXP_FORCED)
+                       return dentry;
+
                /*
                 * A symlink can't be "busy" in the usual sense so
                 * just check last used for expire timeout.
                 */
-               if (autofs_can_expire(dentry, timeout, do_now))
+               if (autofs_can_expire(dentry, timeout, how))
                        return dentry;
                return NULL;
        }
@@ -391,27 +417,33 @@ static struct dentry *should_expire(struct dentry *dentry,
                return NULL;
 
        /* Case 2: tree mount, expire iff entire tree is not busy */
-       if (!exp_leaves) {
-               /* Path walk currently on this dentry? */
-               ino_count = atomic_read(&ino->count) + 1;
-               if (d_count(dentry) > ino_count)
-                       return NULL;
+       if (!(how & AUTOFS_EXP_LEAVES)) {
+               /* Not a forced expire? */
+               if (!(how & AUTOFS_EXP_FORCED)) {
+                       /* ref-walk currently on this dentry? */
+                       ino_count = atomic_read(&ino->count) + 1;
+                       if (d_count(dentry) > ino_count)
+                               return NULL;
+               }
 
-               if (!autofs_tree_busy(mnt, dentry, timeout, do_now))
+               if (!autofs_tree_busy(mnt, dentry, timeout, how))
                        return dentry;
        /*
         * Case 3: pseudo direct mount, expire individual leaves
         *         (autofs-4.1).
         */
        } else {
-               /* Path walk currently on this dentry? */
                struct dentry *expired;
 
-               ino_count = atomic_read(&ino->count) + 1;
-               if (d_count(dentry) > ino_count)
-                       return NULL;
+               /* Not a forced expire? */
+               if (!(how & AUTOFS_EXP_FORCED)) {
+                       /* ref-walk currently on this dentry? */
+                       ino_count = atomic_read(&ino->count) + 1;
+                       if (d_count(dentry) > ino_count)
+                               return NULL;
+               }
 
-               expired = autofs_check_leaves(mnt, dentry, timeout, do_now);
+               expired = autofs_check_leaves(mnt, dentry, timeout, how);
                if (expired) {
                        if (expired == dentry)
                                dput(dentry);
@@ -427,10 +459,10 @@ static struct dentry *should_expire(struct dentry *dentry,
  *  - it is unused by any user process
  *  - it has been unused for exp_timeout time
  */
-struct dentry *autofs_expire_indirect(struct super_block *sb,
-                                     struct vfsmount *mnt,
-                                     struct autofs_sb_info *sbi,
-                                     int how)
+static struct dentry *autofs_expire_indirect(struct super_block *sb,
+                                            struct vfsmount *mnt,
+                                            struct autofs_sb_info *sbi,
+                                            unsigned int how)
 {
        unsigned long timeout;
        struct dentry *root = sb->s_root;
@@ -442,13 +474,10 @@ struct dentry *autofs_expire_indirect(struct super_block *sb,
        if (!root)
                return NULL;
 
-       now = jiffies;
        timeout = sbi->exp_timeout;
 
        dentry = NULL;
        while ((dentry = get_next_positive_subdir(dentry, root))) {
-               int flags = how;
-
                spin_lock(&sbi->fs_lock);
                ino = autofs_dentry_ino(dentry);
                if (ino->flags & AUTOFS_INF_WANT_EXPIRE) {
@@ -457,7 +486,7 @@ struct dentry *autofs_expire_indirect(struct super_block *sb,
                }
                spin_unlock(&sbi->fs_lock);
 
-               expired = should_expire(dentry, mnt, timeout, flags);
+               expired = should_expire(dentry, mnt, timeout, how);
                if (!expired)
                        continue;
 
@@ -470,7 +499,7 @@ struct dentry *autofs_expire_indirect(struct super_block *sb,
                /* Make sure a reference is not taken on found if
                 * things have changed.
                 */
-               flags &= ~AUTOFS_EXP_LEAVES;
+               how &= ~AUTOFS_EXP_LEAVES;
                found = should_expire(expired, mnt, timeout, how);
                if (!found || found != expired)
                        /* Something has changed, continue */
@@ -575,7 +604,7 @@ int autofs_expire_run(struct super_block *sb,
        spin_lock(&sbi->fs_lock);
        ino = autofs_dentry_ino(dentry);
        /* avoid rapid-fire expire attempts if expiry fails */
-       ino->last_used = now;
+       ino->last_used = jiffies;
        ino->flags &= ~(AUTOFS_INF_EXPIRING|AUTOFS_INF_WANT_EXPIRE);
        complete_all(&ino->expire_complete);
        spin_unlock(&sbi->fs_lock);
@@ -584,15 +613,15 @@ int autofs_expire_run(struct super_block *sb,
 }
 
 int autofs_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
-                          struct autofs_sb_info *sbi, int when)
+                          struct autofs_sb_info *sbi, unsigned int how)
 {
        struct dentry *dentry;
        int ret = -EAGAIN;
 
        if (autofs_type_trigger(sbi->type))
-               dentry = autofs_expire_direct(sb, mnt, sbi, when);
+               dentry = autofs_expire_direct(sb, mnt, sbi, how);
        else
-               dentry = autofs_expire_indirect(sb, mnt, sbi, when);
+               dentry = autofs_expire_indirect(sb, mnt, sbi, how);
 
        if (dentry) {
                struct autofs_info *ino = autofs_dentry_ino(dentry);
@@ -605,7 +634,7 @@ int autofs_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
 
                spin_lock(&sbi->fs_lock);
                /* avoid rapid-fire expire attempts if expiry fails */
-               ino->last_used = now;
+               ino->last_used = jiffies;
                ino->flags &= ~(AUTOFS_INF_EXPIRING|AUTOFS_INF_WANT_EXPIRE);
                complete_all(&ino->expire_complete);
                spin_unlock(&sbi->fs_lock);
@@ -622,10 +651,10 @@ int autofs_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
 int autofs_expire_multi(struct super_block *sb, struct vfsmount *mnt,
                        struct autofs_sb_info *sbi, int __user *arg)
 {
-       int do_now = 0;
+       unsigned int how = 0;
 
-       if (arg && get_user(do_now, arg))
+       if (arg && get_user(how, arg))
                return -EFAULT;
 
-       return autofs_do_expire_multi(sb, mnt, sbi, do_now);
+       return autofs_do_expire_multi(sb, mnt, sbi, how);
 }
index b51980fc274e6c6b26fef944974a076523ae33a3..846c052569dd4913e1aea268ad88a0521251002e 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/seq_file.h>
 #include <linux/pagemap.h>
 #include <linux/parser.h>
-#include <linux/magic.h>
 
 #include "autofs_i.h"
 
index a3d4141505784cb759883a8015ab1fbdb5a5aaae..782e57b911abcf0cd1d7aae2095333554e1f1d74 100644 (file)
@@ -559,6 +559,13 @@ static int autofs_dir_symlink(struct inode *dir,
        if (!autofs_oz_mode(sbi))
                return -EACCES;
 
+       /* autofs_oz_mode() needs to allow path walks when the
+        * autofs mount is catatonic but the state of an autofs
+        * file system needs to be preserved over restarts.
+        */
+       if (sbi->catatonic)
+               return -EACCES;
+
        BUG_ON(!ino);
 
        autofs_clean_ino(ino);
@@ -612,9 +619,15 @@ static int autofs_dir_unlink(struct inode *dir, struct dentry *dentry)
        struct autofs_info *ino = autofs_dentry_ino(dentry);
        struct autofs_info *p_ino;
 
-       /* This allows root to remove symlinks */
-       if (!autofs_oz_mode(sbi) && !capable(CAP_SYS_ADMIN))
-               return -EPERM;
+       if (!autofs_oz_mode(sbi))
+               return -EACCES;
+
+       /* autofs_oz_mode() needs to allow path walks when the
+        * autofs mount is catatonic but the state of an autofs
+        * file system needs to be preserved over restarts.
+        */
+       if (sbi->catatonic)
+               return -EACCES;
 
        if (atomic_dec_and_test(&ino->count)) {
                p_ino = autofs_dentry_ino(dentry->d_parent);
@@ -697,6 +710,13 @@ static int autofs_dir_rmdir(struct inode *dir, struct dentry *dentry)
        if (!autofs_oz_mode(sbi))
                return -EACCES;
 
+       /* autofs_oz_mode() needs to allow path walks when the
+        * autofs mount is catatonic but the state of an autofs
+        * file system needs to be preserved over restarts.
+        */
+       if (sbi->catatonic)
+               return -EACCES;
+
        spin_lock(&sbi->lookup_lock);
        if (!simple_empty(dentry)) {
                spin_unlock(&sbi->lookup_lock);
@@ -735,6 +755,13 @@ static int autofs_dir_mkdir(struct inode *dir,
        if (!autofs_oz_mode(sbi))
                return -EACCES;
 
+       /* autofs_oz_mode() needs to allow path walks when the
+        * autofs mount is catatonic but the state of an autofs
+        * file system needs to be preserved over restarts.
+        */
+       if (sbi->catatonic)
+               return -EACCES;
+
        pr_debug("dentry %p, creating %pd\n", dentry, dentry);
 
        BUG_ON(!ino);
index 318be786407220bdbc74dfd385ef5db136859486..2cddfe7806a412e4ecf26a61887fe4474ab380de 100644 (file)
@@ -1280,6 +1280,7 @@ struct btrfs_root {
        int send_in_progress;
        struct btrfs_subvolume_writers *subv_writers;
        atomic_t will_be_snapshotted;
+       atomic_t snapshot_force_cow;
 
        /* For qgroup metadata reserved space */
        spinlock_t qgroup_meta_rsv_lock;
@@ -3217,8 +3218,9 @@ void btrfs_get_block_group_info(struct list_head *groups_list,
                                struct btrfs_ioctl_space_info *space);
 void btrfs_update_ioctl_balance_args(struct btrfs_fs_info *fs_info,
                               struct btrfs_ioctl_balance_args *bargs);
-ssize_t btrfs_dedupe_file_range(struct file *src_file, u64 loff, u64 olen,
-                          struct file *dst_file, u64 dst_loff);
+int btrfs_dedupe_file_range(struct file *src_file, loff_t src_loff,
+                           struct file *dst_file, loff_t dst_loff,
+                           u64 olen);
 
 /* file.c */
 int __init btrfs_auto_defrag_init(void);
@@ -3389,9 +3391,9 @@ do {                                                                      \
 #define btrfs_debug(fs_info, fmt, args...) \
        btrfs_no_printk(fs_info, KERN_DEBUG fmt, ##args)
 #define btrfs_debug_in_rcu(fs_info, fmt, args...) \
-       btrfs_no_printk(fs_info, KERN_DEBUG fmt, ##args)
+       btrfs_no_printk_in_rcu(fs_info, KERN_DEBUG fmt, ##args)
 #define btrfs_debug_rl_in_rcu(fs_info, fmt, args...) \
-       btrfs_no_printk(fs_info, KERN_DEBUG fmt, ##args)
+       btrfs_no_printk_in_rcu(fs_info, KERN_DEBUG fmt, ##args)
 #define btrfs_debug_rl(fs_info, fmt, args...) \
        btrfs_no_printk(fs_info, KERN_DEBUG fmt, ##args)
 #endif
@@ -3403,6 +3405,13 @@ do {                                                     \
        rcu_read_unlock();                              \
 } while (0)
 
+#define btrfs_no_printk_in_rcu(fs_info, fmt, args...)  \
+do {                                                   \
+       rcu_read_lock();                                \
+       btrfs_no_printk(fs_info, fmt, ##args);          \
+       rcu_read_unlock();                              \
+} while (0)
+
 #define btrfs_printk_ratelimited(fs_info, fmt, args...)                \
 do {                                                           \
        static DEFINE_RATELIMIT_STATE(_rs,                      \
index 5124c15705ce777ef88950529343310c389686df..05dc3c17cb62aa38dc7a18adc886475ac22fd80b 100644 (file)
@@ -1187,6 +1187,7 @@ static void __setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info,
        atomic_set(&root->log_batch, 0);
        refcount_set(&root->refs, 1);
        atomic_set(&root->will_be_snapshotted, 0);
+       atomic_set(&root->snapshot_force_cow, 0);
        root->log_transid = 0;
        root->log_transid_committed = -1;
        root->last_log_commit = 0;
index de6f75f5547bdb159cf0764e5d4bfaf19a2c1085..2d9074295d7f0bb327010feeccffb1630c455477 100644 (file)
@@ -5800,7 +5800,7 @@ void btrfs_trans_release_chunk_metadata(struct btrfs_trans_handle *trans)
  * root: the root of the parent directory
  * rsv: block reservation
  * items: the number of items that we need do reservation
- * qgroup_reserved: used to return the reserved size in qgroup
+ * use_global_rsv: allow fallback to the global block reservation
  *
  * This function is used to reserve the space for snapshot/subvolume
  * creation and deletion. Those operations are different with the
@@ -5810,10 +5810,10 @@ void btrfs_trans_release_chunk_metadata(struct btrfs_trans_handle *trans)
  * the space reservation mechanism in start_transaction().
  */
 int btrfs_subvolume_reserve_metadata(struct btrfs_root *root,
-                                    struct btrfs_block_rsv *rsv,
-                                    int items,
+                                    struct btrfs_block_rsv *rsv, int items,
                                     bool use_global_rsv)
 {
+       u64 qgroup_num_bytes = 0;
        u64 num_bytes;
        int ret;
        struct btrfs_fs_info *fs_info = root->fs_info;
@@ -5821,12 +5821,11 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root,
 
        if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) {
                /* One for parent inode, two for dir entries */
-               num_bytes = 3 * fs_info->nodesize;
-               ret = btrfs_qgroup_reserve_meta_prealloc(root, num_bytes, true);
+               qgroup_num_bytes = 3 * fs_info->nodesize;
+               ret = btrfs_qgroup_reserve_meta_prealloc(root,
+                               qgroup_num_bytes, true);
                if (ret)
                        return ret;
-       } else {
-               num_bytes = 0;
        }
 
        num_bytes = btrfs_calc_trans_metadata_size(fs_info, items);
@@ -5838,8 +5837,8 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root,
        if (ret == -ENOSPC && use_global_rsv)
                ret = btrfs_block_rsv_migrate(global_rsv, rsv, num_bytes, 1);
 
-       if (ret && num_bytes)
-               btrfs_qgroup_free_meta_prealloc(root, num_bytes);
+       if (ret && qgroup_num_bytes)
+               btrfs_qgroup_free_meta_prealloc(root, qgroup_num_bytes);
 
        return ret;
 }
index 9357a19d2bff2c76de1b29d2e221333b6f76da7e..3ea5339603cff14f8dc103f6561091e83dc0b81a 100644 (file)
@@ -1271,7 +1271,7 @@ static noinline int run_delalloc_nocow(struct inode *inode,
        u64 disk_num_bytes;
        u64 ram_bytes;
        int extent_type;
-       int ret, err;
+       int ret;
        int type;
        int nocow;
        int check_prev = 1;
@@ -1403,11 +1403,8 @@ next_slot:
                         * if there are pending snapshots for this root,
                         * we fall into common COW way.
                         */
-                       if (!nolock) {
-                               err = btrfs_start_write_no_snapshotting(root);
-                               if (!err)
-                                       goto out_check;
-                       }
+                       if (!nolock && atomic_read(&root->snapshot_force_cow))
+                               goto out_check;
                        /*
                         * force cow if csum exists in the range.
                         * this ensure that csum for a given extent are
@@ -1416,9 +1413,6 @@ next_slot:
                        ret = csum_exist_in_range(fs_info, disk_bytenr,
                                                  num_bytes);
                        if (ret) {
-                               if (!nolock)
-                                       btrfs_end_write_no_snapshotting(root);
-
                                /*
                                 * ret could be -EIO if the above fails to read
                                 * metadata.
@@ -1431,11 +1425,8 @@ next_slot:
                                WARN_ON_ONCE(nolock);
                                goto out_check;
                        }
-                       if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr)) {
-                               if (!nolock)
-                                       btrfs_end_write_no_snapshotting(root);
+                       if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr))
                                goto out_check;
-                       }
                        nocow = 1;
                } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
                        extent_end = found_key.offset +
@@ -1448,8 +1439,6 @@ next_slot:
 out_check:
                if (extent_end <= start) {
                        path->slots[0]++;
-                       if (!nolock && nocow)
-                               btrfs_end_write_no_snapshotting(root);
                        if (nocow)
                                btrfs_dec_nocow_writers(fs_info, disk_bytenr);
                        goto next_slot;
@@ -1471,8 +1460,6 @@ out_check:
                                             end, page_started, nr_written, 1,
                                             NULL);
                        if (ret) {
-                               if (!nolock && nocow)
-                                       btrfs_end_write_no_snapshotting(root);
                                if (nocow)
                                        btrfs_dec_nocow_writers(fs_info,
                                                                disk_bytenr);
@@ -1492,8 +1479,6 @@ out_check:
                                          ram_bytes, BTRFS_COMPRESS_NONE,
                                          BTRFS_ORDERED_PREALLOC);
                        if (IS_ERR(em)) {
-                               if (!nolock && nocow)
-                                       btrfs_end_write_no_snapshotting(root);
                                if (nocow)
                                        btrfs_dec_nocow_writers(fs_info,
                                                                disk_bytenr);
@@ -1532,8 +1517,6 @@ out_check:
                                             EXTENT_CLEAR_DATA_RESV,
                                             PAGE_UNLOCK | PAGE_SET_PRIVATE2);
 
-               if (!nolock && nocow)
-                       btrfs_end_write_no_snapshotting(root);
                cur_offset = extent_end;
 
                /*
@@ -6639,6 +6622,8 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
                drop_inode = 1;
        } else {
                struct dentry *parent = dentry->d_parent;
+               int ret;
+
                err = btrfs_update_inode(trans, root, inode);
                if (err)
                        goto fail;
@@ -6652,7 +6637,12 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
                                goto fail;
                }
                d_instantiate(dentry, inode);
-               btrfs_log_new_name(trans, BTRFS_I(inode), NULL, parent);
+               ret = btrfs_log_new_name(trans, BTRFS_I(inode), NULL, parent,
+                                        true, NULL);
+               if (ret == BTRFS_NEED_TRANS_COMMIT) {
+                       err = btrfs_commit_transaction(trans);
+                       trans = NULL;
+               }
        }
 
 fail:
@@ -9388,14 +9378,21 @@ static int btrfs_rename_exchange(struct inode *old_dir,
        u64 new_idx = 0;
        u64 root_objectid;
        int ret;
-       int ret2;
        bool root_log_pinned = false;
        bool dest_log_pinned = false;
+       struct btrfs_log_ctx ctx_root;
+       struct btrfs_log_ctx ctx_dest;
+       bool sync_log_root = false;
+       bool sync_log_dest = false;
+       bool commit_transaction = false;
 
        /* we only allow rename subvolume link between subvolumes */
        if (old_ino != BTRFS_FIRST_FREE_OBJECTID && root != dest)
                return -EXDEV;
 
+       btrfs_init_log_ctx(&ctx_root, old_inode);
+       btrfs_init_log_ctx(&ctx_dest, new_inode);
+
        /* close the race window with snapshot create/destroy ioctl */
        if (old_ino == BTRFS_FIRST_FREE_OBJECTID)
                down_read(&fs_info->subvol_sem);
@@ -9542,15 +9539,29 @@ static int btrfs_rename_exchange(struct inode *old_dir,
 
        if (root_log_pinned) {
                parent = new_dentry->d_parent;
-               btrfs_log_new_name(trans, BTRFS_I(old_inode), BTRFS_I(old_dir),
-                               parent);
+               ret = btrfs_log_new_name(trans, BTRFS_I(old_inode),
+                                        BTRFS_I(old_dir), parent,
+                                        false, &ctx_root);
+               if (ret == BTRFS_NEED_LOG_SYNC)
+                       sync_log_root = true;
+               else if (ret == BTRFS_NEED_TRANS_COMMIT)
+                       commit_transaction = true;
+               ret = 0;
                btrfs_end_log_trans(root);
                root_log_pinned = false;
        }
        if (dest_log_pinned) {
-               parent = old_dentry->d_parent;
-               btrfs_log_new_name(trans, BTRFS_I(new_inode), BTRFS_I(new_dir),
-                               parent);
+               if (!commit_transaction) {
+                       parent = old_dentry->d_parent;
+                       ret = btrfs_log_new_name(trans, BTRFS_I(new_inode),
+                                                BTRFS_I(new_dir), parent,
+                                                false, &ctx_dest);
+                       if (ret == BTRFS_NEED_LOG_SYNC)
+                               sync_log_dest = true;
+                       else if (ret == BTRFS_NEED_TRANS_COMMIT)
+                               commit_transaction = true;
+                       ret = 0;
+               }
                btrfs_end_log_trans(dest);
                dest_log_pinned = false;
        }
@@ -9583,8 +9594,26 @@ out_fail:
                        dest_log_pinned = false;
                }
        }
-       ret2 = btrfs_end_transaction(trans);
-       ret = ret ? ret : ret2;
+       if (!ret && sync_log_root && !commit_transaction) {
+               ret = btrfs_sync_log(trans, BTRFS_I(old_inode)->root,
+                                    &ctx_root);
+               if (ret)
+                       commit_transaction = true;
+       }
+       if (!ret && sync_log_dest && !commit_transaction) {
+               ret = btrfs_sync_log(trans, BTRFS_I(new_inode)->root,
+                                    &ctx_dest);
+               if (ret)
+                       commit_transaction = true;
+       }
+       if (commit_transaction) {
+               ret = btrfs_commit_transaction(trans);
+       } else {
+               int ret2;
+
+               ret2 = btrfs_end_transaction(trans);
+               ret = ret ? ret : ret2;
+       }
 out_notrans:
        if (new_ino == BTRFS_FIRST_FREE_OBJECTID)
                up_read(&fs_info->subvol_sem);
@@ -9661,6 +9690,9 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        int ret;
        u64 old_ino = btrfs_ino(BTRFS_I(old_inode));
        bool log_pinned = false;
+       struct btrfs_log_ctx ctx;
+       bool sync_log = false;
+       bool commit_transaction = false;
 
        if (btrfs_ino(BTRFS_I(new_dir)) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)
                return -EPERM;
@@ -9818,8 +9850,15 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        if (log_pinned) {
                struct dentry *parent = new_dentry->d_parent;
 
-               btrfs_log_new_name(trans, BTRFS_I(old_inode), BTRFS_I(old_dir),
-                               parent);
+               btrfs_init_log_ctx(&ctx, old_inode);
+               ret = btrfs_log_new_name(trans, BTRFS_I(old_inode),
+                                        BTRFS_I(old_dir), parent,
+                                        false, &ctx);
+               if (ret == BTRFS_NEED_LOG_SYNC)
+                       sync_log = true;
+               else if (ret == BTRFS_NEED_TRANS_COMMIT)
+                       commit_transaction = true;
+               ret = 0;
                btrfs_end_log_trans(root);
                log_pinned = false;
        }
@@ -9856,7 +9895,19 @@ out_fail:
                btrfs_end_log_trans(root);
                log_pinned = false;
        }
-       btrfs_end_transaction(trans);
+       if (!ret && sync_log) {
+               ret = btrfs_sync_log(trans, BTRFS_I(old_inode)->root, &ctx);
+               if (ret)
+                       commit_transaction = true;
+       }
+       if (commit_transaction) {
+               ret = btrfs_commit_transaction(trans);
+       } else {
+               int ret2;
+
+               ret2 = btrfs_end_transaction(trans);
+               ret = ret ? ret : ret2;
+       }
 out_notrans:
        if (old_ino == BTRFS_FIRST_FREE_OBJECTID)
                up_read(&fs_info->subvol_sem);
index d3a5d2a41e5f19dfc4a0311f00d91464e2048733..d60b6caf09e857ef7c39e8ce337171d04cca1d72 100644 (file)
@@ -747,6 +747,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
        struct btrfs_pending_snapshot *pending_snapshot;
        struct btrfs_trans_handle *trans;
        int ret;
+       bool snapshot_force_cow = false;
 
        if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state))
                return -EINVAL;
@@ -763,6 +764,11 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
                goto free_pending;
        }
 
+       /*
+        * Force new buffered writes to reserve space even when NOCOW is
+        * possible. This is to avoid later writeback (running dealloc) to
+        * fallback to COW mode and unexpectedly fail with ENOSPC.
+        */
        atomic_inc(&root->will_be_snapshotted);
        smp_mb__after_atomic();
        /* wait for no snapshot writes */
@@ -773,6 +779,14 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
        if (ret)
                goto dec_and_free;
 
+       /*
+        * All previous writes have started writeback in NOCOW mode, so now
+        * we force future writes to fallback to COW mode during snapshot
+        * creation.
+        */
+       atomic_inc(&root->snapshot_force_cow);
+       snapshot_force_cow = true;
+
        btrfs_wait_ordered_extents(root, U64_MAX, 0, (u64)-1);
 
        btrfs_init_block_rsv(&pending_snapshot->block_rsv,
@@ -837,6 +851,8 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
 fail:
        btrfs_subvolume_release_metadata(fs_info, &pending_snapshot->block_rsv);
 dec_and_free:
+       if (snapshot_force_cow)
+               atomic_dec(&root->snapshot_force_cow);
        if (atomic_dec_and_test(&root->will_be_snapshotted))
                wake_up_var(&root->will_be_snapshotted);
 free_pending:
@@ -3453,6 +3469,25 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 olen,
 
                same_lock_start = min_t(u64, loff, dst_loff);
                same_lock_len = max_t(u64, loff, dst_loff) + len - same_lock_start;
+       } else {
+               /*
+                * If the source and destination inodes are different, the
+                * source's range end offset matches the source's i_size, that
+                * i_size is not a multiple of the sector size, and the
+                * destination range does not go past the destination's i_size,
+                * we must round down the length to the nearest sector size
+                * multiple. If we don't do this adjustment we end replacing
+                * with zeroes the bytes in the range that starts at the
+                * deduplication range's end offset and ends at the next sector
+                * size multiple.
+                */
+               if (loff + olen == i_size_read(src) &&
+                   dst_loff + len < i_size_read(dst)) {
+                       const u64 sz = BTRFS_I(src)->root->fs_info->sectorsize;
+
+                       len = round_down(i_size_read(src), sz) - loff;
+                       olen = len;
+               }
        }
 
 again:
@@ -3592,13 +3627,13 @@ out_unlock:
        return ret;
 }
 
-ssize_t btrfs_dedupe_file_range(struct file *src_file, u64 loff, u64 olen,
-                               struct file *dst_file, u64 dst_loff)
+int btrfs_dedupe_file_range(struct file *src_file, loff_t src_loff,
+                           struct file *dst_file, loff_t dst_loff,
+                           u64 olen)
 {
        struct inode *src = file_inode(src_file);
        struct inode *dst = file_inode(dst_file);
        u64 bs = BTRFS_I(src)->root->fs_info->sb->s_blocksize;
-       ssize_t res;
 
        if (WARN_ON_ONCE(bs < PAGE_SIZE)) {
                /*
@@ -3609,10 +3644,7 @@ ssize_t btrfs_dedupe_file_range(struct file *src_file, u64 loff, u64 olen,
                return -EINVAL;
        }
 
-       res = btrfs_extent_same(src, loff, olen, dst, dst_loff);
-       if (res)
-               return res;
-       return olen;
+       return btrfs_extent_same(src, src_loff, olen, dst, dst_loff);
 }
 
 static int clone_finish_inode_update(struct btrfs_trans_handle *trans,
index 4353bb69bb8672267286562c1bdd629fecca4e9b..d4917c0cddf57f11b6fbb600d73e629fcbd14093 100644 (file)
@@ -1019,10 +1019,9 @@ out_add_root:
        spin_unlock(&fs_info->qgroup_lock);
 
        ret = btrfs_commit_transaction(trans);
-       if (ret) {
-               trans = NULL;
+       trans = NULL;
+       if (ret)
                goto out_free_path;
-       }
 
        ret = qgroup_rescan_init(fs_info, 0, 1);
        if (!ret) {
index 1650dc44a5e37e483efebcf1a9e84117b0a1ed6a..3c2ae0e4f25a8de78040f6ca0ca94d070f158dd2 100644 (file)
@@ -6025,14 +6025,25 @@ void btrfs_record_snapshot_destroy(struct btrfs_trans_handle *trans,
  * Call this after adding a new name for a file and it will properly
  * update the log to reflect the new name.
  *
- * It will return zero if all goes well, and it will return 1 if a
- * full transaction commit is required.
+ * @ctx can not be NULL when @sync_log is false, and should be NULL when it's
+ * true (because it's not used).
+ *
+ * Return value depends on whether @sync_log is true or false.
+ * When true: returns BTRFS_NEED_TRANS_COMMIT if the transaction needs to be
+ *            committed by the caller, and BTRFS_DONT_NEED_TRANS_COMMIT
+ *            otherwise.
+ * When false: returns BTRFS_DONT_NEED_LOG_SYNC if the caller does not need to
+ *             to sync the log, BTRFS_NEED_LOG_SYNC if it needs to sync the log,
+ *             or BTRFS_NEED_TRANS_COMMIT if the transaction needs to be
+ *             committed (without attempting to sync the log).
  */
 int btrfs_log_new_name(struct btrfs_trans_handle *trans,
                        struct btrfs_inode *inode, struct btrfs_inode *old_dir,
-                       struct dentry *parent)
+                       struct dentry *parent,
+                       bool sync_log, struct btrfs_log_ctx *ctx)
 {
        struct btrfs_fs_info *fs_info = trans->fs_info;
+       int ret;
 
        /*
         * this will force the logging code to walk the dentry chain
@@ -6047,9 +6058,34 @@ int btrfs_log_new_name(struct btrfs_trans_handle *trans,
         */
        if (inode->logged_trans <= fs_info->last_trans_committed &&
            (!old_dir || old_dir->logged_trans <= fs_info->last_trans_committed))
-               return 0;
+               return sync_log ? BTRFS_DONT_NEED_TRANS_COMMIT :
+                       BTRFS_DONT_NEED_LOG_SYNC;
+
+       if (sync_log) {
+               struct btrfs_log_ctx ctx2;
+
+               btrfs_init_log_ctx(&ctx2, &inode->vfs_inode);
+               ret = btrfs_log_inode_parent(trans, inode, parent, 0, LLONG_MAX,
+                                            LOG_INODE_EXISTS, &ctx2);
+               if (ret == BTRFS_NO_LOG_SYNC)
+                       return BTRFS_DONT_NEED_TRANS_COMMIT;
+               else if (ret)
+                       return BTRFS_NEED_TRANS_COMMIT;
+
+               ret = btrfs_sync_log(trans, inode->root, &ctx2);
+               if (ret)
+                       return BTRFS_NEED_TRANS_COMMIT;
+               return BTRFS_DONT_NEED_TRANS_COMMIT;
+       }
+
+       ASSERT(ctx);
+       ret = btrfs_log_inode_parent(trans, inode, parent, 0, LLONG_MAX,
+                                    LOG_INODE_EXISTS, ctx);
+       if (ret == BTRFS_NO_LOG_SYNC)
+               return BTRFS_DONT_NEED_LOG_SYNC;
+       else if (ret)
+               return BTRFS_NEED_TRANS_COMMIT;
 
-       return btrfs_log_inode_parent(trans, inode, parent, 0, LLONG_MAX,
-                                     LOG_INODE_EXISTS, NULL);
+       return BTRFS_NEED_LOG_SYNC;
 }
 
index 122e68b89a5ade4d64dcaf7ce887980c17fc9d5e..7ab9bb88a63935664a3d0dc556987f8f08f1561e 100644 (file)
@@ -71,8 +71,16 @@ void btrfs_record_unlink_dir(struct btrfs_trans_handle *trans,
                             int for_rename);
 void btrfs_record_snapshot_destroy(struct btrfs_trans_handle *trans,
                                   struct btrfs_inode *dir);
+/* Return values for btrfs_log_new_name() */
+enum {
+       BTRFS_DONT_NEED_TRANS_COMMIT,
+       BTRFS_NEED_TRANS_COMMIT,
+       BTRFS_DONT_NEED_LOG_SYNC,
+       BTRFS_NEED_LOG_SYNC,
+};
 int btrfs_log_new_name(struct btrfs_trans_handle *trans,
                        struct btrfs_inode *inode, struct btrfs_inode *old_dir,
-                       struct dentry *parent);
+                       struct dentry *parent,
+                       bool sync_log, struct btrfs_log_ctx *ctx);
 
 #endif
index da86706123ffa4d85ce19148be2157edb9d7d3a4..f4405e430da6e003306e1a4d471731e1a13c9230 100644 (file)
@@ -4491,7 +4491,12 @@ again:
 
        /* Now btrfs_update_device() will change the on-disk size. */
        ret = btrfs_update_device(trans, device);
-       btrfs_end_transaction(trans);
+       if (ret < 0) {
+               btrfs_abort_transaction(trans, ret);
+               btrfs_end_transaction(trans);
+       } else {
+               ret = btrfs_commit_transaction(trans);
+       }
 done:
        btrfs_free_path(path);
        if (ret) {
index 4cc679d5bf58c7bc0d0a7eb09cbc07ab0575197d..6f1ae3ac97896c6fff85e947b9fe7a6553368457 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/buffer_head.h>
 #include <linux/task_io_accounting_ops.h>
 #include <linux/bio.h>
-#include <linux/notifier.h>
 #include <linux/cpu.h>
 #include <linux/bitops.h>
 #include <linux/mpage.h>
index 59cb307b15fbea58eca82535b7a7b30ec6db5409..027408d55aeed946c13fc42ded7e3146f5a5fffa 100644 (file)
@@ -45,6 +45,7 @@ static inline void ceph_set_cached_acl(struct inode *inode,
 struct posix_acl *ceph_get_acl(struct inode *inode, int type)
 {
        int size;
+       unsigned int retry_cnt = 0;
        const char *name;
        char *value = NULL;
        struct posix_acl *acl;
@@ -60,6 +61,7 @@ struct posix_acl *ceph_get_acl(struct inode *inode, int type)
                BUG();
        }
 
+retry:
        size = __ceph_getxattr(inode, name, "", 0);
        if (size > 0) {
                value = kzalloc(size, GFP_NOFS);
@@ -68,12 +70,22 @@ struct posix_acl *ceph_get_acl(struct inode *inode, int type)
                size = __ceph_getxattr(inode, name, value, size);
        }
 
-       if (size > 0)
+       if (size == -ERANGE && retry_cnt < 10) {
+               retry_cnt++;
+               kfree(value);
+               value = NULL;
+               goto retry;
+       }
+
+       if (size > 0) {
                acl = posix_acl_from_xattr(&init_user_ns, value, size);
-       else if (size == -ERANGE || size == -ENODATA || size == 0)
+       } else if (size == -ENODATA || size == 0) {
                acl = NULL;
-       else
+       } else {
+               pr_err_ratelimited("get acl %llx.%llx failed, err=%d\n",
+                                  ceph_vinop(inode), size);
                acl = ERR_PTR(-EIO);
+       }
 
        kfree(value);
 
@@ -89,6 +101,7 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
        const char *name = NULL;
        char *value = NULL;
        struct iattr newattrs;
+       struct timespec64 old_ctime = inode->i_ctime;
        umode_t new_mode = inode->i_mode, old_mode = inode->i_mode;
 
        switch (type) {
@@ -133,7 +146,7 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
        if (new_mode != old_mode) {
                newattrs.ia_ctime = current_time(inode);
                newattrs.ia_mode = new_mode;
-               newattrs.ia_valid = ATTR_MODE;
+               newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
                ret = __ceph_setattr(inode, &newattrs);
                if (ret)
                        goto out_free;
@@ -142,8 +155,9 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
        ret = __ceph_setxattr(inode, name, value, size, 0);
        if (ret) {
                if (new_mode != old_mode) {
+                       newattrs.ia_ctime = old_ctime;
                        newattrs.ia_mode = old_mode;
-                       newattrs.ia_valid = ATTR_MODE;
+                       newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
                        __ceph_setattr(inode, &newattrs);
                }
                goto out_free;
@@ -171,10 +185,10 @@ int ceph_pre_init_acls(struct inode *dir, umode_t *mode,
                return err;
 
        if (acl) {
-               int ret = posix_acl_equiv_mode(acl, mode);
-               if (ret < 0)
+               err = posix_acl_equiv_mode(acl, mode);
+               if (err < 0)
                        goto out_err;
-               if (ret == 0) {
+               if (err == 0) {
                        posix_acl_release(acl);
                        acl = NULL;
                }
index 292b3d72d72505579d3b642083e57983927ee1bc..9c332a6f66678a04cfe4b6cf05a33253c85f30f5 100644 (file)
@@ -574,7 +574,6 @@ static u64 get_writepages_data_length(struct inode *inode,
  */
 static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
 {
-       struct timespec ts;
        struct inode *inode;
        struct ceph_inode_info *ci;
        struct ceph_fs_client *fsc;
@@ -625,12 +624,11 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
                set_bdi_congested(inode_to_bdi(inode), BLK_RW_ASYNC);
 
        set_page_writeback(page);
-       ts = timespec64_to_timespec(inode->i_mtime);
        err = ceph_osdc_writepages(&fsc->client->osdc, ceph_vino(inode),
                                   &ci->i_layout, snapc, page_off, len,
                                   ceph_wbc.truncate_seq,
                                   ceph_wbc.truncate_size,
-                                  &ts, &page, 1);
+                                  &inode->i_mtime, &page, 1);
        if (err < 0) {
                struct writeback_control tmp_wbc;
                if (!wbc)
@@ -1134,7 +1132,7 @@ new_request:
                        pages = NULL;
                }
 
-               req->r_mtime = timespec64_to_timespec(inode->i_mtime);
+               req->r_mtime = inode->i_mtime;
                rc = ceph_osdc_start_request(&fsc->client->osdc, req, true);
                BUG_ON(rc);
                req = NULL;
@@ -1431,7 +1429,7 @@ static void ceph_restore_sigs(sigset_t *oldset)
 /*
  * vm ops
  */
-static int ceph_filemap_fault(struct vm_fault *vmf)
+static vm_fault_t ceph_filemap_fault(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
        struct inode *inode = file_inode(vma->vm_file);
@@ -1439,8 +1437,9 @@ static int ceph_filemap_fault(struct vm_fault *vmf)
        struct ceph_file_info *fi = vma->vm_file->private_data;
        struct page *pinned_page = NULL;
        loff_t off = vmf->pgoff << PAGE_SHIFT;
-       int want, got, ret;
+       int want, got, err;
        sigset_t oldset;
+       vm_fault_t ret = VM_FAULT_SIGBUS;
 
        ceph_block_sigs(&oldset);
 
@@ -1452,8 +1451,8 @@ static int ceph_filemap_fault(struct vm_fault *vmf)
                want = CEPH_CAP_FILE_CACHE;
 
        got = 0;
-       ret = ceph_get_caps(ci, CEPH_CAP_FILE_RD, want, -1, &got, &pinned_page);
-       if (ret < 0)
+       err = ceph_get_caps(ci, CEPH_CAP_FILE_RD, want, -1, &got, &pinned_page);
+       if (err < 0)
                goto out_restore;
 
        dout("filemap_fault %p %llu~%zd got cap refs on %s\n",
@@ -1465,16 +1464,17 @@ static int ceph_filemap_fault(struct vm_fault *vmf)
                ceph_add_rw_context(fi, &rw_ctx);
                ret = filemap_fault(vmf);
                ceph_del_rw_context(fi, &rw_ctx);
+               dout("filemap_fault %p %llu~%zd drop cap refs %s ret %x\n",
+                       inode, off, (size_t)PAGE_SIZE,
+                               ceph_cap_string(got), ret);
        } else
-               ret = -EAGAIN;
+               err = -EAGAIN;
 
-       dout("filemap_fault %p %llu~%zd dropping cap refs on %s ret %d\n",
-            inode, off, (size_t)PAGE_SIZE, ceph_cap_string(got), ret);
        if (pinned_page)
                put_page(pinned_page);
        ceph_put_cap_refs(ci, got);
 
-       if (ret != -EAGAIN)
+       if (err != -EAGAIN)
                goto out_restore;
 
        /* read inline data */
@@ -1482,7 +1482,6 @@ static int ceph_filemap_fault(struct vm_fault *vmf)
                /* does not support inline data > PAGE_SIZE */
                ret = VM_FAULT_SIGBUS;
        } else {
-               int ret1;
                struct address_space *mapping = inode->i_mapping;
                struct page *page = find_or_create_page(mapping, 0,
                                                mapping_gfp_constraint(mapping,
@@ -1491,32 +1490,32 @@ static int ceph_filemap_fault(struct vm_fault *vmf)
                        ret = VM_FAULT_OOM;
                        goto out_inline;
                }
-               ret1 = __ceph_do_getattr(inode, page,
+               err = __ceph_do_getattr(inode, page,
                                         CEPH_STAT_CAP_INLINE_DATA, true);
-               if (ret1 < 0 || off >= i_size_read(inode)) {
+               if (err < 0 || off >= i_size_read(inode)) {
                        unlock_page(page);
                        put_page(page);
-                       if (ret1 < 0)
-                               ret = ret1;
+                       if (err == -ENOMEM)
+                               ret = VM_FAULT_OOM;
                        else
                                ret = VM_FAULT_SIGBUS;
                        goto out_inline;
                }
-               if (ret1 < PAGE_SIZE)
-                       zero_user_segment(page, ret1, PAGE_SIZE);
+               if (err < PAGE_SIZE)
+                       zero_user_segment(page, err, PAGE_SIZE);
                else
                        flush_dcache_page(page);
                SetPageUptodate(page);
                vmf->page = page;
                ret = VM_FAULT_MAJOR | VM_FAULT_LOCKED;
 out_inline:
-               dout("filemap_fault %p %llu~%zd read inline data ret %d\n",
+               dout("filemap_fault %p %llu~%zd read inline data ret %x\n",
                     inode, off, (size_t)PAGE_SIZE, ret);
        }
 out_restore:
        ceph_restore_sigs(&oldset);
-       if (ret < 0)
-               ret = (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS;
+       if (err < 0)
+               ret = vmf_error(err);
 
        return ret;
 }
@@ -1524,7 +1523,7 @@ out_restore:
 /*
  * Reuse write_begin here for simplicity.
  */
-static int ceph_page_mkwrite(struct vm_fault *vmf)
+static vm_fault_t ceph_page_mkwrite(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
        struct inode *inode = file_inode(vma->vm_file);
@@ -1535,8 +1534,9 @@ static int ceph_page_mkwrite(struct vm_fault *vmf)
        loff_t off = page_offset(page);
        loff_t size = i_size_read(inode);
        size_t len;
-       int want, got, ret;
+       int want, got, err;
        sigset_t oldset;
+       vm_fault_t ret = VM_FAULT_SIGBUS;
 
        prealloc_cf = ceph_alloc_cap_flush();
        if (!prealloc_cf)
@@ -1550,10 +1550,10 @@ static int ceph_page_mkwrite(struct vm_fault *vmf)
                        lock_page(page);
                        locked_page = page;
                }
-               ret = ceph_uninline_data(vma->vm_file, locked_page);
+               err = ceph_uninline_data(vma->vm_file, locked_page);
                if (locked_page)
                        unlock_page(locked_page);
-               if (ret < 0)
+               if (err < 0)
                        goto out_free;
        }
 
@@ -1570,9 +1570,9 @@ static int ceph_page_mkwrite(struct vm_fault *vmf)
                want = CEPH_CAP_FILE_BUFFER;
 
        got = 0;
-       ret = ceph_get_caps(ci, CEPH_CAP_FILE_WR, want, off + len,
+       err = ceph_get_caps(ci, CEPH_CAP_FILE_WR, want, off + len,
                            &got, NULL);
-       if (ret < 0)
+       if (err < 0)
                goto out_free;
 
        dout("page_mkwrite %p %llu~%zd got cap refs on %s\n",
@@ -1590,13 +1590,13 @@ static int ceph_page_mkwrite(struct vm_fault *vmf)
                        break;
                }
 
-               ret = ceph_update_writeable_page(vma->vm_file, off, len, page);
-               if (ret >= 0) {
+               err = ceph_update_writeable_page(vma->vm_file, off, len, page);
+               if (err >= 0) {
                        /* success.  we'll keep the page locked. */
                        set_page_dirty(page);
                        ret = VM_FAULT_LOCKED;
                }
-       } while (ret == -EAGAIN);
+       } while (err == -EAGAIN);
 
        if (ret == VM_FAULT_LOCKED ||
            ci->i_inline_version != CEPH_INLINE_NONE) {
@@ -1610,14 +1610,14 @@ static int ceph_page_mkwrite(struct vm_fault *vmf)
                        __mark_inode_dirty(inode, dirty);
        }
 
-       dout("page_mkwrite %p %llu~%zd dropping cap refs on %s ret %d\n",
+       dout("page_mkwrite %p %llu~%zd dropping cap refs on %s ret %x\n",
             inode, off, len, ceph_cap_string(got), ret);
        ceph_put_cap_refs(ci, got);
 out_free:
        ceph_restore_sigs(&oldset);
        ceph_free_cap_flush(prealloc_cf);
-       if (ret < 0)
-               ret = (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS;
+       if (err < 0)
+               ret = vmf_error(err);
        return ret;
 }
 
@@ -1734,7 +1734,7 @@ int ceph_uninline_data(struct file *filp, struct page *locked_page)
                goto out;
        }
 
-       req->r_mtime = timespec64_to_timespec(inode->i_mtime);
+       req->r_mtime = inode->i_mtime;
        err = ceph_osdc_start_request(&fsc->client->osdc, req, false);
        if (!err)
                err = ceph_osdc_wait_request(&fsc->client->osdc, req);
@@ -1776,7 +1776,7 @@ int ceph_uninline_data(struct file *filp, struct page *locked_page)
                        goto out_put;
        }
 
-       req->r_mtime = timespec64_to_timespec(inode->i_mtime);
+       req->r_mtime = inode->i_mtime;
        err = ceph_osdc_start_request(&fsc->client->osdc, req, false);
        if (!err)
                err = ceph_osdc_wait_request(&fsc->client->osdc, req);
@@ -1937,7 +1937,7 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci,
                                     0, false, true);
        err = ceph_osdc_start_request(&fsc->client->osdc, rd_req, false);
 
-       wr_req->r_mtime = timespec64_to_timespec(ci->vfs_inode.i_mtime);
+       wr_req->r_mtime = ci->vfs_inode.i_mtime;
        err2 = ceph_osdc_start_request(&fsc->client->osdc, wr_req, false);
 
        if (!err)
index 362900e424245bd7c5714fde340f9b6a286ce6f3..1bf3502bdd6f59b2f65ec4310e3b445e09ca9a98 100644 (file)
@@ -25,8 +25,9 @@
 #include "cache.h"
 
 struct ceph_aux_inode {
-       u64             version;
-       struct timespec mtime;
+       u64     version;
+       u64     mtime_sec;
+       u64     mtime_nsec;
 };
 
 struct fscache_netfs ceph_cache_netfs = {
@@ -130,7 +131,8 @@ static enum fscache_checkaux ceph_fscache_inode_check_aux(
 
        memset(&aux, 0, sizeof(aux));
        aux.version = ci->i_version;
-       aux.mtime = timespec64_to_timespec(inode->i_mtime);
+       aux.mtime_sec = inode->i_mtime.tv_sec;
+       aux.mtime_nsec = inode->i_mtime.tv_nsec;
 
        if (memcmp(data, &aux, sizeof(aux)) != 0)
                return FSCACHE_CHECKAUX_OBSOLETE;
@@ -163,7 +165,8 @@ void ceph_fscache_register_inode_cookie(struct inode *inode)
        if (!ci->fscache) {
                memset(&aux, 0, sizeof(aux));
                aux.version = ci->i_version;
-               aux.mtime = timespec64_to_timespec(inode->i_mtime);
+               aux.mtime_sec = inode->i_mtime.tv_sec;
+               aux.mtime_nsec = inode->i_mtime.tv_nsec;
                ci->fscache = fscache_acquire_cookie(fsc->fscache,
                                                     &ceph_fscache_inode_object_def,
                                                     &ci->i_vino, sizeof(ci->i_vino),
index 990258cbd836c810df88bb4949d897fca1b7f043..dd7dfdd2ba13903575aee52a0b8fc27660cda2f8 100644 (file)
@@ -156,6 +156,37 @@ void ceph_adjust_min_caps(struct ceph_mds_client *mdsc, int delta)
        spin_unlock(&mdsc->caps_list_lock);
 }
 
+static void __ceph_unreserve_caps(struct ceph_mds_client *mdsc, int nr_caps)
+{
+       struct ceph_cap *cap;
+       int i;
+
+       if (nr_caps) {
+               BUG_ON(mdsc->caps_reserve_count < nr_caps);
+               mdsc->caps_reserve_count -= nr_caps;
+               if (mdsc->caps_avail_count >=
+                   mdsc->caps_reserve_count + mdsc->caps_min_count) {
+                       mdsc->caps_total_count -= nr_caps;
+                       for (i = 0; i < nr_caps; i++) {
+                               cap = list_first_entry(&mdsc->caps_list,
+                                       struct ceph_cap, caps_item);
+                               list_del(&cap->caps_item);
+                               kmem_cache_free(ceph_cap_cachep, cap);
+                       }
+               } else {
+                       mdsc->caps_avail_count += nr_caps;
+               }
+
+               dout("%s: caps %d = %d used + %d resv + %d avail\n",
+                    __func__,
+                    mdsc->caps_total_count, mdsc->caps_use_count,
+                    mdsc->caps_reserve_count, mdsc->caps_avail_count);
+               BUG_ON(mdsc->caps_total_count != mdsc->caps_use_count +
+                                                mdsc->caps_reserve_count +
+                                                mdsc->caps_avail_count);
+       }
+}
+
 /*
  * Called under mdsc->mutex.
  */
@@ -167,6 +198,7 @@ int ceph_reserve_caps(struct ceph_mds_client *mdsc,
        int have;
        int alloc = 0;
        int max_caps;
+       int err = 0;
        bool trimmed = false;
        struct ceph_mds_session *s;
        LIST_HEAD(newcaps);
@@ -233,9 +265,14 @@ int ceph_reserve_caps(struct ceph_mds_client *mdsc,
 
                pr_warn("reserve caps ctx=%p ENOMEM need=%d got=%d\n",
                        ctx, need, have + alloc);
-               goto out_nomem;
+               err = -ENOMEM;
+               break;
+       }
+
+       if (!err) {
+               BUG_ON(have + alloc != need);
+               ctx->count = need;
        }
-       BUG_ON(have + alloc != need);
 
        spin_lock(&mdsc->caps_list_lock);
        mdsc->caps_total_count += alloc;
@@ -245,77 +282,26 @@ int ceph_reserve_caps(struct ceph_mds_client *mdsc,
        BUG_ON(mdsc->caps_total_count != mdsc->caps_use_count +
                                         mdsc->caps_reserve_count +
                                         mdsc->caps_avail_count);
+
+       if (err)
+               __ceph_unreserve_caps(mdsc, have + alloc);
+
        spin_unlock(&mdsc->caps_list_lock);
 
-       ctx->count = need;
        dout("reserve caps ctx=%p %d = %d used + %d resv + %d avail\n",
             ctx, mdsc->caps_total_count, mdsc->caps_use_count,
             mdsc->caps_reserve_count, mdsc->caps_avail_count);
-       return 0;
-
-out_nomem:
-
-       spin_lock(&mdsc->caps_list_lock);
-       mdsc->caps_avail_count += have;
-       mdsc->caps_reserve_count -= have;
-
-       while (!list_empty(&newcaps)) {
-               cap = list_first_entry(&newcaps,
-                               struct ceph_cap, caps_item);
-               list_del(&cap->caps_item);
-
-               /* Keep some preallocated caps around (ceph_min_count), to
-                * avoid lots of free/alloc churn. */
-               if (mdsc->caps_avail_count >=
-                   mdsc->caps_reserve_count + mdsc->caps_min_count) {
-                       kmem_cache_free(ceph_cap_cachep, cap);
-               } else {
-                       mdsc->caps_avail_count++;
-                       mdsc->caps_total_count++;
-                       list_add(&cap->caps_item, &mdsc->caps_list);
-               }
-       }
-
-       BUG_ON(mdsc->caps_total_count != mdsc->caps_use_count +
-                                        mdsc->caps_reserve_count +
-                                        mdsc->caps_avail_count);
-       spin_unlock(&mdsc->caps_list_lock);
-       return -ENOMEM;
+       return err;
 }
 
-int ceph_unreserve_caps(struct ceph_mds_client *mdsc,
+void ceph_unreserve_caps(struct ceph_mds_client *mdsc,
                        struct ceph_cap_reservation *ctx)
 {
-       int i;
-       struct ceph_cap *cap;
-
        dout("unreserve caps ctx=%p count=%d\n", ctx, ctx->count);
-       if (ctx->count) {
-               spin_lock(&mdsc->caps_list_lock);
-               BUG_ON(mdsc->caps_reserve_count < ctx->count);
-               mdsc->caps_reserve_count -= ctx->count;
-               if (mdsc->caps_avail_count >=
-                   mdsc->caps_reserve_count + mdsc->caps_min_count) {
-                       mdsc->caps_total_count -= ctx->count;
-                       for (i = 0; i < ctx->count; i++) {
-                               cap = list_first_entry(&mdsc->caps_list,
-                                       struct ceph_cap, caps_item);
-                               list_del(&cap->caps_item);
-                               kmem_cache_free(ceph_cap_cachep, cap);
-                       }
-               } else {
-                       mdsc->caps_avail_count += ctx->count;
-               }
-               ctx->count = 0;
-               dout("unreserve caps %d = %d used + %d resv + %d avail\n",
-                    mdsc->caps_total_count, mdsc->caps_use_count,
-                    mdsc->caps_reserve_count, mdsc->caps_avail_count);
-               BUG_ON(mdsc->caps_total_count != mdsc->caps_use_count +
-                                                mdsc->caps_reserve_count +
-                                                mdsc->caps_avail_count);
-               spin_unlock(&mdsc->caps_list_lock);
-       }
-       return 0;
+       spin_lock(&mdsc->caps_list_lock);
+       __ceph_unreserve_caps(mdsc, ctx->count);
+       ctx->count = 0;
+       spin_unlock(&mdsc->caps_list_lock);
 }
 
 struct ceph_cap *ceph_get_cap(struct ceph_mds_client *mdsc,
@@ -1125,7 +1111,7 @@ struct cap_msg_args {
        u64                     flush_tid, oldest_flush_tid, size, max_size;
        u64                     xattr_version;
        struct ceph_buffer      *xattr_buf;
-       struct timespec         atime, mtime, ctime;
+       struct timespec64       atime, mtime, ctime;
        int                     op, caps, wanted, dirty;
        u32                     seq, issue_seq, mseq, time_warp_seq;
        u32                     flags;
@@ -1146,7 +1132,7 @@ static int send_cap_msg(struct cap_msg_args *arg)
        struct ceph_msg *msg;
        void *p;
        size_t extra_len;
-       struct timespec zerotime = {0};
+       struct timespec64 zerotime = {0};
        struct ceph_osd_client *osdc = &arg->session->s_mdsc->fsc->client->osdc;
 
        dout("send_cap_msg %s %llx %llx caps %s wanted %s dirty %s"
@@ -1186,9 +1172,9 @@ static int send_cap_msg(struct cap_msg_args *arg)
 
        fc->size = cpu_to_le64(arg->size);
        fc->max_size = cpu_to_le64(arg->max_size);
-       ceph_encode_timespec(&fc->mtime, &arg->mtime);
-       ceph_encode_timespec(&fc->atime, &arg->atime);
-       ceph_encode_timespec(&fc->ctime, &arg->ctime);
+       ceph_encode_timespec64(&fc->mtime, &arg->mtime);
+       ceph_encode_timespec64(&fc->atime, &arg->atime);
+       ceph_encode_timespec64(&fc->ctime, &arg->ctime);
        fc->time_warp_seq = cpu_to_le32(arg->time_warp_seq);
 
        fc->uid = cpu_to_le32(from_kuid(&init_user_ns, arg->uid));
@@ -1237,7 +1223,7 @@ static int send_cap_msg(struct cap_msg_args *arg)
         * We just zero these out for now, as the MDS ignores them unless
         * the requisite feature flags are set (which we don't do yet).
         */
-       ceph_encode_timespec(p, &zerotime);
+       ceph_encode_timespec64(p, &zerotime);
        p += sizeof(struct ceph_timespec);
        ceph_encode_64(&p, 0);
 
@@ -1360,9 +1346,9 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
                arg.xattr_buf = NULL;
        }
 
-       arg.mtime = timespec64_to_timespec(inode->i_mtime);
-       arg.atime = timespec64_to_timespec(inode->i_atime);
-       arg.ctime = timespec64_to_timespec(inode->i_ctime);
+       arg.mtime = inode->i_mtime;
+       arg.atime = inode->i_atime;
+       arg.ctime = inode->i_ctime;
 
        arg.op = op;
        arg.caps = cap->implemented;
@@ -3148,11 +3134,11 @@ static void handle_cap_grant(struct inode *inode,
        }
 
        if (newcaps & CEPH_CAP_ANY_RD) {
-               struct timespec mtime, atime, ctime;
+               struct timespec64 mtime, atime, ctime;
                /* ctime/mtime/atime? */
-               ceph_decode_timespec(&mtime, &grant->mtime);
-               ceph_decode_timespec(&atime, &grant->atime);
-               ceph_decode_timespec(&ctime, &grant->ctime);
+               ceph_decode_timespec64(&mtime, &grant->mtime);
+               ceph_decode_timespec64(&atime, &grant->atime);
+               ceph_decode_timespec64(&ctime, &grant->ctime);
                ceph_fill_file_time(inode, extra_info->issued,
                                    le32_to_cpu(grant->time_warp_seq),
                                    &ctime, &mtime, &atime);
index 036ac0f3a393afe98278cd388de4e68b7e4b286c..82928cea02095a315fa9c631cbb19218af83774d 100644 (file)
@@ -827,12 +827,14 @@ static int ceph_mknod(struct inode *dir, struct dentry *dentry,
        if (ceph_snap(dir) != CEPH_NOSNAP)
                return -EROFS;
 
-       if (ceph_quota_is_max_files_exceeded(dir))
-               return -EDQUOT;
+       if (ceph_quota_is_max_files_exceeded(dir)) {
+               err = -EDQUOT;
+               goto out;
+       }
 
        err = ceph_pre_init_acls(dir, &mode, &acls);
        if (err < 0)
-               return err;
+               goto out;
 
        dout("mknod in dir %p dentry %p mode 0%ho rdev %d\n",
             dir, dentry, mode, rdev);
@@ -883,8 +885,10 @@ static int ceph_symlink(struct inode *dir, struct dentry *dentry,
        if (ceph_snap(dir) != CEPH_NOSNAP)
                return -EROFS;
 
-       if (ceph_quota_is_max_files_exceeded(dir))
-               return -EDQUOT;
+       if (ceph_quota_is_max_files_exceeded(dir)) {
+               err = -EDQUOT;
+               goto out;
+       }
 
        dout("symlink in dir %p dentry %p to '%s'\n", dir, dentry, dest);
        req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SYMLINK, USE_AUTH_MDS);
@@ -1393,7 +1397,7 @@ static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size,
                                " rfiles:   %20lld\n"
                                " rsubdirs: %20lld\n"
                                "rbytes:    %20lld\n"
-                               "rctime:    %10ld.%09ld\n",
+                               "rctime:    %10lld.%09ld\n",
                                ci->i_files + ci->i_subdirs,
                                ci->i_files,
                                ci->i_subdirs,
@@ -1401,8 +1405,8 @@ static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size,
                                ci->i_rfiles,
                                ci->i_rsubdirs,
                                ci->i_rbytes,
-                               (long)ci->i_rctime.tv_sec,
-                               (long)ci->i_rctime.tv_nsec);
+                               ci->i_rctime.tv_sec,
+                               ci->i_rctime.tv_nsec);
        }
 
        if (*ppos >= dfi->dir_info_len)
index e2679e8a25358d0fc96ee7aca8d304ff204bea99..92ab2043368291e68c5c4b67b2da7e6bfdd25fcf 100644 (file)
@@ -720,7 +720,7 @@ struct ceph_aio_request {
        struct list_head osd_reqs;
        unsigned num_reqs;
        atomic_t pending_reqs;
-       struct timespec mtime;
+       struct timespec64 mtime;
        struct ceph_cap_flush *prealloc_cf;
 };
 
@@ -922,7 +922,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
        int num_pages = 0;
        int flags;
        int ret;
-       struct timespec mtime = timespec64_to_timespec(current_time(inode));
+       struct timespec64 mtime = current_time(inode);
        size_t count = iov_iter_count(iter);
        loff_t pos = iocb->ki_pos;
        bool write = iov_iter_rw(iter) == WRITE;
@@ -1130,7 +1130,7 @@ ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
        int flags;
        int ret;
        bool check_caps = false;
-       struct timespec mtime = timespec64_to_timespec(current_time(inode));
+       struct timespec64 mtime = current_time(inode);
        size_t count = iov_iter_count(from);
 
        if (ceph_snap(file_inode(file)) != CEPH_NOSNAP)
@@ -1383,12 +1383,12 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
        struct ceph_file_info *fi = file->private_data;
        struct inode *inode = file_inode(file);
        struct ceph_inode_info *ci = ceph_inode(inode);
-       struct ceph_osd_client *osdc =
-               &ceph_sb_to_client(inode->i_sb)->client->osdc;
+       struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
        struct ceph_cap_flush *prealloc_cf;
        ssize_t count, written = 0;
        int err, want, got;
        loff_t pos;
+       loff_t limit = max(i_size_read(inode), fsc->max_file_size);
 
        if (ceph_snap(inode) != CEPH_NOSNAP)
                return -EROFS;
@@ -1414,6 +1414,13 @@ retry_snap:
                goto out;
 
        pos = iocb->ki_pos;
+       if (unlikely(pos >= limit)) {
+               err = -EFBIG;
+               goto out;
+       } else {
+               iov_iter_truncate(from, limit - pos);
+       }
+
        count = iov_iter_count(from);
        if (ceph_quota_is_max_bytes_exceeded(inode, pos + count)) {
                err = -EDQUOT;
@@ -1435,7 +1442,7 @@ retry_snap:
        }
 
        /* FIXME: not complete since it doesn't account for being at quota */
-       if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL)) {
+       if (ceph_osdmap_flag(&fsc->client->osdc, CEPH_OSDMAP_FULL)) {
                err = -ENOSPC;
                goto out;
        }
@@ -1525,7 +1532,7 @@ retry_snap:
        }
 
        if (written >= 0) {
-               if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_NEARFULL))
+               if (ceph_osdmap_flag(&fsc->client->osdc, CEPH_OSDMAP_NEARFULL))
                        iocb->ki_flags |= IOCB_DSYNC;
                written = generic_write_sync(iocb, written);
        }
@@ -1546,6 +1553,7 @@ out_unlocked:
 static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
 {
        struct inode *inode = file->f_mapping->host;
+       struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
        loff_t i_size;
        loff_t ret;
 
@@ -1590,7 +1598,7 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
                break;
        }
 
-       ret = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
+       ret = vfs_setpos(file, offset, max(i_size, fsc->max_file_size));
 
 out:
        inode_unlock(inode);
@@ -1662,7 +1670,7 @@ static int ceph_zero_partial_object(struct inode *inode,
                goto out;
        }
 
-       req->r_mtime = timespec64_to_timespec(inode->i_mtime);
+       req->r_mtime = inode->i_mtime;
        ret = ceph_osdc_start_request(&fsc->client->osdc, req, false);
        if (!ret) {
                ret = ceph_osdc_wait_request(&fsc->client->osdc, req);
@@ -1727,8 +1735,7 @@ static long ceph_fallocate(struct file *file, int mode,
        struct ceph_file_info *fi = file->private_data;
        struct inode *inode = file_inode(file);
        struct ceph_inode_info *ci = ceph_inode(inode);
-       struct ceph_osd_client *osdc =
-               &ceph_inode_to_client(inode)->client->osdc;
+       struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
        struct ceph_cap_flush *prealloc_cf;
        int want, got = 0;
        int dirty;
@@ -1736,6 +1743,9 @@ static long ceph_fallocate(struct file *file, int mode,
        loff_t endoff = 0;
        loff_t size;
 
+       if ((offset + length) > max(i_size_read(inode), fsc->max_file_size))
+               return -EFBIG;
+
        if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
                return -EOPNOTSUPP;
 
@@ -1759,7 +1769,7 @@ static long ceph_fallocate(struct file *file, int mode,
                goto unlock;
        }
 
-       if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL) &&
+       if (ceph_osdmap_flag(&fsc->client->osdc, CEPH_OSDMAP_FULL) &&
            !(mode & FALLOC_FL_PUNCH_HOLE)) {
                ret = -ENOSPC;
                goto unlock;
index a866be999216a81bcfa90dfcb17cc11177442731..ebc7bdaed2d0d3674013b4800bf4e0265eada596 100644 (file)
@@ -658,13 +658,10 @@ int ceph_fill_file_size(struct inode *inode, int issued,
 }
 
 void ceph_fill_file_time(struct inode *inode, int issued,
-                        u64 time_warp_seq, struct timespec *ctime,
-                        struct timespec *mtime, struct timespec *atime)
+                        u64 time_warp_seq, struct timespec64 *ctime,
+                        struct timespec64 *mtime, struct timespec64 *atime)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
-       struct timespec64 ctime64 = timespec_to_timespec64(*ctime);
-       struct timespec64 mtime64 = timespec_to_timespec64(*mtime);
-       struct timespec64 atime64 = timespec_to_timespec64(*atime);
        int warn = 0;
 
        if (issued & (CEPH_CAP_FILE_EXCL|
@@ -673,39 +670,39 @@ void ceph_fill_file_time(struct inode *inode, int issued,
                      CEPH_CAP_AUTH_EXCL|
                      CEPH_CAP_XATTR_EXCL)) {
                if (ci->i_version == 0 ||
-                   timespec64_compare(&ctime64, &inode->i_ctime) > 0) {
+                   timespec64_compare(ctime, &inode->i_ctime) > 0) {
                        dout("ctime %lld.%09ld -> %lld.%09ld inc w/ cap\n",
-                            (long long)inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
-                            (long long)ctime->tv_sec, ctime->tv_nsec);
-                       inode->i_ctime = ctime64;
+                            inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
+                            ctime->tv_sec, ctime->tv_nsec);
+                       inode->i_ctime = *ctime;
                }
                if (ci->i_version == 0 ||
                    ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) {
                        /* the MDS did a utimes() */
                        dout("mtime %lld.%09ld -> %lld.%09ld "
                             "tw %d -> %d\n",
-                            (long long)inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
-                            (long long)mtime->tv_sec, mtime->tv_nsec,
+                            inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
+                            mtime->tv_sec, mtime->tv_nsec,
                             ci->i_time_warp_seq, (int)time_warp_seq);
 
-                       inode->i_mtime = mtime64;
-                       inode->i_atime = atime64;
+                       inode->i_mtime = *mtime;
+                       inode->i_atime = *atime;
                        ci->i_time_warp_seq = time_warp_seq;
                } else if (time_warp_seq == ci->i_time_warp_seq) {
                        /* nobody did utimes(); take the max */
-                       if (timespec64_compare(&mtime64, &inode->i_mtime) > 0) {
+                       if (timespec64_compare(mtime, &inode->i_mtime) > 0) {
                                dout("mtime %lld.%09ld -> %lld.%09ld inc\n",
-                                    (long long)inode->i_mtime.tv_sec,
+                                    inode->i_mtime.tv_sec,
                                     inode->i_mtime.tv_nsec,
-                                    (long long)mtime->tv_sec, mtime->tv_nsec);
-                               inode->i_mtime = mtime64;
+                                    mtime->tv_sec, mtime->tv_nsec);
+                               inode->i_mtime = *mtime;
                        }
-                       if (timespec64_compare(&atime64, &inode->i_atime) > 0) {
+                       if (timespec64_compare(atime, &inode->i_atime) > 0) {
                                dout("atime %lld.%09ld -> %lld.%09ld inc\n",
-                                    (long long)inode->i_atime.tv_sec,
+                                    inode->i_atime.tv_sec,
                                     inode->i_atime.tv_nsec,
-                                    (long long)atime->tv_sec, atime->tv_nsec);
-                               inode->i_atime = atime64;
+                                    atime->tv_sec, atime->tv_nsec);
+                               inode->i_atime = *atime;
                        }
                } else if (issued & CEPH_CAP_FILE_EXCL) {
                        /* we did a utimes(); ignore mds values */
@@ -715,9 +712,9 @@ void ceph_fill_file_time(struct inode *inode, int issued,
        } else {
                /* we have no write|excl caps; whatever the MDS says is true */
                if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) >= 0) {
-                       inode->i_ctime = ctime64;
-                       inode->i_mtime = mtime64;
-                       inode->i_atime = atime64;
+                       inode->i_ctime = *ctime;
+                       inode->i_mtime = *mtime;
+                       inode->i_atime = *atime;
                        ci->i_time_warp_seq = time_warp_seq;
                } else {
                        warn = 1;
@@ -743,7 +740,7 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
        struct ceph_mds_reply_inode *info = iinfo->in;
        struct ceph_inode_info *ci = ceph_inode(inode);
        int issued, new_issued, info_caps;
-       struct timespec mtime, atime, ctime;
+       struct timespec64 mtime, atime, ctime;
        struct ceph_buffer *xattr_blob = NULL;
        struct ceph_string *pool_ns = NULL;
        struct ceph_cap *new_cap = NULL;
@@ -823,9 +820,9 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
 
        if (new_version || (new_issued & CEPH_CAP_ANY_RD)) {
                /* be careful with mtime, atime, size */
-               ceph_decode_timespec(&atime, &info->atime);
-               ceph_decode_timespec(&mtime, &info->mtime);
-               ceph_decode_timespec(&ctime, &info->ctime);
+               ceph_decode_timespec64(&atime, &info->atime);
+               ceph_decode_timespec64(&mtime, &info->mtime);
+               ceph_decode_timespec64(&ctime, &info->ctime);
                ceph_fill_file_time(inode, issued,
                                le32_to_cpu(info->time_warp_seq),
                                &ctime, &mtime, &atime);
@@ -872,7 +869,7 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
                        ci->i_rbytes = le64_to_cpu(info->rbytes);
                        ci->i_rfiles = le64_to_cpu(info->rfiles);
                        ci->i_rsubdirs = le64_to_cpu(info->rsubdirs);
-                       ceph_decode_timespec(&ci->i_rctime, &info->rctime);
+                       ceph_decode_timespec64(&ci->i_rctime, &info->rctime);
                }
        }
 
@@ -1954,7 +1951,6 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
        int err = 0;
        int inode_dirty_flags = 0;
        bool lock_snap_rwsem = false;
-       struct timespec ts;
 
        prealloc_cf = ceph_alloc_cap_flush();
        if (!prealloc_cf)
@@ -2030,8 +2026,8 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
 
        if (ia_valid & ATTR_ATIME) {
                dout("setattr %p atime %lld.%ld -> %lld.%ld\n", inode,
-                    (long long)inode->i_atime.tv_sec, inode->i_atime.tv_nsec,
-                    (long long)attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec);
+                    inode->i_atime.tv_sec, inode->i_atime.tv_nsec,
+                    attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec);
                if (issued & CEPH_CAP_FILE_EXCL) {
                        ci->i_time_warp_seq++;
                        inode->i_atime = attr->ia_atime;
@@ -2043,8 +2039,8 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
                        dirtied |= CEPH_CAP_FILE_WR;
                } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
                           !timespec64_equal(&inode->i_atime, &attr->ia_atime)) {
-                       ts = timespec64_to_timespec(attr->ia_atime);
-                       ceph_encode_timespec(&req->r_args.setattr.atime, &ts);
+                       ceph_encode_timespec64(&req->r_args.setattr.atime,
+                                              &attr->ia_atime);
                        mask |= CEPH_SETATTR_ATIME;
                        release |= CEPH_CAP_FILE_SHARED |
                                   CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR;
@@ -2052,8 +2048,8 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
        }
        if (ia_valid & ATTR_MTIME) {
                dout("setattr %p mtime %lld.%ld -> %lld.%ld\n", inode,
-                    (long long)inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
-                    (long long)attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec);
+                    inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
+                    attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec);
                if (issued & CEPH_CAP_FILE_EXCL) {
                        ci->i_time_warp_seq++;
                        inode->i_mtime = attr->ia_mtime;
@@ -2065,8 +2061,8 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
                        dirtied |= CEPH_CAP_FILE_WR;
                } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
                           !timespec64_equal(&inode->i_mtime, &attr->ia_mtime)) {
-                       ts = timespec64_to_timespec(attr->ia_mtime);
-                       ceph_encode_timespec(&req->r_args.setattr.mtime, &ts);
+                       ceph_encode_timespec64(&req->r_args.setattr.mtime,
+                                              &attr->ia_mtime);
                        mask |= CEPH_SETATTR_MTIME;
                        release |= CEPH_CAP_FILE_SHARED |
                                   CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR;
@@ -2097,8 +2093,8 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
                bool only = (ia_valid & (ATTR_SIZE|ATTR_MTIME|ATTR_ATIME|
                                         ATTR_MODE|ATTR_UID|ATTR_GID)) == 0;
                dout("setattr %p ctime %lld.%ld -> %lld.%ld (%s)\n", inode,
-                    (long long)inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
-                    (long long)attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec,
+                    inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
+                    attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec,
                     only ? "ctime only" : "ignored");
                if (only) {
                        /*
@@ -2140,7 +2136,7 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
                req->r_inode_drop = release;
                req->r_args.setattr.mask = cpu_to_le32(mask);
                req->r_num_caps = 1;
-               req->r_stamp = timespec64_to_timespec(attr->ia_ctime);
+               req->r_stamp = attr->ia_ctime;
                err = ceph_mdsc_do_request(mdsc, NULL, req);
        }
        dout("setattr %p result=%d (%s locally, %d remote)\n", inode, err,
@@ -2161,6 +2157,7 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
 int ceph_setattr(struct dentry *dentry, struct iattr *attr)
 {
        struct inode *inode = d_inode(dentry);
+       struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
        int err;
 
        if (ceph_snap(inode) != CEPH_NOSNAP)
@@ -2170,6 +2167,10 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
        if (err != 0)
                return err;
 
+       if ((attr->ia_valid & ATTR_SIZE) &&
+           attr->ia_size > max(inode->i_size, fsc->max_file_size))
+               return -EFBIG;
+
        if ((attr->ia_valid & ATTR_SIZE) &&
            ceph_quota_is_max_bytes_exceeded(inode, attr->ia_size))
                return -EDQUOT;
index dc8bc664a8716a5c946c70efa2dc5911cfb32962..bc43c822426a27673eb19754dabc282d182bfc12 100644 (file)
@@ -902,6 +902,27 @@ static struct ceph_msg *create_session_msg(u32 op, u64 seq)
        return msg;
 }
 
+static void encode_supported_features(void **p, void *end)
+{
+       static const unsigned char bits[] = CEPHFS_FEATURES_CLIENT_SUPPORTED;
+       static const size_t count = ARRAY_SIZE(bits);
+
+       if (count > 0) {
+               size_t i;
+               size_t size = ((size_t)bits[count - 1] + 64) / 64 * 8;
+
+               BUG_ON(*p + 4 + size > end);
+               ceph_encode_32(p, size);
+               memset(*p, 0, size);
+               for (i = 0; i < count; i++)
+                       ((unsigned char*)(*p))[i / 8] |= 1 << (bits[i] % 8);
+               *p += size;
+       } else {
+               BUG_ON(*p + 4 > end);
+               ceph_encode_32(p, 0);
+       }
+}
+
 /*
  * session message, specialization for CEPH_SESSION_REQUEST_OPEN
  * to include additional client metadata fields.
@@ -911,11 +932,11 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
        struct ceph_msg *msg;
        struct ceph_mds_session_head *h;
        int i = -1;
-       int metadata_bytes = 0;
+       int extra_bytes = 0;
        int metadata_key_count = 0;
        struct ceph_options *opt = mdsc->fsc->client->options;
        struct ceph_mount_options *fsopt = mdsc->fsc->mount_options;
-       void *p;
+       void *p, *end;
 
        const char* metadata[][2] = {
                {"hostname", mdsc->nodename},
@@ -926,21 +947,26 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
        };
 
        /* Calculate serialized length of metadata */
-       metadata_bytes = 4;  /* map length */
+       extra_bytes = 4;  /* map length */
        for (i = 0; metadata[i][0]; ++i) {
-               metadata_bytes += 8 + strlen(metadata[i][0]) +
+               extra_bytes += 8 + strlen(metadata[i][0]) +
                        strlen(metadata[i][1]);
                metadata_key_count++;
        }
+       /* supported feature */
+       extra_bytes += 4 + 8;
 
        /* Allocate the message */
-       msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h) + metadata_bytes,
+       msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h) + extra_bytes,
                           GFP_NOFS, false);
        if (!msg) {
                pr_err("create_session_msg ENOMEM creating msg\n");
                return NULL;
        }
-       h = msg->front.iov_base;
+       p = msg->front.iov_base;
+       end = p + msg->front.iov_len;
+
+       h = p;
        h->op = cpu_to_le32(CEPH_SESSION_REQUEST_OPEN);
        h->seq = cpu_to_le64(seq);
 
@@ -950,11 +976,11 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
         *
         * ClientSession messages with metadata are v2
         */
-       msg->hdr.version = cpu_to_le16(2);
+       msg->hdr.version = cpu_to_le16(3);
        msg->hdr.compat_version = cpu_to_le16(1);
 
        /* The write pointer, following the session_head structure */
-       p = msg->front.iov_base + sizeof(*h);
+       p += sizeof(*h);
 
        /* Number of entries in the map */
        ceph_encode_32(&p, metadata_key_count);
@@ -972,6 +998,10 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
                p += val_len;
        }
 
+       encode_supported_features(&p, end);
+       msg->front.iov_len = p - msg->front.iov_base;
+       msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
+
        return msg;
 }
 
@@ -1779,6 +1809,7 @@ struct ceph_mds_request *
 ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
 {
        struct ceph_mds_request *req = kzalloc(sizeof(*req), GFP_NOFS);
+       struct timespec64 ts;
 
        if (!req)
                return ERR_PTR(-ENOMEM);
@@ -1797,7 +1828,8 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
        init_completion(&req->r_safe_completion);
        INIT_LIST_HEAD(&req->r_unsafe_item);
 
-       req->r_stamp = timespec_trunc(current_kernel_time(), mdsc->fsc->sb->s_time_gran);
+       ktime_get_coarse_real_ts64(&ts);
+       req->r_stamp = timespec64_trunc(ts, mdsc->fsc->sb->s_time_gran);
 
        req->r_op = op;
        req->r_direct_mode = mode;
@@ -2094,7 +2126,7 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
        /* time stamp */
        {
                struct ceph_timespec ts;
-               ceph_encode_timespec(&ts, &req->r_stamp);
+               ceph_encode_timespec64(&ts, &req->r_stamp);
                ceph_encode_copy(&p, &ts, sizeof(ts));
        }
 
@@ -2187,7 +2219,7 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc,
                p = msg->front.iov_base + req->r_request_release_offset;
                {
                        struct ceph_timespec ts;
-                       ceph_encode_timespec(&ts, &req->r_stamp);
+                       ceph_encode_timespec64(&ts, &req->r_stamp);
                        ceph_encode_copy(&p, &ts, sizeof(ts));
                }
 
@@ -2225,7 +2257,7 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc,
 /*
  * send request, or put it on the appropriate wait list.
  */
-static int __do_request(struct ceph_mds_client *mdsc,
+static void __do_request(struct ceph_mds_client *mdsc,
                        struct ceph_mds_request *req)
 {
        struct ceph_mds_session *session = NULL;
@@ -2235,7 +2267,7 @@ static int __do_request(struct ceph_mds_client *mdsc,
        if (req->r_err || test_bit(CEPH_MDS_R_GOT_RESULT, &req->r_req_flags)) {
                if (test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags))
                        __unregister_request(mdsc, req);
-               goto out;
+               return;
        }
 
        if (req->r_timeout &&
@@ -2258,7 +2290,7 @@ static int __do_request(struct ceph_mds_client *mdsc,
                if (mdsc->mdsmap->m_epoch == 0) {
                        dout("do_request no mdsmap, waiting for map\n");
                        list_add(&req->r_wait, &mdsc->waiting_for_map);
-                       goto finish;
+                       return;
                }
                if (!(mdsc->fsc->mount_options->flags &
                      CEPH_MOUNT_OPT_MOUNTWAIT) &&
@@ -2276,7 +2308,7 @@ static int __do_request(struct ceph_mds_client *mdsc,
            ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) {
                dout("do_request no mds or not active, waiting for map\n");
                list_add(&req->r_wait, &mdsc->waiting_for_map);
-               goto out;
+               return;
        }
 
        /* get, open session */
@@ -2326,8 +2358,7 @@ finish:
                complete_request(mdsc, req);
                __unregister_request(mdsc, req);
        }
-out:
-       return err;
+       return;
 }
 
 /*
@@ -2748,7 +2779,7 @@ static void handle_session(struct ceph_mds_session *session,
        int wake = 0;
 
        /* decode */
-       if (msg->front.iov_len != sizeof(*h))
+       if (msg->front.iov_len < sizeof(*h))
                goto bad;
        op = le32_to_cpu(h->op);
        seq = le64_to_cpu(h->seq);
@@ -2958,15 +2989,12 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap,
                rec.v2.flock_len = (__force __le32)
                        ((ci->i_ceph_flags & CEPH_I_ERROR_FILELOCK) ? 0 : 1);
        } else {
-               struct timespec ts;
                rec.v1.cap_id = cpu_to_le64(cap->cap_id);
                rec.v1.wanted = cpu_to_le32(__ceph_caps_wanted(ci));
                rec.v1.issued = cpu_to_le32(cap->issued);
                rec.v1.size = cpu_to_le64(inode->i_size);
-               ts = timespec64_to_timespec(inode->i_mtime);
-               ceph_encode_timespec(&rec.v1.mtime, &ts);
-               ts = timespec64_to_timespec(inode->i_atime);
-               ceph_encode_timespec(&rec.v1.atime, &ts);
+               ceph_encode_timespec64(&rec.v1.mtime, &inode->i_mtime);
+               ceph_encode_timespec64(&rec.v1.atime, &inode->i_atime);
                rec.v1.snaprealm = cpu_to_le64(ci->i_snap_realm->ino);
                rec.v1.pathbase = cpu_to_le64(pathbase);
        }
@@ -3378,10 +3406,10 @@ static void handle_lease(struct ceph_mds_client *mdsc,
        vino.ino = le64_to_cpu(h->ino);
        vino.snap = CEPH_NOSNAP;
        seq = le32_to_cpu(h->seq);
-       dname.name = (void *)h + sizeof(*h) + sizeof(u32);
-       dname.len = msg->front.iov_len - sizeof(*h) - sizeof(u32);
-       if (dname.len != get_unaligned_le32(h+1))
+       dname.len = get_unaligned_le32(h + 1);
+       if (msg->front.iov_len < sizeof(*h) + sizeof(u32) + dname.len)
                goto bad;
+       dname.name = (void *)(h + 1) + sizeof(u32);
 
        /* lookup inode */
        inode = ceph_find_inode(sb, vino);
@@ -3644,8 +3672,8 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
        init_rwsem(&mdsc->pool_perm_rwsem);
        mdsc->pool_perm_tree = RB_ROOT;
 
-       strncpy(mdsc->nodename, utsname()->nodename,
-               sizeof(mdsc->nodename) - 1);
+       strscpy(mdsc->nodename, utsname()->nodename,
+               sizeof(mdsc->nodename));
        return 0;
 }
 
@@ -4019,7 +4047,8 @@ void ceph_mdsc_handle_mdsmap(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
        } else {
                mdsc->mdsmap = newmap;  /* first mds map */
        }
-       mdsc->fsc->sb->s_maxbytes = mdsc->mdsmap->m_max_file_size;
+       mdsc->fsc->max_file_size = min((loff_t)mdsc->mdsmap->m_max_file_size,
+                                       MAX_LFS_FILESIZE);
 
        __wake_requests(mdsc, &mdsc->waiting_for_map);
        ceph_monc_got_map(&mdsc->fsc->client->monc, CEPH_SUB_MDSMAP,
@@ -4155,6 +4184,16 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con,
        return auth;
 }
 
+static int add_authorizer_challenge(struct ceph_connection *con,
+                                   void *challenge_buf, int challenge_buf_len)
+{
+       struct ceph_mds_session *s = con->private;
+       struct ceph_mds_client *mdsc = s->s_mdsc;
+       struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth;
+
+       return ceph_auth_add_authorizer_challenge(ac, s->s_auth.authorizer,
+                                           challenge_buf, challenge_buf_len);
+}
 
 static int verify_authorizer_reply(struct ceph_connection *con)
 {
@@ -4218,6 +4257,7 @@ static const struct ceph_connection_operations mds_con_ops = {
        .put = con_put,
        .dispatch = dispatch,
        .get_authorizer = get_authorizer,
+       .add_authorizer_challenge = add_authorizer_challenge,
        .verify_authorizer_reply = verify_authorizer_reply,
        .invalidate_authorizer = invalidate_authorizer,
        .peer_reset = peer_reset,
index 2ec3b5b350671a1fa1e574ae67d6a67567762dd8..32fcce0d4d3cbbc47a106b0297a61aa39f6c6e84 100644 (file)
 #include <linux/ceph/mdsmap.h>
 #include <linux/ceph/auth.h>
 
+/* The first 8 bits are reserved for old ceph releases */
+#define CEPHFS_FEATURE_MIMIC    8
+
+#define CEPHFS_FEATURES_ALL {           \
+  0, 1, 2, 3, 4, 5, 6, 7,              \
+  CEPHFS_FEATURE_MIMIC,                 \
+}
+
+#define CEPHFS_FEATURES_CLIENT_SUPPORTED CEPHFS_FEATURES_ALL
+#define CEPHFS_FEATURES_CLIENT_REQUIRED {}
+
+
 /*
  * Some lock dependencies:
  *
@@ -229,7 +241,7 @@ struct ceph_mds_request {
        int r_fmode;        /* file mode, if expecting cap */
        kuid_t r_uid;
        kgid_t r_gid;
-       struct timespec r_stamp;
+       struct timespec64 r_stamp;
 
        /* for choosing which mds to send this request to */
        int r_direct_mode;
index 242bfa5c0539ba3ba49bcca9f17760a6346688ea..32d4f13784ba5da85e420a565297eff6b3bf132a 100644 (file)
@@ -48,7 +48,7 @@ void ceph_handle_quota(struct ceph_mds_client *mdsc,
        struct inode *inode;
        struct ceph_inode_info *ci;
 
-       if (msg->front.iov_len != sizeof(*h)) {
+       if (msg->front.iov_len < sizeof(*h)) {
                pr_err("%s corrupt message mds%d len %d\n", __func__,
                       session->s_mds, (int)msg->front.iov_len);
                ceph_msg_dump(msg);
index af81555c14fd00a006ee360c95edf7335fc1f1fe..041c27ea8de155a0002bdb5af25eb2fc5f8e6efa 100644 (file)
@@ -594,9 +594,9 @@ int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
 
        BUG_ON(capsnap->writing);
        capsnap->size = inode->i_size;
-       capsnap->mtime = timespec64_to_timespec(inode->i_mtime);
-       capsnap->atime = timespec64_to_timespec(inode->i_atime);
-       capsnap->ctime = timespec64_to_timespec(inode->i_ctime);
+       capsnap->mtime = inode->i_mtime;
+       capsnap->atime = inode->i_atime;
+       capsnap->ctime = inode->i_ctime;
        capsnap->time_warp_seq = ci->i_time_warp_seq;
        capsnap->truncate_size = ci->i_truncate_size;
        capsnap->truncate_seq = ci->i_truncate_seq;
index 95a3b3ac9b6e251437d978d4fc7d513d2ea59507..eab1359d05532afb6960c7acfb5c4fee2891eac9 100644 (file)
@@ -219,8 +219,7 @@ static int parse_fsopt_token(char *c, void *private)
        if (token < Opt_last_int) {
                ret = match_int(&argstr[0], &intval);
                if (ret < 0) {
-                       pr_err("bad mount option arg (not int) "
-                              "at '%s'\n", c);
+                       pr_err("bad option arg (not int) at '%s'\n", c);
                        return ret;
                }
                dout("got int token %d val %d\n", token, intval);
@@ -603,6 +602,8 @@ static int extra_mon_dispatch(struct ceph_client *client, struct ceph_msg *msg)
 
 /*
  * create a new fs client
+ *
+ * Success or not, this function consumes @fsopt and @opt.
  */
 static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
                                        struct ceph_options *opt)
@@ -610,17 +611,20 @@ static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
        struct ceph_fs_client *fsc;
        int page_count;
        size_t size;
-       int err = -ENOMEM;
+       int err;
 
        fsc = kzalloc(sizeof(*fsc), GFP_KERNEL);
-       if (!fsc)
-               return ERR_PTR(-ENOMEM);
+       if (!fsc) {
+               err = -ENOMEM;
+               goto fail;
+       }
 
        fsc->client = ceph_create_client(opt, fsc);
        if (IS_ERR(fsc->client)) {
                err = PTR_ERR(fsc->client);
                goto fail;
        }
+       opt = NULL; /* fsc->client now owns this */
 
        fsc->client->extra_mon_dispatch = extra_mon_dispatch;
        fsc->client->osdc.abort_on_full = true;
@@ -678,6 +682,9 @@ fail_client:
        ceph_destroy_client(fsc->client);
 fail:
        kfree(fsc);
+       if (opt)
+               ceph_destroy_options(opt);
+       destroy_mount_options(fsopt);
        return ERR_PTR(err);
 }
 
@@ -941,11 +948,12 @@ static int ceph_set_super(struct super_block *s, void *data)
        dout("set_super %p data %p\n", s, data);
 
        s->s_flags = fsc->mount_options->sb_flags;
-       s->s_maxbytes = 1ULL << 40;  /* temp value until we get mdsmap */
+       s->s_maxbytes = MAX_LFS_FILESIZE;
 
        s->s_xattr = ceph_xattr_handlers;
        s->s_fs_info = fsc;
        fsc->sb = s;
+       fsc->max_file_size = 1ULL << 40; /* temp value until we get mdsmap */
 
        s->s_op = &ceph_super_ops;
        s->s_d_op = &ceph_dentry_ops;
@@ -1042,8 +1050,6 @@ static struct dentry *ceph_mount(struct file_system_type *fs_type,
        fsc = create_fs_client(fsopt, opt);
        if (IS_ERR(fsc)) {
                res = ERR_CAST(fsc);
-               destroy_mount_options(fsopt);
-               ceph_destroy_options(opt);
                goto out_final;
        }
 
index 971328b99edecc3ccb58421b6e458ca7fbb01278..582e28fd1b7bf1c6bda93b4796eb92cc4883fdd2 100644 (file)
@@ -98,6 +98,7 @@ struct ceph_fs_client {
 
        unsigned long mount_state;
        int min_caps;                  /* min caps i added */
+       loff_t max_file_size;
 
        struct ceph_mds_client *mdsc;
 
@@ -193,7 +194,7 @@ struct ceph_cap_snap {
        u64 xattr_version;
 
        u64 size;
-       struct timespec mtime, atime, ctime;
+       struct timespec64 mtime, atime, ctime;
        u64 time_warp_seq;
        u64 truncate_size;
        u32 truncate_seq;
@@ -307,7 +308,7 @@ struct ceph_inode_info {
        char *i_symlink;
 
        /* for dirs */
-       struct timespec i_rctime;
+       struct timespec64 i_rctime;
        u64 i_rbytes, i_rfiles, i_rsubdirs;
        u64 i_files, i_subdirs;
 
@@ -655,7 +656,7 @@ extern void ceph_caps_finalize(struct ceph_mds_client *mdsc);
 extern void ceph_adjust_min_caps(struct ceph_mds_client *mdsc, int delta);
 extern int ceph_reserve_caps(struct ceph_mds_client *mdsc,
                             struct ceph_cap_reservation *ctx, int need);
-extern int ceph_unreserve_caps(struct ceph_mds_client *mdsc,
+extern void ceph_unreserve_caps(struct ceph_mds_client *mdsc,
                               struct ceph_cap_reservation *ctx);
 extern void ceph_reservation_status(struct ceph_fs_client *client,
                                    int *total, int *avail, int *used,
@@ -857,8 +858,9 @@ extern struct inode *ceph_get_snapdir(struct inode *parent);
 extern int ceph_fill_file_size(struct inode *inode, int issued,
                               u32 truncate_seq, u64 truncate_size, u64 size);
 extern void ceph_fill_file_time(struct inode *inode, int issued,
-                               u64 time_warp_seq, struct timespec *ctime,
-                               struct timespec *mtime, struct timespec *atime);
+                               u64 time_warp_seq, struct timespec64 *ctime,
+                               struct timespec64 *mtime,
+                               struct timespec64 *atime);
 extern int ceph_fill_trace(struct super_block *sb,
                           struct ceph_mds_request *req);
 extern int ceph_readdir_prepopulate(struct ceph_mds_request *req,
index 5bc8edb4c2a60ce82bfd03ac55b48c7f3003fde3..5cc8b94f8206972ce6ce988b92b5103504b335b1 100644 (file)
@@ -224,8 +224,8 @@ static size_t ceph_vxattrcb_dir_rbytes(struct ceph_inode_info *ci, char *val,
 static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val,
                                       size_t size)
 {
-       return snprintf(val, size, "%ld.09%ld", (long)ci->i_rctime.tv_sec,
-                       (long)ci->i_rctime.tv_nsec);
+       return snprintf(val, size, "%lld.09%ld", ci->i_rctime.tv_sec,
+                       ci->i_rctime.tv_nsec);
 }
 
 /* quotas */
index b380e0871372df09635079008c970f6c8b6933c0..a2b2355e7f019c3bac02da2a6ffc3c9786c39f57 100644 (file)
@@ -105,9 +105,6 @@ convert_sfm_char(const __u16 src_char, char *target)
        case SFM_LESSTHAN:
                *target = '<';
                break;
-       case SFM_SLASH:
-               *target = '\\';
-               break;
        case SFM_SPACE:
                *target = ' ';
                break;
index f3a78efc31094f5cb34de2601744f46b7d9925ab..f047e87871a1c83a5c35106c8d99fe6358c8d79b 100644 (file)
@@ -148,5 +148,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
 extern const struct export_operations cifs_export_ops;
 #endif /* CONFIG_CIFS_NFSD_EXPORT */
 
-#define CIFS_VERSION   "2.12"
+#define CIFS_VERSION   "2.13"
 #endif                         /* _CIFSFS_H */
index c832a8a1970aabf11001237998df6f4c58208796..7aa08dba4719cde8c88c18bcb5ee4a4ddae733f1 100644 (file)
@@ -2547,7 +2547,7 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb_vol *volume_info)
        if (tcon == NULL)
                return -ENOMEM;
 
-       snprintf(unc, sizeof(unc), "\\\\%s\\IPC$", ses->serverName);
+       snprintf(unc, sizeof(unc), "\\\\%s\\IPC$", ses->server->hostname);
 
        /* cannot fail */
        nls_codepage = load_nls_default();
index d32eaa4b243767a9c65f0fc19906fdc00e0e4ece..6e8765f445086d2208a567825b5fb6022e564900 100644 (file)
@@ -467,6 +467,8 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path,
        oparms.cifs_sb = cifs_sb;
        oparms.desired_access = GENERIC_READ;
        oparms.create_options = CREATE_NOT_DIR;
+       if (backup_cred(cifs_sb))
+               oparms.create_options |= CREATE_OPEN_BACKUP_INTENT;
        oparms.disposition = FILE_OPEN;
        oparms.path = path;
        oparms.fid = &fid;
index 8b0502cd39afb6b27f89b24fdb63e8122f162aee..aa23c00367ec4644118090a73d5f9eb995229555 100644 (file)
@@ -398,6 +398,12 @@ int build_ntlmssp_auth_blob(unsigned char **pbuffer,
                goto setup_ntlmv2_ret;
        }
        *pbuffer = kmalloc(size_of_ntlmssp_blob(ses), GFP_KERNEL);
+       if (!*pbuffer) {
+               rc = -ENOMEM;
+               cifs_dbg(VFS, "Error %d during NTLMSSP allocation\n", rc);
+               *buflen = 0;
+               goto setup_ntlmv2_ret;
+       }
        sec_blob = (AUTHENTICATE_MESSAGE *)*pbuffer;
 
        memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
index 303d4592ebe727ea4d053d61f0036be69cfaa389..6a9c47541c53d0983a068703106ddacdbc834e04 100644 (file)
@@ -237,20 +237,31 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)
                if (clc_len == len + 1)
                        return 0;
 
+               /*
+                * Some windows servers (win2016) will pad also the final
+                * PDU in a compound to 8 bytes.
+                */
+               if (((clc_len + 7) & ~7) == len)
+                       return 0;
+
                /*
                 * MacOS server pads after SMB2.1 write response with 3 bytes
                 * of junk. Other servers match RFC1001 len to actual
                 * SMB2/SMB3 frame length (header + smb2 response specific data)
-                * Some windows servers do too when compounding is used.
-                * Log the server error (once), but allow it and continue
+                * Some windows servers also pad up to 8 bytes when compounding.
+                * If pad is longer than eight bytes, log the server behavior
+                * (once), since may indicate a problem but allow it and continue
                 * since the frame is parseable.
                 */
                if (clc_len < len) {
-                       printk_once(KERN_WARNING
-                               "SMB2 server sent bad RFC1001 len %d not %d\n",
-                               len, clc_len);
+                       pr_warn_once(
+                            "srv rsp padded more than expected. Length %d not %d for cmd:%d mid:%llu\n",
+                            len, clc_len, command, mid);
                        return 0;
                }
+               pr_warn_once(
+                       "srv rsp too short, len %d not %d. cmd:%d mid:%llu\n",
+                       len, clc_len, command, mid);
 
                return 1;
        }
index 541258447c4c4ec203f32cc1696af56f1fdb2509..d954ce36b4734c06ca63e2fdb0343f6109d2ec57 100644 (file)
@@ -630,7 +630,10 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
        oparms.tcon = tcon;
        oparms.desired_access = FILE_READ_ATTRIBUTES;
        oparms.disposition = FILE_OPEN;
-       oparms.create_options = 0;
+       if (backup_cred(cifs_sb))
+               oparms.create_options = CREATE_OPEN_BACKUP_INTENT;
+       else
+               oparms.create_options = 0;
        oparms.fid = &fid;
        oparms.reconnect = false;
 
@@ -779,7 +782,10 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon,
        oparms.tcon = tcon;
        oparms.desired_access = FILE_READ_EA;
        oparms.disposition = FILE_OPEN;
-       oparms.create_options = 0;
+       if (backup_cred(cifs_sb))
+               oparms.create_options = CREATE_OPEN_BACKUP_INTENT;
+       else
+               oparms.create_options = 0;
        oparms.fid = &fid;
        oparms.reconnect = false;
 
@@ -858,7 +864,10 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
        oparms.tcon = tcon;
        oparms.desired_access = FILE_WRITE_EA;
        oparms.disposition = FILE_OPEN;
-       oparms.create_options = 0;
+       if (backup_cred(cifs_sb))
+               oparms.create_options = CREATE_OPEN_BACKUP_INTENT;
+       else
+               oparms.create_options = 0;
        oparms.fid = &fid;
        oparms.reconnect = false;
 
@@ -1453,7 +1462,10 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
        oparms.tcon = tcon;
        oparms.desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA;
        oparms.disposition = FILE_OPEN;
-       oparms.create_options = 0;
+       if (backup_cred(cifs_sb))
+               oparms.create_options = CREATE_OPEN_BACKUP_INTENT;
+       else
+               oparms.create_options = 0;
        oparms.fid = fid;
        oparms.reconnect = false;
 
@@ -1582,7 +1594,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
        struct smb_rqst rqst[3];
        int resp_buftype[3];
        struct kvec rsp_iov[3];
-       struct kvec open_iov[5]; /* 4 + potential padding. */
+       struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
        struct kvec qi_iov[1];
        struct kvec close_iov[1];
        struct cifs_ses *ses = tcon->ses;
@@ -1603,7 +1615,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
 
        memset(&open_iov, 0, sizeof(open_iov));
        rqst[0].rq_iov = open_iov;
-       rqst[0].rq_nvec = 4;
+       rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
 
        oparms.tcon = tcon;
        oparms.desired_access = FILE_READ_ATTRIBUTES;
@@ -1857,7 +1869,10 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
        oparms.tcon = tcon;
        oparms.desired_access = FILE_READ_ATTRIBUTES;
        oparms.disposition = FILE_OPEN;
-       oparms.create_options = 0;
+       if (backup_cred(cifs_sb))
+               oparms.create_options = CREATE_OPEN_BACKUP_INTENT;
+       else
+               oparms.create_options = 0;
        oparms.fid = &fid;
        oparms.reconnect = false;
 
@@ -3639,7 +3654,7 @@ struct smb_version_values smb21_values = {
 struct smb_version_values smb3any_values = {
        .version_string = SMB3ANY_VERSION_STRING,
        .protocol_id = SMB302_PROT_ID, /* doesn't matter, send protocol array */
-       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION,
+       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
        .large_lock_type = 0,
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
@@ -3660,7 +3675,7 @@ struct smb_version_values smb3any_values = {
 struct smb_version_values smbdefault_values = {
        .version_string = SMBDEFAULT_VERSION_STRING,
        .protocol_id = SMB302_PROT_ID, /* doesn't matter, send protocol array */
-       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION,
+       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
        .large_lock_type = 0,
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
@@ -3681,7 +3696,7 @@ struct smb_version_values smbdefault_values = {
 struct smb_version_values smb30_values = {
        .version_string = SMB30_VERSION_STRING,
        .protocol_id = SMB30_PROT_ID,
-       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION,
+       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
        .large_lock_type = 0,
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
@@ -3702,7 +3717,7 @@ struct smb_version_values smb30_values = {
 struct smb_version_values smb302_values = {
        .version_string = SMB302_VERSION_STRING,
        .protocol_id = SMB302_PROT_ID,
-       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION,
+       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
        .large_lock_type = 0,
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
@@ -3723,7 +3738,7 @@ struct smb_version_values smb302_values = {
 struct smb_version_values smb311_values = {
        .version_string = SMB311_VERSION_STRING,
        .protocol_id = SMB311_PROT_ID,
-       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION,
+       .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING,
        .large_lock_type = 0,
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
index 2f193801139537ad7b5f2659a6f0f26545e2d412..c08acfc77abcf6f5190a0ce65d110a1b2f897875 100644 (file)
@@ -2178,6 +2178,9 @@ SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock,
        if (!(server->capabilities & SMB2_GLOBAL_CAP_LEASING) ||
            *oplock == SMB2_OPLOCK_LEVEL_NONE)
                req->RequestedOplockLevel = *oplock;
+       else if (!(server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) &&
+                 (oparms->create_options & CREATE_NOT_FILE))
+               req->RequestedOplockLevel = *oplock; /* no srv lease support */
        else {
                rc = add_lease_context(server, iov, &n_iov,
                                       oparms->fid->lease_key, oplock);
@@ -2256,7 +2259,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
        struct TCP_Server_Info *server;
        struct cifs_tcon *tcon = oparms->tcon;
        struct cifs_ses *ses = tcon->ses;
-       struct kvec iov[5]; /* make sure at least one for each open context */
+       struct kvec iov[SMB2_CREATE_IOV_SIZE];
        struct kvec rsp_iov = {NULL, 0};
        int resp_buftype;
        int rc = 0;
@@ -2274,7 +2277,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
        memset(&rqst, 0, sizeof(struct smb_rqst));
        memset(&iov, 0, sizeof(iov));
        rqst.rq_iov = iov;
-       rqst.rq_nvec = 5;
+       rqst.rq_nvec = SMB2_CREATE_IOV_SIZE;
 
        rc = SMB2_open_init(tcon, &rqst, oplock, oparms, path);
        if (rc)
index a2eeae9e0432529c27360e99f480e5afc451c259..8fb7887f2b3d98d4100a0aef9cdf000d0f119df0 100644 (file)
@@ -614,6 +614,18 @@ struct smb2_tree_disconnect_rsp {
 #define SMB2_CREATE_TAG_POSIX          0x93AD25509CB411E7B42383DE968BCD7C
 
 
+/*
+ * Maximum number of iovs we need for an open/create request.
+ * [0] : struct smb2_create_req
+ * [1] : path
+ * [2] : lease context
+ * [3] : durable context
+ * [4] : posix context
+ * [5] : time warp context
+ * [6] : compound padding
+ */
+#define SMB2_CREATE_IOV_SIZE 7
+
 struct smb2_create_req {
        struct smb2_sync_hdr sync_hdr;
        __le16 StructureSize;   /* Must be 57 */
index 897b51e41d8f0f741c7514bc3ddd8c5bb4277b4a..f32d7125ad0f237d61173cd72383683ac380c4e4 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -226,8 +226,8 @@ static inline void *unlock_slot(struct address_space *mapping, void **slot)
  *
  * Must be called with the i_pages lock held.
  */
-static void *get_unlocked_mapping_entry(struct address_space *mapping,
-                                       pgoff_t index, void ***slotp)
+static void *__get_unlocked_mapping_entry(struct address_space *mapping,
+               pgoff_t index, void ***slotp, bool (*wait_fn)(void))
 {
        void *entry, **slot;
        struct wait_exceptional_entry_queue ewait;
@@ -237,6 +237,8 @@ static void *get_unlocked_mapping_entry(struct address_space *mapping,
        ewait.wait.func = wake_exceptional_entry_func;
 
        for (;;) {
+               bool revalidate;
+
                entry = __radix_tree_lookup(&mapping->i_pages, index, NULL,
                                          &slot);
                if (!entry ||
@@ -251,14 +253,31 @@ static void *get_unlocked_mapping_entry(struct address_space *mapping,
                prepare_to_wait_exclusive(wq, &ewait.wait,
                                          TASK_UNINTERRUPTIBLE);
                xa_unlock_irq(&mapping->i_pages);
-               schedule();
+               revalidate = wait_fn();
                finish_wait(wq, &ewait.wait);
                xa_lock_irq(&mapping->i_pages);
+               if (revalidate)
+                       return ERR_PTR(-EAGAIN);
        }
 }
 
-static void dax_unlock_mapping_entry(struct address_space *mapping,
-                                    pgoff_t index)
+static bool entry_wait(void)
+{
+       schedule();
+       /*
+        * Never return an ERR_PTR() from
+        * __get_unlocked_mapping_entry(), just keep looping.
+        */
+       return false;
+}
+
+static void *get_unlocked_mapping_entry(struct address_space *mapping,
+               pgoff_t index, void ***slotp)
+{
+       return __get_unlocked_mapping_entry(mapping, index, slotp, entry_wait);
+}
+
+static void unlock_mapping_entry(struct address_space *mapping, pgoff_t index)
 {
        void *entry, **slot;
 
@@ -277,7 +296,7 @@ static void dax_unlock_mapping_entry(struct address_space *mapping,
 static void put_locked_mapping_entry(struct address_space *mapping,
                pgoff_t index)
 {
-       dax_unlock_mapping_entry(mapping, index);
+       unlock_mapping_entry(mapping, index);
 }
 
 /*
@@ -319,18 +338,27 @@ static unsigned long dax_radix_end_pfn(void *entry)
        for (pfn = dax_radix_pfn(entry); \
                        pfn < dax_radix_end_pfn(entry); pfn++)
 
-static void dax_associate_entry(void *entry, struct address_space *mapping)
+/*
+ * TODO: for reflink+dax we need a way to associate a single page with
+ * multiple address_space instances at different linear_page_index()
+ * offsets.
+ */
+static void dax_associate_entry(void *entry, struct address_space *mapping,
+               struct vm_area_struct *vma, unsigned long address)
 {
-       unsigned long pfn;
+       unsigned long size = dax_entry_size(entry), pfn, index;
+       int i = 0;
 
        if (IS_ENABLED(CONFIG_FS_DAX_LIMITED))
                return;
 
+       index = linear_page_index(vma, address & ~(size - 1));
        for_each_mapped_pfn(entry, pfn) {
                struct page *page = pfn_to_page(pfn);
 
                WARN_ON_ONCE(page->mapping);
                page->mapping = mapping;
+               page->index = index + i++;
        }
 }
 
@@ -348,6 +376,7 @@ static void dax_disassociate_entry(void *entry, struct address_space *mapping,
                WARN_ON_ONCE(trunc && page_ref_count(page) > 1);
                WARN_ON_ONCE(page->mapping && page->mapping != mapping);
                page->mapping = NULL;
+               page->index = 0;
        }
 }
 
@@ -364,6 +393,84 @@ static struct page *dax_busy_page(void *entry)
        return NULL;
 }
 
+static bool entry_wait_revalidate(void)
+{
+       rcu_read_unlock();
+       schedule();
+       rcu_read_lock();
+
+       /*
+        * Tell __get_unlocked_mapping_entry() to take a break, we need
+        * to revalidate page->mapping after dropping locks
+        */
+       return true;
+}
+
+bool dax_lock_mapping_entry(struct page *page)
+{
+       pgoff_t index;
+       struct inode *inode;
+       bool did_lock = false;
+       void *entry = NULL, **slot;
+       struct address_space *mapping;
+
+       rcu_read_lock();
+       for (;;) {
+               mapping = READ_ONCE(page->mapping);
+
+               if (!dax_mapping(mapping))
+                       break;
+
+               /*
+                * In the device-dax case there's no need to lock, a
+                * struct dev_pagemap pin is sufficient to keep the
+                * inode alive, and we assume we have dev_pagemap pin
+                * otherwise we would not have a valid pfn_to_page()
+                * translation.
+                */
+               inode = mapping->host;
+               if (S_ISCHR(inode->i_mode)) {
+                       did_lock = true;
+                       break;
+               }
+
+               xa_lock_irq(&mapping->i_pages);
+               if (mapping != page->mapping) {
+                       xa_unlock_irq(&mapping->i_pages);
+                       continue;
+               }
+               index = page->index;
+
+               entry = __get_unlocked_mapping_entry(mapping, index, &slot,
+                               entry_wait_revalidate);
+               if (!entry) {
+                       xa_unlock_irq(&mapping->i_pages);
+                       break;
+               } else if (IS_ERR(entry)) {
+                       WARN_ON_ONCE(PTR_ERR(entry) != -EAGAIN);
+                       continue;
+               }
+               lock_slot(mapping, slot);
+               did_lock = true;
+               xa_unlock_irq(&mapping->i_pages);
+               break;
+       }
+       rcu_read_unlock();
+
+       return did_lock;
+}
+
+void dax_unlock_mapping_entry(struct page *page)
+{
+       struct address_space *mapping = page->mapping;
+       struct inode *inode = mapping->host;
+
+       if (S_ISCHR(inode->i_mode))
+               return;
+
+       unlock_mapping_entry(mapping, page->index);
+}
+
 /*
  * Find radix tree entry at given index. If it points to an exceptional entry,
  * return it with the radix tree entry locked. If the radix tree doesn't
@@ -655,7 +762,6 @@ static int copy_user_dax(struct block_device *bdev, struct dax_device *dax_dev,
 {
        void *vto, *kaddr;
        pgoff_t pgoff;
-       pfn_t pfn;
        long rc;
        int id;
 
@@ -664,7 +770,7 @@ static int copy_user_dax(struct block_device *bdev, struct dax_device *dax_dev,
                return rc;
 
        id = dax_read_lock();
-       rc = dax_direct_access(dax_dev, pgoff, PHYS_PFN(size), &kaddr, &pfn);
+       rc = dax_direct_access(dax_dev, pgoff, PHYS_PFN(size), &kaddr, NULL);
        if (rc < 0) {
                dax_read_unlock(id);
                return rc;
@@ -709,7 +815,7 @@ static void *dax_insert_mapping_entry(struct address_space *mapping,
        new_entry = dax_radix_locked_entry(pfn, flags);
        if (dax_entry_size(entry) != dax_entry_size(new_entry)) {
                dax_disassociate_entry(entry, mapping, false);
-               dax_associate_entry(new_entry, mapping);
+               dax_associate_entry(new_entry, mapping, vmf->vma, vmf->address);
        }
 
        if (dax_is_zero_entry(entry) || dax_is_empty_entry(entry)) {
@@ -975,7 +1081,6 @@ static int dax_iomap_pfn(struct iomap *iomap, loff_t pos, size_t size,
 {
        const sector_t sector = dax_iomap_sector(iomap, pos);
        pgoff_t pgoff;
-       void *kaddr;
        int id, rc;
        long length;
 
@@ -984,7 +1089,7 @@ static int dax_iomap_pfn(struct iomap *iomap, loff_t pos, size_t size,
                return rc;
        id = dax_read_lock();
        length = dax_direct_access(iomap->dax_dev, pgoff, PHYS_PFN(size),
-                                  &kaddr, pfnp);
+                                  NULL, pfnp);
        if (length < 0) {
                rc = length;
                goto out;
@@ -1060,15 +1165,13 @@ int __dax_zero_page_range(struct block_device *bdev,
                pgoff_t pgoff;
                long rc, id;
                void *kaddr;
-               pfn_t pfn;
 
                rc = bdev_dax_pgoff(bdev, sector, PAGE_SIZE, &pgoff);
                if (rc)
                        return rc;
 
                id = dax_read_lock();
-               rc = dax_direct_access(dax_dev, pgoff, 1, &kaddr,
-                               &pfn);
+               rc = dax_direct_access(dax_dev, pgoff, 1, &kaddr, NULL);
                if (rc < 0) {
                        dax_read_unlock(id);
                        return rc;
@@ -1124,7 +1227,6 @@ dax_iomap_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
                ssize_t map_len;
                pgoff_t pgoff;
                void *kaddr;
-               pfn_t pfn;
 
                if (fatal_signal_pending(current)) {
                        ret = -EINTR;
@@ -1136,7 +1238,7 @@ dax_iomap_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
                        break;
 
                map_len = dax_direct_access(dax_dev, pgoff, PHYS_PFN(size),
-                               &kaddr, &pfn);
+                               &kaddr, NULL);
                if (map_len < 0) {
                        ret = map_len;
                        break;
index e072e955ce3334e44bdc529c2650518a6ca74a6c..c53814539070d5ac5d2196e2f4b7383055e11dd1 100644 (file)
@@ -46,7 +46,7 @@ static int pty_limit = NR_UNIX98_PTY_DEFAULT;
 static int pty_reserve = NR_UNIX98_PTY_RESERVE;
 static int pty_limit_min;
 static int pty_limit_max = INT_MAX;
-static int pty_count;
+static atomic_t pty_count = ATOMIC_INIT(0);
 
 static struct ctl_table pty_table[] = {
        {
@@ -93,8 +93,6 @@ static struct ctl_table pty_root_table[] = {
        {}
 };
 
-static DEFINE_MUTEX(allocated_ptys_lock);
-
 struct pts_mount_opts {
        int setuid;
        int setgid;
@@ -533,44 +531,25 @@ static struct file_system_type devpts_fs_type = {
 
 int devpts_new_index(struct pts_fs_info *fsi)
 {
-       int index;
-       int ida_ret;
-
-retry:
-       if (!ida_pre_get(&fsi->allocated_ptys, GFP_KERNEL))
-               return -ENOMEM;
-
-       mutex_lock(&allocated_ptys_lock);
-       if (pty_count >= (pty_limit -
-                         (fsi->mount_opts.reserve ? 0 : pty_reserve))) {
-               mutex_unlock(&allocated_ptys_lock);
-               return -ENOSPC;
-       }
+       int index = -ENOSPC;
 
-       ida_ret = ida_get_new(&fsi->allocated_ptys, &index);
-       if (ida_ret < 0) {
-               mutex_unlock(&allocated_ptys_lock);
-               if (ida_ret == -EAGAIN)
-                       goto retry;
-               return -EIO;
-       }
+       if (atomic_inc_return(&pty_count) >= (pty_limit -
+                         (fsi->mount_opts.reserve ? 0 : pty_reserve)))
+               goto out;
 
-       if (index >= fsi->mount_opts.max) {
-               ida_remove(&fsi->allocated_ptys, index);
-               mutex_unlock(&allocated_ptys_lock);
-               return -ENOSPC;
-       }
-       pty_count++;
-       mutex_unlock(&allocated_ptys_lock);
+       index = ida_alloc_max(&fsi->allocated_ptys, fsi->mount_opts.max - 1,
+                       GFP_KERNEL);
+
+out:
+       if (index < 0)
+               atomic_dec(&pty_count);
        return index;
 }
 
 void devpts_kill_index(struct pts_fs_info *fsi, int idx)
 {
-       mutex_lock(&allocated_ptys_lock);
-       ida_remove(&fsi->allocated_ptys, idx);
-       pty_count--;
-       mutex_unlock(&allocated_ptys_lock);
+       ida_free(&fsi->allocated_ptys, idx);
+       atomic_dec(&pty_count);
 }
 
 /**
index 67db22fe99c5ce8bf0ba606c0a45f221cbf69b38..42bbe6824b4bffc1fb5388c993abf102fcd8ea2b 100644 (file)
  *
  * 1) epmutex (mutex)
  * 2) ep->mtx (mutex)
- * 3) ep->lock (spinlock)
+ * 3) ep->wq.lock (spinlock)
  *
  * The acquire order is the one listed above, from 1 to 3.
- * We need a spinlock (ep->lock) because we manipulate objects
+ * We need a spinlock (ep->wq.lock) because we manipulate objects
  * from inside the poll callback, that might be triggered from
  * a wake_up() that in turn might be called from IRQ context.
  * So we can't sleep inside the poll callback and hence we need
@@ -85,7 +85,7 @@
  * of epoll file descriptors, we use the current recursion depth as
  * the lockdep subkey.
  * It is possible to drop the "ep->mtx" and to use the global
- * mutex "epmutex" (together with "ep->lock") to have it working,
+ * mutex "epmutex" (together with "ep->wq.lock") to have it working,
  * but having "ep->mtx" will make the interface more scalable.
  * Events that require holding "epmutex" are very rare, while for
  * normal operations the epoll private "ep->mtx" will guarantee
@@ -182,11 +182,10 @@ struct epitem {
  * This structure is stored inside the "private_data" member of the file
  * structure and represents the main data structure for the eventpoll
  * interface.
+ *
+ * Access to it is protected by the lock inside wq.
  */
 struct eventpoll {
-       /* Protect the access to this structure */
-       spinlock_t lock;
-
        /*
         * This mutex is used to ensure that files are not removed
         * while epoll is using them. This is held during the event
@@ -210,7 +209,7 @@ struct eventpoll {
        /*
         * This is a single linked list that chains all the "struct epitem" that
         * happened while transferring ready events to userspace w/out
-        * holding ->lock.
+        * holding ->wq.lock.
         */
        struct epitem *ovflist;
 
@@ -337,9 +336,9 @@ static inline int ep_cmp_ffd(struct epoll_filefd *p1,
 }
 
 /* Tells us if the item is currently linked */
-static inline int ep_is_linked(struct list_head *p)
+static inline int ep_is_linked(struct epitem *epi)
 {
-       return !list_empty(p);
+       return !list_empty(&epi->rdllink);
 }
 
 static inline struct eppoll_entry *ep_pwq_from_wait(wait_queue_entry_t *p)
@@ -392,7 +391,6 @@ static bool ep_busy_loop_end(void *p, unsigned long start_time)
 
        return ep_events_available(ep) || busy_loop_timeout(start_time);
 }
-#endif /* CONFIG_NET_RX_BUSY_POLL */
 
 /*
  * Busy poll if globally on and supporting sockets found && no events,
@@ -402,20 +400,16 @@ static bool ep_busy_loop_end(void *p, unsigned long start_time)
  */
 static void ep_busy_loop(struct eventpoll *ep, int nonblock)
 {
-#ifdef CONFIG_NET_RX_BUSY_POLL
        unsigned int napi_id = READ_ONCE(ep->napi_id);
 
        if ((napi_id >= MIN_NAPI_ID) && net_busy_loop_on())
                napi_busy_loop(napi_id, nonblock ? NULL : ep_busy_loop_end, ep);
-#endif
 }
 
 static inline void ep_reset_busy_poll_napi_id(struct eventpoll *ep)
 {
-#ifdef CONFIG_NET_RX_BUSY_POLL
        if (ep->napi_id)
                ep->napi_id = 0;
-#endif
 }
 
 /*
@@ -423,7 +417,6 @@ static inline void ep_reset_busy_poll_napi_id(struct eventpoll *ep)
  */
 static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
 {
-#ifdef CONFIG_NET_RX_BUSY_POLL
        struct eventpoll *ep;
        unsigned int napi_id;
        struct socket *sock;
@@ -453,9 +446,24 @@ static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
 
        /* record NAPI ID for use in next busy poll */
        ep->napi_id = napi_id;
-#endif
 }
 
+#else
+
+static inline void ep_busy_loop(struct eventpoll *ep, int nonblock)
+{
+}
+
+static inline void ep_reset_busy_poll_napi_id(struct eventpoll *ep)
+{
+}
+
+static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
+{
+}
+
+#endif /* CONFIG_NET_RX_BUSY_POLL */
+
 /**
  * ep_call_nested - Perform a bound (possibly) nested call, by checking
  *                  that the recursion limit is not exceeded, and that
@@ -668,10 +676,11 @@ static __poll_t ep_scan_ready_list(struct eventpoll *ep,
 {
        __poll_t res;
        int pwake = 0;
-       unsigned long flags;
        struct epitem *epi, *nepi;
        LIST_HEAD(txlist);
 
+       lockdep_assert_irqs_enabled();
+
        /*
         * We need to lock this because we could be hit by
         * eventpoll_release_file() and epoll_ctl().
@@ -688,17 +697,17 @@ static __poll_t ep_scan_ready_list(struct eventpoll *ep,
         * because we want the "sproc" callback to be able to do it
         * in a lockless way.
         */
-       spin_lock_irqsave(&ep->lock, flags);
+       spin_lock_irq(&ep->wq.lock);
        list_splice_init(&ep->rdllist, &txlist);
        ep->ovflist = NULL;
-       spin_unlock_irqrestore(&ep->lock, flags);
+       spin_unlock_irq(&ep->wq.lock);
 
        /*
         * Now call the callback function.
         */
        res = (*sproc)(ep, &txlist, priv);
 
-       spin_lock_irqsave(&ep->lock, flags);
+       spin_lock_irq(&ep->wq.lock);
        /*
         * During the time we spent inside the "sproc" callback, some
         * other events might have been queued by the poll callback.
@@ -712,7 +721,7 @@ static __poll_t ep_scan_ready_list(struct eventpoll *ep,
                 * queued into ->ovflist but the "txlist" might already
                 * contain them, and the list_splice() below takes care of them.
                 */
-               if (!ep_is_linked(&epi->rdllink)) {
+               if (!ep_is_linked(epi)) {
                        list_add_tail(&epi->rdllink, &ep->rdllist);
                        ep_pm_stay_awake(epi);
                }
@@ -740,7 +749,7 @@ static __poll_t ep_scan_ready_list(struct eventpoll *ep,
                if (waitqueue_active(&ep->poll_wait))
                        pwake++;
        }
-       spin_unlock_irqrestore(&ep->lock, flags);
+       spin_unlock_irq(&ep->wq.lock);
 
        if (!ep_locked)
                mutex_unlock(&ep->mtx);
@@ -764,16 +773,12 @@ static void epi_rcu_free(struct rcu_head *head)
  */
 static int ep_remove(struct eventpoll *ep, struct epitem *epi)
 {
-       unsigned long flags;
        struct file *file = epi->ffd.file;
 
+       lockdep_assert_irqs_enabled();
+
        /*
-        * Removes poll wait queue hooks. We _have_ to do this without holding
-        * the "ep->lock" otherwise a deadlock might occur. This because of the
-        * sequence of the lock acquisition. Here we do "ep->lock" then the wait
-        * queue head lock when unregistering the wait queue. The wakeup callback
-        * will run by holding the wait queue head lock and will call our callback
-        * that will try to get "ep->lock".
+        * Removes poll wait queue hooks.
         */
        ep_unregister_pollwait(ep, epi);
 
@@ -784,10 +789,10 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi)
 
        rb_erase_cached(&epi->rbn, &ep->rbr);
 
-       spin_lock_irqsave(&ep->lock, flags);
-       if (ep_is_linked(&epi->rdllink))
+       spin_lock_irq(&ep->wq.lock);
+       if (ep_is_linked(epi))
                list_del_init(&epi->rdllink);
-       spin_unlock_irqrestore(&ep->lock, flags);
+       spin_unlock_irq(&ep->wq.lock);
 
        wakeup_source_unregister(ep_wakeup_source(epi));
        /*
@@ -837,7 +842,7 @@ static void ep_free(struct eventpoll *ep)
         * Walks through the whole tree by freeing each "struct epitem". At this
         * point we are sure no poll callbacks will be lingering around, and also by
         * holding "epmutex" we can be sure that no file cleanup code will hit
-        * us during this operation. So we can avoid the lock on "ep->lock".
+        * us during this operation. So we can avoid the lock on "ep->wq.lock".
         * We do not need to lock ep->mtx, either, we only do it to prevent
         * a lockdep warning.
         */
@@ -1017,7 +1022,6 @@ static int ep_alloc(struct eventpoll **pep)
        if (unlikely(!ep))
                goto free_uid;
 
-       spin_lock_init(&ep->lock);
        mutex_init(&ep->mtx);
        init_waitqueue_head(&ep->wq);
        init_waitqueue_head(&ep->poll_wait);
@@ -1122,7 +1126,7 @@ static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, v
        __poll_t pollflags = key_to_poll(key);
        int ewake = 0;
 
-       spin_lock_irqsave(&ep->lock, flags);
+       spin_lock_irqsave(&ep->wq.lock, flags);
 
        ep_set_busy_poll_napi_id(epi);
 
@@ -1167,7 +1171,7 @@ static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, v
        }
 
        /* If this file is already in the ready list we exit soon */
-       if (!ep_is_linked(&epi->rdllink)) {
+       if (!ep_is_linked(epi)) {
                list_add_tail(&epi->rdllink, &ep->rdllist);
                ep_pm_stay_awake_rcu(epi);
        }
@@ -1199,7 +1203,7 @@ static int ep_poll_callback(wait_queue_entry_t *wait, unsigned mode, int sync, v
                pwake++;
 
 out_unlock:
-       spin_unlock_irqrestore(&ep->lock, flags);
+       spin_unlock_irqrestore(&ep->wq.lock, flags);
 
        /* We have to call this outside the lock */
        if (pwake)
@@ -1417,11 +1421,12 @@ static int ep_insert(struct eventpoll *ep, const struct epoll_event *event,
 {
        int error, pwake = 0;
        __poll_t revents;
-       unsigned long flags;
        long user_watches;
        struct epitem *epi;
        struct ep_pqueue epq;
 
+       lockdep_assert_irqs_enabled();
+
        user_watches = atomic_long_read(&ep->user->epoll_watches);
        if (unlikely(user_watches >= max_user_watches))
                return -ENOSPC;
@@ -1484,13 +1489,13 @@ static int ep_insert(struct eventpoll *ep, const struct epoll_event *event,
                goto error_remove_epi;
 
        /* We have to drop the new item inside our item list to keep track of it */
-       spin_lock_irqsave(&ep->lock, flags);
+       spin_lock_irq(&ep->wq.lock);
 
        /* record NAPI ID of new item if present */
        ep_set_busy_poll_napi_id(epi);
 
        /* If the file is already "ready" we drop it inside the ready list */
-       if (revents && !ep_is_linked(&epi->rdllink)) {
+       if (revents && !ep_is_linked(epi)) {
                list_add_tail(&epi->rdllink, &ep->rdllist);
                ep_pm_stay_awake(epi);
 
@@ -1501,7 +1506,7 @@ static int ep_insert(struct eventpoll *ep, const struct epoll_event *event,
                        pwake++;
        }
 
-       spin_unlock_irqrestore(&ep->lock, flags);
+       spin_unlock_irq(&ep->wq.lock);
 
        atomic_long_inc(&ep->user->epoll_watches);
 
@@ -1527,10 +1532,10 @@ error_unregister:
         * list, since that is used/cleaned only inside a section bound by "mtx".
         * And ep_insert() is called with "mtx" held.
         */
-       spin_lock_irqsave(&ep->lock, flags);
-       if (ep_is_linked(&epi->rdllink))
+       spin_lock_irq(&ep->wq.lock);
+       if (ep_is_linked(epi))
                list_del_init(&epi->rdllink);
-       spin_unlock_irqrestore(&ep->lock, flags);
+       spin_unlock_irq(&ep->wq.lock);
 
        wakeup_source_unregister(ep_wakeup_source(epi));
 
@@ -1550,6 +1555,8 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi,
        int pwake = 0;
        poll_table pt;
 
+       lockdep_assert_irqs_enabled();
+
        init_poll_funcptr(&pt, NULL);
 
        /*
@@ -1572,9 +1579,9 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi,
         * 1) Flush epi changes above to other CPUs.  This ensures
         *    we do not miss events from ep_poll_callback if an
         *    event occurs immediately after we call f_op->poll().
-        *    We need this because we did not take ep->lock while
+        *    We need this because we did not take ep->wq.lock while
         *    changing epi above (but ep_poll_callback does take
-        *    ep->lock).
+        *    ep->wq.lock).
         *
         * 2) We also need to ensure we do not miss _past_ events
         *    when calling f_op->poll().  This barrier also
@@ -1593,8 +1600,8 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi,
         * list, push it inside.
         */
        if (ep_item_poll(epi, &pt, 1)) {
-               spin_lock_irq(&ep->lock);
-               if (!ep_is_linked(&epi->rdllink)) {
+               spin_lock_irq(&ep->wq.lock);
+               if (!ep_is_linked(epi)) {
                        list_add_tail(&epi->rdllink, &ep->rdllist);
                        ep_pm_stay_awake(epi);
 
@@ -1604,7 +1611,7 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi,
                        if (waitqueue_active(&ep->poll_wait))
                                pwake++;
                }
-               spin_unlock_irq(&ep->lock);
+               spin_unlock_irq(&ep->wq.lock);
        }
 
        /* We have to call this outside the lock */
@@ -1739,11 +1746,12 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
                   int maxevents, long timeout)
 {
        int res = 0, eavail, timed_out = 0;
-       unsigned long flags;
        u64 slack = 0;
        wait_queue_entry_t wait;
        ktime_t expires, *to = NULL;
 
+       lockdep_assert_irqs_enabled();
+
        if (timeout > 0) {
                struct timespec64 end_time = ep_set_mstimeout(timeout);
 
@@ -1756,7 +1764,7 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
                 * caller specified a non blocking operation.
                 */
                timed_out = 1;
-               spin_lock_irqsave(&ep->lock, flags);
+               spin_lock_irq(&ep->wq.lock);
                goto check_events;
        }
 
@@ -1765,7 +1773,7 @@ fetch_events:
        if (!ep_events_available(ep))
                ep_busy_loop(ep, timed_out);
 
-       spin_lock_irqsave(&ep->lock, flags);
+       spin_lock_irq(&ep->wq.lock);
 
        if (!ep_events_available(ep)) {
                /*
@@ -1807,11 +1815,11 @@ fetch_events:
                                break;
                        }
 
-                       spin_unlock_irqrestore(&ep->lock, flags);
+                       spin_unlock_irq(&ep->wq.lock);
                        if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS))
                                timed_out = 1;
 
-                       spin_lock_irqsave(&ep->lock, flags);
+                       spin_lock_irq(&ep->wq.lock);
                }
 
                __remove_wait_queue(&ep->wq, &wait);
@@ -1821,7 +1829,7 @@ check_events:
        /* Is it worth to try to dig for events ? */
        eavail = ep_events_available(ep);
 
-       spin_unlock_irqrestore(&ep->lock, flags);
+       spin_unlock_irq(&ep->wq.lock);
 
        /*
         * Try to transfer events to user space. In case we get 0 events and
index bdd0eacefdf575b1351b5d00bf5d7d1bb05b50a1..1ebf6e5a521d9924aa6572bedba504efaf32ee9b 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1145,6 +1145,7 @@ static int de_thread(struct task_struct *tsk)
                 */
                tsk->pid = leader->pid;
                change_pid(tsk, PIDTYPE_PID, task_pid(leader));
+               transfer_pid(leader, tsk, PIDTYPE_TGID);
                transfer_pid(leader, tsk, PIDTYPE_PGID);
                transfer_pid(leader, tsk, PIDTYPE_SID);
 
index 9f1c96caebda1b63a3703d08742fc2309b7be349..e8b6b89bddb865e488c4213dcbf09fa79e4d83cb 100644 (file)
@@ -28,6 +28,7 @@ struct kmem_cache *f2fs_inode_entry_slab;
 
 void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io)
 {
+       f2fs_build_fault_attr(sbi, 0, 0);
        set_ckpt_flags(sbi, CP_ERROR_FLAG);
        if (!end_io)
                f2fs_flush_merged_writes(sbi);
@@ -70,6 +71,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
                .encrypted_page = NULL,
                .is_meta = is_meta,
        };
+       int err;
 
        if (unlikely(!is_meta))
                fio.op_flags &= ~REQ_META;
@@ -84,9 +86,10 @@ repeat:
 
        fio.page = page;
 
-       if (f2fs_submit_page_bio(&fio)) {
+       err = f2fs_submit_page_bio(&fio);
+       if (err) {
                f2fs_put_page(page, 1);
-               goto repeat;
+               return ERR_PTR(err);
        }
 
        lock_page(page);
@@ -95,14 +98,9 @@ repeat:
                goto repeat;
        }
 
-       /*
-        * if there is any IO error when accessing device, make our filesystem
-        * readonly and make sure do not write checkpoint with non-uptodate
-        * meta page.
-        */
        if (unlikely(!PageUptodate(page))) {
-               memset(page_address(page), 0, PAGE_SIZE);
-               f2fs_stop_checkpoint(sbi, false);
+               f2fs_put_page(page, 1);
+               return ERR_PTR(-EIO);
        }
 out:
        return page;
@@ -113,13 +111,32 @@ struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index)
        return __get_meta_page(sbi, index, true);
 }
 
+struct page *f2fs_get_meta_page_nofail(struct f2fs_sb_info *sbi, pgoff_t index)
+{
+       struct page *page;
+       int count = 0;
+
+retry:
+       page = __get_meta_page(sbi, index, true);
+       if (IS_ERR(page)) {
+               if (PTR_ERR(page) == -EIO &&
+                               ++count <= DEFAULT_RETRY_IO_COUNT)
+                       goto retry;
+
+               f2fs_stop_checkpoint(sbi, false);
+               f2fs_bug_on(sbi, 1);
+       }
+
+       return page;
+}
+
 /* for POR only */
 struct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index)
 {
        return __get_meta_page(sbi, index, false);
 }
 
-bool f2fs_is_valid_meta_blkaddr(struct f2fs_sb_info *sbi,
+bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
                                        block_t blkaddr, int type)
 {
        switch (type) {
@@ -140,8 +157,20 @@ bool f2fs_is_valid_meta_blkaddr(struct f2fs_sb_info *sbi,
                        return false;
                break;
        case META_POR:
+       case DATA_GENERIC:
                if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
-                       blkaddr < MAIN_BLKADDR(sbi)))
+                       blkaddr < MAIN_BLKADDR(sbi))) {
+                       if (type == DATA_GENERIC) {
+                               f2fs_msg(sbi->sb, KERN_WARNING,
+                                       "access invalid blkaddr:%u", blkaddr);
+                               WARN_ON(1);
+                       }
+                       return false;
+               }
+               break;
+       case META_GENERIC:
+               if (unlikely(blkaddr < SEG0_BLKADDR(sbi) ||
+                       blkaddr >= MAIN_BLKADDR(sbi)))
                        return false;
                break;
        default:
@@ -176,7 +205,7 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
        blk_start_plug(&plug);
        for (; nrpages-- > 0; blkno++) {
 
-               if (!f2fs_is_valid_meta_blkaddr(sbi, blkno, type))
+               if (!f2fs_is_valid_blkaddr(sbi, blkno, type))
                        goto out;
 
                switch (type) {
@@ -242,11 +271,8 @@ static int __f2fs_write_meta_page(struct page *page,
 
        trace_f2fs_writepage(page, META);
 
-       if (unlikely(f2fs_cp_error(sbi))) {
-               dec_page_count(sbi, F2FS_DIRTY_META);
-               unlock_page(page);
-               return 0;
-       }
+       if (unlikely(f2fs_cp_error(sbi)))
+               goto redirty_out;
        if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
                goto redirty_out;
        if (wbc->for_reclaim && page->index < GET_SUM_BLOCK(sbi, 0))
@@ -529,13 +555,12 @@ int f2fs_acquire_orphan_inode(struct f2fs_sb_info *sbi)
 
        spin_lock(&im->ino_lock);
 
-#ifdef CONFIG_F2FS_FAULT_INJECTION
        if (time_to_inject(sbi, FAULT_ORPHAN)) {
                spin_unlock(&im->ino_lock);
                f2fs_show_injection_info(FAULT_ORPHAN);
                return -ENOSPC;
        }
-#endif
+
        if (unlikely(im->ino_num >= sbi->max_orphans))
                err = -ENOSPC;
        else
@@ -572,12 +597,7 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
 {
        struct inode *inode;
        struct node_info ni;
-       int err = f2fs_acquire_orphan_inode(sbi);
-
-       if (err)
-               goto err_out;
-
-       __add_ino_entry(sbi, ino, 0, ORPHAN_INO);
+       int err;
 
        inode = f2fs_iget_retry(sbi->sb, ino);
        if (IS_ERR(inode)) {
@@ -600,14 +620,15 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
        /* truncate all the data during iput */
        iput(inode);
 
-       f2fs_get_node_info(sbi, ino, &ni);
+       err = f2fs_get_node_info(sbi, ino, &ni);
+       if (err)
+               goto err_out;
 
        /* ENOMEM was fully retried in f2fs_evict_inode. */
        if (ni.blk_addr != NULL_ADDR) {
                err = -EIO;
                goto err_out;
        }
-       __remove_ino_entry(sbi, ino, ORPHAN_INO);
        return 0;
 
 err_out:
@@ -639,7 +660,10 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi)
        /* Needed for iput() to work correctly and not trash data */
        sbi->sb->s_flags |= SB_ACTIVE;
 
-       /* Turn on quotas so that they are updated correctly */
+       /*
+        * Turn on quotas which were not enabled for read-only mounts if
+        * filesystem has quota feature, so that they are updated correctly.
+        */
        quota_enabled = f2fs_enable_quota_files(sbi, s_flags & SB_RDONLY);
 #endif
 
@@ -649,9 +673,15 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi)
        f2fs_ra_meta_pages(sbi, start_blk, orphan_blocks, META_CP, true);
 
        for (i = 0; i < orphan_blocks; i++) {
-               struct page *page = f2fs_get_meta_page(sbi, start_blk + i);
+               struct page *page;
                struct f2fs_orphan_block *orphan_blk;
 
+               page = f2fs_get_meta_page(sbi, start_blk + i);
+               if (IS_ERR(page)) {
+                       err = PTR_ERR(page);
+                       goto out;
+               }
+
                orphan_blk = (struct f2fs_orphan_block *)page_address(page);
                for (j = 0; j < le32_to_cpu(orphan_blk->entry_count); j++) {
                        nid_t ino = le32_to_cpu(orphan_blk->ino[j]);
@@ -742,10 +772,14 @@ static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr,
        __u32 crc = 0;
 
        *cp_page = f2fs_get_meta_page(sbi, cp_addr);
+       if (IS_ERR(*cp_page))
+               return PTR_ERR(*cp_page);
+
        *cp_block = (struct f2fs_checkpoint *)page_address(*cp_page);
 
        crc_offset = le32_to_cpu((*cp_block)->checksum_offset);
        if (crc_offset > (blk_size - sizeof(__le32))) {
+               f2fs_put_page(*cp_page, 1);
                f2fs_msg(sbi->sb, KERN_WARNING,
                        "invalid crc_offset: %zu", crc_offset);
                return -EINVAL;
@@ -753,6 +787,7 @@ static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr,
 
        crc = cur_cp_crc(*cp_block);
        if (!f2fs_crc_valid(sbi, crc, *cp_block, crc_offset)) {
+               f2fs_put_page(*cp_page, 1);
                f2fs_msg(sbi->sb, KERN_WARNING, "invalid crc value");
                return -EINVAL;
        }
@@ -772,14 +807,22 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
        err = get_checkpoint_version(sbi, cp_addr, &cp_block,
                                        &cp_page_1, version);
        if (err)
-               goto invalid_cp1;
+               return NULL;
+
+       if (le32_to_cpu(cp_block->cp_pack_total_block_count) >
+                                       sbi->blocks_per_seg) {
+               f2fs_msg(sbi->sb, KERN_WARNING,
+                       "invalid cp_pack_total_block_count:%u",
+                       le32_to_cpu(cp_block->cp_pack_total_block_count));
+               goto invalid_cp;
+       }
        pre_version = *version;
 
        cp_addr += le32_to_cpu(cp_block->cp_pack_total_block_count) - 1;
        err = get_checkpoint_version(sbi, cp_addr, &cp_block,
                                        &cp_page_2, version);
        if (err)
-               goto invalid_cp2;
+               goto invalid_cp;
        cur_version = *version;
 
        if (cur_version == pre_version) {
@@ -787,9 +830,8 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
                f2fs_put_page(cp_page_2, 1);
                return cp_page_1;
        }
-invalid_cp2:
        f2fs_put_page(cp_page_2, 1);
-invalid_cp1:
+invalid_cp:
        f2fs_put_page(cp_page_1, 1);
        return NULL;
 }
@@ -838,15 +880,15 @@ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi)
        cp_block = (struct f2fs_checkpoint *)page_address(cur_page);
        memcpy(sbi->ckpt, cp_block, blk_size);
 
-       /* Sanity checking of checkpoint */
-       if (f2fs_sanity_check_ckpt(sbi))
-               goto free_fail_no_cp;
-
        if (cur_page == cp1)
                sbi->cur_cp_pack = 1;
        else
                sbi->cur_cp_pack = 2;
 
+       /* Sanity checking of checkpoint */
+       if (f2fs_sanity_check_ckpt(sbi))
+               goto free_fail_no_cp;
+
        if (cp_blks <= 1)
                goto done;
 
@@ -859,6 +901,8 @@ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi)
                unsigned char *ckpt = (unsigned char *)sbi->ckpt;
 
                cur_page = f2fs_get_meta_page(sbi, cp_blk_no + i);
+               if (IS_ERR(cur_page))
+                       goto free_fail_no_cp;
                sit_bitmap_ptr = page_address(cur_page);
                memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size);
                f2fs_put_page(cur_page, 1);
@@ -980,12 +1024,10 @@ retry:
 
                iput(inode);
                /* We need to give cpu to another writers. */
-               if (ino == cur_ino) {
-                       congestion_wait(BLK_RW_ASYNC, HZ/50);
+               if (ino == cur_ino)
                        cond_resched();
-               } else {
+               else
                        ino = cur_ino;
-               }
        } else {
                /*
                 * We should submit bio, since it exists several
@@ -1119,7 +1161,7 @@ static void unblock_operations(struct f2fs_sb_info *sbi)
        f2fs_unlock_all(sbi);
 }
 
-static void wait_on_all_pages_writeback(struct f2fs_sb_info *sbi)
+void f2fs_wait_on_all_pages_writeback(struct f2fs_sb_info *sbi)
 {
        DEFINE_WAIT(wait);
 
@@ -1129,6 +1171,9 @@ static void wait_on_all_pages_writeback(struct f2fs_sb_info *sbi)
                if (!get_pages(sbi, F2FS_WB_CP_DATA))
                        break;
 
+               if (unlikely(f2fs_cp_error(sbi)))
+                       break;
+
                io_schedule_timeout(5*HZ);
        }
        finish_wait(&sbi->cp_wait, &wait);
@@ -1202,8 +1247,12 @@ static void commit_checkpoint(struct f2fs_sb_info *sbi,
 
        /* writeout cp pack 2 page */
        err = __f2fs_write_meta_page(page, &wbc, FS_CP_META_IO);
-       f2fs_bug_on(sbi, err);
+       if (unlikely(err && f2fs_cp_error(sbi))) {
+               f2fs_put_page(page, 1);
+               return;
+       }
 
+       f2fs_bug_on(sbi, err);
        f2fs_put_page(page, 0);
 
        /* submit checkpoint (with barrier if NOBARRIER is not set) */
@@ -1229,7 +1278,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
        while (get_pages(sbi, F2FS_DIRTY_META)) {
                f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO);
                if (unlikely(f2fs_cp_error(sbi)))
-                       return -EIO;
+                       break;
        }
 
        /*
@@ -1309,7 +1358,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
                        f2fs_sync_meta_pages(sbi, META, LONG_MAX,
                                                        FS_CP_META_IO);
                        if (unlikely(f2fs_cp_error(sbi)))
-                               return -EIO;
+                               break;
                }
        }
 
@@ -1348,10 +1397,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
        f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO);
 
        /* wait for previous submitted meta pages writeback */
-       wait_on_all_pages_writeback(sbi);
-
-       if (unlikely(f2fs_cp_error(sbi)))
-               return -EIO;
+       f2fs_wait_on_all_pages_writeback(sbi);
 
        /* flush all device cache */
        err = f2fs_flush_device_cache(sbi);
@@ -1360,12 +1406,19 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 
        /* barrier and flush checkpoint cp pack 2 page if it can */
        commit_checkpoint(sbi, ckpt, start_blk);
-       wait_on_all_pages_writeback(sbi);
+       f2fs_wait_on_all_pages_writeback(sbi);
+
+       /*
+        * invalidate intermediate page cache borrowed from meta inode
+        * which are used for migration of encrypted inode's blocks.
+        */
+       if (f2fs_sb_has_encrypt(sbi->sb))
+               invalidate_mapping_pages(META_MAPPING(sbi),
+                               MAIN_BLKADDR(sbi), MAX_BLKADDR(sbi) - 1);
 
        f2fs_release_ino_entry(sbi, false);
 
-       if (unlikely(f2fs_cp_error(sbi)))
-               return -EIO;
+       f2fs_reset_fsync_node_info(sbi);
 
        clear_sbi_flag(sbi, SBI_IS_DIRTY);
        clear_sbi_flag(sbi, SBI_NEED_CP);
@@ -1381,7 +1434,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 
        f2fs_bug_on(sbi, get_pages(sbi, F2FS_DIRTY_DENTS));
 
-       return 0;
+       return unlikely(f2fs_cp_error(sbi)) ? -EIO : 0;
 }
 
 /*
index b7c9b58acf3eae3594c7c893b94cdd25f5ad8e91..382c1ef9a9e4d6e9df05e39031ce0f5958e51663 100644 (file)
@@ -126,12 +126,10 @@ static bool f2fs_bio_post_read_required(struct bio *bio)
 
 static void f2fs_read_end_io(struct bio *bio)
 {
-#ifdef CONFIG_F2FS_FAULT_INJECTION
        if (time_to_inject(F2FS_P_SB(bio_first_page_all(bio)), FAULT_IO)) {
                f2fs_show_injection_info(FAULT_IO);
                bio->bi_status = BLK_STS_IOERR;
        }
-#endif
 
        if (f2fs_bio_post_read_required(bio)) {
                struct bio_post_read_ctx *ctx = bio->bi_private;
@@ -177,6 +175,8 @@ static void f2fs_write_end_io(struct bio *bio)
                                        page->index != nid_of_node(page));
 
                dec_page_count(sbi, type);
+               if (f2fs_in_warm_node_list(sbi, page))
+                       f2fs_del_fsync_node_entry(sbi, page);
                clear_cold_data(page);
                end_page_writeback(page);
        }
@@ -264,7 +264,7 @@ static inline void __submit_bio(struct f2fs_sb_info *sbi,
                if (type != DATA && type != NODE)
                        goto submit_io;
 
-               if (f2fs_sb_has_blkzoned(sbi->sb) && current->plug)
+               if (test_opt(sbi, LFS) && current->plug)
                        blk_finish_plug(current->plug);
 
                start = bio->bi_iter.bi_size >> F2FS_BLKSIZE_BITS;
@@ -441,7 +441,10 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)
        struct page *page = fio->encrypted_page ?
                        fio->encrypted_page : fio->page;
 
-       verify_block_addr(fio, fio->new_blkaddr);
+       if (!f2fs_is_valid_blkaddr(fio->sbi, fio->new_blkaddr,
+                       __is_meta_io(fio) ? META_GENERIC : DATA_GENERIC))
+               return -EFAULT;
+
        trace_f2fs_submit_page_bio(page, fio);
        f2fs_trace_ios(fio, 0);
 
@@ -485,7 +488,7 @@ next:
                spin_unlock(&io->io_lock);
        }
 
-       if (is_valid_blkaddr(fio->old_blkaddr))
+       if (__is_valid_data_blkaddr(fio->old_blkaddr))
                verify_block_addr(fio, fio->old_blkaddr);
        verify_block_addr(fio, fio->new_blkaddr);
 
@@ -534,19 +537,22 @@ out:
 }
 
 static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,
-                                                        unsigned nr_pages)
+                                       unsigned nr_pages, unsigned op_flag)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        struct bio *bio;
        struct bio_post_read_ctx *ctx;
        unsigned int post_read_steps = 0;
 
+       if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC))
+               return ERR_PTR(-EFAULT);
+
        bio = f2fs_bio_alloc(sbi, min_t(int, nr_pages, BIO_MAX_PAGES), false);
        if (!bio)
                return ERR_PTR(-ENOMEM);
        f2fs_target_device(sbi, blkaddr, bio);
        bio->bi_end_io = f2fs_read_end_io;
-       bio_set_op_attrs(bio, REQ_OP_READ, 0);
+       bio_set_op_attrs(bio, REQ_OP_READ, op_flag);
 
        if (f2fs_encrypted_file(inode))
                post_read_steps |= 1 << STEP_DECRYPT;
@@ -571,7 +577,7 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,
 static int f2fs_submit_page_read(struct inode *inode, struct page *page,
                                                        block_t blkaddr)
 {
-       struct bio *bio = f2fs_grab_read_bio(inode, blkaddr, 1);
+       struct bio *bio = f2fs_grab_read_bio(inode, blkaddr, 1, 0);
 
        if (IS_ERR(bio))
                return PTR_ERR(bio);
@@ -869,6 +875,7 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
        struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
        struct f2fs_summary sum;
        struct node_info ni;
+       block_t old_blkaddr;
        pgoff_t fofs;
        blkcnt_t count = 1;
        int err;
@@ -876,6 +883,10 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
        if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
                return -EPERM;
 
+       err = f2fs_get_node_info(sbi, dn->nid, &ni);
+       if (err)
+               return err;
+
        dn->data_blkaddr = datablock_addr(dn->inode,
                                dn->node_page, dn->ofs_in_node);
        if (dn->data_blkaddr == NEW_ADDR)
@@ -885,11 +896,13 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
                return err;
 
 alloc:
-       f2fs_get_node_info(sbi, dn->nid, &ni);
        set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
-
-       f2fs_allocate_data_block(sbi, NULL, dn->data_blkaddr, &dn->data_blkaddr,
+       old_blkaddr = dn->data_blkaddr;
+       f2fs_allocate_data_block(sbi, NULL, old_blkaddr, &dn->data_blkaddr,
                                        &sum, seg_type, NULL, false);
+       if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO)
+               invalidate_mapping_pages(META_MAPPING(sbi),
+                                       old_blkaddr, old_blkaddr);
        f2fs_set_data_blkaddr(dn);
 
        /* update i_size */
@@ -1045,7 +1058,13 @@ next_dnode:
 next_block:
        blkaddr = datablock_addr(dn.inode, dn.node_page, dn.ofs_in_node);
 
-       if (!is_valid_blkaddr(blkaddr)) {
+       if (__is_valid_data_blkaddr(blkaddr) &&
+               !f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC)) {
+               err = -EFAULT;
+               goto sync_out;
+       }
+
+       if (!is_valid_data_blkaddr(sbi, blkaddr)) {
                if (create) {
                        if (unlikely(f2fs_cp_error(sbi))) {
                                err = -EIO;
@@ -1282,7 +1301,11 @@ static int f2fs_xattr_fiemap(struct inode *inode,
                if (!page)
                        return -ENOMEM;
 
-               f2fs_get_node_info(sbi, inode->i_ino, &ni);
+               err = f2fs_get_node_info(sbi, inode->i_ino, &ni);
+               if (err) {
+                       f2fs_put_page(page, 1);
+                       return err;
+               }
 
                phys = (__u64)blk_to_logical(inode, ni.blk_addr);
                offset = offsetof(struct f2fs_inode, i_addr) +
@@ -1309,7 +1332,11 @@ static int f2fs_xattr_fiemap(struct inode *inode,
                if (!page)
                        return -ENOMEM;
 
-               f2fs_get_node_info(sbi, xnid, &ni);
+               err = f2fs_get_node_info(sbi, xnid, &ni);
+               if (err) {
+                       f2fs_put_page(page, 1);
+                       return err;
+               }
 
                phys = (__u64)blk_to_logical(inode, ni.blk_addr);
                len = inode->i_sb->s_blocksize;
@@ -1425,11 +1452,11 @@ out:
  * Note that the aops->readpages() function is ONLY used for read-ahead. If
  * this function ever deviates from doing just read-ahead, it should either
  * use ->readpage() or do the necessary surgery to decouple ->readpages()
- * readom read-ahead.
+ * from read-ahead.
  */
 static int f2fs_mpage_readpages(struct address_space *mapping,
                        struct list_head *pages, struct page *page,
-                       unsigned nr_pages)
+                       unsigned nr_pages, bool is_readahead)
 {
        struct bio *bio = NULL;
        sector_t last_block_in_bio = 0;
@@ -1500,6 +1527,10 @@ got_it:
                                SetPageUptodate(page);
                                goto confused;
                        }
+
+                       if (!f2fs_is_valid_blkaddr(F2FS_I_SB(inode), block_nr,
+                                                               DATA_GENERIC))
+                               goto set_error_page;
                } else {
                        zero_user_segment(page, 0, PAGE_SIZE);
                        if (!PageUptodate(page))
@@ -1519,7 +1550,8 @@ submit_and_realloc:
                        bio = NULL;
                }
                if (bio == NULL) {
-                       bio = f2fs_grab_read_bio(inode, block_nr, nr_pages);
+                       bio = f2fs_grab_read_bio(inode, block_nr, nr_pages,
+                                       is_readahead ? REQ_RAHEAD : 0);
                        if (IS_ERR(bio)) {
                                bio = NULL;
                                goto set_error_page;
@@ -1563,7 +1595,7 @@ static int f2fs_read_data_page(struct file *file, struct page *page)
        if (f2fs_has_inline_data(inode))
                ret = f2fs_read_inline_data(inode, page);
        if (ret == -EAGAIN)
-               ret = f2fs_mpage_readpages(page->mapping, NULL, page, 1);
+               ret = f2fs_mpage_readpages(page->mapping, NULL, page, 1, false);
        return ret;
 }
 
@@ -1580,12 +1612,13 @@ static int f2fs_read_data_pages(struct file *file,
        if (f2fs_has_inline_data(inode))
                return 0;
 
-       return f2fs_mpage_readpages(mapping, pages, NULL, nr_pages);
+       return f2fs_mpage_readpages(mapping, pages, NULL, nr_pages, true);
 }
 
 static int encrypt_one_page(struct f2fs_io_info *fio)
 {
        struct inode *inode = fio->page->mapping->host;
+       struct page *mpage;
        gfp_t gfp_flags = GFP_NOFS;
 
        if (!f2fs_encrypted_file(inode))
@@ -1597,17 +1630,25 @@ static int encrypt_one_page(struct f2fs_io_info *fio)
 retry_encrypt:
        fio->encrypted_page = fscrypt_encrypt_page(inode, fio->page,
                        PAGE_SIZE, 0, fio->page->index, gfp_flags);
-       if (!IS_ERR(fio->encrypted_page))
-               return 0;
+       if (IS_ERR(fio->encrypted_page)) {
+               /* flush pending IOs and wait for a while in the ENOMEM case */
+               if (PTR_ERR(fio->encrypted_page) == -ENOMEM) {
+                       f2fs_flush_merged_writes(fio->sbi);
+                       congestion_wait(BLK_RW_ASYNC, HZ/50);
+                       gfp_flags |= __GFP_NOFAIL;
+                       goto retry_encrypt;
+               }
+               return PTR_ERR(fio->encrypted_page);
+       }
 
-       /* flush pending IOs and wait for a while in the ENOMEM case */
-       if (PTR_ERR(fio->encrypted_page) == -ENOMEM) {
-               f2fs_flush_merged_writes(fio->sbi);
-               congestion_wait(BLK_RW_ASYNC, HZ/50);
-               gfp_flags |= __GFP_NOFAIL;
-               goto retry_encrypt;
+       mpage = find_lock_page(META_MAPPING(fio->sbi), fio->old_blkaddr);
+       if (mpage) {
+               if (PageUptodate(mpage))
+                       memcpy(page_address(mpage),
+                               page_address(fio->encrypted_page), PAGE_SIZE);
+               f2fs_put_page(mpage, 1);
        }
-       return PTR_ERR(fio->encrypted_page);
+       return 0;
 }
 
 static inline bool check_inplace_update_policy(struct inode *inode,
@@ -1691,6 +1732,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
        struct inode *inode = page->mapping->host;
        struct dnode_of_data dn;
        struct extent_info ei = {0,0,0};
+       struct node_info ni;
        bool ipu_force = false;
        int err = 0;
 
@@ -1699,11 +1741,13 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
                        f2fs_lookup_extent_cache(inode, page->index, &ei)) {
                fio->old_blkaddr = ei.blk + page->index - ei.fofs;
 
-               if (is_valid_blkaddr(fio->old_blkaddr)) {
-                       ipu_force = true;
-                       fio->need_lock = LOCK_DONE;
-                       goto got_it;
-               }
+               if (!f2fs_is_valid_blkaddr(fio->sbi, fio->old_blkaddr,
+                                                       DATA_GENERIC))
+                       return -EFAULT;
+
+               ipu_force = true;
+               fio->need_lock = LOCK_DONE;
+               goto got_it;
        }
 
        /* Deadlock due to between page->lock and f2fs_lock_op */
@@ -1722,11 +1766,17 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
                goto out_writepage;
        }
 got_it:
+       if (__is_valid_data_blkaddr(fio->old_blkaddr) &&
+               !f2fs_is_valid_blkaddr(fio->sbi, fio->old_blkaddr,
+                                                       DATA_GENERIC)) {
+               err = -EFAULT;
+               goto out_writepage;
+       }
        /*
         * If current allocation needs SSR,
         * it had better in-place writes for updated data.
         */
-       if (ipu_force || (is_valid_blkaddr(fio->old_blkaddr) &&
+       if (ipu_force || (is_valid_data_blkaddr(fio->sbi, fio->old_blkaddr) &&
                                        need_inplace_update(fio))) {
                err = encrypt_one_page(fio);
                if (err)
@@ -1751,6 +1801,12 @@ got_it:
                fio->need_lock = LOCK_REQ;
        }
 
+       err = f2fs_get_node_info(fio->sbi, dn.nid, &ni);
+       if (err)
+               goto out_writepage;
+
+       fio->version = ni.version;
+
        err = encrypt_one_page(fio);
        if (err)
                goto out_writepage;
@@ -2079,6 +2135,18 @@ continue_unlock:
        return ret;
 }
 
+static inline bool __should_serialize_io(struct inode *inode,
+                                       struct writeback_control *wbc)
+{
+       if (!S_ISREG(inode->i_mode))
+               return false;
+       if (wbc->sync_mode != WB_SYNC_ALL)
+               return true;
+       if (get_dirty_pages(inode) >= SM_I(F2FS_I_SB(inode))->min_seq_blocks)
+               return true;
+       return false;
+}
+
 static int __f2fs_write_data_pages(struct address_space *mapping,
                                                struct writeback_control *wbc,
                                                enum iostat_type io_type)
@@ -2087,6 +2155,7 @@ static int __f2fs_write_data_pages(struct address_space *mapping,
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        struct blk_plug plug;
        int ret;
+       bool locked = false;
 
        /* deal with chardevs and other special file */
        if (!mapping->a_ops->writepage)
@@ -2117,10 +2186,18 @@ static int __f2fs_write_data_pages(struct address_space *mapping,
        else if (atomic_read(&sbi->wb_sync_req[DATA]))
                goto skip_write;
 
+       if (__should_serialize_io(inode, wbc)) {
+               mutex_lock(&sbi->writepages);
+               locked = true;
+       }
+
        blk_start_plug(&plug);
        ret = f2fs_write_cache_pages(mapping, wbc, io_type);
        blk_finish_plug(&plug);
 
+       if (locked)
+               mutex_unlock(&sbi->writepages);
+
        if (wbc->sync_mode == WB_SYNC_ALL)
                atomic_dec(&sbi->wb_sync_req[DATA]);
        /*
@@ -2153,10 +2230,14 @@ static void f2fs_write_failed(struct address_space *mapping, loff_t to)
        loff_t i_size = i_size_read(inode);
 
        if (to > i_size) {
+               down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
                down_write(&F2FS_I(inode)->i_mmap_sem);
+
                truncate_pagecache(inode, i_size);
                f2fs_truncate_blocks(inode, i_size, true);
+
                up_write(&F2FS_I(inode)->i_mmap_sem);
+               up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
        }
 }
 
@@ -2251,8 +2332,9 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
 
        trace_f2fs_write_begin(inode, pos, len, flags);
 
-       if (f2fs_is_atomic_file(inode) &&
-                       !f2fs_available_free_memory(sbi, INMEM_PAGES)) {
+       if ((f2fs_is_atomic_file(inode) &&
+                       !f2fs_available_free_memory(sbi, INMEM_PAGES)) ||
+                       is_inode_flag_set(inode, FI_ATOMIC_REVOKE_REQUEST)) {
                err = -ENOMEM;
                drop_atomic = true;
                goto fail;
@@ -2376,14 +2458,20 @@ unlock_out:
 static int check_direct_IO(struct inode *inode, struct iov_iter *iter,
                           loff_t offset)
 {
-       unsigned blocksize_mask = inode->i_sb->s_blocksize - 1;
-
-       if (offset & blocksize_mask)
-               return -EINVAL;
-
-       if (iov_iter_alignment(iter) & blocksize_mask)
-               return -EINVAL;
-
+       unsigned i_blkbits = READ_ONCE(inode->i_blkbits);
+       unsigned blkbits = i_blkbits;
+       unsigned blocksize_mask = (1 << blkbits) - 1;
+       unsigned long align = offset | iov_iter_alignment(iter);
+       struct block_device *bdev = inode->i_sb->s_bdev;
+
+       if (align & blocksize_mask) {
+               if (bdev)
+                       blkbits = blksize_bits(bdev_logical_block_size(bdev));
+               blocksize_mask = (1 << blkbits) - 1;
+               if (align & blocksize_mask)
+                       return -EINVAL;
+               return 1;
+       }
        return 0;
 }
 
@@ -2401,7 +2489,7 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 
        err = check_direct_IO(inode, iter, offset);
        if (err)
-               return err;
+               return err < 0 ? err : 0;
 
        if (f2fs_force_buffered_io(inode, rw))
                return 0;
@@ -2495,6 +2583,10 @@ static int f2fs_set_data_page_dirty(struct page *page)
        if (!PageUptodate(page))
                SetPageUptodate(page);
 
+       /* don't remain PG_checked flag which was set during GC */
+       if (is_cold_data(page))
+               clear_cold_data(page);
+
        if (f2fs_is_atomic_file(inode) && !f2fs_is_commit_atomic_write(inode)) {
                if (!IS_ATOMIC_WRITTEN_PAGE(page)) {
                        f2fs_register_inmem_page(inode, page);
index 2d65e77ae5cf92ac17227d532cff1337b10ea2d2..214a968962a1d2b89791417adebabda0592e8653 100644 (file)
@@ -215,7 +215,8 @@ static void update_mem_info(struct f2fs_sb_info *sbi)
        si->base_mem += sizeof(struct f2fs_nm_info);
        si->base_mem += __bitmap_size(sbi, NAT_BITMAP);
        si->base_mem += (NM_I(sbi)->nat_bits_blocks << F2FS_BLKSIZE_BITS);
-       si->base_mem += NM_I(sbi)->nat_blocks * NAT_ENTRY_BITMAP_SIZE;
+       si->base_mem += NM_I(sbi)->nat_blocks *
+                               f2fs_bitmap_size(NAT_ENTRY_PER_BLOCK);
        si->base_mem += NM_I(sbi)->nat_blocks / 8;
        si->base_mem += NM_I(sbi)->nat_blocks * sizeof(unsigned short);
 
index 7f955c4e86a45e56a870c2f014ab9eee71fef84b..ecc3a4e2be96d8a25fd6814a9d09476b30095eaa 100644 (file)
@@ -517,12 +517,11 @@ int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name,
        }
 
 start:
-#ifdef CONFIG_F2FS_FAULT_INJECTION
        if (time_to_inject(F2FS_I_SB(dir), FAULT_DIR_DEPTH)) {
                f2fs_show_injection_info(FAULT_DIR_DEPTH);
                return -ENOSPC;
        }
-#endif
+
        if (unlikely(current_depth == MAX_DIR_HASH_DEPTH))
                return -ENOSPC;
 
index 6799c3fc44e30d5f2c475d215e5a19d2dde1d2a0..abf925664d9c5b9bf50f155824d34c9c86ce750f 100644 (file)
@@ -41,7 +41,6 @@
        } while (0)
 #endif
 
-#ifdef CONFIG_F2FS_FAULT_INJECTION
 enum {
        FAULT_KMALLOC,
        FAULT_KVMALLOC,
@@ -56,16 +55,20 @@ enum {
        FAULT_TRUNCATE,
        FAULT_IO,
        FAULT_CHECKPOINT,
+       FAULT_DISCARD,
        FAULT_MAX,
 };
 
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+#define F2FS_ALL_FAULT_TYPE            ((1 << FAULT_MAX) - 1)
+
 struct f2fs_fault_info {
        atomic_t inject_ops;
        unsigned int inject_rate;
        unsigned int inject_type;
 };
 
-extern char *fault_name[FAULT_MAX];
+extern char *f2fs_fault_name[FAULT_MAX];
 #define IS_FAULT_SET(fi, type) ((fi)->inject_type & (1 << (type)))
 #endif
 
@@ -178,7 +181,6 @@ enum {
 
 #define MAX_DISCARD_BLOCKS(sbi)                BLKS_PER_SEC(sbi)
 #define DEF_MAX_DISCARD_REQUEST                8       /* issue 8 discards per round */
-#define DEF_MAX_DISCARD_LEN            512     /* Max. 2MB per discard */
 #define DEF_MIN_DISCARD_ISSUE_TIME     50      /* 50 ms, if exists */
 #define DEF_MID_DISCARD_ISSUE_TIME     500     /* 500 ms, if device busy */
 #define DEF_MAX_DISCARD_ISSUE_TIME     60000   /* 60 s, if no candidates */
@@ -194,7 +196,7 @@ struct cp_control {
 };
 
 /*
- * For CP/NAT/SIT/SSA readahead
+ * indicate meta/data type
  */
 enum {
        META_CP,
@@ -202,6 +204,8 @@ enum {
        META_SIT,
        META_SSA,
        META_POR,
+       DATA_GENERIC,
+       META_GENERIC,
 };
 
 /* for the list of ino */
@@ -226,6 +230,12 @@ struct inode_entry {
        struct inode *inode;    /* vfs inode pointer */
 };
 
+struct fsync_node_entry {
+       struct list_head list;  /* list head */
+       struct page *page;      /* warm node page pointer */
+       unsigned int seq_id;    /* sequence id */
+};
+
 /* for the bitmap indicate blocks to be discarded */
 struct discard_entry {
        struct list_head list;  /* list head */
@@ -242,9 +252,10 @@ struct discard_entry {
                                        (MAX_PLIST_NUM - 1) : (blk_num - 1))
 
 enum {
-       D_PREP,
-       D_SUBMIT,
-       D_DONE,
+       D_PREP,                 /* initial */
+       D_PARTIAL,              /* partially submitted */
+       D_SUBMIT,               /* all submitted */
+       D_DONE,                 /* finished */
 };
 
 struct discard_info {
@@ -269,7 +280,10 @@ struct discard_cmd {
        struct block_device *bdev;      /* bdev */
        unsigned short ref;             /* reference count */
        unsigned char state;            /* state */
+       unsigned char issuing;          /* issuing discard */
        int error;                      /* bio error */
+       spinlock_t lock;                /* for state/bio_ref updating */
+       unsigned short bio_ref;         /* bio reference count */
 };
 
 enum {
@@ -289,6 +303,7 @@ struct discard_policy {
        unsigned int io_aware_gran;     /* minimum granularity discard not be aware of I/O */
        bool io_aware;                  /* issue discard in idle time */
        bool sync;                      /* submit discard with REQ_SYNC flag */
+       bool ordered;                   /* issue discard by lba order */
        unsigned int granularity;       /* discard granularity */
 };
 
@@ -305,10 +320,12 @@ struct discard_cmd_control {
        unsigned int max_discards;              /* max. discards to be issued */
        unsigned int discard_granularity;       /* discard granularity */
        unsigned int undiscard_blks;            /* # of undiscard blocks */
+       unsigned int next_pos;                  /* next discard position */
        atomic_t issued_discard;                /* # of issued discard */
        atomic_t issing_discard;                /* # of issing discard */
        atomic_t discard_cmd_cnt;               /* # of cached cmd count */
        struct rb_root root;                    /* root of discard rb-tree */
+       bool rbtree_check;                      /* config for consistence check */
 };
 
 /* for the list of fsync inodes, used only during recovery */
@@ -508,13 +525,12 @@ enum {
                                         */
 };
 
+#define DEFAULT_RETRY_IO_COUNT 8       /* maximum retry read IO count */
+
 #define F2FS_LINK_MAX  0xffffffff      /* maximum link count per file */
 
 #define MAX_DIR_RA_PAGES       4       /* maximum ra pages of dir */
 
-/* vector size for gang look-up from extent cache that consists of radix tree */
-#define EXT_TREE_VEC_SIZE      64
-
 /* for in-memory extent cache entry */
 #define F2FS_MIN_EXTENT_LEN    64      /* minimum extent length */
 
@@ -600,6 +616,8 @@ enum {
 #define FADVISE_HOT_BIT                0x20
 #define FADVISE_VERITY_BIT     0x40    /* reserved */
 
+#define FADVISE_MODIFIABLE_BITS        (FADVISE_COLD_BIT | FADVISE_HOT_BIT)
+
 #define file_is_cold(inode)    is_file(inode, FADVISE_COLD_BIT)
 #define file_wrong_pino(inode) is_file(inode, FADVISE_LOST_PINO_BIT)
 #define file_set_cold(inode)   set_file(inode, FADVISE_COLD_BIT)
@@ -669,8 +687,8 @@ struct f2fs_inode_info {
        int i_extra_isize;              /* size of extra space located in i_addr */
        kprojid_t i_projid;             /* id for project quota */
        int i_inline_xattr_size;        /* inline xattr size */
-       struct timespec i_crtime;       /* inode creation time */
-       struct timespec i_disk_time[4]; /* inode disk times */
+       struct timespec64 i_crtime;     /* inode creation time */
+       struct timespec64 i_disk_time[4];/* inode disk times */
 };
 
 static inline void get_extent_info(struct extent_info *ext,
@@ -698,22 +716,22 @@ static inline void set_extent_info(struct extent_info *ei, unsigned int fofs,
 }
 
 static inline bool __is_discard_mergeable(struct discard_info *back,
-                                               struct discard_info *front)
+                       struct discard_info *front, unsigned int max_len)
 {
        return (back->lstart + back->len == front->lstart) &&
-               (back->len + front->len < DEF_MAX_DISCARD_LEN);
+               (back->len + front->len <= max_len);
 }
 
 static inline bool __is_discard_back_mergeable(struct discard_info *cur,
-                                               struct discard_info *back)
+                       struct discard_info *back, unsigned int max_len)
 {
-       return __is_discard_mergeable(back, cur);
+       return __is_discard_mergeable(back, cur, max_len);
 }
 
 static inline bool __is_discard_front_mergeable(struct discard_info *cur,
-                                               struct discard_info *front)
+                       struct discard_info *front, unsigned int max_len)
 {
-       return __is_discard_mergeable(cur, front);
+       return __is_discard_mergeable(cur, front, max_len);
 }
 
 static inline bool __is_extent_mergeable(struct extent_info *back,
@@ -768,6 +786,7 @@ struct f2fs_nm_info {
        struct radix_tree_root nat_set_root;/* root of the nat set cache */
        struct rw_semaphore nat_tree_lock;      /* protect nat_tree_lock */
        struct list_head nat_entries;   /* cached nat entry list (clean) */
+       spinlock_t nat_list_lock;       /* protect clean nat entry list */
        unsigned int nat_cnt;           /* the # of cached nat entries */
        unsigned int dirty_nat_cnt;     /* total num of nat entries in set */
        unsigned int nat_blocks;        /* # of nat blocks */
@@ -894,6 +913,7 @@ struct f2fs_sm_info {
        unsigned int ipu_policy;        /* in-place-update policy */
        unsigned int min_ipu_util;      /* in-place-update threshold */
        unsigned int min_fsync_blocks;  /* threshold for fsync */
+       unsigned int min_seq_blocks;    /* threshold for sequential blocks */
        unsigned int min_hot_blocks;    /* threshold for hot block allocation */
        unsigned int min_ssr_sections;  /* threshold to trigger SSR allocation */
 
@@ -1015,6 +1035,7 @@ struct f2fs_io_info {
        bool retry;             /* need to reallocate block address */
        enum iostat_type io_type;       /* io type */
        struct writeback_control *io_wbc; /* writeback control */
+       unsigned char version;          /* version of the node */
 };
 
 #define is_read_io(rw) ((rw) == READ)
@@ -1066,6 +1087,7 @@ enum {
        SBI_POR_DOING,                          /* recovery is doing or not */
        SBI_NEED_SB_WRITE,                      /* need to recover superblock */
        SBI_NEED_CP,                            /* need to checkpoint */
+       SBI_IS_SHUTDOWN,                        /* shutdown by ioctl */
 };
 
 enum {
@@ -1112,6 +1134,7 @@ struct f2fs_sb_info {
        struct rw_semaphore sb_lock;            /* lock for raw super block */
        int valid_super_block;                  /* valid super block no */
        unsigned long s_flag;                           /* flags for sbi */
+       struct mutex writepages;                /* mutex for writepages() */
 
 #ifdef CONFIG_BLK_DEV_ZONED
        unsigned int blocks_per_blkz;           /* F2FS blocks per zone */
@@ -1148,6 +1171,11 @@ struct f2fs_sb_info {
 
        struct inode_management im[MAX_INO_ENTRY];      /* manage inode cache */
 
+       spinlock_t fsync_node_lock;             /* for node entry lock */
+       struct list_head fsync_node_list;       /* node list head */
+       unsigned int fsync_seg_id;              /* sequence id */
+       unsigned int fsync_node_num;            /* number of node entries */
+
        /* for orphan inode, use 0'th array */
        unsigned int max_orphans;               /* max orphan inodes */
 
@@ -1215,6 +1243,7 @@ struct f2fs_sb_info {
        unsigned int gc_mode;                   /* current GC state */
        /* for skip statistic */
        unsigned long long skipped_atomic_files[2];     /* FG_GC and BG_GC */
+       unsigned long long skipped_gc_rwsem;            /* FG_GC only */
 
        /* threshold for gc trials on pinned files */
        u64 gc_pin_file_threshold;
@@ -1279,7 +1308,7 @@ struct f2fs_sb_info {
 #ifdef CONFIG_F2FS_FAULT_INJECTION
 #define f2fs_show_injection_info(type)                         \
        printk("%sF2FS-fs : inject %s in %s of %pF\n",          \
-               KERN_INFO, fault_name[type],                    \
+               KERN_INFO, f2fs_fault_name[type],               \
                __func__, __builtin_return_address(0))
 static inline bool time_to_inject(struct f2fs_sb_info *sbi, int type)
 {
@@ -1298,6 +1327,12 @@ static inline bool time_to_inject(struct f2fs_sb_info *sbi, int type)
        }
        return false;
 }
+#else
+#define f2fs_show_injection_info(type) do { } while (0)
+static inline bool time_to_inject(struct f2fs_sb_info *sbi, int type)
+{
+       return false;
+}
 #endif
 
 /* For write statistics. Suppose sector size is 512 bytes,
@@ -1326,7 +1361,7 @@ static inline bool is_idle(struct f2fs_sb_info *sbi)
        struct request_list *rl = &q->root_rl;
 
        if (rl->count[BLK_RW_SYNC] || rl->count[BLK_RW_ASYNC])
-               return 0;
+               return false;
 
        return f2fs_time_over(sbi, REQ_TIME);
 }
@@ -1650,13 +1685,12 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
        if (ret)
                return ret;
 
-#ifdef CONFIG_F2FS_FAULT_INJECTION
        if (time_to_inject(sbi, FAULT_BLOCK)) {
                f2fs_show_injection_info(FAULT_BLOCK);
                release = *count;
                goto enospc;
        }
-#endif
+
        /*
         * let's increase this in prior to actual block count change in order
         * for f2fs_sync_file to avoid data races when deciding checkpoint.
@@ -1680,18 +1714,20 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
                sbi->total_valid_block_count -= diff;
                if (!*count) {
                        spin_unlock(&sbi->stat_lock);
-                       percpu_counter_sub(&sbi->alloc_valid_block_count, diff);
                        goto enospc;
                }
        }
        spin_unlock(&sbi->stat_lock);
 
-       if (unlikely(release))
+       if (unlikely(release)) {
+               percpu_counter_sub(&sbi->alloc_valid_block_count, release);
                dquot_release_reservation_block(inode, release);
+       }
        f2fs_i_blocks_write(inode, *count, true, true);
        return 0;
 
 enospc:
+       percpu_counter_sub(&sbi->alloc_valid_block_count, release);
        dquot_release_reservation_block(inode, release);
        return -ENOSPC;
 }
@@ -1863,12 +1899,10 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
                        return ret;
        }
 
-#ifdef CONFIG_F2FS_FAULT_INJECTION
        if (time_to_inject(sbi, FAULT_BLOCK)) {
                f2fs_show_injection_info(FAULT_BLOCK);
                goto enospc;
        }
-#endif
 
        spin_lock(&sbi->stat_lock);
 
@@ -1953,17 +1987,23 @@ static inline s64 valid_inode_count(struct f2fs_sb_info *sbi)
 static inline struct page *f2fs_grab_cache_page(struct address_space *mapping,
                                                pgoff_t index, bool for_write)
 {
-#ifdef CONFIG_F2FS_FAULT_INJECTION
-       struct page *page = find_lock_page(mapping, index);
+       struct page *page;
 
-       if (page)
-               return page;
+       if (IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION)) {
+               if (!for_write)
+                       page = find_get_page_flags(mapping, index,
+                                                       FGP_LOCK | FGP_ACCESSED);
+               else
+                       page = find_lock_page(mapping, index);
+               if (page)
+                       return page;
 
-       if (time_to_inject(F2FS_M_SB(mapping), FAULT_PAGE_ALLOC)) {
-               f2fs_show_injection_info(FAULT_PAGE_ALLOC);
-               return NULL;
+               if (time_to_inject(F2FS_M_SB(mapping), FAULT_PAGE_ALLOC)) {
+                       f2fs_show_injection_info(FAULT_PAGE_ALLOC);
+                       return NULL;
+               }
        }
-#endif
+
        if (!for_write)
                return grab_cache_page(mapping, index);
        return grab_cache_page_write_begin(mapping, index, AOP_FLAG_NOFS);
@@ -1973,12 +2013,11 @@ static inline struct page *f2fs_pagecache_get_page(
                                struct address_space *mapping, pgoff_t index,
                                int fgp_flags, gfp_t gfp_mask)
 {
-#ifdef CONFIG_F2FS_FAULT_INJECTION
        if (time_to_inject(F2FS_M_SB(mapping), FAULT_PAGE_GET)) {
                f2fs_show_injection_info(FAULT_PAGE_GET);
                return NULL;
        }
-#endif
+
        return pagecache_get_page(mapping, index, fgp_flags, gfp_mask);
 }
 
@@ -2043,12 +2082,11 @@ static inline struct bio *f2fs_bio_alloc(struct f2fs_sb_info *sbi,
                        bio = bio_alloc(GFP_NOIO | __GFP_NOFAIL, npages);
                return bio;
        }
-#ifdef CONFIG_F2FS_FAULT_INJECTION
        if (time_to_inject(sbi, FAULT_ALLOC_BIO)) {
                f2fs_show_injection_info(FAULT_ALLOC_BIO);
                return NULL;
        }
-#endif
+
        return bio_alloc(GFP_KERNEL, npages);
 }
 
@@ -2518,7 +2556,6 @@ static inline void clear_file(struct inode *inode, int type)
 
 static inline bool f2fs_skip_inode_update(struct inode *inode, int dsync)
 {
-       struct timespec ts;
        bool ret;
 
        if (dsync) {
@@ -2534,16 +2571,13 @@ static inline bool f2fs_skip_inode_update(struct inode *inode, int dsync)
                        i_size_read(inode) & ~PAGE_MASK)
                return false;
 
-       ts = timespec64_to_timespec(inode->i_atime);
-       if (!timespec_equal(F2FS_I(inode)->i_disk_time, &ts))
+       if (!timespec64_equal(F2FS_I(inode)->i_disk_time, &inode->i_atime))
                return false;
-       ts = timespec64_to_timespec(inode->i_ctime);
-       if (!timespec_equal(F2FS_I(inode)->i_disk_time + 1, &ts))
+       if (!timespec64_equal(F2FS_I(inode)->i_disk_time + 1, &inode->i_ctime))
                return false;
-       ts = timespec64_to_timespec(inode->i_mtime);
-       if (!timespec_equal(F2FS_I(inode)->i_disk_time + 2, &ts))
+       if (!timespec64_equal(F2FS_I(inode)->i_disk_time + 2, &inode->i_mtime))
                return false;
-       if (!timespec_equal(F2FS_I(inode)->i_disk_time + 3,
+       if (!timespec64_equal(F2FS_I(inode)->i_disk_time + 3,
                                                &F2FS_I(inode)->i_crtime))
                return false;
 
@@ -2587,12 +2621,11 @@ static inline bool f2fs_may_extent_tree(struct inode *inode)
 static inline void *f2fs_kmalloc(struct f2fs_sb_info *sbi,
                                        size_t size, gfp_t flags)
 {
-#ifdef CONFIG_F2FS_FAULT_INJECTION
        if (time_to_inject(sbi, FAULT_KMALLOC)) {
                f2fs_show_injection_info(FAULT_KMALLOC);
                return NULL;
        }
-#endif
+
        return kmalloc(size, flags);
 }
 
@@ -2605,12 +2638,11 @@ static inline void *f2fs_kzalloc(struct f2fs_sb_info *sbi,
 static inline void *f2fs_kvmalloc(struct f2fs_sb_info *sbi,
                                        size_t size, gfp_t flags)
 {
-#ifdef CONFIG_F2FS_FAULT_INJECTION
        if (time_to_inject(sbi, FAULT_KVMALLOC)) {
                f2fs_show_injection_info(FAULT_KVMALLOC);
                return NULL;
        }
-#endif
+
        return kvmalloc(size, flags);
 }
 
@@ -2669,13 +2701,39 @@ static inline void f2fs_update_iostat(struct f2fs_sb_info *sbi,
        spin_unlock(&sbi->iostat_lock);
 }
 
-static inline bool is_valid_blkaddr(block_t blkaddr)
+#define __is_meta_io(fio) (PAGE_TYPE_OF_BIO(fio->type) == META &&      \
+                               (!is_read_io(fio->op) || fio->is_meta))
+
+bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
+                                       block_t blkaddr, int type);
+void f2fs_msg(struct super_block *sb, const char *level, const char *fmt, ...);
+static inline void verify_blkaddr(struct f2fs_sb_info *sbi,
+                                       block_t blkaddr, int type)
+{
+       if (!f2fs_is_valid_blkaddr(sbi, blkaddr, type)) {
+               f2fs_msg(sbi->sb, KERN_ERR,
+                       "invalid blkaddr: %u, type: %d, run fsck to fix.",
+                       blkaddr, type);
+               f2fs_bug_on(sbi, 1);
+       }
+}
+
+static inline bool __is_valid_data_blkaddr(block_t blkaddr)
 {
        if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR)
                return false;
        return true;
 }
 
+static inline bool is_valid_data_blkaddr(struct f2fs_sb_info *sbi,
+                                               block_t blkaddr)
+{
+       if (!__is_valid_data_blkaddr(blkaddr))
+               return false;
+       verify_blkaddr(sbi, blkaddr, DATA_GENERIC);
+       return true;
+}
+
 /*
  * file.c
  */
@@ -2790,16 +2848,21 @@ struct node_info;
 
 int f2fs_check_nid_range(struct f2fs_sb_info *sbi, nid_t nid);
 bool f2fs_available_free_memory(struct f2fs_sb_info *sbi, int type);
+bool f2fs_in_warm_node_list(struct f2fs_sb_info *sbi, struct page *page);
+void f2fs_init_fsync_node_info(struct f2fs_sb_info *sbi);
+void f2fs_del_fsync_node_entry(struct f2fs_sb_info *sbi, struct page *page);
+void f2fs_reset_fsync_node_info(struct f2fs_sb_info *sbi);
 int f2fs_need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid);
 bool f2fs_is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid);
 bool f2fs_need_inode_block_update(struct f2fs_sb_info *sbi, nid_t ino);
-void f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
+int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
                                                struct node_info *ni);
 pgoff_t f2fs_get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs);
 int f2fs_get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode);
 int f2fs_truncate_inode_blocks(struct inode *inode, pgoff_t from);
 int f2fs_truncate_xattr_node(struct inode *inode);
-int f2fs_wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino);
+int f2fs_wait_on_node_pages_writeback(struct f2fs_sb_info *sbi,
+                                       unsigned int seq_id);
 int f2fs_remove_inode_page(struct inode *inode);
 struct page *f2fs_new_inode_page(struct inode *inode);
 struct page *f2fs_new_node_page(struct dnode_of_data *dn, unsigned int ofs);
@@ -2808,11 +2871,12 @@ struct page *f2fs_get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid);
 struct page *f2fs_get_node_page_ra(struct page *parent, int start);
 void f2fs_move_node_page(struct page *node_page, int gc_type);
 int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
-                       struct writeback_control *wbc, bool atomic);
+                       struct writeback_control *wbc, bool atomic,
+                       unsigned int *seq_id);
 int f2fs_sync_node_pages(struct f2fs_sb_info *sbi,
                        struct writeback_control *wbc,
                        bool do_balance, enum iostat_type io_type);
-void f2fs_build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount);
+int f2fs_build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount);
 bool f2fs_alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid);
 void f2fs_alloc_nid_done(struct f2fs_sb_info *sbi, nid_t nid);
 void f2fs_alloc_nid_failed(struct f2fs_sb_info *sbi, nid_t nid);
@@ -2820,7 +2884,7 @@ int f2fs_try_to_free_nids(struct f2fs_sb_info *sbi, int nr_shrink);
 void f2fs_recover_inline_xattr(struct inode *inode, struct page *page);
 int f2fs_recover_xattr_data(struct inode *inode, struct page *page);
 int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page);
-void f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
+int f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
                        unsigned int segno, struct f2fs_summary_block *sum);
 void f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc);
 int f2fs_build_node_manager(struct f2fs_sb_info *sbi);
@@ -2898,9 +2962,10 @@ enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
 void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io);
 struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
 struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
+struct page *f2fs_get_meta_page_nofail(struct f2fs_sb_info *sbi, pgoff_t index);
 struct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index);
-bool f2fs_is_valid_meta_blkaddr(struct f2fs_sb_info *sbi,
-                       block_t blkaddr, int type);
+bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
+                                       block_t blkaddr, int type);
 int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
                        int type, bool sync);
 void f2fs_ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index);
@@ -2924,6 +2989,7 @@ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi);
 void f2fs_update_dirty_page(struct inode *inode, struct page *page);
 void f2fs_remove_dirty_inode(struct inode *inode);
 int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type);
+void f2fs_wait_on_all_pages_writeback(struct f2fs_sb_info *sbi);
 int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc);
 void f2fs_init_ino_entry_info(struct f2fs_sb_info *sbi);
 int __init f2fs_create_checkpoint_caches(void);
@@ -3362,7 +3428,7 @@ static inline bool f2fs_may_encrypt(struct inode *inode)
 
        return (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode));
 #else
-       return 0;
+       return false;
 #endif
 }
 
@@ -3373,4 +3439,11 @@ static inline bool f2fs_force_buffered_io(struct inode *inode, int rw)
                        F2FS_I_SB(inode)->s_ndevs);
 }
 
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+extern void f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned int rate,
+                                                       unsigned int type);
+#else
+#define f2fs_build_fault_attr(sbi, rate, type)         do { } while (0)
+#endif
+
 #endif
index 6880c6f78d58d0670bf28863d53de0c1e6afb3b0..5474aaa274b91d52c8259d31cfc072e5f8674d54 100644 (file)
@@ -213,6 +213,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end,
                .nr_to_write = LONG_MAX,
                .for_reclaim = 0,
        };
+       unsigned int seq_id = 0;
 
        if (unlikely(f2fs_readonly(inode->i_sb)))
                return 0;
@@ -275,7 +276,7 @@ go_write:
        }
 sync_nodes:
        atomic_inc(&sbi->wb_sync_req[NODE]);
-       ret = f2fs_fsync_node_pages(sbi, inode, &wbc, atomic);
+       ret = f2fs_fsync_node_pages(sbi, inode, &wbc, atomic, &seq_id);
        atomic_dec(&sbi->wb_sync_req[NODE]);
        if (ret)
                goto out;
@@ -301,7 +302,7 @@ sync_nodes:
         * given fsync mark.
         */
        if (!atomic) {
-               ret = f2fs_wait_on_node_pages_writeback(sbi, ino);
+               ret = f2fs_wait_on_node_pages_writeback(sbi, seq_id);
                if (ret)
                        goto out;
        }
@@ -350,13 +351,13 @@ static pgoff_t __get_first_dirty_index(struct address_space *mapping,
        return pgofs;
 }
 
-static bool __found_offset(block_t blkaddr, pgoff_t dirty, pgoff_t pgofs,
-                                                       int whence)
+static bool __found_offset(struct f2fs_sb_info *sbi, block_t blkaddr,
+                               pgoff_t dirty, pgoff_t pgofs, int whence)
 {
        switch (whence) {
        case SEEK_DATA:
                if ((blkaddr == NEW_ADDR && dirty == pgofs) ||
-                       is_valid_blkaddr(blkaddr))
+                       is_valid_data_blkaddr(sbi, blkaddr))
                        return true;
                break;
        case SEEK_HOLE:
@@ -420,7 +421,15 @@ static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence)
                        blkaddr = datablock_addr(dn.inode,
                                        dn.node_page, dn.ofs_in_node);
 
-                       if (__found_offset(blkaddr, dirty, pgofs, whence)) {
+                       if (__is_valid_data_blkaddr(blkaddr) &&
+                               !f2fs_is_valid_blkaddr(F2FS_I_SB(inode),
+                                               blkaddr, DATA_GENERIC)) {
+                               f2fs_put_dnode(&dn);
+                               goto fail;
+                       }
+
+                       if (__found_offset(F2FS_I_SB(inode), blkaddr, dirty,
+                                                       pgofs, whence)) {
                                f2fs_put_dnode(&dn);
                                goto found;
                        }
@@ -513,6 +522,11 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count)
 
                dn->data_blkaddr = NULL_ADDR;
                f2fs_set_data_blkaddr(dn);
+
+               if (__is_valid_data_blkaddr(blkaddr) &&
+                       !f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC))
+                       continue;
+
                f2fs_invalidate_blocks(sbi, blkaddr);
                if (dn->ofs_in_node == 0 && IS_INODE(dn->node_page))
                        clear_inode_flag(dn->inode, FI_FIRST_BLOCK_WRITTEN);
@@ -654,12 +668,11 @@ int f2fs_truncate(struct inode *inode)
 
        trace_f2fs_truncate(inode);
 
-#ifdef CONFIG_F2FS_FAULT_INJECTION
        if (time_to_inject(F2FS_I_SB(inode), FAULT_TRUNCATE)) {
                f2fs_show_injection_info(FAULT_TRUNCATE);
                return -EIO;
        }
-#endif
+
        /* we should check inline_data size */
        if (!f2fs_may_inline_data(inode)) {
                err = f2fs_convert_inline_inode(inode);
@@ -782,22 +795,26 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
        }
 
        if (attr->ia_valid & ATTR_SIZE) {
-               if (attr->ia_size <= i_size_read(inode)) {
-                       down_write(&F2FS_I(inode)->i_mmap_sem);
-                       truncate_setsize(inode, attr->ia_size);
+               bool to_smaller = (attr->ia_size <= i_size_read(inode));
+
+               down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+               down_write(&F2FS_I(inode)->i_mmap_sem);
+
+               truncate_setsize(inode, attr->ia_size);
+
+               if (to_smaller)
                        err = f2fs_truncate(inode);
-                       up_write(&F2FS_I(inode)->i_mmap_sem);
-                       if (err)
-                               return err;
-               } else {
-                       /*
-                        * do not trim all blocks after i_size if target size is
-                        * larger than i_size.
-                        */
-                       down_write(&F2FS_I(inode)->i_mmap_sem);
-                       truncate_setsize(inode, attr->ia_size);
-                       up_write(&F2FS_I(inode)->i_mmap_sem);
+               /*
+                * do not trim all blocks after i_size if target size is
+                * larger than i_size.
+                */
+               up_write(&F2FS_I(inode)->i_mmap_sem);
+               up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+
+               if (err)
+                       return err;
 
+               if (!to_smaller) {
                        /* should convert inline inode here */
                        if (!f2fs_may_inline_data(inode)) {
                                err = f2fs_convert_inline_inode(inode);
@@ -944,14 +961,19 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len)
 
                        blk_start = (loff_t)pg_start << PAGE_SHIFT;
                        blk_end = (loff_t)pg_end << PAGE_SHIFT;
+
+                       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
                        down_write(&F2FS_I(inode)->i_mmap_sem);
+
                        truncate_inode_pages_range(mapping, blk_start,
                                        blk_end - 1);
 
                        f2fs_lock_op(sbi);
                        ret = f2fs_truncate_hole(inode, pg_start, pg_end);
                        f2fs_unlock_op(sbi);
+
                        up_write(&F2FS_I(inode)->i_mmap_sem);
+                       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
                }
        }
 
@@ -1054,7 +1076,12 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode,
                        if (ret)
                                return ret;
 
-                       f2fs_get_node_info(sbi, dn.nid, &ni);
+                       ret = f2fs_get_node_info(sbi, dn.nid, &ni);
+                       if (ret) {
+                               f2fs_put_dnode(&dn);
+                               return ret;
+                       }
+
                        ilen = min((pgoff_t)
                                ADDRS_PER_PAGE(dn.node_page, dst_inode) -
                                                dn.ofs_in_node, len - i);
@@ -1161,25 +1188,33 @@ roll_back:
        return ret;
 }
 
-static int f2fs_do_collapse(struct inode *inode, pgoff_t start, pgoff_t end)
+static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        pgoff_t nrpages = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE;
+       pgoff_t start = offset >> PAGE_SHIFT;
+       pgoff_t end = (offset + len) >> PAGE_SHIFT;
        int ret;
 
        f2fs_balance_fs(sbi, true);
-       f2fs_lock_op(sbi);
 
-       f2fs_drop_extent_tree(inode);
+       /* avoid gc operation during block exchange */
+       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+       down_write(&F2FS_I(inode)->i_mmap_sem);
 
+       f2fs_lock_op(sbi);
+       f2fs_drop_extent_tree(inode);
+       truncate_pagecache(inode, offset);
        ret = __exchange_data_block(inode, inode, end, start, nrpages - end, true);
        f2fs_unlock_op(sbi);
+
+       up_write(&F2FS_I(inode)->i_mmap_sem);
+       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
        return ret;
 }
 
 static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len)
 {
-       pgoff_t pg_start, pg_end;
        loff_t new_size;
        int ret;
 
@@ -1194,25 +1229,17 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len)
        if (ret)
                return ret;
 
-       pg_start = offset >> PAGE_SHIFT;
-       pg_end = (offset + len) >> PAGE_SHIFT;
-
-       /* avoid gc operation during block exchange */
-       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
-
-       down_write(&F2FS_I(inode)->i_mmap_sem);
        /* write out all dirty pages from offset */
        ret = filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
        if (ret)
-               goto out_unlock;
-
-       truncate_pagecache(inode, offset);
+               return ret;
 
-       ret = f2fs_do_collapse(inode, pg_start, pg_end);
+       ret = f2fs_do_collapse(inode, offset, len);
        if (ret)
-               goto out_unlock;
+               return ret;
 
        /* write out all moved pages, if possible */
+       down_write(&F2FS_I(inode)->i_mmap_sem);
        filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
        truncate_pagecache(inode, offset);
 
@@ -1220,11 +1247,9 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len)
        truncate_pagecache(inode, new_size);
 
        ret = f2fs_truncate_blocks(inode, new_size, true);
+       up_write(&F2FS_I(inode)->i_mmap_sem);
        if (!ret)
                f2fs_i_size_write(inode, new_size);
-out_unlock:
-       up_write(&F2FS_I(inode)->i_mmap_sem);
-       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
        return ret;
 }
 
@@ -1290,12 +1315,9 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
        if (ret)
                return ret;
 
-       down_write(&F2FS_I(inode)->i_mmap_sem);
        ret = filemap_write_and_wait_range(mapping, offset, offset + len - 1);
        if (ret)
-               goto out_sem;
-
-       truncate_pagecache_range(inode, offset, offset + len - 1);
+               return ret;
 
        pg_start = ((unsigned long long) offset) >> PAGE_SHIFT;
        pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT;
@@ -1307,7 +1329,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
                ret = fill_zero(inode, pg_start, off_start,
                                                off_end - off_start);
                if (ret)
-                       goto out_sem;
+                       return ret;
 
                new_size = max_t(loff_t, new_size, offset + len);
        } else {
@@ -1315,7 +1337,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
                        ret = fill_zero(inode, pg_start++, off_start,
                                                PAGE_SIZE - off_start);
                        if (ret)
-                               goto out_sem;
+                               return ret;
 
                        new_size = max_t(loff_t, new_size,
                                        (loff_t)pg_start << PAGE_SHIFT);
@@ -1326,12 +1348,21 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
                        unsigned int end_offset;
                        pgoff_t end;
 
+                       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+                       down_write(&F2FS_I(inode)->i_mmap_sem);
+
+                       truncate_pagecache_range(inode,
+                               (loff_t)index << PAGE_SHIFT,
+                               ((loff_t)pg_end << PAGE_SHIFT) - 1);
+
                        f2fs_lock_op(sbi);
 
                        set_new_dnode(&dn, inode, NULL, NULL, 0);
                        ret = f2fs_get_dnode_of_data(&dn, index, ALLOC_NODE);
                        if (ret) {
                                f2fs_unlock_op(sbi);
+                               up_write(&F2FS_I(inode)->i_mmap_sem);
+                               up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
                                goto out;
                        }
 
@@ -1340,7 +1371,10 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
 
                        ret = f2fs_do_zero_range(&dn, index, end);
                        f2fs_put_dnode(&dn);
+
                        f2fs_unlock_op(sbi);
+                       up_write(&F2FS_I(inode)->i_mmap_sem);
+                       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
 
                        f2fs_balance_fs(sbi, dn.node_changed);
 
@@ -1368,9 +1402,6 @@ out:
                else
                        f2fs_i_size_write(inode, new_size);
        }
-out_sem:
-       up_write(&F2FS_I(inode)->i_mmap_sem);
-
        return ret;
 }
 
@@ -1399,26 +1430,27 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
 
        f2fs_balance_fs(sbi, true);
 
-       /* avoid gc operation during block exchange */
-       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
-
        down_write(&F2FS_I(inode)->i_mmap_sem);
        ret = f2fs_truncate_blocks(inode, i_size_read(inode), true);
+       up_write(&F2FS_I(inode)->i_mmap_sem);
        if (ret)
-               goto out;
+               return ret;
 
        /* write out all dirty pages from offset */
        ret = filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
        if (ret)
-               goto out;
-
-       truncate_pagecache(inode, offset);
+               return ret;
 
        pg_start = offset >> PAGE_SHIFT;
        pg_end = (offset + len) >> PAGE_SHIFT;
        delta = pg_end - pg_start;
        idx = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE;
 
+       /* avoid gc operation during block exchange */
+       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+       down_write(&F2FS_I(inode)->i_mmap_sem);
+       truncate_pagecache(inode, offset);
+
        while (!ret && idx > pg_start) {
                nr = idx - pg_start;
                if (nr > delta)
@@ -1432,16 +1464,17 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
                                        idx + delta, nr, false);
                f2fs_unlock_op(sbi);
        }
+       up_write(&F2FS_I(inode)->i_mmap_sem);
+       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
 
        /* write out all moved pages, if possible */
+       down_write(&F2FS_I(inode)->i_mmap_sem);
        filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
        truncate_pagecache(inode, offset);
+       up_write(&F2FS_I(inode)->i_mmap_sem);
 
        if (!ret)
                f2fs_i_size_write(inode, new_size);
-out:
-       up_write(&F2FS_I(inode)->i_mmap_sem);
-       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
        return ret;
 }
 
@@ -1597,7 +1630,7 @@ static int f2fs_ioc_getflags(struct file *filp, unsigned long arg)
        struct f2fs_inode_info *fi = F2FS_I(inode);
        unsigned int flags = fi->i_flags;
 
-       if (file_is_encrypt(inode))
+       if (f2fs_encrypted_inode(inode))
                flags |= F2FS_ENCRYPT_FL;
        if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode))
                flags |= F2FS_INLINE_DATA_FL;
@@ -1688,15 +1721,18 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
 
        inode_lock(inode);
 
-       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
-
-       if (f2fs_is_atomic_file(inode))
+       if (f2fs_is_atomic_file(inode)) {
+               if (is_inode_flag_set(inode, FI_ATOMIC_REVOKE_REQUEST))
+                       ret = -EINVAL;
                goto out;
+       }
 
        ret = f2fs_convert_inline_inode(inode);
        if (ret)
                goto out;
 
+       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+
        if (!get_dirty_pages(inode))
                goto skip_flush;
 
@@ -1704,18 +1740,20 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
                "Unexpected flush for atomic writes: ino=%lu, npages=%u",
                                        inode->i_ino, get_dirty_pages(inode));
        ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
-       if (ret)
+       if (ret) {
+               up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
                goto out;
+       }
 skip_flush:
        set_inode_flag(inode, FI_ATOMIC_FILE);
        clear_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST);
-       f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
+       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
 
+       f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
        F2FS_I(inode)->inmem_task = current;
        stat_inc_atomic_write(inode);
        stat_update_max_atomic_write(inode);
 out:
-       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
        inode_unlock(inode);
        mnt_drop_write_file(filp);
        return ret;
@@ -1733,9 +1771,9 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp)
        if (ret)
                return ret;
 
-       inode_lock(inode);
+       f2fs_balance_fs(F2FS_I_SB(inode), true);
 
-       down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+       inode_lock(inode);
 
        if (f2fs_is_volatile_file(inode)) {
                ret = -EINVAL;
@@ -1761,7 +1799,6 @@ err_out:
                clear_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST);
                ret = -EINVAL;
        }
-       up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
        inode_unlock(inode);
        mnt_drop_write_file(filp);
        return ret;
@@ -1853,6 +1890,8 @@ static int f2fs_ioc_abort_volatile_write(struct file *filp)
                ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 0, true);
        }
 
+       clear_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST);
+
        inode_unlock(inode);
 
        mnt_drop_write_file(filp);
@@ -1866,7 +1905,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        struct super_block *sb = sbi->sb;
        __u32 in;
-       int ret;
+       int ret = 0;
 
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
@@ -1889,6 +1928,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
                }
                if (sb) {
                        f2fs_stop_checkpoint(sbi, false);
+                       set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
                        thaw_bdev(sb->s_bdev, sb);
                }
                break;
@@ -1898,13 +1938,16 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
                if (ret)
                        goto out;
                f2fs_stop_checkpoint(sbi, false);
+               set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
                break;
        case F2FS_GOING_DOWN_NOSYNC:
                f2fs_stop_checkpoint(sbi, false);
+               set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
                break;
        case F2FS_GOING_DOWN_METAFLUSH:
                f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_META_IO);
                f2fs_stop_checkpoint(sbi, false);
+               set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
                break;
        default:
                ret = -EINVAL;
@@ -2107,7 +2150,7 @@ out:
        return ret;
 }
 
-static int f2fs_ioc_f2fs_write_checkpoint(struct file *filp, unsigned long arg)
+static int f2fs_ioc_write_checkpoint(struct file *filp, unsigned long arg)
 {
        struct inode *inode = file_inode(filp);
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
@@ -2351,15 +2394,10 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in,
        }
 
        inode_lock(src);
-       down_write(&F2FS_I(src)->i_gc_rwsem[WRITE]);
        if (src != dst) {
                ret = -EBUSY;
                if (!inode_trylock(dst))
                        goto out;
-               if (!down_write_trylock(&F2FS_I(dst)->i_gc_rwsem[WRITE])) {
-                       inode_unlock(dst);
-                       goto out;
-               }
        }
 
        ret = -EINVAL;
@@ -2404,6 +2442,14 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in,
                goto out_unlock;
 
        f2fs_balance_fs(sbi, true);
+
+       down_write(&F2FS_I(src)->i_gc_rwsem[WRITE]);
+       if (src != dst) {
+               ret = -EBUSY;
+               if (!down_write_trylock(&F2FS_I(dst)->i_gc_rwsem[WRITE]))
+                       goto out_src;
+       }
+
        f2fs_lock_op(sbi);
        ret = __exchange_data_block(src, dst, pos_in >> F2FS_BLKSIZE_BITS,
                                pos_out >> F2FS_BLKSIZE_BITS,
@@ -2416,13 +2462,15 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in,
                        f2fs_i_size_write(dst, dst_osize);
        }
        f2fs_unlock_op(sbi);
-out_unlock:
-       if (src != dst) {
+
+       if (src != dst)
                up_write(&F2FS_I(dst)->i_gc_rwsem[WRITE]);
+out_src:
+       up_write(&F2FS_I(src)->i_gc_rwsem[WRITE]);
+out_unlock:
+       if (src != dst)
                inode_unlock(dst);
-       }
 out:
-       up_write(&F2FS_I(src)->i_gc_rwsem[WRITE]);
        inode_unlock(src);
        return ret;
 }
@@ -2782,7 +2830,7 @@ static int f2fs_ioc_set_pin_file(struct file *filp, unsigned long arg)
 
        if (!pin) {
                clear_inode_flag(inode, FI_PIN_FILE);
-               F2FS_I(inode)->i_gc_failures[GC_FAILURE_PIN] = 1;
+               f2fs_i_gc_failures_write(inode, 0);
                goto done;
        }
 
@@ -2888,7 +2936,7 @@ long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        case F2FS_IOC_GARBAGE_COLLECT_RANGE:
                return f2fs_ioc_gc_range(filp, arg);
        case F2FS_IOC_WRITE_CHECKPOINT:
-               return f2fs_ioc_f2fs_write_checkpoint(filp, arg);
+               return f2fs_ioc_write_checkpoint(filp, arg);
        case F2FS_IOC_DEFRAGMENT:
                return f2fs_ioc_defragment(filp, arg);
        case F2FS_IOC_MOVE_RANGE:
index 9093be6e7a7db80ca8c1f07f391875541ec99e13..5c8d004222372990c1445ff62172ea7d16759d74 100644 (file)
@@ -53,12 +53,10 @@ static int gc_thread_func(void *data)
                        continue;
                }
 
-#ifdef CONFIG_F2FS_FAULT_INJECTION
                if (time_to_inject(sbi, FAULT_CHECKPOINT)) {
                        f2fs_show_injection_info(FAULT_CHECKPOINT);
                        f2fs_stop_checkpoint(sbi, false);
                }
-#endif
 
                if (!sb_start_write_trylock(sbi->sb))
                        continue;
@@ -517,7 +515,11 @@ next_step:
                        continue;
                }
 
-               f2fs_get_node_info(sbi, nid, &ni);
+               if (f2fs_get_node_info(sbi, nid, &ni)) {
+                       f2fs_put_page(node_page, 1);
+                       continue;
+               }
+
                if (ni.blk_addr != start_addr + off) {
                        f2fs_put_page(node_page, 1);
                        continue;
@@ -576,7 +578,10 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
        if (IS_ERR(node_page))
                return false;
 
-       f2fs_get_node_info(sbi, nid, dni);
+       if (f2fs_get_node_info(sbi, nid, dni)) {
+               f2fs_put_page(node_page, 1);
+               return false;
+       }
 
        if (sum->version != dni->version) {
                f2fs_msg(sbi->sb, KERN_WARNING,
@@ -594,6 +599,72 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
        return true;
 }
 
+static int ra_data_block(struct inode *inode, pgoff_t index)
+{
+       struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+       struct address_space *mapping = inode->i_mapping;
+       struct dnode_of_data dn;
+       struct page *page;
+       struct extent_info ei = {0, 0, 0};
+       struct f2fs_io_info fio = {
+               .sbi = sbi,
+               .ino = inode->i_ino,
+               .type = DATA,
+               .temp = COLD,
+               .op = REQ_OP_READ,
+               .op_flags = 0,
+               .encrypted_page = NULL,
+               .in_list = false,
+               .retry = false,
+       };
+       int err;
+
+       page = f2fs_grab_cache_page(mapping, index, true);
+       if (!page)
+               return -ENOMEM;
+
+       if (f2fs_lookup_extent_cache(inode, index, &ei)) {
+               dn.data_blkaddr = ei.blk + index - ei.fofs;
+               goto got_it;
+       }
+
+       set_new_dnode(&dn, inode, NULL, NULL, 0);
+       err = f2fs_get_dnode_of_data(&dn, index, LOOKUP_NODE);
+       if (err)
+               goto put_page;
+       f2fs_put_dnode(&dn);
+
+       if (unlikely(!f2fs_is_valid_blkaddr(sbi, dn.data_blkaddr,
+                                               DATA_GENERIC))) {
+               err = -EFAULT;
+               goto put_page;
+       }
+got_it:
+       /* read page */
+       fio.page = page;
+       fio.new_blkaddr = fio.old_blkaddr = dn.data_blkaddr;
+
+       fio.encrypted_page = f2fs_pagecache_get_page(META_MAPPING(sbi),
+                                       dn.data_blkaddr,
+                                       FGP_LOCK | FGP_CREAT, GFP_NOFS);
+       if (!fio.encrypted_page) {
+               err = -ENOMEM;
+               goto put_page;
+       }
+
+       err = f2fs_submit_page_bio(&fio);
+       if (err)
+               goto put_encrypted_page;
+       f2fs_put_page(fio.encrypted_page, 0);
+       f2fs_put_page(page, 1);
+       return 0;
+put_encrypted_page:
+       f2fs_put_page(fio.encrypted_page, 1);
+put_page:
+       f2fs_put_page(page, 1);
+       return err;
+}
+
 /*
  * Move data block via META_MAPPING while keeping locked data page.
  * This can be used to move blocks, aka LBAs, directly on disk.
@@ -615,7 +686,7 @@ static void move_data_block(struct inode *inode, block_t bidx,
        struct dnode_of_data dn;
        struct f2fs_summary sum;
        struct node_info ni;
-       struct page *page;
+       struct page *page, *mpage;
        block_t newaddr;
        int err;
        bool lfs_mode = test_opt(fio.sbi, LFS);
@@ -655,7 +726,10 @@ static void move_data_block(struct inode *inode, block_t bidx,
         */
        f2fs_wait_on_page_writeback(page, DATA, true);
 
-       f2fs_get_node_info(fio.sbi, dn.nid, &ni);
+       err = f2fs_get_node_info(fio.sbi, dn.nid, &ni);
+       if (err)
+               goto put_out;
+
        set_summary(&sum, dn.nid, dn.ofs_in_node, ni.version);
 
        /* read page */
@@ -675,6 +749,23 @@ static void move_data_block(struct inode *inode, block_t bidx,
                goto recover_block;
        }
 
+       mpage = f2fs_pagecache_get_page(META_MAPPING(fio.sbi),
+                                       fio.old_blkaddr, FGP_LOCK, GFP_NOFS);
+       if (mpage) {
+               bool updated = false;
+
+               if (PageUptodate(mpage)) {
+                       memcpy(page_address(fio.encrypted_page),
+                                       page_address(mpage), PAGE_SIZE);
+                       updated = true;
+               }
+               f2fs_put_page(mpage, 1);
+               invalidate_mapping_pages(META_MAPPING(fio.sbi),
+                                       fio.old_blkaddr, fio.old_blkaddr);
+               if (updated)
+                       goto write_page;
+       }
+
        err = f2fs_submit_page_bio(&fio);
        if (err)
                goto put_page_out;
@@ -691,6 +782,7 @@ static void move_data_block(struct inode *inode, block_t bidx,
                goto put_page_out;
        }
 
+write_page:
        set_page_dirty(fio.encrypted_page);
        f2fs_wait_on_page_writeback(fio.encrypted_page, DATA, true);
        if (clear_page_dirty_for_io(fio.encrypted_page))
@@ -865,22 +957,30 @@ next_step:
                        if (IS_ERR(inode) || is_bad_inode(inode))
                                continue;
 
-                       /* if inode uses special I/O path, let's go phase 3 */
-                       if (f2fs_post_read_required(inode)) {
-                               add_gc_inode(gc_list, inode);
-                               continue;
-                       }
-
                        if (!down_write_trylock(
                                &F2FS_I(inode)->i_gc_rwsem[WRITE])) {
                                iput(inode);
+                               sbi->skipped_gc_rwsem++;
+                               continue;
+                       }
+
+                       start_bidx = f2fs_start_bidx_of_node(nofs, inode) +
+                                                               ofs_in_node;
+
+                       if (f2fs_post_read_required(inode)) {
+                               int err = ra_data_block(inode, start_bidx);
+
+                               up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
+                               if (err) {
+                                       iput(inode);
+                                       continue;
+                               }
+                               add_gc_inode(gc_list, inode);
                                continue;
                        }
 
-                       start_bidx = f2fs_start_bidx_of_node(nofs, inode);
                        data_page = f2fs_get_read_data_page(inode,
-                                       start_bidx + ofs_in_node, REQ_RAHEAD,
-                                       true);
+                                               start_bidx, REQ_RAHEAD, true);
                        up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
                        if (IS_ERR(data_page)) {
                                iput(inode);
@@ -903,6 +1003,7 @@ next_step:
                                        continue;
                                if (!down_write_trylock(
                                                &fi->i_gc_rwsem[WRITE])) {
+                                       sbi->skipped_gc_rwsem++;
                                        up_write(&fi->i_gc_rwsem[READ]);
                                        continue;
                                }
@@ -986,7 +1087,13 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
                        goto next;
 
                sum = page_address(sum_page);
-               f2fs_bug_on(sbi, type != GET_SUM_TYPE((&sum->footer)));
+               if (type != GET_SUM_TYPE((&sum->footer))) {
+                       f2fs_msg(sbi->sb, KERN_ERR, "Inconsistent segment (%u) "
+                               "type [%d, %d] in SSA and SIT",
+                               segno, type, GET_SUM_TYPE((&sum->footer)));
+                       set_sbi_flag(sbi, SBI_NEED_FSCK);
+                       goto next;
+               }
 
                /*
                 * this is to avoid deadlock:
@@ -1034,6 +1141,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
                .iroot = RADIX_TREE_INIT(gc_list.iroot, GFP_NOFS),
        };
        unsigned long long last_skipped = sbi->skipped_atomic_files[FG_GC];
+       unsigned long long first_skipped;
        unsigned int skipped_round = 0, round = 0;
 
        trace_f2fs_gc_begin(sbi->sb, sync, background,
@@ -1046,6 +1154,8 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
                                prefree_segments(sbi));
 
        cpc.reason = __get_cp_reason(sbi);
+       sbi->skipped_gc_rwsem = 0;
+       first_skipped = last_skipped;
 gc_more:
        if (unlikely(!(sbi->sb->s_flags & SB_ACTIVE))) {
                ret = -EINVAL;
@@ -1087,7 +1197,8 @@ gc_more:
        total_freed += seg_freed;
 
        if (gc_type == FG_GC) {
-               if (sbi->skipped_atomic_files[FG_GC] > last_skipped)
+               if (sbi->skipped_atomic_files[FG_GC] > last_skipped ||
+                                               sbi->skipped_gc_rwsem)
                        skipped_round++;
                last_skipped = sbi->skipped_atomic_files[FG_GC];
                round++;
@@ -1096,15 +1207,23 @@ gc_more:
        if (gc_type == FG_GC)
                sbi->cur_victim_sec = NULL_SEGNO;
 
-       if (!sync) {
-               if (has_not_enough_free_secs(sbi, sec_freed, 0)) {
-                       if (skipped_round > MAX_SKIP_ATOMIC_COUNT &&
-                               skipped_round * 2 >= round)
-                               f2fs_drop_inmem_pages_all(sbi, true);
+       if (sync)
+               goto stop;
+
+       if (has_not_enough_free_secs(sbi, sec_freed, 0)) {
+               if (skipped_round <= MAX_SKIP_GC_COUNT ||
+                                       skipped_round * 2 < round) {
                        segno = NULL_SEGNO;
                        goto gc_more;
                }
 
+               if (first_skipped < last_skipped &&
+                               (last_skipped - first_skipped) >
+                                               sbi->skipped_gc_rwsem) {
+                       f2fs_drop_inmem_pages_all(sbi, true);
+                       segno = NULL_SEGNO;
+                       goto gc_more;
+               }
                if (gc_type == FG_GC)
                        ret = f2fs_write_checkpoint(sbi, &cpc);
        }
index 043830be5662f865b3c5824da2be23a7641dc6d5..115dc219344b15be987905121b38961b8fdcd630 100644 (file)
@@ -121,6 +121,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
                .encrypted_page = NULL,
                .io_type = FS_DATA_IO,
        };
+       struct node_info ni;
        int dirty, err;
 
        if (!f2fs_exist_data(dn->inode))
@@ -130,6 +131,24 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
        if (err)
                return err;
 
+       err = f2fs_get_node_info(fio.sbi, dn->nid, &ni);
+       if (err) {
+               f2fs_put_dnode(dn);
+               return err;
+       }
+
+       fio.version = ni.version;
+
+       if (unlikely(dn->data_blkaddr != NEW_ADDR)) {
+               f2fs_put_dnode(dn);
+               set_sbi_flag(fio.sbi, SBI_NEED_FSCK);
+               f2fs_msg(fio.sbi->sb, KERN_WARNING,
+                       "%s: corrupted inline inode ino=%lx, i_addr[0]:0x%x, "
+                       "run fsck to fix.",
+                       __func__, dn->inode->i_ino, dn->data_blkaddr);
+               return -EINVAL;
+       }
+
        f2fs_bug_on(F2FS_P_SB(page), PageWriteback(page));
 
        f2fs_do_read_inline_data(page, dn->inode_page);
@@ -363,6 +382,17 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage,
        if (err)
                goto out;
 
+       if (unlikely(dn.data_blkaddr != NEW_ADDR)) {
+               f2fs_put_dnode(&dn);
+               set_sbi_flag(F2FS_P_SB(page), SBI_NEED_FSCK);
+               f2fs_msg(F2FS_P_SB(page)->sb, KERN_WARNING,
+                       "%s: corrupted inline inode ino=%lx, i_addr[0]:0x%x, "
+                       "run fsck to fix.",
+                       __func__, dir->i_ino, dn.data_blkaddr);
+               err = -EINVAL;
+               goto out;
+       }
+
        f2fs_wait_on_page_writeback(page, DATA, true);
 
        dentry_blk = page_address(page);
@@ -477,6 +507,7 @@ static int f2fs_move_rehashed_dirents(struct inode *dir, struct page *ipage,
        return 0;
 recover:
        lock_page(ipage);
+       f2fs_wait_on_page_writeback(ipage, NODE, true);
        memcpy(inline_dentry, backup_dentry, MAX_INLINE_DATA(dir));
        f2fs_i_depth_write(dir, 0);
        f2fs_i_size_write(dir, MAX_INLINE_DATA(dir));
@@ -668,7 +699,10 @@ int f2fs_inline_data_fiemap(struct inode *inode,
                ilen = start + len;
        ilen -= start;
 
-       f2fs_get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni);
+       err = f2fs_get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni);
+       if (err)
+               goto out;
+
        byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits;
        byteaddr += (char *)inline_data_addr(inode, ipage) -
                                        (char *)F2FS_INODE(ipage);
index f121c864f4c0d9cfe5f7c6601d23b8af4fe88501..959df2249875c484d6b7a51369fd97466e9002a8 100644 (file)
@@ -68,13 +68,16 @@ static void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri)
        }
 }
 
-static bool __written_first_block(struct f2fs_inode *ri)
+static int __written_first_block(struct f2fs_sb_info *sbi,
+                                       struct f2fs_inode *ri)
 {
        block_t addr = le32_to_cpu(ri->i_addr[offset_in_addr(ri)]);
 
-       if (is_valid_blkaddr(addr))
-               return true;
-       return false;
+       if (!__is_valid_data_blkaddr(addr))
+               return 1;
+       if (!f2fs_is_valid_blkaddr(sbi, addr, DATA_GENERIC))
+               return -EFAULT;
+       return 0;
 }
 
 static void __set_inode_rdev(struct inode *inode, struct f2fs_inode *ri)
@@ -121,7 +124,7 @@ static bool f2fs_enable_inode_chksum(struct f2fs_sb_info *sbi, struct page *page
        if (!f2fs_sb_has_inode_chksum(sbi->sb))
                return false;
 
-       if (!RAW_IS_INODE(F2FS_NODE(page)) || !(ri->i_inline & F2FS_EXTRA_ATTR))
+       if (!IS_INODE(page) || !(ri->i_inline & F2FS_EXTRA_ATTR))
                return false;
 
        if (!F2FS_FITS_IN_INODE(ri, le16_to_cpu(ri->i_extra_isize),
@@ -159,8 +162,15 @@ bool f2fs_inode_chksum_verify(struct f2fs_sb_info *sbi, struct page *page)
        struct f2fs_inode *ri;
        __u32 provided, calculated;
 
+       if (unlikely(is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN)))
+               return true;
+
+#ifdef CONFIG_F2FS_CHECK_FS
+       if (!f2fs_enable_inode_chksum(sbi, page))
+#else
        if (!f2fs_enable_inode_chksum(sbi, page) ||
                        PageDirty(page) || PageWriteback(page))
+#endif
                return true;
 
        ri = &F2FS_NODE(page)->i;
@@ -185,9 +195,31 @@ void f2fs_inode_chksum_set(struct f2fs_sb_info *sbi, struct page *page)
        ri->i_inode_checksum = cpu_to_le32(f2fs_inode_chksum(sbi, page));
 }
 
-static bool sanity_check_inode(struct inode *inode)
+static bool sanity_check_inode(struct inode *inode, struct page *node_page)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+       struct f2fs_inode_info *fi = F2FS_I(inode);
+       unsigned long long iblocks;
+
+       iblocks = le64_to_cpu(F2FS_INODE(node_page)->i_blocks);
+       if (!iblocks) {
+               set_sbi_flag(sbi, SBI_NEED_FSCK);
+               f2fs_msg(sbi->sb, KERN_WARNING,
+                       "%s: corrupted inode i_blocks i_ino=%lx iblocks=%llu, "
+                       "run fsck to fix.",
+                       __func__, inode->i_ino, iblocks);
+               return false;
+       }
+
+       if (ino_of_node(node_page) != nid_of_node(node_page)) {
+               set_sbi_flag(sbi, SBI_NEED_FSCK);
+               f2fs_msg(sbi->sb, KERN_WARNING,
+                       "%s: corrupted inode footer i_ino=%lx, ino,nid: "
+                       "[%u, %u] run fsck to fix.",
+                       __func__, inode->i_ino,
+                       ino_of_node(node_page), nid_of_node(node_page));
+               return false;
+       }
 
        if (f2fs_sb_has_flexible_inline_xattr(sbi->sb)
                        && !f2fs_has_extra_attr(inode)) {
@@ -197,6 +229,64 @@ static bool sanity_check_inode(struct inode *inode)
                        __func__, inode->i_ino);
                return false;
        }
+
+       if (f2fs_has_extra_attr(inode) &&
+                       !f2fs_sb_has_extra_attr(sbi->sb)) {
+               set_sbi_flag(sbi, SBI_NEED_FSCK);
+               f2fs_msg(sbi->sb, KERN_WARNING,
+                       "%s: inode (ino=%lx) is with extra_attr, "
+                       "but extra_attr feature is off",
+                       __func__, inode->i_ino);
+               return false;
+       }
+
+       if (fi->i_extra_isize > F2FS_TOTAL_EXTRA_ATTR_SIZE ||
+                       fi->i_extra_isize % sizeof(__le32)) {
+               set_sbi_flag(sbi, SBI_NEED_FSCK);
+               f2fs_msg(sbi->sb, KERN_WARNING,
+                       "%s: inode (ino=%lx) has corrupted i_extra_isize: %d, "
+                       "max: %zu",
+                       __func__, inode->i_ino, fi->i_extra_isize,
+                       F2FS_TOTAL_EXTRA_ATTR_SIZE);
+               return false;
+       }
+
+       if (F2FS_I(inode)->extent_tree) {
+               struct extent_info *ei = &F2FS_I(inode)->extent_tree->largest;
+
+               if (ei->len &&
+                       (!f2fs_is_valid_blkaddr(sbi, ei->blk, DATA_GENERIC) ||
+                       !f2fs_is_valid_blkaddr(sbi, ei->blk + ei->len - 1,
+                                                       DATA_GENERIC))) {
+                       set_sbi_flag(sbi, SBI_NEED_FSCK);
+                       f2fs_msg(sbi->sb, KERN_WARNING,
+                               "%s: inode (ino=%lx) extent info [%u, %u, %u] "
+                               "is incorrect, run fsck to fix",
+                               __func__, inode->i_ino,
+                               ei->blk, ei->fofs, ei->len);
+                       return false;
+               }
+       }
+
+       if (f2fs_has_inline_data(inode) &&
+                       (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode))) {
+               set_sbi_flag(sbi, SBI_NEED_FSCK);
+               f2fs_msg(sbi->sb, KERN_WARNING,
+                       "%s: inode (ino=%lx, mode=%u) should not have "
+                       "inline_data, run fsck to fix",
+                       __func__, inode->i_ino, inode->i_mode);
+               return false;
+       }
+
+       if (f2fs_has_inline_dentry(inode) && !S_ISDIR(inode->i_mode)) {
+               set_sbi_flag(sbi, SBI_NEED_FSCK);
+               f2fs_msg(sbi->sb, KERN_WARNING,
+                       "%s: inode (ino=%lx, mode=%u) should not have "
+                       "inline_dentry, run fsck to fix",
+                       __func__, inode->i_ino, inode->i_mode);
+               return false;
+       }
+
        return true;
 }
 
@@ -207,6 +297,7 @@ static int do_read_inode(struct inode *inode)
        struct page *node_page;
        struct f2fs_inode *ri;
        projid_t i_projid;
+       int err;
 
        /* Check if ino is within scope */
        if (f2fs_check_nid_range(sbi, inode->i_ino))
@@ -268,6 +359,11 @@ static int do_read_inode(struct inode *inode)
                fi->i_inline_xattr_size = 0;
        }
 
+       if (!sanity_check_inode(inode, node_page)) {
+               f2fs_put_page(node_page, 1);
+               return -EINVAL;
+       }
+
        /* check data exist */
        if (f2fs_has_inline_data(inode) && !f2fs_exist_data(inode))
                __recover_inline_status(inode, node_page);
@@ -275,8 +371,15 @@ static int do_read_inode(struct inode *inode)
        /* get rdev by using inline_info */
        __get_inode_rdev(inode, ri);
 
-       if (__written_first_block(ri))
-               set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN);
+       if (S_ISREG(inode->i_mode)) {
+               err = __written_first_block(sbi, ri);
+               if (err < 0) {
+                       f2fs_put_page(node_page, 1);
+                       return err;
+               }
+               if (!err)
+                       set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN);
+       }
 
        if (!f2fs_need_inode_block_update(sbi, inode->i_ino))
                fi->last_disk_size = inode->i_size;
@@ -297,9 +400,9 @@ static int do_read_inode(struct inode *inode)
                fi->i_crtime.tv_nsec = le32_to_cpu(ri->i_crtime_nsec);
        }
 
-       F2FS_I(inode)->i_disk_time[0] = timespec64_to_timespec(inode->i_atime);
-       F2FS_I(inode)->i_disk_time[1] = timespec64_to_timespec(inode->i_ctime);
-       F2FS_I(inode)->i_disk_time[2] = timespec64_to_timespec(inode->i_mtime);
+       F2FS_I(inode)->i_disk_time[0] = inode->i_atime;
+       F2FS_I(inode)->i_disk_time[1] = inode->i_ctime;
+       F2FS_I(inode)->i_disk_time[2] = inode->i_mtime;
        F2FS_I(inode)->i_disk_time[3] = F2FS_I(inode)->i_crtime;
        f2fs_put_page(node_page, 1);
 
@@ -330,10 +433,6 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino)
        ret = do_read_inode(inode);
        if (ret)
                goto bad_inode;
-       if (!sanity_check_inode(inode)) {
-               ret = -EINVAL;
-               goto bad_inode;
-       }
 make_now:
        if (ino == F2FS_NODE_INO(sbi)) {
                inode->i_mapping->a_ops = &f2fs_node_aops;
@@ -470,10 +569,14 @@ void f2fs_update_inode(struct inode *inode, struct page *node_page)
        if (inode->i_nlink == 0)
                clear_inline_node(node_page);
 
-       F2FS_I(inode)->i_disk_time[0] = timespec64_to_timespec(inode->i_atime);
-       F2FS_I(inode)->i_disk_time[1] = timespec64_to_timespec(inode->i_ctime);
-       F2FS_I(inode)->i_disk_time[2] = timespec64_to_timespec(inode->i_mtime);
+       F2FS_I(inode)->i_disk_time[0] = inode->i_atime;
+       F2FS_I(inode)->i_disk_time[1] = inode->i_ctime;
+       F2FS_I(inode)->i_disk_time[2] = inode->i_mtime;
        F2FS_I(inode)->i_disk_time[3] = F2FS_I(inode)->i_crtime;
+
+#ifdef CONFIG_F2FS_CHECK_FS
+       f2fs_inode_chksum_set(F2FS_I_SB(inode), node_page);
+#endif
 }
 
 void f2fs_update_inode_page(struct inode *inode)
@@ -558,12 +661,11 @@ retry:
        if (F2FS_HAS_BLOCKS(inode))
                err = f2fs_truncate(inode);
 
-#ifdef CONFIG_F2FS_FAULT_INJECTION
        if (time_to_inject(sbi, FAULT_EVICT_INODE)) {
                f2fs_show_injection_info(FAULT_EVICT_INODE);
                err = -EIO;
        }
-#endif
+
        if (!err) {
                f2fs_lock_op(sbi);
                err = f2fs_remove_inode_page(inode);
@@ -626,6 +728,7 @@ void f2fs_handle_failed_inode(struct inode *inode)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        struct node_info ni;
+       int err;
 
        /*
         * clear nlink of inode in order to release resource of inode
@@ -648,10 +751,16 @@ void f2fs_handle_failed_inode(struct inode *inode)
         * so we can prevent losing this orphan when encoutering checkpoint
         * and following suddenly power-off.
         */
-       f2fs_get_node_info(sbi, inode->i_ino, &ni);
+       err = f2fs_get_node_info(sbi, inode->i_ino, &ni);
+       if (err) {
+               set_sbi_flag(sbi, SBI_NEED_FSCK);
+               f2fs_msg(sbi->sb, KERN_WARNING,
+                       "May loss orphan inode, run fsck to fix.");
+               goto out;
+       }
 
        if (ni.blk_addr != NULL_ADDR) {
-               int err = f2fs_acquire_orphan_inode(sbi);
+               err = f2fs_acquire_orphan_inode(sbi);
                if (err) {
                        set_sbi_flag(sbi, SBI_NEED_FSCK);
                        f2fs_msg(sbi->sb, KERN_WARNING,
@@ -664,6 +773,7 @@ void f2fs_handle_failed_inode(struct inode *inode)
                set_inode_flag(inode, FI_FREE_NID);
        }
 
+out:
        f2fs_unlock_op(sbi);
 
        /* iput will drop the inode object */
index 231b7f3ea7d3f0e27863bebf4b7886df753bf805..1f67e389169f5388a4883a1f89398b7f43cabaa0 100644 (file)
@@ -51,7 +51,7 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
        inode->i_ino = ino;
        inode->i_blocks = 0;
        inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
-       F2FS_I(inode)->i_crtime = timespec64_to_timespec(inode->i_mtime);
+       F2FS_I(inode)->i_crtime = inode->i_mtime;
        inode->i_generation = sbi->s_next_generation++;
 
        if (S_ISDIR(inode->i_mode))
@@ -246,7 +246,7 @@ int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name,
                return -EINVAL;
 
        if (hot) {
-               strncpy(extlist[count], name, strlen(name));
+               memcpy(extlist[count], name, strlen(name));
                sbi->raw_super->hot_ext_count = hot_count + 1;
        } else {
                char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN];
@@ -254,7 +254,7 @@ int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name,
                memcpy(buf, &extlist[cold_count],
                                F2FS_EXTENSION_LEN * hot_count);
                memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN);
-               strncpy(extlist[cold_count], name, strlen(name));
+               memcpy(extlist[cold_count], name, strlen(name));
                memcpy(&extlist[cold_count + 1], buf,
                                F2FS_EXTENSION_LEN * hot_count);
                sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1);
index 10643b11bd591d16f8b1e55ff5a8bdae648e5a10..dd2e45a661aacdb123b63c92f84e717f17fa59c1 100644 (file)
@@ -28,6 +28,7 @@
 static struct kmem_cache *nat_entry_slab;
 static struct kmem_cache *free_nid_slab;
 static struct kmem_cache *nat_entry_set_slab;
+static struct kmem_cache *fsync_node_entry_slab;
 
 /*
  * Check whether the given nid is within node id range.
@@ -112,25 +113,22 @@ static void clear_node_page_dirty(struct page *page)
 
 static struct page *get_current_nat_page(struct f2fs_sb_info *sbi, nid_t nid)
 {
-       pgoff_t index = current_nat_addr(sbi, nid);
-       return f2fs_get_meta_page(sbi, index);
+       return f2fs_get_meta_page_nofail(sbi, current_nat_addr(sbi, nid));
 }
 
 static struct page *get_next_nat_page(struct f2fs_sb_info *sbi, nid_t nid)
 {
        struct page *src_page;
        struct page *dst_page;
-       pgoff_t src_off;
        pgoff_t dst_off;
        void *src_addr;
        void *dst_addr;
        struct f2fs_nm_info *nm_i = NM_I(sbi);
 
-       src_off = current_nat_addr(sbi, nid);
-       dst_off = next_nat_addr(sbi, src_off);
+       dst_off = next_nat_addr(sbi, current_nat_addr(sbi, nid));
 
        /* get current nat block page with lock */
-       src_page = f2fs_get_meta_page(sbi, src_off);
+       src_page = get_current_nat_page(sbi, nid);
        dst_page = f2fs_grab_meta_page(sbi, dst_off);
        f2fs_bug_on(sbi, PageDirty(src_page));
 
@@ -176,14 +174,30 @@ static struct nat_entry *__init_nat_entry(struct f2fs_nm_info *nm_i,
 
        if (raw_ne)
                node_info_from_raw_nat(&ne->ni, raw_ne);
+
+       spin_lock(&nm_i->nat_list_lock);
        list_add_tail(&ne->list, &nm_i->nat_entries);
+       spin_unlock(&nm_i->nat_list_lock);
+
        nm_i->nat_cnt++;
        return ne;
 }
 
 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);
+       struct nat_entry *ne;
+
+       ne = radix_tree_lookup(&nm_i->nat_root, n);
+
+       /* for recent accessed nat entry, move it to tail of lru list */
+       if (ne && !get_nat_flag(ne, IS_DIRTY)) {
+               spin_lock(&nm_i->nat_list_lock);
+               if (!list_empty(&ne->list))
+                       list_move_tail(&ne->list, &nm_i->nat_entries);
+               spin_unlock(&nm_i->nat_list_lock);
+       }
+
+       return ne;
 }
 
 static unsigned int __gang_lookup_nat_cache(struct f2fs_nm_info *nm_i,
@@ -194,7 +208,6 @@ static unsigned int __gang_lookup_nat_cache(struct f2fs_nm_info *nm_i,
 
 static void __del_from_nat_cache(struct f2fs_nm_info *nm_i, struct nat_entry *e)
 {
-       list_del(&e->list);
        radix_tree_delete(&nm_i->nat_root, nat_get_nid(e));
        nm_i->nat_cnt--;
        __free_nat_entry(e);
@@ -245,16 +258,21 @@ static void __set_nat_cache_dirty(struct f2fs_nm_info *nm_i,
        nm_i->dirty_nat_cnt++;
        set_nat_flag(ne, IS_DIRTY, true);
 refresh_list:
+       spin_lock(&nm_i->nat_list_lock);
        if (new_ne)
                list_del_init(&ne->list);
        else
                list_move_tail(&ne->list, &head->entry_list);
+       spin_unlock(&nm_i->nat_list_lock);
 }
 
 static void __clear_nat_cache_dirty(struct f2fs_nm_info *nm_i,
                struct nat_entry_set *set, struct nat_entry *ne)
 {
+       spin_lock(&nm_i->nat_list_lock);
        list_move_tail(&ne->list, &nm_i->nat_entries);
+       spin_unlock(&nm_i->nat_list_lock);
+
        set_nat_flag(ne, IS_DIRTY, false);
        set->entry_cnt--;
        nm_i->dirty_nat_cnt--;
@@ -267,6 +285,72 @@ static unsigned int __gang_lookup_nat_set(struct f2fs_nm_info *nm_i,
                                                        start, nr);
 }
 
+bool f2fs_in_warm_node_list(struct f2fs_sb_info *sbi, struct page *page)
+{
+       return NODE_MAPPING(sbi) == page->mapping &&
+                       IS_DNODE(page) && is_cold_node(page);
+}
+
+void f2fs_init_fsync_node_info(struct f2fs_sb_info *sbi)
+{
+       spin_lock_init(&sbi->fsync_node_lock);
+       INIT_LIST_HEAD(&sbi->fsync_node_list);
+       sbi->fsync_seg_id = 0;
+       sbi->fsync_node_num = 0;
+}
+
+static unsigned int f2fs_add_fsync_node_entry(struct f2fs_sb_info *sbi,
+                                                       struct page *page)
+{
+       struct fsync_node_entry *fn;
+       unsigned long flags;
+       unsigned int seq_id;
+
+       fn = f2fs_kmem_cache_alloc(fsync_node_entry_slab, GFP_NOFS);
+
+       get_page(page);
+       fn->page = page;
+       INIT_LIST_HEAD(&fn->list);
+
+       spin_lock_irqsave(&sbi->fsync_node_lock, flags);
+       list_add_tail(&fn->list, &sbi->fsync_node_list);
+       fn->seq_id = sbi->fsync_seg_id++;
+       seq_id = fn->seq_id;
+       sbi->fsync_node_num++;
+       spin_unlock_irqrestore(&sbi->fsync_node_lock, flags);
+
+       return seq_id;
+}
+
+void f2fs_del_fsync_node_entry(struct f2fs_sb_info *sbi, struct page *page)
+{
+       struct fsync_node_entry *fn;
+       unsigned long flags;
+
+       spin_lock_irqsave(&sbi->fsync_node_lock, flags);
+       list_for_each_entry(fn, &sbi->fsync_node_list, list) {
+               if (fn->page == page) {
+                       list_del(&fn->list);
+                       sbi->fsync_node_num--;
+                       spin_unlock_irqrestore(&sbi->fsync_node_lock, flags);
+                       kmem_cache_free(fsync_node_entry_slab, fn);
+                       put_page(page);
+                       return;
+               }
+       }
+       spin_unlock_irqrestore(&sbi->fsync_node_lock, flags);
+       f2fs_bug_on(sbi, 1);
+}
+
+void f2fs_reset_fsync_node_info(struct f2fs_sb_info *sbi)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&sbi->fsync_node_lock, flags);
+       sbi->fsync_seg_id = 0;
+       spin_unlock_irqrestore(&sbi->fsync_node_lock, flags);
+}
+
 int f2fs_need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
@@ -371,7 +455,7 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni,
                        new_blkaddr == NULL_ADDR);
        f2fs_bug_on(sbi, nat_get_blkaddr(e) == NEW_ADDR &&
                        new_blkaddr == NEW_ADDR);
-       f2fs_bug_on(sbi, is_valid_blkaddr(nat_get_blkaddr(e)) &&
+       f2fs_bug_on(sbi, is_valid_data_blkaddr(sbi, nat_get_blkaddr(e)) &&
                        new_blkaddr == NEW_ADDR);
 
        /* increment version no as node is removed */
@@ -382,7 +466,7 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni,
 
        /* change address */
        nat_set_blkaddr(e, new_blkaddr);
-       if (!is_valid_blkaddr(new_blkaddr))
+       if (!is_valid_data_blkaddr(sbi, new_blkaddr))
                set_nat_flag(e, IS_CHECKPOINTED, false);
        __set_nat_cache_dirty(nm_i, e);
 
@@ -405,13 +489,25 @@ int f2fs_try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink)
        if (!down_write_trylock(&nm_i->nat_tree_lock))
                return 0;
 
-       while (nr_shrink && !list_empty(&nm_i->nat_entries)) {
+       spin_lock(&nm_i->nat_list_lock);
+       while (nr_shrink) {
                struct nat_entry *ne;
+
+               if (list_empty(&nm_i->nat_entries))
+                       break;
+
                ne = list_first_entry(&nm_i->nat_entries,
                                        struct nat_entry, list);
+               list_del(&ne->list);
+               spin_unlock(&nm_i->nat_list_lock);
+
                __del_from_nat_cache(nm_i, ne);
                nr_shrink--;
+
+               spin_lock(&nm_i->nat_list_lock);
        }
+       spin_unlock(&nm_i->nat_list_lock);
+
        up_write(&nm_i->nat_tree_lock);
        return nr - nr_shrink;
 }
@@ -419,7 +515,7 @@ int f2fs_try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink)
 /*
  * This function always returns success
  */
-void f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
+int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
                                                struct node_info *ni)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
@@ -443,7 +539,7 @@ void f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
                ni->blk_addr = nat_get_blkaddr(e);
                ni->version = nat_get_version(e);
                up_read(&nm_i->nat_tree_lock);
-               return;
+               return 0;
        }
 
        memset(&ne, 0, sizeof(struct f2fs_nat_entry));
@@ -466,6 +562,9 @@ void f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
        up_read(&nm_i->nat_tree_lock);
 
        page = f2fs_get_meta_page(sbi, index);
+       if (IS_ERR(page))
+               return PTR_ERR(page);
+
        nat_blk = (struct f2fs_nat_block *)page_address(page);
        ne = nat_blk->entries[nid - start_nid];
        node_info_from_raw_nat(ni, &ne);
@@ -473,6 +572,7 @@ void f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
 cache:
        /* cache nat entry */
        cache_nat_entry(sbi, nid, &ne);
+       return 0;
 }
 
 /*
@@ -722,12 +822,15 @@ release_out:
        return err;
 }
 
-static void truncate_node(struct dnode_of_data *dn)
+static int truncate_node(struct dnode_of_data *dn)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
        struct node_info ni;
+       int err;
 
-       f2fs_get_node_info(sbi, dn->nid, &ni);
+       err = f2fs_get_node_info(sbi, dn->nid, &ni);
+       if (err)
+               return err;
 
        /* Deallocate node address */
        f2fs_invalidate_blocks(sbi, ni.blk_addr);
@@ -750,11 +853,14 @@ static void truncate_node(struct dnode_of_data *dn)
 
        dn->node_page = NULL;
        trace_f2fs_truncate_node(dn->inode, dn->nid, ni.blk_addr);
+
+       return 0;
 }
 
 static int truncate_dnode(struct dnode_of_data *dn)
 {
        struct page *page;
+       int err;
 
        if (dn->nid == 0)
                return 1;
@@ -770,7 +876,10 @@ static int truncate_dnode(struct dnode_of_data *dn)
        dn->node_page = page;
        dn->ofs_in_node = 0;
        f2fs_truncate_data_blocks(dn);
-       truncate_node(dn);
+       err = truncate_node(dn);
+       if (err)
+               return err;
+
        return 1;
 }
 
@@ -835,7 +944,9 @@ static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs,
        if (!ofs) {
                /* remove current indirect node */
                dn->node_page = page;
-               truncate_node(dn);
+               ret = truncate_node(dn);
+               if (ret)
+                       goto out_err;
                freed++;
        } else {
                f2fs_put_page(page, 1);
@@ -893,7 +1004,9 @@ static int truncate_partial_nodes(struct dnode_of_data *dn,
        if (offset[idx + 1] == 0) {
                dn->node_page = pages[idx];
                dn->nid = nid[idx];
-               truncate_node(dn);
+               err = truncate_node(dn);
+               if (err)
+                       goto fail;
        } else {
                f2fs_put_page(pages[idx], 1);
        }
@@ -1014,6 +1127,7 @@ int f2fs_truncate_xattr_node(struct inode *inode)
        nid_t nid = F2FS_I(inode)->i_xattr_nid;
        struct dnode_of_data dn;
        struct page *npage;
+       int err;
 
        if (!nid)
                return 0;
@@ -1022,10 +1136,15 @@ int f2fs_truncate_xattr_node(struct inode *inode)
        if (IS_ERR(npage))
                return PTR_ERR(npage);
 
+       set_new_dnode(&dn, inode, NULL, npage, nid);
+       err = truncate_node(&dn);
+       if (err) {
+               f2fs_put_page(npage, 1);
+               return err;
+       }
+
        f2fs_i_xnid_write(inode, 0);
 
-       set_new_dnode(&dn, inode, NULL, npage, nid);
-       truncate_node(&dn);
        return 0;
 }
 
@@ -1055,11 +1174,19 @@ int f2fs_remove_inode_page(struct inode *inode)
                f2fs_truncate_data_blocks_range(&dn, 1);
 
        /* 0 is possible, after f2fs_new_inode() has failed */
+       if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) {
+               f2fs_put_dnode(&dn);
+               return -EIO;
+       }
        f2fs_bug_on(F2FS_I_SB(inode),
                        inode->i_blocks != 0 && inode->i_blocks != 8);
 
        /* will put inode & node pages */
-       truncate_node(&dn);
+       err = truncate_node(&dn);
+       if (err) {
+               f2fs_put_dnode(&dn);
+               return err;
+       }
        return 0;
 }
 
@@ -1092,7 +1219,11 @@ struct page *f2fs_new_node_page(struct dnode_of_data *dn, unsigned int ofs)
                goto fail;
 
 #ifdef CONFIG_F2FS_CHECK_FS
-       f2fs_get_node_info(sbi, dn->nid, &new_ni);
+       err = f2fs_get_node_info(sbi, dn->nid, &new_ni);
+       if (err) {
+               dec_valid_node_count(sbi, dn->inode, !ofs);
+               goto fail;
+       }
        f2fs_bug_on(sbi, new_ni.blk_addr != NULL_ADDR);
 #endif
        new_ni.nid = dn->nid;
@@ -1140,13 +1271,21 @@ static int read_node_page(struct page *page, int op_flags)
                .page = page,
                .encrypted_page = NULL,
        };
+       int err;
 
-       if (PageUptodate(page))
+       if (PageUptodate(page)) {
+#ifdef CONFIG_F2FS_CHECK_FS
+               f2fs_bug_on(sbi, !f2fs_inode_chksum_verify(sbi, page));
+#endif
                return LOCKED_PAGE;
+       }
 
-       f2fs_get_node_info(sbi, page->index, &ni);
+       err = f2fs_get_node_info(sbi, page->index, &ni);
+       if (err)
+               return err;
 
-       if (unlikely(ni.blk_addr == NULL_ADDR)) {
+       if (unlikely(ni.blk_addr == NULL_ADDR) ||
+                       is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN)) {
                ClearPageUptodate(page);
                return -ENOENT;
        }
@@ -1348,7 +1487,7 @@ continue_unlock:
 
 static int __write_node_page(struct page *page, bool atomic, bool *submitted,
                                struct writeback_control *wbc, bool do_balance,
-                               enum iostat_type io_type)
+                               enum iostat_type io_type, unsigned int *seq_id)
 {
        struct f2fs_sb_info *sbi = F2FS_P_SB(page);
        nid_t nid;
@@ -1365,6 +1504,7 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted,
                .io_type = io_type,
                .io_wbc = wbc,
        };
+       unsigned int seq;
 
        trace_f2fs_writepage(page, NODE);
 
@@ -1374,10 +1514,17 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted,
        if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
                goto redirty_out;
 
+       if (wbc->sync_mode == WB_SYNC_NONE &&
+                       IS_DNODE(page) && is_cold_node(page))
+               goto redirty_out;
+
        /* get old block addr of this node page */
        nid = nid_of_node(page);
        f2fs_bug_on(sbi, page->index != nid);
 
+       if (f2fs_get_node_info(sbi, nid, &ni))
+               goto redirty_out;
+
        if (wbc->for_reclaim) {
                if (!down_read_trylock(&sbi->node_write))
                        goto redirty_out;
@@ -1385,8 +1532,6 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted,
                down_read(&sbi->node_write);
        }
 
-       f2fs_get_node_info(sbi, nid, &ni);
-
        /* This page is already truncated */
        if (unlikely(ni.blk_addr == NULL_ADDR)) {
                ClearPageUptodate(page);
@@ -1396,11 +1541,22 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted,
                return 0;
        }
 
+       if (__is_valid_data_blkaddr(ni.blk_addr) &&
+               !f2fs_is_valid_blkaddr(sbi, ni.blk_addr, DATA_GENERIC))
+               goto redirty_out;
+
        if (atomic && !test_opt(sbi, NOBARRIER))
                fio.op_flags |= REQ_PREFLUSH | REQ_FUA;
 
        set_page_writeback(page);
        ClearPageError(page);
+
+       if (f2fs_in_warm_node_list(sbi, page)) {
+               seq = f2fs_add_fsync_node_entry(sbi, page);
+               if (seq_id)
+                       *seq_id = seq;
+       }
+
        fio.old_blkaddr = ni.blk_addr;
        f2fs_do_write_node_page(nid, &fio);
        set_node_addr(sbi, &ni, fio.new_blkaddr, is_fsync_dnode(page));
@@ -1448,7 +1604,7 @@ void f2fs_move_node_page(struct page *node_page, int gc_type)
                        goto out_page;
 
                if (__write_node_page(node_page, false, NULL,
-                                       &wbc, false, FS_GC_NODE_IO))
+                                       &wbc, false, FS_GC_NODE_IO, NULL))
                        unlock_page(node_page);
                goto release_page;
        } else {
@@ -1465,11 +1621,13 @@ release_page:
 static int f2fs_write_node_page(struct page *page,
                                struct writeback_control *wbc)
 {
-       return __write_node_page(page, false, NULL, wbc, false, FS_NODE_IO);
+       return __write_node_page(page, false, NULL, wbc, false,
+                                               FS_NODE_IO, NULL);
 }
 
 int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
-                       struct writeback_control *wbc, bool atomic)
+                       struct writeback_control *wbc, bool atomic,
+                       unsigned int *seq_id)
 {
        pgoff_t index;
        pgoff_t last_idx = ULONG_MAX;
@@ -1550,7 +1708,7 @@ continue_unlock:
                        ret = __write_node_page(page, atomic &&
                                                page == last_page,
                                                &submitted, wbc, true,
-                                               FS_NODE_IO);
+                                               FS_NODE_IO, seq_id);
                        if (ret) {
                                unlock_page(page);
                                f2fs_put_page(last_page, 0);
@@ -1633,7 +1791,9 @@ next_step:
                                                !is_cold_node(page)))
                                continue;
 lock_node:
-                       if (!trylock_page(page))
+                       if (wbc->sync_mode == WB_SYNC_ALL)
+                               lock_page(page);
+                       else if (!trylock_page(page))
                                continue;
 
                        if (unlikely(page->mapping != NODE_MAPPING(sbi))) {
@@ -1665,7 +1825,7 @@ continue_unlock:
                        set_dentry_mark(page, 0);
 
                        ret = __write_node_page(page, false, &submitted,
-                                               wbc, do_balance, io_type);
+                                               wbc, do_balance, io_type, NULL);
                        if (ret)
                                unlock_page(page);
                        else if (submitted)
@@ -1684,10 +1844,12 @@ continue_unlock:
        }
 
        if (step < 2) {
+               if (wbc->sync_mode == WB_SYNC_NONE && step == 1)
+                       goto out;
                step++;
                goto next_step;
        }
-
+out:
        if (nwritten)
                f2fs_submit_merged_write(sbi, NODE);
 
@@ -1696,35 +1858,46 @@ continue_unlock:
        return ret;
 }
 
-int f2fs_wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino)
+int f2fs_wait_on_node_pages_writeback(struct f2fs_sb_info *sbi,
+                                               unsigned int seq_id)
 {
-       pgoff_t index = 0;
-       struct pagevec pvec;
+       struct fsync_node_entry *fn;
+       struct page *page;
+       struct list_head *head = &sbi->fsync_node_list;
+       unsigned long flags;
+       unsigned int cur_seq_id = 0;
        int ret2, ret = 0;
-       int nr_pages;
 
-       pagevec_init(&pvec);
+       while (seq_id && cur_seq_id < seq_id) {
+               spin_lock_irqsave(&sbi->fsync_node_lock, flags);
+               if (list_empty(head)) {
+                       spin_unlock_irqrestore(&sbi->fsync_node_lock, flags);
+                       break;
+               }
+               fn = list_first_entry(head, struct fsync_node_entry, list);
+               if (fn->seq_id > seq_id) {
+                       spin_unlock_irqrestore(&sbi->fsync_node_lock, flags);
+                       break;
+               }
+               cur_seq_id = fn->seq_id;
+               page = fn->page;
+               get_page(page);
+               spin_unlock_irqrestore(&sbi->fsync_node_lock, flags);
 
-       while ((nr_pages = pagevec_lookup_tag(&pvec, NODE_MAPPING(sbi), &index,
-                               PAGECACHE_TAG_WRITEBACK))) {
-               int i;
+               f2fs_wait_on_page_writeback(page, NODE, true);
+               if (TestClearPageError(page))
+                       ret = -EIO;
 
-               for (i = 0; i < nr_pages; i++) {
-                       struct page *page = pvec.pages[i];
+               put_page(page);
 
-                       if (ino && ino_of_node(page) == ino) {
-                               f2fs_wait_on_page_writeback(page, NODE, true);
-                               if (TestClearPageError(page))
-                                       ret = -EIO;
-                       }
-               }
-               pagevec_release(&pvec);
-               cond_resched();
+               if (ret)
+                       break;
        }
 
        ret2 = filemap_check_errors(NODE_MAPPING(sbi));
        if (!ret)
                ret = ret2;
+
        return ret;
 }
 
@@ -1774,6 +1947,10 @@ static int f2fs_set_node_page_dirty(struct page *page)
 
        if (!PageUptodate(page))
                SetPageUptodate(page);
+#ifdef CONFIG_F2FS_CHECK_FS
+       if (IS_INODE(page))
+               f2fs_inode_chksum_set(F2FS_P_SB(page), page);
+#endif
        if (!PageDirty(page)) {
                __set_page_dirty_nobuffers(page);
                inc_page_count(F2FS_P_SB(page), F2FS_DIRTY_NODES);
@@ -1968,7 +2145,7 @@ static void remove_free_nid(struct f2fs_sb_info *sbi, nid_t nid)
                kmem_cache_free(free_nid_slab, i);
 }
 
-static void scan_nat_page(struct f2fs_sb_info *sbi,
+static int scan_nat_page(struct f2fs_sb_info *sbi,
                        struct page *nat_page, nid_t start_nid)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
@@ -1986,7 +2163,10 @@ static void scan_nat_page(struct f2fs_sb_info *sbi,
                        break;
 
                blk_addr = le32_to_cpu(nat_blk->entries[i].block_addr);
-               f2fs_bug_on(sbi, blk_addr == NEW_ADDR);
+
+               if (blk_addr == NEW_ADDR)
+                       return -EINVAL;
+
                if (blk_addr == NULL_ADDR) {
                        add_free_nid(sbi, start_nid, true, true);
                } else {
@@ -1995,6 +2175,8 @@ static void scan_nat_page(struct f2fs_sb_info *sbi,
                        spin_unlock(&NM_I(sbi)->nid_list_lock);
                }
        }
+
+       return 0;
 }
 
 static void scan_curseg_cache(struct f2fs_sb_info *sbi)
@@ -2050,11 +2232,11 @@ out:
        up_read(&nm_i->nat_tree_lock);
 }
 
-static void __f2fs_build_free_nids(struct f2fs_sb_info *sbi,
+static int __f2fs_build_free_nids(struct f2fs_sb_info *sbi,
                                                bool sync, bool mount)
 {
        struct f2fs_nm_info *nm_i = NM_I(sbi);
-       int i = 0;
+       int i = 0, ret;
        nid_t nid = nm_i->next_scan_nid;
 
        if (unlikely(nid >= nm_i->max_nid))
@@ -2062,17 +2244,17 @@ static void __f2fs_build_free_nids(struct f2fs_sb_info *sbi,
 
        /* Enough entries */
        if (nm_i->nid_cnt[FREE_NID] >= NAT_ENTRY_PER_BLOCK)
-               return;
+               return 0;
 
        if (!sync && !f2fs_available_free_memory(sbi, FREE_NIDS))
-               return;
+               return 0;
 
        if (!mount) {
                /* try to find free nids in free_nid_bitmap */
                scan_free_nid_bits(sbi);
 
                if (nm_i->nid_cnt[FREE_NID] >= NAT_ENTRY_PER_BLOCK)
-                       return;
+                       return 0;
        }
 
        /* readahead nat pages to be scanned */
@@ -2086,8 +2268,16 @@ static void __f2fs_build_free_nids(struct f2fs_sb_info *sbi,
                                                nm_i->nat_block_bitmap)) {
                        struct page *page = get_current_nat_page(sbi, nid);
 
-                       scan_nat_page(sbi, page, nid);
+                       ret = scan_nat_page(sbi, page, nid);
                        f2fs_put_page(page, 1);
+
+                       if (ret) {
+                               up_read(&nm_i->nat_tree_lock);
+                               f2fs_bug_on(sbi, !mount);
+                               f2fs_msg(sbi->sb, KERN_ERR,
+                                       "NAT is corrupt, run fsck to fix it");
+                               return -EINVAL;
+                       }
                }
 
                nid += (NAT_ENTRY_PER_BLOCK - (nid % NAT_ENTRY_PER_BLOCK));
@@ -2108,13 +2298,19 @@ static void __f2fs_build_free_nids(struct f2fs_sb_info *sbi,
 
        f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nm_i->next_scan_nid),
                                        nm_i->ra_nid_pages, META_NAT, false);
+
+       return 0;
 }
 
-void f2fs_build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount)
+int f2fs_build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount)
 {
+       int ret;
+
        mutex_lock(&NM_I(sbi)->build_lock);
-       __f2fs_build_free_nids(sbi, sync, mount);
+       ret = __f2fs_build_free_nids(sbi, sync, mount);
        mutex_unlock(&NM_I(sbi)->build_lock);
+
+       return ret;
 }
 
 /*
@@ -2127,12 +2323,11 @@ bool f2fs_alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid)
        struct f2fs_nm_info *nm_i = NM_I(sbi);
        struct free_nid *i = NULL;
 retry:
-#ifdef CONFIG_F2FS_FAULT_INJECTION
        if (time_to_inject(sbi, FAULT_ALLOC_NID)) {
                f2fs_show_injection_info(FAULT_ALLOC_NID);
                return false;
        }
-#endif
+
        spin_lock(&nm_i->nid_list_lock);
 
        if (unlikely(nm_i->available_nids == 0)) {
@@ -2277,12 +2472,16 @@ int f2fs_recover_xattr_data(struct inode *inode, struct page *page)
        struct dnode_of_data dn;
        struct node_info ni;
        struct page *xpage;
+       int err;
 
        if (!prev_xnid)
                goto recover_xnid;
 
        /* 1: invalidate the previous xattr nid */
-       f2fs_get_node_info(sbi, prev_xnid, &ni);
+       err = f2fs_get_node_info(sbi, prev_xnid, &ni);
+       if (err)
+               return err;
+
        f2fs_invalidate_blocks(sbi, ni.blk_addr);
        dec_valid_node_count(sbi, inode, false);
        set_node_addr(sbi, &ni, NULL_ADDR, false);
@@ -2317,8 +2516,11 @@ int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)
        nid_t ino = ino_of_node(page);
        struct node_info old_ni, new_ni;
        struct page *ipage;
+       int err;
 
-       f2fs_get_node_info(sbi, ino, &old_ni);
+       err = f2fs_get_node_info(sbi, ino, &old_ni);
+       if (err)
+               return err;
 
        if (unlikely(old_ni.blk_addr != NULL_ADDR))
                return -EINVAL;
@@ -2372,7 +2574,7 @@ retry:
        return 0;
 }
 
-void f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
+int f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
                        unsigned int segno, struct f2fs_summary_block *sum)
 {
        struct f2fs_node *rn;
@@ -2394,6 +2596,9 @@ void f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
                for (idx = addr; idx < addr + nrpages; idx++) {
                        struct page *page = f2fs_get_tmp_page(sbi, idx);
 
+                       if (IS_ERR(page))
+                               return PTR_ERR(page);
+
                        rn = F2FS_NODE(page);
                        sum_entry->nid = rn->footer.nid;
                        sum_entry->version = 0;
@@ -2405,6 +2610,7 @@ void f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
                invalidate_mapping_pages(META_MAPPING(sbi), addr,
                                                        addr + nrpages);
        }
+       return 0;
 }
 
 static void remove_nats_in_journal(struct f2fs_sb_info *sbi)
@@ -2582,6 +2788,13 @@ void f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
        nid_t set_idx = 0;
        LIST_HEAD(sets);
 
+       /* during unmount, let's flush nat_bits before checking dirty_nat_cnt */
+       if (enabled_nat_bits(sbi, cpc)) {
+               down_write(&nm_i->nat_tree_lock);
+               remove_nats_in_journal(sbi);
+               up_write(&nm_i->nat_tree_lock);
+       }
+
        if (!nm_i->dirty_nat_cnt)
                return;
 
@@ -2634,7 +2847,13 @@ static int __get_nat_bitmaps(struct f2fs_sb_info *sbi)
        nat_bits_addr = __start_cp_addr(sbi) + sbi->blocks_per_seg -
                                                nm_i->nat_bits_blocks;
        for (i = 0; i < nm_i->nat_bits_blocks; i++) {
-               struct page *page = f2fs_get_meta_page(sbi, nat_bits_addr++);
+               struct page *page;
+
+               page = f2fs_get_meta_page(sbi, nat_bits_addr++);
+               if (IS_ERR(page)) {
+                       disable_nat_bits(sbi, true);
+                       return PTR_ERR(page);
+               }
 
                memcpy(nm_i->nat_bits + (i << F2FS_BLKSIZE_BITS),
                                        page_address(page), F2FS_BLKSIZE);
@@ -2718,6 +2937,7 @@ static int init_node_manager(struct f2fs_sb_info *sbi)
        INIT_RADIX_TREE(&nm_i->nat_root, GFP_NOIO);
        INIT_RADIX_TREE(&nm_i->nat_set_root, GFP_NOIO);
        INIT_LIST_HEAD(&nm_i->nat_entries);
+       spin_lock_init(&nm_i->nat_list_lock);
 
        mutex_init(&nm_i->build_lock);
        spin_lock_init(&nm_i->nid_list_lock);
@@ -2762,8 +2982,8 @@ static int init_free_nid_cache(struct f2fs_sb_info *sbi)
 
        for (i = 0; i < nm_i->nat_blocks; i++) {
                nm_i->free_nid_bitmap[i] = f2fs_kvzalloc(sbi,
-                               NAT_ENTRY_BITMAP_SIZE_ALIGNED, GFP_KERNEL);
-               if (!nm_i->free_nid_bitmap)
+                       f2fs_bitmap_size(NAT_ENTRY_PER_BLOCK), GFP_KERNEL);
+               if (!nm_i->free_nid_bitmap[i])
                        return -ENOMEM;
        }
 
@@ -2801,8 +3021,7 @@ int f2fs_build_node_manager(struct f2fs_sb_info *sbi)
        /* load free nid status from nat_bits table */
        load_free_nid_bitmap(sbi);
 
-       f2fs_build_free_nids(sbi, true, true);
-       return 0;
+       return f2fs_build_free_nids(sbi, true, true);
 }
 
 void f2fs_destroy_node_manager(struct f2fs_sb_info *sbi)
@@ -2837,8 +3056,13 @@ void f2fs_destroy_node_manager(struct f2fs_sb_info *sbi)
                unsigned idx;
 
                nid = nat_get_nid(natvec[found - 1]) + 1;
-               for (idx = 0; idx < found; idx++)
+               for (idx = 0; idx < found; idx++) {
+                       spin_lock(&nm_i->nat_list_lock);
+                       list_del(&natvec[idx]->list);
+                       spin_unlock(&nm_i->nat_list_lock);
+
                        __del_from_nat_cache(nm_i, natvec[idx]);
+               }
        }
        f2fs_bug_on(sbi, nm_i->nat_cnt);
 
@@ -2893,8 +3117,15 @@ int __init f2fs_create_node_manager_caches(void)
                        sizeof(struct nat_entry_set));
        if (!nat_entry_set_slab)
                goto destroy_free_nid;
+
+       fsync_node_entry_slab = f2fs_kmem_cache_create("fsync_node_entry",
+                       sizeof(struct fsync_node_entry));
+       if (!fsync_node_entry_slab)
+               goto destroy_nat_entry_set;
        return 0;
 
+destroy_nat_entry_set:
+       kmem_cache_destroy(nat_entry_set_slab);
 destroy_free_nid:
        kmem_cache_destroy(free_nid_slab);
 destroy_nat_entry:
@@ -2905,6 +3136,7 @@ fail:
 
 void f2fs_destroy_node_manager_caches(void)
 {
+       kmem_cache_destroy(fsync_node_entry_slab);
        kmem_cache_destroy(nat_entry_set_slab);
        kmem_cache_destroy(free_nid_slab);
        kmem_cache_destroy(nat_entry_slab);
index b95e49e4a928a77c421f53175a8b8cde36c2ef6b..0f4db7a6125473b24e3a0135c080757f12b0b41d 100644 (file)
@@ -135,6 +135,11 @@ static inline bool excess_cached_nats(struct f2fs_sb_info *sbi)
        return NM_I(sbi)->nat_cnt >= DEF_NAT_CACHE_THRESHOLD;
 }
 
+static inline bool excess_dirty_nodes(struct f2fs_sb_info *sbi)
+{
+       return get_pages(sbi, F2FS_DIRTY_NODES) >= sbi->blocks_per_seg * 8;
+}
+
 enum mem_type {
        FREE_NIDS,      /* indicates the free nid list */
        NAT_ENTRIES,    /* indicates the cached nat entry */
@@ -444,6 +449,10 @@ static inline void set_mark(struct page *page, int mark, int type)
        else
                flag &= ~(0x1 << type);
        rn->footer.flag = cpu_to_le32(flag);
+
+#ifdef CONFIG_F2FS_CHECK_FS
+       f2fs_inode_chksum_set(F2FS_P_SB(page), page);
+#endif
 }
 #define set_dentry_mark(page, mark)    set_mark(page, mark, DENT_BIT_SHIFT)
 #define set_fsync_mark(page, mark)     set_mark(page, mark, FSYNC_BIT_SHIFT)
index 38f25f0b193a18f7d8d489092029fd2dc13634d0..95511ed11a22650018ba2ffc9593dbf7c0d063db 100644 (file)
@@ -241,8 +241,8 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
        struct page *page = NULL;
        block_t blkaddr;
        unsigned int loop_cnt = 0;
-       unsigned int free_blocks = sbi->user_block_count -
-                                       valid_user_blocks(sbi);
+       unsigned int free_blocks = MAIN_SEGS(sbi) * sbi->blocks_per_seg -
+                                               valid_user_blocks(sbi);
        int err = 0;
 
        /* get node pages in the current segment */
@@ -252,10 +252,14 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
        while (1) {
                struct fsync_inode_entry *entry;
 
-               if (!f2fs_is_valid_meta_blkaddr(sbi, blkaddr, META_POR))
+               if (!f2fs_is_valid_blkaddr(sbi, blkaddr, META_POR))
                        return 0;
 
                page = f2fs_get_tmp_page(sbi, blkaddr);
+               if (IS_ERR(page)) {
+                       err = PTR_ERR(page);
+                       break;
+               }
 
                if (!is_recoverable_dnode(page))
                        break;
@@ -471,7 +475,10 @@ retry_dn:
 
        f2fs_wait_on_page_writeback(dn.node_page, NODE, true);
 
-       f2fs_get_node_info(sbi, dn.nid, &ni);
+       err = f2fs_get_node_info(sbi, dn.nid, &ni);
+       if (err)
+               goto err;
+
        f2fs_bug_on(sbi, ni.ino != ino_of_node(page));
        f2fs_bug_on(sbi, ofs_of_node(dn.node_page) != ofs_of_node(page));
 
@@ -507,14 +514,13 @@ retry_dn:
                }
 
                /* dest is valid block, try to recover from src to dest */
-               if (f2fs_is_valid_meta_blkaddr(sbi, dest, META_POR)) {
+               if (f2fs_is_valid_blkaddr(sbi, dest, META_POR)) {
 
                        if (src == NULL_ADDR) {
                                err = f2fs_reserve_new_block(&dn);
-#ifdef CONFIG_F2FS_FAULT_INJECTION
-                               while (err)
+                               while (err &&
+                                      IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION))
                                        err = f2fs_reserve_new_block(&dn);
-#endif
                                /* We should not get -ENOSPC */
                                f2fs_bug_on(sbi, err);
                                if (err)
@@ -568,12 +574,16 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
        while (1) {
                struct fsync_inode_entry *entry;
 
-               if (!f2fs_is_valid_meta_blkaddr(sbi, blkaddr, META_POR))
+               if (!f2fs_is_valid_blkaddr(sbi, blkaddr, META_POR))
                        break;
 
                f2fs_ra_meta_pages_cond(sbi, blkaddr);
 
                page = f2fs_get_tmp_page(sbi, blkaddr);
+               if (IS_ERR(page)) {
+                       err = PTR_ERR(page);
+                       break;
+               }
 
                if (!is_recoverable_dnode(page)) {
                        f2fs_put_page(page, 1);
@@ -628,7 +638,8 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
 #endif
 
        if (s_flags & SB_RDONLY) {
-               f2fs_msg(sbi->sb, KERN_INFO, "orphan cleanup on readonly fs");
+               f2fs_msg(sbi->sb, KERN_INFO,
+                               "recover fsync data on readonly fs");
                sbi->sb->s_flags &= ~SB_RDONLY;
        }
 
index 9efce174c51a9001a5679c6911c7e7e45e34eb81..30779aaa9dbae57c56077cc6948c969b4d9d937e 100644 (file)
@@ -250,7 +250,13 @@ retry:
                                err = -EAGAIN;
                                goto next;
                        }
-                       f2fs_get_node_info(sbi, dn.nid, &ni);
+
+                       err = f2fs_get_node_info(sbi, dn.nid, &ni);
+                       if (err) {
+                               f2fs_put_dnode(&dn);
+                               return err;
+                       }
+
                        if (cur->old_addr == NEW_ADDR) {
                                f2fs_invalidate_blocks(sbi, dn.data_blkaddr);
                                f2fs_update_data_blkaddr(&dn, NEW_ADDR);
@@ -439,8 +445,10 @@ int f2fs_commit_inmem_pages(struct inode *inode)
        int err;
 
        f2fs_balance_fs(sbi, true);
-       f2fs_lock_op(sbi);
 
+       down_write(&fi->i_gc_rwsem[WRITE]);
+
+       f2fs_lock_op(sbi);
        set_inode_flag(inode, FI_ATOMIC_COMMIT);
 
        mutex_lock(&fi->inmem_lock);
@@ -455,6 +463,8 @@ int f2fs_commit_inmem_pages(struct inode *inode)
        clear_inode_flag(inode, FI_ATOMIC_COMMIT);
 
        f2fs_unlock_op(sbi);
+       up_write(&fi->i_gc_rwsem[WRITE]);
+
        return err;
 }
 
@@ -464,12 +474,10 @@ int f2fs_commit_inmem_pages(struct inode *inode)
  */
 void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)
 {
-#ifdef CONFIG_F2FS_FAULT_INJECTION
        if (time_to_inject(sbi, FAULT_CHECKPOINT)) {
                f2fs_show_injection_info(FAULT_CHECKPOINT);
                f2fs_stop_checkpoint(sbi, false);
        }
-#endif
 
        /* balance_fs_bg is able to be pending */
        if (need && excess_cached_nats(sbi))
@@ -503,7 +511,8 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
        else
                f2fs_build_free_nids(sbi, false, false);
 
-       if (!is_idle(sbi) && !excess_dirty_nats(sbi))
+       if (!is_idle(sbi) &&
+               (!excess_dirty_nats(sbi) && !excess_dirty_nodes(sbi)))
                return;
 
        /* checkpoint is the only way to shrink partial cached entries */
@@ -511,6 +520,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
                        !f2fs_available_free_memory(sbi, INO_ENTRIES) ||
                        excess_prefree_segs(sbi) ||
                        excess_dirty_nats(sbi) ||
+                       excess_dirty_nodes(sbi) ||
                        f2fs_time_over(sbi, CP_TIME)) {
                if (test_opt(sbi, DATA_FLUSH)) {
                        struct blk_plug plug;
@@ -831,9 +841,12 @@ static struct discard_cmd *__create_discard_cmd(struct f2fs_sb_info *sbi,
        dc->len = len;
        dc->ref = 0;
        dc->state = D_PREP;
+       dc->issuing = 0;
        dc->error = 0;
        init_completion(&dc->wait);
        list_add_tail(&dc->list, pend_list);
+       spin_lock_init(&dc->lock);
+       dc->bio_ref = 0;
        atomic_inc(&dcc->discard_cmd_cnt);
        dcc->undiscard_blks += len;
 
@@ -860,7 +873,7 @@ static void __detach_discard_cmd(struct discard_cmd_control *dcc,
                                                        struct discard_cmd *dc)
 {
        if (dc->state == D_DONE)
-               atomic_dec(&dcc->issing_discard);
+               atomic_sub(dc->issuing, &dcc->issing_discard);
 
        list_del(&dc->list);
        rb_erase(&dc->rb_node, &dcc->root);
@@ -875,9 +888,17 @@ static void __remove_discard_cmd(struct f2fs_sb_info *sbi,
                                                        struct discard_cmd *dc)
 {
        struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
+       unsigned long flags;
 
        trace_f2fs_remove_discard(dc->bdev, dc->start, dc->len);
 
+       spin_lock_irqsave(&dc->lock, flags);
+       if (dc->bio_ref) {
+               spin_unlock_irqrestore(&dc->lock, flags);
+               return;
+       }
+       spin_unlock_irqrestore(&dc->lock, flags);
+
        f2fs_bug_on(sbi, dc->ref);
 
        if (dc->error == -EOPNOTSUPP)
@@ -893,10 +914,17 @@ static void __remove_discard_cmd(struct f2fs_sb_info *sbi,
 static void f2fs_submit_discard_endio(struct bio *bio)
 {
        struct discard_cmd *dc = (struct discard_cmd *)bio->bi_private;
+       unsigned long flags;
 
        dc->error = blk_status_to_errno(bio->bi_status);
-       dc->state = D_DONE;
-       complete_all(&dc->wait);
+
+       spin_lock_irqsave(&dc->lock, flags);
+       dc->bio_ref--;
+       if (!dc->bio_ref && dc->state == D_SUBMIT) {
+               dc->state = D_DONE;
+               complete_all(&dc->wait);
+       }
+       spin_unlock_irqrestore(&dc->lock, flags);
        bio_put(bio);
 }
 
@@ -934,6 +962,7 @@ static void __init_discard_policy(struct f2fs_sb_info *sbi,
        /* common policy */
        dpolicy->type = discard_type;
        dpolicy->sync = true;
+       dpolicy->ordered = false;
        dpolicy->granularity = granularity;
 
        dpolicy->max_requests = DEF_MAX_DISCARD_REQUEST;
@@ -945,6 +974,7 @@ static void __init_discard_policy(struct f2fs_sb_info *sbi,
                dpolicy->max_interval = DEF_MAX_DISCARD_ISSUE_TIME;
                dpolicy->io_aware = true;
                dpolicy->sync = false;
+               dpolicy->ordered = true;
                if (utilization(sbi) > DEF_DISCARD_URGENT_UTIL) {
                        dpolicy->granularity = 1;
                        dpolicy->max_interval = DEF_MIN_DISCARD_ISSUE_TIME;
@@ -962,48 +992,115 @@ static void __init_discard_policy(struct f2fs_sb_info *sbi,
        }
 }
 
-
+static void __update_discard_tree_range(struct f2fs_sb_info *sbi,
+                               struct block_device *bdev, block_t lstart,
+                               block_t start, block_t len);
 /* this function is copied from blkdev_issue_discard from block/blk-lib.c */
-static void __submit_discard_cmd(struct f2fs_sb_info *sbi,
+static int __submit_discard_cmd(struct f2fs_sb_info *sbi,
                                                struct discard_policy *dpolicy,
-                                               struct discard_cmd *dc)
+                                               struct discard_cmd *dc,
+                                               unsigned int *issued)
 {
+       struct block_device *bdev = dc->bdev;
+       struct request_queue *q = bdev_get_queue(bdev);
+       unsigned int max_discard_blocks =
+                       SECTOR_TO_BLOCK(q->limits.max_discard_sectors);
        struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
        struct list_head *wait_list = (dpolicy->type == DPOLICY_FSTRIM) ?
                                        &(dcc->fstrim_list) : &(dcc->wait_list);
-       struct bio *bio = NULL;
        int flag = dpolicy->sync ? REQ_SYNC : 0;
+       block_t lstart, start, len, total_len;
+       int err = 0;
 
        if (dc->state != D_PREP)
-               return;
+               return 0;
 
        if (is_sbi_flag_set(sbi, SBI_NEED_FSCK))
-               return;
+               return 0;
 
-       trace_f2fs_issue_discard(dc->bdev, dc->start, dc->len);
+       trace_f2fs_issue_discard(bdev, dc->start, dc->len);
 
-       dc->error = __blkdev_issue_discard(dc->bdev,
-                               SECTOR_FROM_BLOCK(dc->start),
-                               SECTOR_FROM_BLOCK(dc->len),
-                               GFP_NOFS, 0, &bio);
-       if (!dc->error) {
-               /* should keep before submission to avoid D_DONE right away */
-               dc->state = D_SUBMIT;
-               atomic_inc(&dcc->issued_discard);
-               atomic_inc(&dcc->issing_discard);
-               if (bio) {
-                       bio->bi_private = dc;
-                       bio->bi_end_io = f2fs_submit_discard_endio;
-                       bio->bi_opf |= flag;
-                       submit_bio(bio);
-                       list_move_tail(&dc->list, wait_list);
-                       __check_sit_bitmap(sbi, dc->start, dc->start + dc->len);
-
-                       f2fs_update_iostat(sbi, FS_DISCARD, 1);
+       lstart = dc->lstart;
+       start = dc->start;
+       len = dc->len;
+       total_len = len;
+
+       dc->len = 0;
+
+       while (total_len && *issued < dpolicy->max_requests && !err) {
+               struct bio *bio = NULL;
+               unsigned long flags;
+               bool last = true;
+
+               if (len > max_discard_blocks) {
+                       len = max_discard_blocks;
+                       last = false;
                }
-       } else {
-               __remove_discard_cmd(sbi, dc);
+
+               (*issued)++;
+               if (*issued == dpolicy->max_requests)
+                       last = true;
+
+               dc->len += len;
+
+               if (time_to_inject(sbi, FAULT_DISCARD)) {
+                       f2fs_show_injection_info(FAULT_DISCARD);
+                       err = -EIO;
+                       goto submit;
+               }
+               err = __blkdev_issue_discard(bdev,
+                                       SECTOR_FROM_BLOCK(start),
+                                       SECTOR_FROM_BLOCK(len),
+                                       GFP_NOFS, 0, &bio);
+submit:
+               if (err) {
+                       spin_lock_irqsave(&dc->lock, flags);
+                       if (dc->state == D_PARTIAL)
+                               dc->state = D_SUBMIT;
+                       spin_unlock_irqrestore(&dc->lock, flags);
+
+                       break;
+               }
+
+               f2fs_bug_on(sbi, !bio);
+
+               /*
+                * should keep before submission to avoid D_DONE
+                * right away
+                */
+               spin_lock_irqsave(&dc->lock, flags);
+               if (last)
+                       dc->state = D_SUBMIT;
+               else
+                       dc->state = D_PARTIAL;
+               dc->bio_ref++;
+               spin_unlock_irqrestore(&dc->lock, flags);
+
+               atomic_inc(&dcc->issing_discard);
+               dc->issuing++;
+               list_move_tail(&dc->list, wait_list);
+
+               /* sanity check on discard range */
+               __check_sit_bitmap(sbi, start, start + len);
+
+               bio->bi_private = dc;
+               bio->bi_end_io = f2fs_submit_discard_endio;
+               bio->bi_opf |= flag;
+               submit_bio(bio);
+
+               atomic_inc(&dcc->issued_discard);
+
+               f2fs_update_iostat(sbi, FS_DISCARD, 1);
+
+               lstart += len;
+               start += len;
+               total_len -= len;
+               len = total_len;
        }
+
+       if (!err && len)
+               __update_discard_tree_range(sbi, bdev, lstart, start, len);
+       return err;
 }
 
 static struct discard_cmd *__insert_discard_tree(struct f2fs_sb_info *sbi,
@@ -1084,10 +1181,11 @@ static void __update_discard_tree_range(struct f2fs_sb_info *sbi,
        struct discard_cmd *dc;
        struct discard_info di = {0};
        struct rb_node **insert_p = NULL, *insert_parent = NULL;
+       struct request_queue *q = bdev_get_queue(bdev);
+       unsigned int max_discard_blocks =
+                       SECTOR_TO_BLOCK(q->limits.max_discard_sectors);
        block_t end = lstart + len;
 
-       mutex_lock(&dcc->cmd_lock);
-
        dc = (struct discard_cmd *)f2fs_lookup_rb_tree_ret(&dcc->root,
                                        NULL, lstart,
                                        (struct rb_entry **)&prev_dc,
@@ -1127,7 +1225,8 @@ static void __update_discard_tree_range(struct f2fs_sb_info *sbi,
 
                if (prev_dc && prev_dc->state == D_PREP &&
                        prev_dc->bdev == bdev &&
-                       __is_discard_back_mergeable(&di, &prev_dc->di)) {
+                       __is_discard_back_mergeable(&di, &prev_dc->di,
+                                                       max_discard_blocks)) {
                        prev_dc->di.len += di.len;
                        dcc->undiscard_blks += di.len;
                        __relocate_discard_cmd(dcc, prev_dc);
@@ -1138,7 +1237,8 @@ static void __update_discard_tree_range(struct f2fs_sb_info *sbi,
 
                if (next_dc && next_dc->state == D_PREP &&
                        next_dc->bdev == bdev &&
-                       __is_discard_front_mergeable(&di, &next_dc->di)) {
+                       __is_discard_front_mergeable(&di, &next_dc->di,
+                                                       max_discard_blocks)) {
                        next_dc->di.lstart = di.lstart;
                        next_dc->di.len += di.len;
                        next_dc->di.start = di.start;
@@ -1161,8 +1261,6 @@ static void __update_discard_tree_range(struct f2fs_sb_info *sbi,
                node = rb_next(&prev_dc->rb_node);
                next_dc = rb_entry_safe(node, struct discard_cmd, rb_node);
        }
-
-       mutex_unlock(&dcc->cmd_lock);
 }
 
 static int __queue_discard_cmd(struct f2fs_sb_info *sbi,
@@ -1177,10 +1275,72 @@ static int __queue_discard_cmd(struct f2fs_sb_info *sbi,
 
                blkstart -= FDEV(devi).start_blk;
        }
+       mutex_lock(&SM_I(sbi)->dcc_info->cmd_lock);
        __update_discard_tree_range(sbi, bdev, lblkstart, blkstart, blklen);
+       mutex_unlock(&SM_I(sbi)->dcc_info->cmd_lock);
        return 0;
 }
 
+static unsigned int __issue_discard_cmd_orderly(struct f2fs_sb_info *sbi,
+                                       struct discard_policy *dpolicy)
+{
+       struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
+       struct discard_cmd *prev_dc = NULL, *next_dc = NULL;
+       struct rb_node **insert_p = NULL, *insert_parent = NULL;
+       struct discard_cmd *dc;
+       struct blk_plug plug;
+       unsigned int pos = dcc->next_pos;
+       unsigned int issued = 0;
+       bool io_interrupted = false;
+
+       mutex_lock(&dcc->cmd_lock);
+       dc = (struct discard_cmd *)f2fs_lookup_rb_tree_ret(&dcc->root,
+                                       NULL, pos,
+                                       (struct rb_entry **)&prev_dc,
+                                       (struct rb_entry **)&next_dc,
+                                       &insert_p, &insert_parent, true);
+       if (!dc)
+               dc = next_dc;
+
+       blk_start_plug(&plug);
+
+       while (dc) {
+               struct rb_node *node;
+               int err = 0;
+
+               if (dc->state != D_PREP)
+                       goto next;
+
+               if (dpolicy->io_aware && !is_idle(sbi)) {
+                       io_interrupted = true;
+                       break;
+               }
+
+               dcc->next_pos = dc->lstart + dc->len;
+               err = __submit_discard_cmd(sbi, dpolicy, dc, &issued);
+
+               if (issued >= dpolicy->max_requests)
+                       break;
+next:
+               node = rb_next(&dc->rb_node);
+               if (err)
+                       __remove_discard_cmd(sbi, dc);
+               dc = rb_entry_safe(node, struct discard_cmd, rb_node);
+       }
+
+       blk_finish_plug(&plug);
+
+       if (!dc)
+               dcc->next_pos = 0;
+
+       mutex_unlock(&dcc->cmd_lock);
+
+       if (!issued && io_interrupted)
+               issued = -1;
+
+       return issued;
+}
+
 static int __issue_discard_cmd(struct f2fs_sb_info *sbi,
                                        struct discard_policy *dpolicy)
 {
@@ -1188,19 +1348,24 @@ static int __issue_discard_cmd(struct f2fs_sb_info *sbi,
        struct list_head *pend_list;
        struct discard_cmd *dc, *tmp;
        struct blk_plug plug;
-       int i, iter = 0, issued = 0;
+       int i, issued = 0;
        bool io_interrupted = false;
 
        for (i = MAX_PLIST_NUM - 1; i >= 0; i--) {
                if (i + 1 < dpolicy->granularity)
                        break;
+
+               if (i < DEFAULT_DISCARD_GRANULARITY && dpolicy->ordered)
+                       return __issue_discard_cmd_orderly(sbi, dpolicy);
+
                pend_list = &dcc->pend_list[i];
 
                mutex_lock(&dcc->cmd_lock);
                if (list_empty(pend_list))
                        goto next;
-               f2fs_bug_on(sbi,
-                       !f2fs_check_rb_tree_consistence(sbi, &dcc->root));
+               if (unlikely(dcc->rbtree_check))
+                       f2fs_bug_on(sbi, !f2fs_check_rb_tree_consistence(sbi,
+                                                               &dcc->root));
                blk_start_plug(&plug);
                list_for_each_entry_safe(dc, tmp, pend_list, list) {
                        f2fs_bug_on(sbi, dc->state != D_PREP);
@@ -1208,20 +1373,19 @@ static int __issue_discard_cmd(struct f2fs_sb_info *sbi,
                        if (dpolicy->io_aware && i < dpolicy->io_aware_gran &&
                                                                !is_idle(sbi)) {
                                io_interrupted = true;
-                               goto skip;
+                               break;
                        }
 
-                       __submit_discard_cmd(sbi, dpolicy, dc);
-                       issued++;
-skip:
-                       if (++iter >= dpolicy->max_requests)
+                       __submit_discard_cmd(sbi, dpolicy, dc, &issued);
+
+                       if (issued >= dpolicy->max_requests)
                                break;
                }
                blk_finish_plug(&plug);
 next:
                mutex_unlock(&dcc->cmd_lock);
 
-               if (iter >= dpolicy->max_requests)
+               if (issued >= dpolicy->max_requests || io_interrupted)
                        break;
        }
 
@@ -1319,21 +1483,22 @@ next:
        return trimmed;
 }
 
-static void __wait_all_discard_cmd(struct f2fs_sb_info *sbi,
+static unsigned int __wait_all_discard_cmd(struct f2fs_sb_info *sbi,
                                                struct discard_policy *dpolicy)
 {
        struct discard_policy dp;
+       unsigned int discard_blks;
 
-       if (dpolicy) {
-               __wait_discard_cmd_range(sbi, dpolicy, 0, UINT_MAX);
-               return;
-       }
+       if (dpolicy)
+               return __wait_discard_cmd_range(sbi, dpolicy, 0, UINT_MAX);
 
        /* wait all */
        __init_discard_policy(sbi, &dp, DPOLICY_FSTRIM, 1);
-       __wait_discard_cmd_range(sbi, &dp, 0, UINT_MAX);
+       discard_blks = __wait_discard_cmd_range(sbi, &dp, 0, UINT_MAX);
        __init_discard_policy(sbi, &dp, DPOLICY_UMOUNT, 1);
-       __wait_discard_cmd_range(sbi, &dp, 0, UINT_MAX);
+       discard_blks += __wait_discard_cmd_range(sbi, &dp, 0, UINT_MAX);
+
+       return discard_blks;
 }
 
 /* This should be covered by global mutex, &sit_i->sentry_lock */
@@ -1386,6 +1551,8 @@ bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi)
 
        /* just to make sure there is no pending discard commands */
        __wait_all_discard_cmd(sbi, NULL);
+
+       f2fs_bug_on(sbi, atomic_read(&dcc->discard_cmd_cnt));
        return dropped;
 }
 
@@ -1643,21 +1810,30 @@ void f2fs_clear_prefree_segments(struct f2fs_sb_info *sbi,
        unsigned int start = 0, end = -1;
        unsigned int secno, start_segno;
        bool force = (cpc->reason & CP_DISCARD);
+       bool need_align = test_opt(sbi, LFS) && sbi->segs_per_sec > 1;
 
        mutex_lock(&dirty_i->seglist_lock);
 
        while (1) {
                int i;
+
+               if (need_align && end != -1)
+                       end--;
                start = find_next_bit(prefree_map, MAIN_SEGS(sbi), end + 1);
                if (start >= MAIN_SEGS(sbi))
                        break;
                end = find_next_zero_bit(prefree_map, MAIN_SEGS(sbi),
                                                                start + 1);
 
-               for (i = start; i < end; i++)
-                       clear_bit(i, prefree_map);
+               if (need_align) {
+                       start = rounddown(start, sbi->segs_per_sec);
+                       end = roundup(end, sbi->segs_per_sec);
+               }
 
-               dirty_i->nr_dirty[PRE] -= end - start;
+               for (i = start; i < end; i++) {
+                       if (test_and_clear_bit(i, prefree_map))
+                               dirty_i->nr_dirty[PRE]--;
+               }
 
                if (!test_opt(sbi, DISCARD))
                        continue;
@@ -1751,7 +1927,9 @@ static int create_discard_cmd_control(struct f2fs_sb_info *sbi)
        dcc->nr_discards = 0;
        dcc->max_discards = MAIN_SEGS(sbi) << sbi->log_blocks_per_seg;
        dcc->undiscard_blks = 0;
+       dcc->next_pos = 0;
        dcc->root = RB_ROOT;
+       dcc->rbtree_check = false;
 
        init_waitqueue_head(&dcc->discard_wait_queue);
        SM_I(sbi)->dcc_info = dcc;
@@ -1901,6 +2079,8 @@ void f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr)
        if (addr == NEW_ADDR)
                return;
 
+       invalidate_mapping_pages(META_MAPPING(sbi), addr, addr);
+
        /* add it into sit main buffer */
        down_write(&sit_i->sentry_lock);
 
@@ -1919,7 +2099,7 @@ bool f2fs_is_checkpointed_data(struct f2fs_sb_info *sbi, block_t blkaddr)
        struct seg_entry *se;
        bool is_cp = false;
 
-       if (!is_valid_blkaddr(blkaddr))
+       if (!is_valid_data_blkaddr(sbi, blkaddr))
                return true;
 
        down_read(&sit_i->sentry_lock);
@@ -1983,7 +2163,7 @@ int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra)
  */
 struct page *f2fs_get_sum_page(struct f2fs_sb_info *sbi, unsigned int segno)
 {
-       return f2fs_get_meta_page(sbi, GET_SUM_BLOCK(sbi, segno));
+       return f2fs_get_meta_page_nofail(sbi, GET_SUM_BLOCK(sbi, segno));
 }
 
 void f2fs_update_meta_page(struct f2fs_sb_info *sbi,
@@ -2366,7 +2546,7 @@ bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi,
        return has_candidate;
 }
 
-static void __issue_discard_cmd_range(struct f2fs_sb_info *sbi,
+static unsigned int __issue_discard_cmd_range(struct f2fs_sb_info *sbi,
                                        struct discard_policy *dpolicy,
                                        unsigned int start, unsigned int end)
 {
@@ -2376,12 +2556,15 @@ static void __issue_discard_cmd_range(struct f2fs_sb_info *sbi,
        struct discard_cmd *dc;
        struct blk_plug plug;
        int issued;
+       unsigned int trimmed = 0;
 
 next:
        issued = 0;
 
        mutex_lock(&dcc->cmd_lock);
-       f2fs_bug_on(sbi, !f2fs_check_rb_tree_consistence(sbi, &dcc->root));
+       if (unlikely(dcc->rbtree_check))
+               f2fs_bug_on(sbi, !f2fs_check_rb_tree_consistence(sbi,
+                                                               &dcc->root));
 
        dc = (struct discard_cmd *)f2fs_lookup_rb_tree_ret(&dcc->root,
                                        NULL, start,
@@ -2395,6 +2578,7 @@ next:
 
        while (dc && dc->lstart <= end) {
                struct rb_node *node;
+               int err = 0;
 
                if (dc->len < dpolicy->granularity)
                        goto skip;
@@ -2404,19 +2588,24 @@ next:
                        goto skip;
                }
 
-               __submit_discard_cmd(sbi, dpolicy, dc);
+               err = __submit_discard_cmd(sbi, dpolicy, dc, &issued);
 
-               if (++issued >= dpolicy->max_requests) {
+               if (issued >= dpolicy->max_requests) {
                        start = dc->lstart + dc->len;
 
+                       if (err)
+                               __remove_discard_cmd(sbi, dc);
+
                        blk_finish_plug(&plug);
                        mutex_unlock(&dcc->cmd_lock);
-                       __wait_all_discard_cmd(sbi, NULL);
+                       trimmed += __wait_all_discard_cmd(sbi, NULL);
                        congestion_wait(BLK_RW_ASYNC, HZ/50);
                        goto next;
                }
 skip:
                node = rb_next(&dc->rb_node);
+               if (err)
+                       __remove_discard_cmd(sbi, dc);
                dc = rb_entry_safe(node, struct discard_cmd, rb_node);
 
                if (fatal_signal_pending(current))
@@ -2425,6 +2614,8 @@ skip:
 
        blk_finish_plug(&plug);
        mutex_unlock(&dcc->cmd_lock);
+
+       return trimmed;
 }
 
 int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
@@ -2437,12 +2628,13 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
        struct discard_policy dpolicy;
        unsigned long long trimmed = 0;
        int err = 0;
+       bool need_align = test_opt(sbi, LFS) && sbi->segs_per_sec > 1;
 
        if (start >= MAX_BLKADDR(sbi) || range->len < sbi->blocksize)
                return -EINVAL;
 
-       if (end <= MAIN_BLKADDR(sbi))
-               return -EINVAL;
+       if (end < MAIN_BLKADDR(sbi))
+               goto out;
 
        if (is_sbi_flag_set(sbi, SBI_NEED_FSCK)) {
                f2fs_msg(sbi->sb, KERN_WARNING,
@@ -2454,6 +2646,10 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
        start_segno = (start <= MAIN_BLKADDR(sbi)) ? 0 : GET_SEGNO(sbi, start);
        end_segno = (end >= MAX_BLKADDR(sbi)) ? MAIN_SEGS(sbi) - 1 :
                                                GET_SEGNO(sbi, end);
+       if (need_align) {
+               start_segno = rounddown(start_segno, sbi->segs_per_sec);
+               end_segno = roundup(end_segno + 1, sbi->segs_per_sec) - 1;
+       }
 
        cpc.reason = CP_DISCARD;
        cpc.trim_minlen = max_t(__u64, 1, F2FS_BYTES_TO_BLK(range->minlen));
@@ -2469,24 +2665,27 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
        if (err)
                goto out;
 
-       start_block = START_BLOCK(sbi, start_segno);
-       end_block = START_BLOCK(sbi, end_segno + 1);
-
-       __init_discard_policy(sbi, &dpolicy, DPOLICY_FSTRIM, cpc.trim_minlen);
-       __issue_discard_cmd_range(sbi, &dpolicy, start_block, end_block);
-
        /*
         * We filed discard candidates, but actually we don't need to wait for
         * all of them, since they'll be issued in idle time along with runtime
         * discard option. User configuration looks like using runtime discard
         * or periodic fstrim instead of it.
         */
-       if (!test_opt(sbi, DISCARD)) {
-               trimmed = __wait_discard_cmd_range(sbi, &dpolicy,
+       if (test_opt(sbi, DISCARD))
+               goto out;
+
+       start_block = START_BLOCK(sbi, start_segno);
+       end_block = START_BLOCK(sbi, end_segno + 1);
+
+       __init_discard_policy(sbi, &dpolicy, DPOLICY_FSTRIM, cpc.trim_minlen);
+       trimmed = __issue_discard_cmd_range(sbi, &dpolicy,
+                                       start_block, end_block);
+
+       trimmed += __wait_discard_cmd_range(sbi, &dpolicy,
                                        start_block, end_block);
-               range->len = F2FS_BLK_TO_BYTES(trimmed);
-       }
 out:
+       if (!err)
+               range->len = F2FS_BLK_TO_BYTES(trimmed);
        return err;
 }
 
@@ -2639,8 +2838,8 @@ static int __get_segment_type_6(struct f2fs_io_info *fio)
                        return CURSEG_COLD_DATA;
                if (file_is_hot(inode) ||
                                is_inode_flag_set(inode, FI_HOT_DATA) ||
-                               is_inode_flag_set(inode, FI_ATOMIC_FILE) ||
-                               is_inode_flag_set(inode, FI_VOLATILE_FILE))
+                               f2fs_is_atomic_file(inode) ||
+                               f2fs_is_volatile_file(inode))
                        return CURSEG_HOT_DATA;
                return f2fs_rw_hint_to_seg_type(inode->i_write_hint);
        } else {
@@ -2781,6 +2980,9 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio)
 reallocate:
        f2fs_allocate_data_block(fio->sbi, fio->page, fio->old_blkaddr,
                        &fio->new_blkaddr, sum, type, fio, true);
+       if (GET_SEGNO(fio->sbi, fio->old_blkaddr) != NULL_SEGNO)
+               invalidate_mapping_pages(META_MAPPING(fio->sbi),
+                                       fio->old_blkaddr, fio->old_blkaddr);
 
        /* writeout dirty page into bdev */
        f2fs_submit_page_write(fio);
@@ -2836,11 +3038,9 @@ void f2fs_outplace_write_data(struct dnode_of_data *dn,
 {
        struct f2fs_sb_info *sbi = fio->sbi;
        struct f2fs_summary sum;
-       struct node_info ni;
 
        f2fs_bug_on(sbi, dn->data_blkaddr == NULL_ADDR);
-       f2fs_get_node_info(sbi, dn->nid, &ni);
-       set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
+       set_summary(&sum, dn->nid, dn->ofs_in_node, fio->version);
        do_write_page(&sum, fio);
        f2fs_update_data_blkaddr(dn, fio->new_blkaddr);
 
@@ -2937,8 +3137,11 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
 
        if (!recover_curseg || recover_newaddr)
                update_sit_entry(sbi, new_blkaddr, 1);
-       if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO)
+       if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) {
+               invalidate_mapping_pages(META_MAPPING(sbi),
+                                       old_blkaddr, old_blkaddr);
                update_sit_entry(sbi, old_blkaddr, -1);
+       }
 
        locate_dirty_segment(sbi, GET_SEGNO(sbi, old_blkaddr));
        locate_dirty_segment(sbi, GET_SEGNO(sbi, new_blkaddr));
@@ -2992,7 +3195,7 @@ void f2fs_wait_on_block_writeback(struct f2fs_sb_info *sbi, block_t blkaddr)
 {
        struct page *cpage;
 
-       if (!is_valid_blkaddr(blkaddr))
+       if (!is_valid_data_blkaddr(sbi, blkaddr))
                return;
 
        cpage = find_lock_page(META_MAPPING(sbi), blkaddr);
@@ -3002,7 +3205,7 @@ void f2fs_wait_on_block_writeback(struct f2fs_sb_info *sbi, block_t blkaddr)
        }
 }
 
-static void read_compacted_summaries(struct f2fs_sb_info *sbi)
+static int read_compacted_summaries(struct f2fs_sb_info *sbi)
 {
        struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
        struct curseg_info *seg_i;
@@ -3014,6 +3217,8 @@ static void read_compacted_summaries(struct f2fs_sb_info *sbi)
        start = start_sum_block(sbi);
 
        page = f2fs_get_meta_page(sbi, start++);
+       if (IS_ERR(page))
+               return PTR_ERR(page);
        kaddr = (unsigned char *)page_address(page);
 
        /* Step 1: restore nat cache */
@@ -3054,11 +3259,14 @@ static void read_compacted_summaries(struct f2fs_sb_info *sbi)
                        page = NULL;
 
                        page = f2fs_get_meta_page(sbi, start++);
+                       if (IS_ERR(page))
+                               return PTR_ERR(page);
                        kaddr = (unsigned char *)page_address(page);
                        offset = 0;
                }
        }
        f2fs_put_page(page, 1);
+       return 0;
 }
 
 static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
@@ -3070,6 +3278,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
        unsigned short blk_off;
        unsigned int segno = 0;
        block_t blk_addr = 0;
+       int err = 0;
 
        /* get segment number and block addr */
        if (IS_DATASEG(type)) {
@@ -3093,6 +3302,8 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
        }
 
        new = f2fs_get_meta_page(sbi, blk_addr);
+       if (IS_ERR(new))
+               return PTR_ERR(new);
        sum = (struct f2fs_summary_block *)page_address(new);
 
        if (IS_NODESEG(type)) {
@@ -3104,7 +3315,9 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
                                ns->ofs_in_node = 0;
                        }
                } else {
-                       f2fs_restore_node_summary(sbi, segno, sum);
+                       err = f2fs_restore_node_summary(sbi, segno, sum);
+                       if (err)
+                               goto out;
                }
        }
 
@@ -3124,8 +3337,9 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
        curseg->alloc_type = ckpt->alloc_type[type];
        curseg->next_blkoff = blk_off;
        mutex_unlock(&curseg->curseg_mutex);
+out:
        f2fs_put_page(new, 1);
-       return 0;
+       return err;
 }
 
 static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
@@ -3143,7 +3357,9 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
                                                        META_CP, true);
 
                /* restore for compacted data summary */
-               read_compacted_summaries(sbi);
+               err = read_compacted_summaries(sbi);
+               if (err)
+                       return err;
                type = CURSEG_HOT_NODE;
        }
 
@@ -3274,7 +3490,7 @@ int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
 static struct page *get_current_sit_page(struct f2fs_sb_info *sbi,
                                        unsigned int segno)
 {
-       return f2fs_get_meta_page(sbi, current_sit_addr(sbi, segno));
+       return f2fs_get_meta_page_nofail(sbi, current_sit_addr(sbi, segno));
 }
 
 static struct page *get_next_sit_page(struct f2fs_sb_info *sbi,
@@ -3923,6 +4139,7 @@ int f2fs_build_segment_manager(struct f2fs_sb_info *sbi)
                sm_info->ipu_policy = 1 << F2FS_IPU_FSYNC;
        sm_info->min_ipu_util = DEF_MIN_IPU_UTIL;
        sm_info->min_fsync_blocks = DEF_MIN_FSYNC_BLOCKS;
+       sm_info->min_seq_blocks = sbi->blocks_per_seg * sbi->segs_per_sec;
        sm_info->min_hot_blocks = DEF_MIN_HOT_BLOCKS;
        sm_info->min_ssr_sections = reserved_sections(sbi);
 
index f18fc82fbe998c26784d2c60a735e3aec1bdde67..b3d9e317ff0c142b111488911edeb222dfebdbcb 100644 (file)
@@ -85,7 +85,7 @@
        (GET_SEGOFF_FROM_SEG0(sbi, blk_addr) & ((sbi)->blocks_per_seg - 1))
 
 #define GET_SEGNO(sbi, blk_addr)                                       \
-       ((!is_valid_blkaddr(blk_addr)) ?                        \
+       ((!is_valid_data_blkaddr(sbi, blk_addr)) ?                      \
        NULL_SEGNO : GET_L2R_SEGNO(FREE_I(sbi),                 \
                GET_SEGNO_FROM_SEG0(sbi, blk_addr)))
 #define BLKS_PER_SEC(sbi)                                      \
@@ -215,7 +215,7 @@ struct segment_allocation {
 #define IS_DUMMY_WRITTEN_PAGE(page)                    \
                (page_private(page) == (unsigned long)DUMMY_WRITTEN_PAGE)
 
-#define MAX_SKIP_ATOMIC_COUNT                  16
+#define MAX_SKIP_GC_COUNT                      16
 
 struct inmem_pages {
        struct list_head list;
@@ -448,6 +448,8 @@ static inline void __set_test_and_free(struct f2fs_sb_info *sbi,
        if (test_and_clear_bit(segno, free_i->free_segmap)) {
                free_i->free_segments++;
 
+               if (IS_CURSEC(sbi, secno))
+                       goto skip_free;
                next = find_next_bit(free_i->free_segmap,
                                start_segno + sbi->segs_per_sec, start_segno);
                if (next >= start_segno + sbi->segs_per_sec) {
@@ -455,6 +457,7 @@ static inline void __set_test_and_free(struct f2fs_sb_info *sbi,
                                free_i->free_sections++;
                }
        }
+skip_free:
        spin_unlock(&free_i->segmap_lock);
 }
 
@@ -645,13 +648,10 @@ static inline void verify_block_addr(struct f2fs_io_info *fio, block_t blk_addr)
 {
        struct f2fs_sb_info *sbi = fio->sbi;
 
-       if (PAGE_TYPE_OF_BIO(fio->type) == META &&
-                               (!is_read_io(fio->op) || fio->is_meta))
-               BUG_ON(blk_addr < SEG0_BLKADDR(sbi) ||
-                               blk_addr >= MAIN_BLKADDR(sbi));
+       if (__is_meta_io(fio))
+               verify_blkaddr(sbi, blk_addr, META_GENERIC);
        else
-               BUG_ON(blk_addr < MAIN_BLKADDR(sbi) ||
-                               blk_addr >= MAX_BLKADDR(sbi));
+               verify_blkaddr(sbi, blk_addr, DATA_GENERIC);
 }
 
 /*
index 17bcff789c082a5d185b8b8516d97dcaeda6272e..896b885f504e782f2bc37a4aba4da5e9870f2b20 100644 (file)
@@ -41,7 +41,7 @@ static struct kmem_cache *f2fs_inode_cachep;
 
 #ifdef CONFIG_F2FS_FAULT_INJECTION
 
-char *fault_name[FAULT_MAX] = {
+char *f2fs_fault_name[FAULT_MAX] = {
        [FAULT_KMALLOC]         = "kmalloc",
        [FAULT_KVMALLOC]        = "kvmalloc",
        [FAULT_PAGE_ALLOC]      = "page alloc",
@@ -55,20 +55,24 @@ char *fault_name[FAULT_MAX] = {
        [FAULT_TRUNCATE]        = "truncate fail",
        [FAULT_IO]              = "IO error",
        [FAULT_CHECKPOINT]      = "checkpoint error",
+       [FAULT_DISCARD]         = "discard error",
 };
 
-static void f2fs_build_fault_attr(struct f2fs_sb_info *sbi,
-                                               unsigned int rate)
+void f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned int rate,
+                                                       unsigned int type)
 {
        struct f2fs_fault_info *ffi = &F2FS_OPTION(sbi).fault_info;
 
        if (rate) {
                atomic_set(&ffi->inject_ops, 0);
                ffi->inject_rate = rate;
-               ffi->inject_type = (1 << FAULT_MAX) - 1;
-       } else {
-               memset(ffi, 0, sizeof(struct f2fs_fault_info));
        }
+
+       if (type)
+               ffi->inject_type = type;
+
+       if (!rate && !type)
+               memset(ffi, 0, sizeof(struct f2fs_fault_info));
 }
 #endif
 
@@ -113,6 +117,7 @@ enum {
        Opt_mode,
        Opt_io_size_bits,
        Opt_fault_injection,
+       Opt_fault_type,
        Opt_lazytime,
        Opt_nolazytime,
        Opt_quota,
@@ -170,6 +175,7 @@ static match_table_t f2fs_tokens = {
        {Opt_mode, "mode=%s"},
        {Opt_io_size_bits, "io_bits=%u"},
        {Opt_fault_injection, "fault_injection=%u"},
+       {Opt_fault_type, "fault_type=%u"},
        {Opt_lazytime, "lazytime"},
        {Opt_nolazytime, "nolazytime"},
        {Opt_quota, "quota"},
@@ -347,12 +353,6 @@ static int f2fs_check_quota_options(struct f2fs_sb_info *sbi)
                        "QUOTA feature is enabled, so ignore jquota_fmt");
                F2FS_OPTION(sbi).s_jquota_fmt = 0;
        }
-       if (f2fs_sb_has_quota_ino(sbi->sb) && f2fs_readonly(sbi->sb)) {
-               f2fs_msg(sbi->sb, KERN_INFO,
-                        "Filesystem with quota feature cannot be mounted RDWR "
-                        "without CONFIG_QUOTA");
-               return -1;
-       }
        return 0;
 }
 #endif
@@ -606,7 +606,18 @@ static int parse_options(struct super_block *sb, char *options)
                        if (args->from && match_int(args, &arg))
                                return -EINVAL;
 #ifdef CONFIG_F2FS_FAULT_INJECTION
-                       f2fs_build_fault_attr(sbi, arg);
+                       f2fs_build_fault_attr(sbi, arg, F2FS_ALL_FAULT_TYPE);
+                       set_opt(sbi, FAULT_INJECTION);
+#else
+                       f2fs_msg(sb, KERN_INFO,
+                               "FAULT_INJECTION was not selected");
+#endif
+                       break;
+               case Opt_fault_type:
+                       if (args->from && match_int(args, &arg))
+                               return -EINVAL;
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+                       f2fs_build_fault_attr(sbi, 0, arg);
                        set_opt(sbi, FAULT_INJECTION);
 #else
                        f2fs_msg(sb, KERN_INFO,
@@ -775,6 +786,19 @@ static int parse_options(struct super_block *sb, char *options)
 #ifdef CONFIG_QUOTA
        if (f2fs_check_quota_options(sbi))
                return -EINVAL;
+#else
+       if (f2fs_sb_has_quota_ino(sbi->sb) && !f2fs_readonly(sbi->sb)) {
+               f2fs_msg(sbi->sb, KERN_INFO,
+                        "Filesystem with quota feature cannot be mounted RDWR "
+                        "without CONFIG_QUOTA");
+               return -EINVAL;
+       }
+       if (f2fs_sb_has_project_quota(sbi->sb) && !f2fs_readonly(sbi->sb)) {
+               f2fs_msg(sb, KERN_ERR,
+                       "Filesystem with project quota feature cannot be "
+                       "mounted RDWR without CONFIG_QUOTA");
+               return -EINVAL;
+       }
 #endif
 
        if (F2FS_IO_SIZE_BITS(sbi) && !test_opt(sbi, LFS)) {
@@ -1030,6 +1054,10 @@ static void f2fs_put_super(struct super_block *sb)
        /* our cp_error case, we can wait for any writeback page */
        f2fs_flush_merged_writes(sbi);
 
+       f2fs_wait_on_all_pages_writeback(sbi);
+
+       f2fs_bug_on(sbi, sbi->fsync_node_num);
+
        iput(sbi->node_inode);
        iput(sbi->meta_inode);
 
@@ -1118,7 +1146,7 @@ static int f2fs_statfs_project(struct super_block *sb,
        dquot = dqget(sb, qid);
        if (IS_ERR(dquot))
                return PTR_ERR(dquot);
-       spin_lock(&dq_data_lock);
+       spin_lock(&dquot->dq_dqb_lock);
 
        limit = (dquot->dq_dqb.dqb_bsoftlimit ?
                 dquot->dq_dqb.dqb_bsoftlimit :
@@ -1141,7 +1169,7 @@ static int f2fs_statfs_project(struct super_block *sb,
                         (buf->f_files - dquot->dq_dqb.dqb_curinodes) : 0;
        }
 
-       spin_unlock(&dq_data_lock);
+       spin_unlock(&dquot->dq_dqb_lock);
        dqput(dquot);
        return 0;
 }
@@ -1310,9 +1338,12 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
        if (F2FS_IO_SIZE_BITS(sbi))
                seq_printf(seq, ",io_size=%uKB", F2FS_IO_SIZE_KB(sbi));
 #ifdef CONFIG_F2FS_FAULT_INJECTION
-       if (test_opt(sbi, FAULT_INJECTION))
+       if (test_opt(sbi, FAULT_INJECTION)) {
                seq_printf(seq, ",fault_injection=%u",
                                F2FS_OPTION(sbi).fault_info.inject_rate);
+               seq_printf(seq, ",fault_type=%u",
+                               F2FS_OPTION(sbi).fault_info.inject_type);
+       }
 #endif
 #ifdef CONFIG_QUOTA
        if (test_opt(sbi, QUOTA))
@@ -1343,6 +1374,8 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
                seq_printf(seq, ",fsync_mode=%s", "posix");
        else if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT)
                seq_printf(seq, ",fsync_mode=%s", "strict");
+       else if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_NOBARRIER)
+               seq_printf(seq, ",fsync_mode=%s", "nobarrier");
        return 0;
 }
 
@@ -1355,7 +1388,8 @@ static void default_options(struct f2fs_sb_info *sbi)
        F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_DEFAULT;
        F2FS_OPTION(sbi).fsync_mode = FSYNC_MODE_POSIX;
        F2FS_OPTION(sbi).test_dummy_encryption = false;
-       sbi->readdir_ra = 1;
+       F2FS_OPTION(sbi).s_resuid = make_kuid(&init_user_ns, F2FS_DEF_RESUID);
+       F2FS_OPTION(sbi).s_resgid = make_kgid(&init_user_ns, F2FS_DEF_RESGID);
 
        set_opt(sbi, BG_GC);
        set_opt(sbi, INLINE_XATTR);
@@ -1365,12 +1399,12 @@ static void default_options(struct f2fs_sb_info *sbi)
        set_opt(sbi, NOHEAP);
        sbi->sb->s_flags |= SB_LAZYTIME;
        set_opt(sbi, FLUSH_MERGE);
-       if (f2fs_sb_has_blkzoned(sbi->sb)) {
-               set_opt_mode(sbi, F2FS_MOUNT_LFS);
+       if (blk_queue_discard(bdev_get_queue(sbi->sb->s_bdev)))
                set_opt(sbi, DISCARD);
-       } else {
+       if (f2fs_sb_has_blkzoned(sbi->sb))
+               set_opt_mode(sbi, F2FS_MOUNT_LFS);
+       else
                set_opt_mode(sbi, F2FS_MOUNT_ADAPTIVE);
-       }
 
 #ifdef CONFIG_F2FS_FS_XATTR
        set_opt(sbi, XATTR_USER);
@@ -1379,9 +1413,7 @@ static void default_options(struct f2fs_sb_info *sbi)
        set_opt(sbi, POSIX_ACL);
 #endif
 
-#ifdef CONFIG_F2FS_FAULT_INJECTION
-       f2fs_build_fault_attr(sbi, 0);
-#endif
+       f2fs_build_fault_attr(sbi, 0, 0);
 }
 
 #ifdef CONFIG_QUOTA
@@ -2229,9 +2261,9 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
                return 1;
        }
 
-       if (secs_per_zone > total_sections) {
+       if (secs_per_zone > total_sections || !secs_per_zone) {
                f2fs_msg(sb, KERN_INFO,
-                       "Wrong secs_per_zone (%u > %u)",
+                       "Wrong secs_per_zone / total_sections (%u, %u)",
                        secs_per_zone, total_sections);
                return 1;
        }
@@ -2282,12 +2314,20 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi)
        struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
        unsigned int ovp_segments, reserved_segments;
        unsigned int main_segs, blocks_per_seg;
+       unsigned int sit_segs, nat_segs;
+       unsigned int sit_bitmap_size, nat_bitmap_size;
+       unsigned int log_blocks_per_seg;
+       unsigned int segment_count_main;
+       unsigned int cp_pack_start_sum, cp_payload;
+       block_t user_block_count;
        int i;
 
        total = le32_to_cpu(raw_super->segment_count);
        fsmeta = le32_to_cpu(raw_super->segment_count_ckpt);
-       fsmeta += le32_to_cpu(raw_super->segment_count_sit);
-       fsmeta += le32_to_cpu(raw_super->segment_count_nat);
+       sit_segs = le32_to_cpu(raw_super->segment_count_sit);
+       fsmeta += sit_segs;
+       nat_segs = le32_to_cpu(raw_super->segment_count_nat);
+       fsmeta += nat_segs;
        fsmeta += le32_to_cpu(ckpt->rsvd_segment_count);
        fsmeta += le32_to_cpu(raw_super->segment_count_ssa);
 
@@ -2304,6 +2344,16 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi)
                return 1;
        }
 
+       user_block_count = le64_to_cpu(ckpt->user_block_count);
+       segment_count_main = le32_to_cpu(raw_super->segment_count_main);
+       log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg);
+       if (!user_block_count || user_block_count >=
+                       segment_count_main << log_blocks_per_seg) {
+               f2fs_msg(sbi->sb, KERN_ERR,
+                       "Wrong user_block_count: %u", user_block_count);
+               return 1;
+       }
+
        main_segs = le32_to_cpu(raw_super->segment_count_main);
        blocks_per_seg = sbi->blocks_per_seg;
 
@@ -2318,6 +2368,28 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi)
                        return 1;
        }
 
+       sit_bitmap_size = le32_to_cpu(ckpt->sit_ver_bitmap_bytesize);
+       nat_bitmap_size = le32_to_cpu(ckpt->nat_ver_bitmap_bytesize);
+
+       if (sit_bitmap_size != ((sit_segs / 2) << log_blocks_per_seg) / 8 ||
+               nat_bitmap_size != ((nat_segs / 2) << log_blocks_per_seg) / 8) {
+               f2fs_msg(sbi->sb, KERN_ERR,
+                       "Wrong bitmap size: sit: %u, nat:%u",
+                       sit_bitmap_size, nat_bitmap_size);
+               return 1;
+       }
+
+       cp_pack_start_sum = __start_sum_addr(sbi);
+       cp_payload = __cp_payload(sbi);
+       if (cp_pack_start_sum < cp_payload + 1 ||
+               cp_pack_start_sum > blocks_per_seg - 1 -
+                       NR_CURSEG_TYPE) {
+               f2fs_msg(sbi->sb, KERN_ERR,
+                       "Wrong cp_pack_start_sum: %u",
+                       cp_pack_start_sum);
+               return 1;
+       }
+
        if (unlikely(f2fs_cp_error(sbi))) {
                f2fs_msg(sbi->sb, KERN_ERR, "A bug case: need to run fsck");
                return 1;
@@ -2651,6 +2723,8 @@ static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi)
                sm_i->dcc_info->discard_granularity = 1;
                sm_i->ipu_policy = 1 << F2FS_IPU_FORCE;
        }
+
+       sbi->readdir_ra = 1;
 }
 
 static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
@@ -2700,9 +2774,6 @@ try_onemore:
        sb->s_fs_info = sbi;
        sbi->raw_super = raw_super;
 
-       F2FS_OPTION(sbi).s_resuid = make_kuid(&init_user_ns, F2FS_DEF_RESUID);
-       F2FS_OPTION(sbi).s_resgid = make_kgid(&init_user_ns, F2FS_DEF_RESGID);
-
        /* precompute checksum seed for metadata */
        if (f2fs_sb_has_inode_chksum(sb))
                sbi->s_chksum_seed = f2fs_chksum(sbi, ~0, raw_super->uuid,
@@ -2771,6 +2842,7 @@ try_onemore:
        /* init f2fs-specific super block info */
        sbi->valid_super_block = valid_super_block;
        mutex_init(&sbi->gc_mutex);
+       mutex_init(&sbi->writepages);
        mutex_init(&sbi->cp_mutex);
        init_rwsem(&sbi->node_write);
        init_rwsem(&sbi->node_change);
@@ -2865,6 +2937,8 @@ try_onemore:
 
        f2fs_init_ino_entry_info(sbi);
 
+       f2fs_init_fsync_node_info(sbi);
+
        /* setup f2fs internal modules */
        err = f2fs_build_segment_manager(sbi);
        if (err) {
@@ -2912,10 +2986,11 @@ try_onemore:
                err = PTR_ERR(root);
                goto free_stats;
        }
-       if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
+       if (!S_ISDIR(root->i_mode) || !root->i_blocks ||
+                       !root->i_size || !root->i_nlink) {
                iput(root);
                err = -EINVAL;
-               goto free_node_inode;
+               goto free_stats;
        }
 
        sb->s_root = d_make_root(root); /* allocate root dentry */
@@ -2929,10 +3004,7 @@ try_onemore:
                goto free_root_inode;
 
 #ifdef CONFIG_QUOTA
-       /*
-        * Turn on quotas which were not enabled for read-only mounts if
-        * filesystem has quota feature, so that they are updated correctly.
-        */
+       /* Enable quota usage during mount */
        if (f2fs_sb_has_quota_ino(sb) && !f2fs_readonly(sb)) {
                err = f2fs_enable_quotas(sb);
                if (err) {
@@ -3090,9 +3162,19 @@ static struct dentry *f2fs_mount(struct file_system_type *fs_type, int flags,
 static void kill_f2fs_super(struct super_block *sb)
 {
        if (sb->s_root) {
-               set_sbi_flag(F2FS_SB(sb), SBI_IS_CLOSE);
-               f2fs_stop_gc_thread(F2FS_SB(sb));
-               f2fs_stop_discard_thread(F2FS_SB(sb));
+               struct f2fs_sb_info *sbi = F2FS_SB(sb);
+
+               set_sbi_flag(sbi, SBI_IS_CLOSE);
+               f2fs_stop_gc_thread(sbi);
+               f2fs_stop_discard_thread(sbi);
+
+               if (is_sbi_flag_set(sbi, SBI_IS_DIRTY) ||
+                               !is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) {
+                       struct cp_control cpc = {
+                               .reason = CP_UMOUNT,
+                       };
+                       f2fs_write_checkpoint(sbi, &cpc);
+               }
        }
        kill_block_super(sb);
 }
index 2e7e611deaef2df1f61cc7145138db9c7a08dba5..81c0e5337443dee31c5339be2a305f16e91c9ddf 100644 (file)
@@ -9,6 +9,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/compiler.h>
 #include <linux/proc_fs.h>
 #include <linux/f2fs_fs.h>
 #include <linux/seq_file.h>
@@ -252,6 +253,7 @@ out:
                if (t >= 1) {
                        sbi->gc_mode = GC_URGENT;
                        if (sbi->gc_thread) {
+                               sbi->gc_thread->gc_wake = 1;
                                wake_up_interruptible_all(
                                        &sbi->gc_thread->gc_wait_queue_head);
                                wake_up_discard_thread(sbi, true);
@@ -286,8 +288,10 @@ static ssize_t f2fs_sbi_store(struct f2fs_attr *a,
        bool gc_entry = (!strcmp(a->attr.name, "gc_urgent") ||
                                        a->struct_type == GC_THREAD);
 
-       if (gc_entry)
-               down_read(&sbi->sb->s_umount);
+       if (gc_entry) {
+               if (!down_read_trylock(&sbi->sb->s_umount))
+                       return -EAGAIN;
+       }
        ret = __sbi_store(a, sbi, buf, count);
        if (gc_entry)
                up_read(&sbi->sb->s_umount);
@@ -393,6 +397,7 @@ F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, batched_trim_sections, trim_sections);
 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(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks);
+F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_seq_blocks, min_seq_blocks);
 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_hot_blocks, min_hot_blocks);
 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ssr_sections, min_ssr_sections);
 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh);
@@ -445,6 +450,7 @@ static struct attribute *f2fs_attrs[] = {
        ATTR_LIST(ipu_policy),
        ATTR_LIST(min_ipu_util),
        ATTR_LIST(min_fsync_blocks),
+       ATTR_LIST(min_seq_blocks),
        ATTR_LIST(min_hot_blocks),
        ATTR_LIST(min_ssr_sections),
        ATTR_LIST(max_victim_search),
@@ -516,7 +522,8 @@ static struct kobject f2fs_feat = {
        .kset   = &f2fs_kset,
 };
 
-static int segment_info_seq_show(struct seq_file *seq, void *offset)
+static int __maybe_unused segment_info_seq_show(struct seq_file *seq,
+                                               void *offset)
 {
        struct super_block *sb = seq->private;
        struct f2fs_sb_info *sbi = F2FS_SB(sb);
@@ -543,7 +550,8 @@ static int segment_info_seq_show(struct seq_file *seq, void *offset)
        return 0;
 }
 
-static int segment_bits_seq_show(struct seq_file *seq, void *offset)
+static int __maybe_unused segment_bits_seq_show(struct seq_file *seq,
+                                               void *offset)
 {
        struct super_block *sb = seq->private;
        struct f2fs_sb_info *sbi = F2FS_SB(sb);
@@ -567,7 +575,8 @@ static int segment_bits_seq_show(struct seq_file *seq, void *offset)
        return 0;
 }
 
-static int iostat_info_seq_show(struct seq_file *seq, void *offset)
+static int __maybe_unused iostat_info_seq_show(struct seq_file *seq,
+                                              void *offset)
 {
        struct super_block *sb = seq->private;
        struct f2fs_sb_info *sbi = F2FS_SB(sb);
@@ -609,6 +618,28 @@ static int iostat_info_seq_show(struct seq_file *seq, void *offset)
        return 0;
 }
 
+static int __maybe_unused victim_bits_seq_show(struct seq_file *seq,
+                                               void *offset)
+{
+       struct super_block *sb = seq->private;
+       struct f2fs_sb_info *sbi = F2FS_SB(sb);
+       struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
+       int i;
+
+       seq_puts(seq, "format: victim_secmap bitmaps\n");
+
+       for (i = 0; i < MAIN_SECS(sbi); i++) {
+               if ((i % 10) == 0)
+                       seq_printf(seq, "%-10d", i);
+               seq_printf(seq, "%d", test_bit(i, dirty_i->victim_secmap) ? 1 : 0);
+               if ((i % 10) == 9 || i == (MAIN_SECS(sbi) - 1))
+                       seq_putc(seq, '\n');
+               else
+                       seq_putc(seq, ' ');
+       }
+       return 0;
+}
+
 int __init f2fs_init_sysfs(void)
 {
        int ret;
@@ -658,6 +689,8 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi)
                                segment_bits_seq_show, sb);
                proc_create_single_data("iostat_info", S_IRUGO, sbi->s_proc,
                                iostat_info_seq_show, sb);
+               proc_create_single_data("victim_bits", S_IRUGO, sbi->s_proc,
+                               victim_bits_seq_show, sb);
        }
        return 0;
 }
@@ -668,6 +701,7 @@ void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi)
                remove_proc_entry("iostat_info", sbi->s_proc);
                remove_proc_entry("segment_info", sbi->s_proc);
                remove_proc_entry("segment_bits", sbi->s_proc);
+               remove_proc_entry("victim_bits", sbi->s_proc);
                remove_proc_entry(sbi->sb->s_id, f2fs_proc_root);
        }
        kobject_del(&sbi->s_kobj);
index 708271871f945c63a4b11885ef2e8e3453b6bc8f..77a010e625f503b7ec54ca0daef6b8d5d5d4cfaf 100644 (file)
@@ -37,9 +37,6 @@ static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
                        return -EOPNOTSUPP;
                break;
        case F2FS_XATTR_INDEX_TRUSTED:
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-               break;
        case F2FS_XATTR_INDEX_SECURITY:
                break;
        default:
@@ -62,9 +59,6 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
                        return -EOPNOTSUPP;
                break;
        case F2FS_XATTR_INDEX_TRUSTED:
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-               break;
        case F2FS_XATTR_INDEX_SECURITY:
                break;
        default:
@@ -100,12 +94,22 @@ static int f2fs_xattr_advise_set(const struct xattr_handler *handler,
                const char *name, const void *value,
                size_t size, int flags)
 {
+       unsigned char old_advise = F2FS_I(inode)->i_advise;
+       unsigned char new_advise;
+
        if (!inode_owner_or_capable(inode))
                return -EPERM;
        if (value == NULL)
                return -EINVAL;
 
-       F2FS_I(inode)->i_advise |= *(char *)value;
+       new_advise = *(char *)value;
+       if (new_advise & ~FADVISE_MODIFIABLE_BITS)
+               return -EINVAL;
+
+       new_advise = new_advise & FADVISE_MODIFIABLE_BITS;
+       new_advise |= old_advise & ~FADVISE_MODIFIABLE_BITS;
+
+       F2FS_I(inode)->i_advise = new_advise;
        f2fs_mark_inode_dirty_sync(inode, true);
        return 0;
 }
index e9bed49df6b71047b6658063e377fb59ef4c339e..78d501c1fb658f153a9683a95c560a3483c70cd7 100644 (file)
@@ -225,7 +225,8 @@ static inline void cache_init(struct fat_cache_id *cid, int fclus, int dclus)
 int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus)
 {
        struct super_block *sb = inode->i_sb;
-       const int limit = sb->s_maxbytes >> MSDOS_SB(sb)->cluster_bits;
+       struct msdos_sb_info *sbi = MSDOS_SB(sb);
+       const int limit = sb->s_maxbytes >> sbi->cluster_bits;
        struct fat_entry fatent;
        struct fat_cache_id cid;
        int nr;
@@ -234,6 +235,12 @@ int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus)
 
        *fclus = 0;
        *dclus = MSDOS_I(inode)->i_start;
+       if (!fat_valid_entry(sbi, *dclus)) {
+               fat_fs_error_ratelimit(sb,
+                       "%s: invalid start cluster (i_pos %lld, start %08x)",
+                       __func__, MSDOS_I(inode)->i_pos, *dclus);
+               return -EIO;
+       }
        if (cluster == 0)
                return 0;
 
@@ -250,9 +257,8 @@ int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus)
                /* prevent the infinite loop of cluster chain */
                if (*fclus > limit) {
                        fat_fs_error_ratelimit(sb,
-                                       "%s: detected the cluster chain loop"
-                                       " (i_pos %lld)", __func__,
-                                       MSDOS_I(inode)->i_pos);
+                               "%s: detected the cluster chain loop (i_pos %lld)",
+                               __func__, MSDOS_I(inode)->i_pos);
                        nr = -EIO;
                        goto out;
                }
@@ -262,9 +268,8 @@ int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus)
                        goto out;
                else if (nr == FAT_ENT_FREE) {
                        fat_fs_error_ratelimit(sb,
-                                      "%s: invalid cluster chain (i_pos %lld)",
-                                      __func__,
-                                      MSDOS_I(inode)->i_pos);
+                               "%s: invalid cluster chain (i_pos %lld)",
+                               __func__, MSDOS_I(inode)->i_pos);
                        nr = -EIO;
                        goto out;
                } else if (nr == FAT_ENT_EOF) {
index 8e100c3bf72c1a0e3913107b33f9b2859be66882..7f5f3699fc6c086cb169c0f0dd9782971408480f 100644 (file)
@@ -1130,7 +1130,7 @@ error:
        return err;
 }
 
-int fat_alloc_new_dir(struct inode *dir, struct timespec *ts)
+int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts)
 {
        struct super_block *sb = dir->i_sb;
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
index 8fc1093da47d38ebf354e2b96c23d6fb5f086822..9d7d2d5da28bf9e6cfb614a267274612e8579247 100644 (file)
@@ -304,7 +304,7 @@ extern int fat_scan_logstart(struct inode *dir, int i_logstart,
                             struct fat_slot_info *sinfo);
 extern int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh,
                                struct msdos_dir_entry **de);
-extern int fat_alloc_new_dir(struct inode *dir, struct timespec *ts);
+extern int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts);
 extern int fat_add_entries(struct inode *dir, void *slots, int nr_slots,
                           struct fat_slot_info *sinfo);
 extern int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo);
@@ -348,6 +348,11 @@ static inline void fatent_brelse(struct fat_entry *fatent)
        fatent->fat_inode = NULL;
 }
 
+static inline bool fat_valid_entry(struct msdos_sb_info *sbi, int entry)
+{
+       return FAT_START_ENT <= entry && entry < sbi->max_cluster;
+}
+
 extern void fat_ent_access_init(struct super_block *sb);
 extern int fat_ent_read(struct inode *inode, struct fat_entry *fatent,
                        int entry);
@@ -357,6 +362,7 @@ extern int fat_alloc_clusters(struct inode *inode, int *cluster,
                              int nr_cluster);
 extern int fat_free_clusters(struct inode *inode, int cluster);
 extern int fat_count_free_clusters(struct super_block *sb);
+extern int fat_trim_fs(struct inode *inode, struct fstrim_range *range);
 
 /* fat/file.c */
 extern long fat_generic_ioctl(struct file *filp, unsigned int cmd,
@@ -406,9 +412,9 @@ void fat_msg(struct super_block *sb, const char *level, const char *fmt, ...);
         } while (0)
 extern int fat_clusters_flush(struct super_block *sb);
 extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster);
-extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts,
+extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec64 *ts,
                              __le16 __time, __le16 __date, u8 time_cs);
-extern void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec *ts,
+extern void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts,
                              __le16 *time, __le16 *date, u8 *time_cs);
 extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs);
 
index bac10de678cc9645af9eccd2584d0ffc548b9c93..defc2168de915c23406fe869af1ca65834818402 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <linux/blkdev.h>
+#include <linux/sched/signal.h>
 #include "fat.h"
 
 struct fatent_operations {
@@ -23,7 +24,7 @@ static void fat12_ent_blocknr(struct super_block *sb, int entry,
 {
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
        int bytes = entry + (entry >> 1);
-       WARN_ON(entry < FAT_START_ENT || sbi->max_cluster <= entry);
+       WARN_ON(!fat_valid_entry(sbi, entry));
        *offset = bytes & (sb->s_blocksize - 1);
        *blocknr = sbi->fat_start + (bytes >> sb->s_blocksize_bits);
 }
@@ -33,7 +34,7 @@ static void fat_ent_blocknr(struct super_block *sb, int entry,
 {
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
        int bytes = (entry << sbi->fatent_shift);
-       WARN_ON(entry < FAT_START_ENT || sbi->max_cluster <= entry);
+       WARN_ON(!fat_valid_entry(sbi, entry));
        *offset = bytes & (sb->s_blocksize - 1);
        *blocknr = sbi->fat_start + (bytes >> sb->s_blocksize_bits);
 }
@@ -353,7 +354,7 @@ int fat_ent_read(struct inode *inode, struct fat_entry *fatent, int entry)
        int err, offset;
        sector_t blocknr;
 
-       if (entry < FAT_START_ENT || sbi->max_cluster <= entry) {
+       if (!fat_valid_entry(sbi, entry)) {
                fatent_brelse(fatent);
                fat_fs_error(sb, "invalid access to FAT (entry 0x%08x)", entry);
                return -EIO;
@@ -690,3 +691,104 @@ out:
        unlock_fat(sbi);
        return err;
 }
+
+static int fat_trim_clusters(struct super_block *sb, u32 clus, u32 nr_clus)
+{
+       struct msdos_sb_info *sbi = MSDOS_SB(sb);
+       return sb_issue_discard(sb, fat_clus_to_blknr(sbi, clus),
+                               nr_clus * sbi->sec_per_clus, GFP_NOFS, 0);
+}
+
+int fat_trim_fs(struct inode *inode, struct fstrim_range *range)
+{
+       struct super_block *sb = inode->i_sb;
+       struct msdos_sb_info *sbi = MSDOS_SB(sb);
+       const struct fatent_operations *ops = sbi->fatent_ops;
+       struct fat_entry fatent;
+       u64 ent_start, ent_end, minlen, trimmed = 0;
+       u32 free = 0;
+       unsigned long reada_blocks, reada_mask, cur_block = 0;
+       int err = 0;
+
+       /*
+        * FAT data is organized as clusters, trim at the granulary of cluster.
+        *
+        * fstrim_range is in byte, convert vaules to cluster index.
+        * Treat sectors before data region as all used, not to trim them.
+        */
+       ent_start = max_t(u64, range->start>>sbi->cluster_bits, FAT_START_ENT);
+       ent_end = ent_start + (range->len >> sbi->cluster_bits) - 1;
+       minlen = range->minlen >> sbi->cluster_bits;
+
+       if (ent_start >= sbi->max_cluster || range->len < sbi->cluster_size)
+               return -EINVAL;
+       if (ent_end >= sbi->max_cluster)
+               ent_end = sbi->max_cluster - 1;
+
+       reada_blocks = FAT_READA_SIZE >> sb->s_blocksize_bits;
+       reada_mask = reada_blocks - 1;
+
+       fatent_init(&fatent);
+       lock_fat(sbi);
+       fatent_set_entry(&fatent, ent_start);
+       while (fatent.entry <= ent_end) {
+               /* readahead of fat blocks */
+               if ((cur_block & reada_mask) == 0) {
+                       unsigned long rest = sbi->fat_length - cur_block;
+                       fat_ent_reada(sb, &fatent, min(reada_blocks, rest));
+               }
+               cur_block++;
+
+               err = fat_ent_read_block(sb, &fatent);
+               if (err)
+                       goto error;
+               do {
+                       if (ops->ent_get(&fatent) == FAT_ENT_FREE) {
+                               free++;
+                       } else if (free) {
+                               if (free >= minlen) {
+                                       u32 clus = fatent.entry - free;
+
+                                       err = fat_trim_clusters(sb, clus, free);
+                                       if (err && err != -EOPNOTSUPP)
+                                               goto error;
+                                       if (!err)
+                                               trimmed += free;
+                                       err = 0;
+                               }
+                               free = 0;
+                       }
+               } while (fat_ent_next(sbi, &fatent) && fatent.entry <= ent_end);
+
+               if (fatal_signal_pending(current)) {
+                       err = -ERESTARTSYS;
+                       goto error;
+               }
+
+               if (need_resched()) {
+                       fatent_brelse(&fatent);
+                       unlock_fat(sbi);
+                       cond_resched();
+                       lock_fat(sbi);
+               }
+       }
+       /* handle scenario when tail entries are all free */
+       if (free && free >= minlen) {
+               u32 clus = fatent.entry - free;
+
+               err = fat_trim_clusters(sb, clus, free);
+               if (err && err != -EOPNOTSUPP)
+                       goto error;
+               if (!err)
+                       trimmed += free;
+               err = 0;
+       }
+
+error:
+       fatent_brelse(&fatent);
+       unlock_fat(sbi);
+
+       range->len = trimmed << sbi->cluster_bits;
+
+       return err;
+}
index 4724cc9ad65021c8fe80a3cc66783e8d01801907..4f3d72fb1e60d64a71f92e632da19ac4ac132ebc 100644 (file)
@@ -121,6 +121,37 @@ static int fat_ioctl_get_volume_id(struct inode *inode, u32 __user *user_attr)
        return put_user(sbi->vol_id, user_attr);
 }
 
+static int fat_ioctl_fitrim(struct inode *inode, unsigned long arg)
+{
+       struct super_block *sb = inode->i_sb;
+       struct fstrim_range __user *user_range;
+       struct fstrim_range range;
+       struct request_queue *q = bdev_get_queue(sb->s_bdev);
+       int err;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       if (!blk_queue_discard(q))
+               return -EOPNOTSUPP;
+
+       user_range = (struct fstrim_range __user *)arg;
+       if (copy_from_user(&range, user_range, sizeof(range)))
+               return -EFAULT;
+
+       range.minlen = max_t(unsigned int, range.minlen,
+                            q->limits.discard_granularity);
+
+       err = fat_trim_fs(inode, &range);
+       if (err < 0)
+               return err;
+
+       if (copy_to_user(user_range, &range, sizeof(range)))
+               return -EFAULT;
+
+       return 0;
+}
+
 long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        struct inode *inode = file_inode(filp);
@@ -133,6 +164,8 @@ long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                return fat_ioctl_set_attributes(filp, user_attr);
        case FAT_IOCTL_GET_VOLUME_ID:
                return fat_ioctl_get_volume_id(inode, user_attr);
+       case FITRIM:
+               return fat_ioctl_fitrim(inode, arg);
        default:
                return -ENOTTY; /* Inappropriate ioctl for device */
        }
index bfd589ea74c01ebf74e4866d920759143b01be16..d6b81e31f9f5d827be92ffad4cf240fa32e5f767 100644 (file)
@@ -508,7 +508,6 @@ static int fat_validate_dir(struct inode *dir)
 /* doesn't deal with root inode */
 int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
 {
-       struct timespec ts;
        struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
        int error;
 
@@ -559,14 +558,11 @@ int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
        inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
                           & ~((loff_t)sbi->cluster_size - 1)) >> 9;
 
-       fat_time_fat2unix(sbi, &ts, de->time, de->date, 0);
-       inode->i_mtime = timespec_to_timespec64(ts);
+       fat_time_fat2unix(sbi, &inode->i_mtime, de->time, de->date, 0);
        if (sbi->options.isvfat) {
-               fat_time_fat2unix(sbi, &ts, de->ctime,
+               fat_time_fat2unix(sbi, &inode->i_ctime, de->ctime,
                                  de->cdate, de->ctime_cs);
-               inode->i_ctime = timespec_to_timespec64(ts);
-               fat_time_fat2unix(sbi, &ts, 0, de->adate, 0);
-               inode->i_atime = timespec_to_timespec64(ts);
+               fat_time_fat2unix(sbi, &inode->i_atime, 0, de->adate, 0);
        } else
                inode->i_ctime = inode->i_atime = inode->i_mtime;
 
@@ -843,7 +839,6 @@ static int fat_statfs(struct dentry *dentry, struct kstatfs *buf)
 
 static int __fat_write_inode(struct inode *inode, int wait)
 {
-       struct timespec ts;
        struct super_block *sb = inode->i_sb;
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
        struct buffer_head *bh;
@@ -881,16 +876,13 @@ retry:
                raw_entry->size = cpu_to_le32(inode->i_size);
        raw_entry->attr = fat_make_attrs(inode);
        fat_set_start(raw_entry, MSDOS_I(inode)->i_logstart);
-       ts = timespec64_to_timespec(inode->i_mtime);
-       fat_time_unix2fat(sbi, &ts, &raw_entry->time,
+       fat_time_unix2fat(sbi, &inode->i_mtime, &raw_entry->time,
                          &raw_entry->date, NULL);
        if (sbi->options.isvfat) {
                __le16 atime;
-               ts = timespec64_to_timespec(inode->i_ctime);
-               fat_time_unix2fat(sbi, &ts, &raw_entry->ctime,
+               fat_time_unix2fat(sbi, &inode->i_ctime, &raw_entry->ctime,
                                  &raw_entry->cdate, &raw_entry->ctime_cs);
-               ts = timespec64_to_timespec(inode->i_atime);
-               fat_time_unix2fat(sbi, &ts, &atime,
+               fat_time_unix2fat(sbi, &inode->i_atime, &atime,
                                  &raw_entry->adate, NULL);
        }
        spin_unlock(&sbi->inode_hash_lock);
index f9bdc1e01c98e7969d0e49d21bb468bef2eaaddb..573836dcaefc4c1d2720ee213e5b90098a4acb87 100644 (file)
@@ -180,17 +180,18 @@ int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster)
 #define IS_LEAP_YEAR(y)        (!((y) & 3) && (y) != YEAR_2100)
 
 /* Linear day numbers of the respective 1sts in non-leap years. */
-static time_t days_in_year[] = {
+static long days_in_year[] = {
        /* Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct  Nov  Dec */
        0,   0,  31,  59,  90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0,
 };
 
 /* Convert a FAT time/date pair to a UNIX date (seconds since 1 1 70). */
-void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts,
+void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec64 *ts,
                       __le16 __time, __le16 __date, u8 time_cs)
 {
        u16 time = le16_to_cpu(__time), date = le16_to_cpu(__date);
-       time_t second, day, leap_day, month, year;
+       time64_t second;
+       long day, leap_day, month, year;
 
        year  = date >> 9;
        month = max(1, (date >> 5) & 0xf);
@@ -205,7 +206,7 @@ void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts,
        second =  (time & 0x1f) << 1;
        second += ((time >> 5) & 0x3f) * SECS_PER_MIN;
        second += (time >> 11) * SECS_PER_HOUR;
-       second += (year * 365 + leap_day
+       second += (time64_t)(year * 365 + leap_day
                   + days_in_year[month] + day
                   + DAYS_DELTA) * SECS_PER_DAY;
 
@@ -224,11 +225,11 @@ void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts,
 }
 
 /* Convert linear UNIX date to a FAT time/date pair. */
-void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec *ts,
+void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts,
                       __le16 *time, __le16 *date, u8 *time_cs)
 {
        struct tm tm;
-       time_to_tm(ts->tv_sec,
+       time64_to_tm(ts->tv_sec,
                   (sbi->options.tz_set ? sbi->options.time_offset :
                   -sys_tz.tz_minuteswest) * SECS_PER_MIN, &tm);
 
index 16a832c37d663b518432387e5826c1b957fee3d9..efb8c40c9d27467d0d58d10dd5b1ba313c06d9d6 100644 (file)
@@ -225,7 +225,7 @@ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
 /***** Creates a directory entry (name is already formatted). */
 static int msdos_add_entry(struct inode *dir, const unsigned char *name,
                           int is_dir, int is_hid, int cluster,
-                          struct timespec *ts, struct fat_slot_info *sinfo)
+                          struct timespec64 *ts, struct fat_slot_info *sinfo)
 {
        struct msdos_sb_info *sbi = MSDOS_SB(dir->i_sb);
        struct msdos_dir_entry de;
@@ -250,7 +250,7 @@ static int msdos_add_entry(struct inode *dir, const unsigned char *name,
        if (err)
                return err;
 
-       dir->i_ctime = dir->i_mtime = timespec_to_timespec64(*ts);
+       dir->i_ctime = dir->i_mtime = *ts;
        if (IS_DIRSYNC(dir))
                (void)fat_sync_inode(dir);
        else
@@ -267,7 +267,6 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode,
        struct inode *inode = NULL;
        struct fat_slot_info sinfo;
        struct timespec64 ts;
-       struct timespec t;
        unsigned char msdos_name[MSDOS_NAME];
        int err, is_hid;
 
@@ -286,8 +285,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode,
        }
 
        ts = current_time(dir);
-       t = timespec64_to_timespec(ts);
-       err = msdos_add_entry(dir, msdos_name, 0, is_hid, 0, &t, &sinfo);
+       err = msdos_add_entry(dir, msdos_name, 0, is_hid, 0, &ts, &sinfo);
        if (err)
                goto out;
        inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);
@@ -347,7 +345,6 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        struct inode *inode;
        unsigned char msdos_name[MSDOS_NAME];
        struct timespec64 ts;
-       struct timespec t;
        int err, is_hid, cluster;
 
        mutex_lock(&MSDOS_SB(sb)->s_lock);
@@ -365,13 +362,12 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        }
 
        ts = current_time(dir);
-       t = timespec64_to_timespec(ts);
-       cluster = fat_alloc_new_dir(dir, &t);
+       cluster = fat_alloc_new_dir(dir, &ts);
        if (cluster < 0) {
                err = cluster;
                goto out;
        }
-       err = msdos_add_entry(dir, msdos_name, 1, is_hid, cluster, &t, &sinfo);
+       err = msdos_add_entry(dir, msdos_name, 1, is_hid, cluster, &ts, &sinfo);
        if (err)
                goto out_free;
        inc_nlink(dir);
@@ -503,9 +499,8 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
                new_i_pos = MSDOS_I(new_inode)->i_pos;
                fat_detach(new_inode);
        } else {
-               struct timespec t = timespec64_to_timespec(ts);
                err = msdos_add_entry(new_dir, new_name, is_dir, is_hid, 0,
-                                     &t, &sinfo);
+                                     &ts, &sinfo);
                if (err)
                        goto out;
                new_i_pos = sinfo.i_pos;
index 9a5469120caaf4dc6adafc7560da2fb13ffd009b..82cd1e69cbdf283322e8d7fa8566a22cca54fc0a 100644 (file)
@@ -577,7 +577,7 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname,
 
 static int vfat_build_slots(struct inode *dir, const unsigned char *name,
                            int len, int is_dir, int cluster,
-                           struct timespec *ts,
+                           struct timespec64 *ts,
                            struct msdos_dir_slot *slots, int *nr_slots)
 {
        struct msdos_sb_info *sbi = MSDOS_SB(dir->i_sb);
@@ -653,7 +653,7 @@ out_free:
 }
 
 static int vfat_add_entry(struct inode *dir, const struct qstr *qname,
-                         int is_dir, int cluster, struct timespec *ts,
+                         int is_dir, int cluster, struct timespec64 *ts,
                          struct fat_slot_info *sinfo)
 {
        struct msdos_dir_slot *slots;
@@ -678,7 +678,7 @@ static int vfat_add_entry(struct inode *dir, const struct qstr *qname,
                goto cleanup;
 
        /* update timestamp */
-       dir->i_ctime = dir->i_mtime = dir->i_atime = timespec_to_timespec64(*ts);
+       dir->i_ctime = dir->i_mtime = dir->i_atime = *ts;
        if (IS_DIRSYNC(dir))
                (void)fat_sync_inode(dir);
        else
@@ -762,14 +762,12 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
        struct inode *inode;
        struct fat_slot_info sinfo;
        struct timespec64 ts;
-       struct timespec t;
        int err;
 
        mutex_lock(&MSDOS_SB(sb)->s_lock);
 
        ts = current_time(dir);
-       t = timespec64_to_timespec(ts);
-       err = vfat_add_entry(dir, &dentry->d_name, 0, 0, &t, &sinfo);
+       err = vfat_add_entry(dir, &dentry->d_name, 0, 0, &ts, &sinfo);
        if (err)
                goto out;
        inode_inc_iversion(dir);
@@ -853,19 +851,17 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        struct inode *inode;
        struct fat_slot_info sinfo;
        struct timespec64 ts;
-       struct timespec t;
        int err, cluster;
 
        mutex_lock(&MSDOS_SB(sb)->s_lock);
 
        ts = current_time(dir);
-       t = timespec64_to_timespec(ts);
-       cluster = fat_alloc_new_dir(dir, &t);
+       cluster = fat_alloc_new_dir(dir, &ts);
        if (cluster < 0) {
                err = cluster;
                goto out;
        }
-       err = vfat_add_entry(dir, &dentry->d_name, 1, cluster, &t, &sinfo);
+       err = vfat_add_entry(dir, &dentry->d_name, 1, cluster, &ts, &sinfo);
        if (err)
                goto out_free;
        inode_inc_iversion(dir);
@@ -904,7 +900,6 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
        struct inode *old_inode, *new_inode;
        struct fat_slot_info old_sinfo, sinfo;
        struct timespec64 ts;
-       struct timespec t;
        loff_t new_i_pos;
        int err, is_dir, update_dotdot, corrupt = 0;
        struct super_block *sb = old_dir->i_sb;
@@ -939,9 +934,8 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
                new_i_pos = MSDOS_I(new_inode)->i_pos;
                fat_detach(new_inode);
        } else {
-               t = timespec64_to_timespec(ts);
                err = vfat_add_entry(new_dir, &new_dentry->d_name, is_dir, 0,
-                                    &t, &sinfo);
+                                    &ts, &sinfo);
                if (err)
                        goto out;
                new_i_pos = sinfo.i_pos;
index 12273b6ea56dbdeb2a2bff0c6846030e4fc9bcd5..4137d96534a6cb6a73d7a70dc75db543b12a3441 100644 (file)
@@ -116,7 +116,7 @@ int f_setown(struct file *filp, unsigned long arg, int force)
        struct pid *pid = NULL;
        int who = arg, ret = 0;
 
-       type = PIDTYPE_PID;
+       type = PIDTYPE_TGID;
        if (who < 0) {
                /* avoid overflow below */
                if (who == INT_MIN)
@@ -143,7 +143,7 @@ EXPORT_SYMBOL(f_setown);
 
 void f_delown(struct file *filp)
 {
-       f_modown(filp, NULL, PIDTYPE_PID, 1);
+       f_modown(filp, NULL, PIDTYPE_TGID, 1);
 }
 
 pid_t f_getown(struct file *filp)
@@ -171,11 +171,11 @@ static int f_setown_ex(struct file *filp, unsigned long arg)
 
        switch (owner.type) {
        case F_OWNER_TID:
-               type = PIDTYPE_MAX;
+               type = PIDTYPE_PID;
                break;
 
        case F_OWNER_PID:
-               type = PIDTYPE_PID;
+               type = PIDTYPE_TGID;
                break;
 
        case F_OWNER_PGRP:
@@ -206,11 +206,11 @@ static int f_getown_ex(struct file *filp, unsigned long arg)
        read_lock(&filp->f_owner.lock);
        owner.pid = pid_vnr(filp->f_owner.pid);
        switch (filp->f_owner.pid_type) {
-       case PIDTYPE_MAX:
+       case PIDTYPE_PID:
                owner.type = F_OWNER_TID;
                break;
 
-       case PIDTYPE_PID:
+       case PIDTYPE_TGID:
                owner.type = F_OWNER_PID;
                break;
 
@@ -723,7 +723,7 @@ static inline int sigio_perm(struct task_struct *p,
 
 static void send_sigio_to_task(struct task_struct *p,
                               struct fown_struct *fown,
-                              int fd, int reason, int group)
+                              int fd, int reason, enum pid_type type)
 {
        /*
         * F_SETSIG can change ->signum lockless in parallel, make
@@ -767,11 +767,11 @@ static void send_sigio_to_task(struct task_struct *p,
                        else
                                si.si_band = mangle_poll(band_table[reason - POLL_IN]);
                        si.si_fd    = fd;
-                       if (!do_send_sig_info(signum, &si, p, group))
+                       if (!do_send_sig_info(signum, &si, p, type))
                                break;
                /* fall-through: fall back on the old plain SIGIO signal */
                case 0:
-                       do_send_sig_info(SIGIO, SEND_SIG_PRIV, p, group);
+                       do_send_sig_info(SIGIO, SEND_SIG_PRIV, p, type);
        }
 }
 
@@ -780,34 +780,36 @@ void send_sigio(struct fown_struct *fown, int fd, int band)
        struct task_struct *p;
        enum pid_type type;
        struct pid *pid;
-       int group = 1;
        
        read_lock(&fown->lock);
 
        type = fown->pid_type;
-       if (type == PIDTYPE_MAX) {
-               group = 0;
-               type = PIDTYPE_PID;
-       }
-
        pid = fown->pid;
        if (!pid)
                goto out_unlock_fown;
-       
-       read_lock(&tasklist_lock);
-       do_each_pid_task(pid, type, p) {
-               send_sigio_to_task(p, fown, fd, band, group);
-       } while_each_pid_task(pid, type, p);
-       read_unlock(&tasklist_lock);
+
+       if (type <= PIDTYPE_TGID) {
+               rcu_read_lock();
+               p = pid_task(pid, PIDTYPE_PID);
+               if (p)
+                       send_sigio_to_task(p, fown, fd, band, type);
+               rcu_read_unlock();
+       } else {
+               read_lock(&tasklist_lock);
+               do_each_pid_task(pid, type, p) {
+                       send_sigio_to_task(p, fown, fd, band, type);
+               } while_each_pid_task(pid, type, p);
+               read_unlock(&tasklist_lock);
+       }
  out_unlock_fown:
        read_unlock(&fown->lock);
 }
 
 static void send_sigurg_to_task(struct task_struct *p,
-                               struct fown_struct *fown, int group)
+                               struct fown_struct *fown, enum pid_type type)
 {
        if (sigio_perm(p, fown, SIGURG))
-               do_send_sig_info(SIGURG, SEND_SIG_PRIV, p, group);
+               do_send_sig_info(SIGURG, SEND_SIG_PRIV, p, type);
 }
 
 int send_sigurg(struct fown_struct *fown)
@@ -815,28 +817,30 @@ int send_sigurg(struct fown_struct *fown)
        struct task_struct *p;
        enum pid_type type;
        struct pid *pid;
-       int group = 1;
        int ret = 0;
        
        read_lock(&fown->lock);
 
        type = fown->pid_type;
-       if (type == PIDTYPE_MAX) {
-               group = 0;
-               type = PIDTYPE_PID;
-       }
-
        pid = fown->pid;
        if (!pid)
                goto out_unlock_fown;
 
        ret = 1;
-       
-       read_lock(&tasklist_lock);
-       do_each_pid_task(pid, type, p) {
-               send_sigurg_to_task(p, fown, group);
-       } while_each_pid_task(pid, type, p);
-       read_unlock(&tasklist_lock);
+
+       if (type <= PIDTYPE_TGID) {
+               rcu_read_lock();
+               p = pid_task(pid, PIDTYPE_PID);
+               if (p)
+                       send_sigurg_to_task(p, fown, type);
+               rcu_read_unlock();
+       } else {
+               read_lock(&tasklist_lock);
+               do_each_pid_task(pid, type, p) {
+                       send_sigurg_to_task(p, fown, type);
+               } while_each_pid_task(pid, type, p);
+               read_unlock(&tasklist_lock);
+       }
  out_unlock_fown:
        read_unlock(&fown->lock);
        return ret;
index d6eccd04d7038a9937e89630d4e1a00dbed98ef6..e49af4caf15d92e3a33bbd02e4e551d778d8180e 100644 (file)
@@ -52,7 +52,8 @@ static void file_free_rcu(struct rcu_head *head)
 static inline void file_free(struct file *f)
 {
        security_file_free(f);
-       percpu_counter_dec(&nr_files);
+       if (!(f->f_mode & FMODE_NOACCOUNT))
+               percpu_counter_dec(&nr_files);
        call_rcu(&f->f_u.fu_rcuhead, file_free_rcu);
 }
 
@@ -91,6 +92,34 @@ int proc_nr_files(struct ctl_table *table, int write,
 }
 #endif
 
+static struct file *__alloc_file(int flags, const struct cred *cred)
+{
+       struct file *f;
+       int error;
+
+       f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL);
+       if (unlikely(!f))
+               return ERR_PTR(-ENOMEM);
+
+       f->f_cred = get_cred(cred);
+       error = security_file_alloc(f);
+       if (unlikely(error)) {
+               file_free_rcu(&f->f_u.fu_rcuhead);
+               return ERR_PTR(error);
+       }
+
+       atomic_long_set(&f->f_count, 1);
+       rwlock_init(&f->f_owner.lock);
+       spin_lock_init(&f->f_lock);
+       mutex_init(&f->f_pos_lock);
+       eventpoll_init_file(f);
+       f->f_flags = flags;
+       f->f_mode = OPEN_FMODE(flags);
+       /* f->f_version: 0 */
+
+       return f;
+}
+
 /* Find an unused file structure and return a pointer to it.
  * Returns an error pointer if some error happend e.g. we over file
  * structures limit, run out of memory or operation is not permitted.
@@ -105,7 +134,6 @@ struct file *alloc_empty_file(int flags, const struct cred *cred)
 {
        static long old_max;
        struct file *f;
-       int error;
 
        /*
         * Privileged users can go above max_files
@@ -119,26 +147,10 @@ struct file *alloc_empty_file(int flags, const struct cred *cred)
                        goto over;
        }
 
-       f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL);
-       if (unlikely(!f))
-               return ERR_PTR(-ENOMEM);
-
-       f->f_cred = get_cred(cred);
-       error = security_file_alloc(f);
-       if (unlikely(error)) {
-               file_free_rcu(&f->f_u.fu_rcuhead);
-               return ERR_PTR(error);
-       }
+       f = __alloc_file(flags, cred);
+       if (!IS_ERR(f))
+               percpu_counter_inc(&nr_files);
 
-       atomic_long_set(&f->f_count, 1);
-       rwlock_init(&f->f_owner.lock);
-       spin_lock_init(&f->f_lock);
-       mutex_init(&f->f_pos_lock);
-       eventpoll_init_file(f);
-       f->f_flags = flags;
-       f->f_mode = OPEN_FMODE(flags);
-       /* f->f_version: 0 */
-       percpu_counter_inc(&nr_files);
        return f;
 
 over:
@@ -150,6 +162,21 @@ over:
        return ERR_PTR(-ENFILE);
 }
 
+/*
+ * Variant of alloc_empty_file() that doesn't check and modify nr_files.
+ *
+ * Should not be used unless there's a very good reason to do so.
+ */
+struct file *alloc_empty_file_noaccount(int flags, const struct cred *cred)
+{
+       struct file *f = __alloc_file(flags, cred);
+
+       if (!IS_ERR(f))
+               f->f_mode |= FMODE_NOACCOUNT;
+
+       return f;
+}
+
 /**
  * alloc_file - allocate and initialize a 'struct file'
  *
index c6b88fa85e2e5d048ea49b268c402843d53c2c0e..11ea2c4a38abc16a50b78a0a9668706c7d967a62 100644 (file)
@@ -127,6 +127,16 @@ static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background)
        return !fc->initialized || (for_background && fc->blocked);
 }
 
+static void fuse_drop_waiting(struct fuse_conn *fc)
+{
+       if (fc->connected) {
+               atomic_dec(&fc->num_waiting);
+       } else if (atomic_dec_and_test(&fc->num_waiting)) {
+               /* wake up aborters */
+               wake_up_all(&fc->blocked_waitq);
+       }
+}
+
 static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages,
                                       bool for_background)
 {
@@ -175,7 +185,7 @@ static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages,
        return req;
 
  out:
-       atomic_dec(&fc->num_waiting);
+       fuse_drop_waiting(fc);
        return ERR_PTR(err);
 }
 
@@ -285,7 +295,7 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
 
                if (test_bit(FR_WAITING, &req->flags)) {
                        __clear_bit(FR_WAITING, &req->flags);
-                       atomic_dec(&fc->num_waiting);
+                       fuse_drop_waiting(fc);
                }
 
                if (req->stolen_file)
@@ -371,7 +381,7 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
        struct fuse_iqueue *fiq = &fc->iq;
 
        if (test_and_set_bit(FR_FINISHED, &req->flags))
-               return;
+               goto put_request;
 
        spin_lock(&fiq->waitq.lock);
        list_del_init(&req->intr_entry);
@@ -400,6 +410,7 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
        wake_up(&req->waitq);
        if (req->end)
                req->end(fc, req);
+put_request:
        fuse_put_request(fc, req);
 }
 
@@ -1362,8 +1373,8 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
        if (!fud)
                return -EPERM;
 
-       bufs = kmalloc_array(pipe->buffers, sizeof(struct pipe_buffer),
-                            GFP_KERNEL);
+       bufs = kvmalloc_array(pipe->buffers, sizeof(struct pipe_buffer),
+                             GFP_KERNEL);
        if (!bufs)
                return -ENOMEM;
 
@@ -1396,7 +1407,7 @@ out:
        for (; page_nr < cs.nr_segs; page_nr++)
                put_page(bufs[page_nr].page);
 
-       kfree(bufs);
+       kvfree(bufs);
        return ret;
 }
 
@@ -1944,12 +1955,15 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
        if (!fud)
                return -EPERM;
 
-       bufs = kmalloc_array(pipe->buffers, sizeof(struct pipe_buffer),
-                            GFP_KERNEL);
-       if (!bufs)
+       pipe_lock(pipe);
+
+       bufs = kvmalloc_array(pipe->nrbufs, sizeof(struct pipe_buffer),
+                             GFP_KERNEL);
+       if (!bufs) {
+               pipe_unlock(pipe);
                return -ENOMEM;
+       }
 
-       pipe_lock(pipe);
        nbuf = 0;
        rem = 0;
        for (idx = 0; idx < pipe->nrbufs && rem < len; idx++)
@@ -2003,7 +2017,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
                pipe_buf_release(pipe, &bufs[idx]);
 
 out:
-       kfree(bufs);
+       kvfree(bufs);
        return ret;
 }
 
@@ -2087,8 +2101,7 @@ void fuse_abort_conn(struct fuse_conn *fc, bool is_abort)
        if (fc->connected) {
                struct fuse_dev *fud;
                struct fuse_req *req, *next;
-               LIST_HEAD(to_end1);
-               LIST_HEAD(to_end2);
+               LIST_HEAD(to_end);
 
                fc->connected = 0;
                fc->blocked = 0;
@@ -2105,11 +2118,12 @@ void fuse_abort_conn(struct fuse_conn *fc, bool is_abort)
                                set_bit(FR_ABORTED, &req->flags);
                                if (!test_bit(FR_LOCKED, &req->flags)) {
                                        set_bit(FR_PRIVATE, &req->flags);
-                                       list_move(&req->list, &to_end1);
+                                       __fuse_get_request(req);
+                                       list_move(&req->list, &to_end);
                                }
                                spin_unlock(&req->waitq.lock);
                        }
-                       list_splice_init(&fpq->processing, &to_end2);
+                       list_splice_tail_init(&fpq->processing, &to_end);
                        spin_unlock(&fpq->lock);
                }
                fc->max_background = UINT_MAX;
@@ -2117,9 +2131,9 @@ void fuse_abort_conn(struct fuse_conn *fc, bool is_abort)
 
                spin_lock(&fiq->waitq.lock);
                fiq->connected = 0;
-               list_splice_init(&fiq->pending, &to_end2);
-               list_for_each_entry(req, &to_end2, list)
+               list_for_each_entry(req, &fiq->pending, list)
                        clear_bit(FR_PENDING, &req->flags);
+               list_splice_tail_init(&fiq->pending, &to_end);
                while (forget_pending(fiq))
                        kfree(dequeue_forget(fiq, 1, NULL));
                wake_up_all_locked(&fiq->waitq);
@@ -2129,19 +2143,18 @@ void fuse_abort_conn(struct fuse_conn *fc, bool is_abort)
                wake_up_all(&fc->blocked_waitq);
                spin_unlock(&fc->lock);
 
-               while (!list_empty(&to_end1)) {
-                       req = list_first_entry(&to_end1, struct fuse_req, list);
-                       __fuse_get_request(req);
-                       list_del_init(&req->list);
-                       request_end(fc, req);
-               }
-               end_requests(fc, &to_end2);
+               end_requests(fc, &to_end);
        } else {
                spin_unlock(&fc->lock);
        }
 }
 EXPORT_SYMBOL_GPL(fuse_abort_conn);
 
+void fuse_wait_aborted(struct fuse_conn *fc)
+{
+       wait_event(fc->blocked_waitq, atomic_read(&fc->num_waiting) == 0);
+}
+
 int fuse_dev_release(struct inode *inode, struct file *file)
 {
        struct fuse_dev *fud = fuse_get_dev(file);
@@ -2149,9 +2162,15 @@ int fuse_dev_release(struct inode *inode, struct file *file)
        if (fud) {
                struct fuse_conn *fc = fud->fc;
                struct fuse_pqueue *fpq = &fud->pq;
+               LIST_HEAD(to_end);
 
+               spin_lock(&fpq->lock);
                WARN_ON(!list_empty(&fpq->io));
-               end_requests(fc, &fpq->processing);
+               list_splice_init(&fpq->processing, &to_end);
+               spin_unlock(&fpq->lock);
+
+               end_requests(fc, &to_end);
+
                /* Are we the last open device? */
                if (atomic_dec_and_test(&fc->dev_count)) {
                        WARN_ON(fc->iq.fasync != NULL);
index d80aab0d59822e416af65bb0e014902615adf0ac..0979609d6eba8804aac53c5b11f32eeb94f91a75 100644 (file)
@@ -355,11 +355,12 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
        struct inode *inode;
        struct dentry *newent;
        bool outarg_valid = true;
+       bool locked;
 
-       fuse_lock_inode(dir);
+       locked = fuse_lock_inode(dir);
        err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
                               &outarg, &inode);
-       fuse_unlock_inode(dir);
+       fuse_unlock_inode(dir, locked);
        if (err == -ENOENT) {
                outarg_valid = false;
                err = 0;
@@ -1347,6 +1348,7 @@ static int fuse_readdir(struct file *file, struct dir_context *ctx)
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_req *req;
        u64 attr_version = 0;
+       bool locked;
 
        if (is_bad_inode(inode))
                return -EIO;
@@ -1374,9 +1376,9 @@ static int fuse_readdir(struct file *file, struct dir_context *ctx)
                fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
                               FUSE_READDIR);
        }
-       fuse_lock_inode(inode);
+       locked = fuse_lock_inode(inode);
        fuse_request_send(fc, req);
-       fuse_unlock_inode(inode);
+       fuse_unlock_inode(inode, locked);
        nbytes = req->out.args[0].size;
        err = req->out.h.error;
        fuse_put_request(fc, req);
index a201fb0ac64f9cd7f978a82806167db6f9555aeb..32d0b883e74f340d442754a5a87b82629b96658e 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/sched/signal.h>
 #include <linux/module.h>
 #include <linux/compat.h>
 #include <linux/swap.h>
@@ -866,6 +867,7 @@ static int fuse_readpages_fill(void *_data, struct page *page)
        }
 
        if (WARN_ON(req->num_pages >= req->max_pages)) {
+               unlock_page(page);
                fuse_put_request(fc, req);
                return -EIO;
        }
@@ -2048,7 +2050,7 @@ static void fuse_vma_close(struct vm_area_struct *vma)
  * - sync(2)
  * - try_to_free_pages() with order > PAGE_ALLOC_COSTLY_ORDER
  */
-static int fuse_page_mkwrite(struct vm_fault *vmf)
+static vm_fault_t fuse_page_mkwrite(struct vm_fault *vmf)
 {
        struct page *page = vmf->page;
        struct inode *inode = file_inode(vmf->vma->vm_file);
index 5256ad333b05309dda9b2816cc99a0961ca8d63e..f78e9614bb5f712d2936bffa2fa886c7027ba7c1 100644 (file)
@@ -862,6 +862,7 @@ void fuse_request_send_background_locked(struct fuse_conn *fc,
 
 /* Abort all requests */
 void fuse_abort_conn(struct fuse_conn *fc, bool is_abort);
+void fuse_wait_aborted(struct fuse_conn *fc);
 
 /**
  * Invalidate inode attributes
@@ -974,8 +975,8 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
 
 void fuse_set_initialized(struct fuse_conn *fc);
 
-void fuse_unlock_inode(struct inode *inode);
-void fuse_lock_inode(struct inode *inode);
+void fuse_unlock_inode(struct inode *inode, bool locked);
+bool fuse_lock_inode(struct inode *inode);
 
 int fuse_setxattr(struct inode *inode, const char *name, const void *value,
                  size_t size, int flags);
index a24df8861b40d2148e51b98f2503c5c846f9d7ea..db9e60b7eb691bc4f0814c694577f60d363f32a1 100644 (file)
@@ -208,7 +208,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
        struct fuse_inode *fi = get_fuse_inode(inode);
        bool is_wb = fc->writeback_cache;
        loff_t oldsize;
-       struct timespec old_mtime;
+       struct timespec64 old_mtime;
 
        spin_lock(&fc->lock);
        if ((attr_version != 0 && fi->attr_version > attr_version) ||
@@ -217,7 +217,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
                return;
        }
 
-       old_mtime = timespec64_to_timespec(inode->i_mtime);
+       old_mtime = inode->i_mtime;
        fuse_change_attributes_common(inode, attr, attr_valid);
 
        oldsize = inode->i_size;
@@ -237,7 +237,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
                        truncate_pagecache(inode, attr->size);
                        inval = true;
                } else if (fc->auto_inval_data) {
-                       struct timespec new_mtime = {
+                       struct timespec64 new_mtime = {
                                .tv_sec = attr->mtime,
                                .tv_nsec = attr->mtimensec,
                        };
@@ -246,7 +246,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
                         * Auto inval mode also checks and invalidates if mtime
                         * has changed.
                         */
-                       if (!timespec_equal(&old_mtime, &new_mtime))
+                       if (!timespec64_equal(&old_mtime, &new_mtime))
                                inval = true;
                }
 
@@ -357,15 +357,21 @@ int fuse_reverse_inval_inode(struct super_block *sb, u64 nodeid,
        return 0;
 }
 
-void fuse_lock_inode(struct inode *inode)
+bool fuse_lock_inode(struct inode *inode)
 {
-       if (!get_fuse_conn(inode)->parallel_dirops)
+       bool locked = false;
+
+       if (!get_fuse_conn(inode)->parallel_dirops) {
                mutex_lock(&get_fuse_inode(inode)->mutex);
+               locked = true;
+       }
+
+       return locked;
 }
 
-void fuse_unlock_inode(struct inode *inode)
+void fuse_unlock_inode(struct inode *inode, bool locked)
 {
-       if (!get_fuse_conn(inode)->parallel_dirops)
+       if (locked)
                mutex_unlock(&get_fuse_inode(inode)->mutex);
 }
 
@@ -391,9 +397,6 @@ static void fuse_put_super(struct super_block *sb)
 {
        struct fuse_conn *fc = get_fuse_conn_super(sb);
 
-       fuse_send_destroy(fc);
-
-       fuse_abort_conn(fc, false);
        mutex_lock(&fuse_mutex);
        list_del(&fc->entry);
        fuse_ctl_remove_conn(fc);
@@ -1210,16 +1213,25 @@ static struct dentry *fuse_mount(struct file_system_type *fs_type,
        return mount_nodev(fs_type, flags, raw_data, fuse_fill_super);
 }
 
-static void fuse_kill_sb_anon(struct super_block *sb)
+static void fuse_sb_destroy(struct super_block *sb)
 {
        struct fuse_conn *fc = get_fuse_conn_super(sb);
 
        if (fc) {
+               fuse_send_destroy(fc);
+
+               fuse_abort_conn(fc, false);
+               fuse_wait_aborted(fc);
+
                down_write(&fc->killsb);
                fc->sb = NULL;
                up_write(&fc->killsb);
        }
+}
 
+static void fuse_kill_sb_anon(struct super_block *sb)
+{
+       fuse_sb_destroy(sb);
        kill_anon_super(sb);
 }
 
@@ -1242,14 +1254,7 @@ static struct dentry *fuse_mount_blk(struct file_system_type *fs_type,
 
 static void fuse_kill_sb_blk(struct super_block *sb)
 {
-       struct fuse_conn *fc = get_fuse_conn_super(sb);
-
-       if (fc) {
-               down_write(&fc->killsb);
-               fc->sb = NULL;
-               up_write(&fc->killsb);
-       }
-
+       fuse_sb_destroy(sb);
        kill_block_super(sb);
 }
 
index ad04a5741016994374289cf8cc8ba6f97d6c0480..9a8772465a907a5e320a44c8b6ee7ddf61e87410 100644 (file)
@@ -75,9 +75,10 @@ int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len)
        if (!fd->bnode) {
                if (!tree->root)
                        hfs_btree_inc_height(tree);
-               fd->bnode = hfs_bnode_find(tree, tree->leaf_head);
-               if (IS_ERR(fd->bnode))
-                       return PTR_ERR(fd->bnode);
+               node = hfs_bnode_find(tree, tree->leaf_head);
+               if (IS_ERR(node))
+                       return PTR_ERR(node);
+               fd->bnode = node;
                fd->record = -1;
        }
        new_node = NULL;
index 7cc8b4acf66ae4fa89087dbd0b9552c3abe4b6e8..a63371815aaba6a0dfda4399b3b5cf8f789b15c2 100644 (file)
@@ -11,18 +11,3 @@ config HFSPLUS_FS
          MacOS 8. It includes all Mac specific filesystem data such as
          data forks and creator codes, but it also has several UNIX
          style features such as file ownership and permissions.
-
-config HFSPLUS_FS_POSIX_ACL
-       bool "HFS+ POSIX Access Control Lists"
-       depends on HFSPLUS_FS
-       select FS_POSIX_ACL
-       help
-         POSIX Access Control Lists (ACLs) support permissions for users and
-         groups beyond the owner/group/world scheme.
-
-         It needs to understand that POSIX ACLs are treated only under
-         Linux. POSIX ACLs doesn't mean something under Mac OS X.
-         Mac OS X beginning with version 10.4 ("Tiger") support NFSv4 ACLs,
-         which are part of the NFSv4 standard.
-
-         If you don't know what Access Control Lists are, say N
index f6a56542f8d7d6a4057a22bb624be768ce477c1e..9ed20e64b983937085d0a471574c91d630b107e7 100644 (file)
@@ -8,5 +8,3 @@ obj-$(CONFIG_HFSPLUS_FS) += hfsplus.o
 hfsplus-objs := super.o options.o inode.o ioctl.o extents.o catalog.o dir.o btree.o \
                bnode.o brec.o bfind.o tables.o unicode.o wrapper.o bitmap.o part_tbl.o \
                attributes.o xattr.o xattr_user.o xattr_security.o xattr_trusted.o
-
-hfsplus-$(CONFIG_HFSPLUS_FS_POSIX_ACL) += posix_acl.o
diff --git a/fs/hfsplus/acl.h b/fs/hfsplus/acl.h
deleted file mode 100644 (file)
index 488c2b7..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * linux/fs/hfsplus/acl.h
- *
- * Vyacheslav Dubeyko <slava@dubeyko.com>
- *
- * Handler for Posix Access Control Lists (ACLs) support.
- */
-
-#include <linux/posix_acl_xattr.h>
-
-#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
-
-/* posix_acl.c */
-struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type);
-int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
-               int type);
-extern int hfsplus_init_posix_acl(struct inode *, struct inode *);
-
-#else  /* CONFIG_HFSPLUS_FS_POSIX_ACL */
-#define hfsplus_get_posix_acl NULL
-#define hfsplus_set_posix_acl NULL
-
-static inline int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir)
-{
-       return 0;
-}
-#endif  /* CONFIG_HFSPLUS_FS_POSIX_ACL */
index 808f4d8c859c997f72753bf064b5308f0f10063e..ed8eacb34452f02107c253c3d57a9c89532daa93 100644 (file)
@@ -73,9 +73,10 @@ int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len)
        if (!fd->bnode) {
                if (!tree->root)
                        hfs_btree_inc_height(tree);
-               fd->bnode = hfs_bnode_find(tree, tree->leaf_head);
-               if (IS_ERR(fd->bnode))
-                       return PTR_ERR(fd->bnode);
+               node = hfs_bnode_find(tree, tree->leaf_head);
+               if (IS_ERR(node))
+                       return PTR_ERR(node);
+               fd->bnode = node;
                fd->record = -1;
        }
        new_node = NULL;
index b5254378f0113ca28d98c793a61528f62ea6f122..f37662675c3a3467e36510d087833236415dbf67 100644 (file)
@@ -18,7 +18,6 @@
 #include "hfsplus_fs.h"
 #include "hfsplus_raw.h"
 #include "xattr.h"
-#include "acl.h"
 
 static inline void hfsplus_instantiate(struct dentry *dentry,
                                       struct inode *inode, u32 cnid)
@@ -78,13 +77,13 @@ again:
                                cpu_to_be32(HFSP_HARDLINK_TYPE) &&
                                entry.file.user_info.fdCreator ==
                                cpu_to_be32(HFSP_HFSPLUS_CREATOR) &&
+                               HFSPLUS_SB(sb)->hidden_dir &&
                                (entry.file.create_date ==
                                        HFSPLUS_I(HFSPLUS_SB(sb)->hidden_dir)->
                                                create_date ||
                                entry.file.create_date ==
                                        HFSPLUS_I(d_inode(sb->s_root))->
-                                               create_date) &&
-                               HFSPLUS_SB(sb)->hidden_dir) {
+                                               create_date)) {
                        struct qstr str;
                        char name[32];
 
@@ -455,7 +454,7 @@ static int hfsplus_symlink(struct inode *dir, struct dentry *dentry,
        if (res)
                goto out_err;
 
-       res = hfsplus_init_inode_security(inode, dir, &dentry->d_name);
+       res = hfsplus_init_security(inode, dir, &dentry->d_name);
        if (res == -EOPNOTSUPP)
                res = 0; /* Operation is not supported. */
        else if (res) {
@@ -496,7 +495,7 @@ static int hfsplus_mknod(struct inode *dir, struct dentry *dentry,
        if (res)
                goto failed_mknod;
 
-       res = hfsplus_init_inode_security(inode, dir, &dentry->d_name);
+       res = hfsplus_init_security(inode, dir, &dentry->d_name);
        if (res == -EOPNOTSUPP)
                res = 0; /* Operation is not supported. */
        else if (res) {
@@ -567,10 +566,6 @@ const struct inode_operations hfsplus_dir_inode_operations = {
        .mknod                  = hfsplus_mknod,
        .rename                 = hfsplus_rename,
        .listxattr              = hfsplus_listxattr,
-#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
-       .get_acl                = hfsplus_get_posix_acl,
-       .set_acl                = hfsplus_set_posix_acl,
-#endif
 };
 
 const struct file_operations hfsplus_dir_operations = {
index e8770935ce6d8588fc636661485c2fe23a3bafad..8e0f59767694b61ecfc0b57cd25d1a23ea1b94d5 100644 (file)
@@ -336,6 +336,9 @@ static int hfsplus_free_extents(struct super_block *sb,
        int i;
        int err = 0;
 
+       /* Mapping the allocation file may lock the extent tree */
+       WARN_ON(mutex_is_locked(&HFSPLUS_SB(sb)->ext_tree->tree_lock));
+
        hfsplus_dump_extent(extent);
        for (i = 0; i < 8; extent++, i++) {
                count = be32_to_cpu(extent->block_count);
@@ -415,11 +418,13 @@ int hfsplus_free_fork(struct super_block *sb, u32 cnid,
                if (res)
                        break;
                start = be32_to_cpu(fd.key->ext.start_block);
-               hfsplus_free_extents(sb, ext_entry,
-                                    total_blocks - start,
-                                    total_blocks);
                hfs_brec_remove(&fd);
+
+               mutex_unlock(&fd.tree->tree_lock);
+               hfsplus_free_extents(sb, ext_entry, total_blocks - start,
+                                    total_blocks);
                total_blocks = start;
+               mutex_lock(&fd.tree->tree_lock);
        } while (total_blocks > blocks);
        hfs_find_exit(&fd);
 
@@ -576,15 +581,20 @@ void hfsplus_file_truncate(struct inode *inode)
        }
        while (1) {
                if (alloc_cnt == hip->first_blocks) {
+                       mutex_unlock(&fd.tree->tree_lock);
                        hfsplus_free_extents(sb, hip->first_extents,
                                             alloc_cnt, alloc_cnt - blk_cnt);
                        hfsplus_dump_extent(hip->first_extents);
                        hip->first_blocks = blk_cnt;
+                       mutex_lock(&fd.tree->tree_lock);
                        break;
                }
                res = __hfsplus_ext_cache_extent(&fd, inode, alloc_cnt);
                if (res)
                        break;
+               hfs_brec_remove(&fd);
+
+               mutex_unlock(&fd.tree->tree_lock);
                start = hip->cached_start;
                hfsplus_free_extents(sb, hip->cached_extents,
                                     alloc_cnt - start, alloc_cnt - blk_cnt);
@@ -596,7 +606,7 @@ void hfsplus_file_truncate(struct inode *inode)
                alloc_cnt = start;
                hip->cached_start = hip->cached_blocks = 0;
                hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW);
-               hfs_brec_remove(&fd);
+               mutex_lock(&fd.tree->tree_lock);
        }
        hfs_find_exit(&fd);
 
index d9255abafb81ff594d69490531fe865874ca034e..8e039435958a82700dd22aea4cf7b99fa80b6448 100644 (file)
@@ -31,7 +31,6 @@
 #define DBG_EXTENT     0x00000020
 #define DBG_BITMAP     0x00000040
 #define DBG_ATTR_MOD   0x00000080
-#define DBG_ACL_MOD    0x00000100
 
 #if 0
 #define DBG_MASK       (DBG_EXTENT|DBG_INODE|DBG_BNODE_MOD)
index c824f702feec438eb1cbd59aa721ba19ea280a25..8e9427a42b8195e95c77fab60eae4e84e8b51674 100644 (file)
@@ -21,7 +21,6 @@
 #include "hfsplus_fs.h"
 #include "hfsplus_raw.h"
 #include "xattr.h"
-#include "acl.h"
 
 static int hfsplus_readpage(struct file *file, struct page *page)
 {
@@ -267,12 +266,6 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr)
        setattr_copy(inode, attr);
        mark_inode_dirty(inode);
 
-       if (attr->ia_valid & ATTR_MODE) {
-               error = posix_acl_chmod(inode, inode->i_mode);
-               if (unlikely(error))
-                       return error;
-       }
-
        return 0;
 }
 
@@ -336,10 +329,6 @@ int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end,
 static const struct inode_operations hfsplus_file_inode_operations = {
        .setattr        = hfsplus_setattr,
        .listxattr      = hfsplus_listxattr,
-#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
-       .get_acl        = hfsplus_get_posix_acl,
-       .set_acl        = hfsplus_set_posix_acl,
-#endif
 };
 
 static const struct file_operations hfsplus_file_operations = {
diff --git a/fs/hfsplus/posix_acl.c b/fs/hfsplus/posix_acl.c
deleted file mode 100644 (file)
index 066114d..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * linux/fs/hfsplus/posix_acl.c
- *
- * Vyacheslav Dubeyko <slava@dubeyko.com>
- *
- * Handler for Posix Access Control Lists (ACLs) support.
- */
-
-#include "hfsplus_fs.h"
-#include "xattr.h"
-#include "acl.h"
-
-struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type)
-{
-       struct posix_acl *acl;
-       char *xattr_name;
-       char *value = NULL;
-       ssize_t size;
-
-       hfs_dbg(ACL_MOD, "[%s]: ino %lu\n", __func__, inode->i_ino);
-
-       switch (type) {
-       case ACL_TYPE_ACCESS:
-               xattr_name = XATTR_NAME_POSIX_ACL_ACCESS;
-               break;
-       case ACL_TYPE_DEFAULT:
-               xattr_name = XATTR_NAME_POSIX_ACL_DEFAULT;
-               break;
-       default:
-               return ERR_PTR(-EINVAL);
-       }
-
-       size = __hfsplus_getxattr(inode, xattr_name, NULL, 0);
-
-       if (size > 0) {
-               value = (char *)hfsplus_alloc_attr_entry();
-               if (unlikely(!value))
-                       return ERR_PTR(-ENOMEM);
-               size = __hfsplus_getxattr(inode, xattr_name, value, size);
-       }
-
-       if (size > 0)
-               acl = posix_acl_from_xattr(&init_user_ns, value, size);
-       else if (size == -ENODATA)
-               acl = NULL;
-       else
-               acl = ERR_PTR(size);
-
-       hfsplus_destroy_attr_entry((hfsplus_attr_entry *)value);
-
-       return acl;
-}
-
-static int __hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
-                                  int type)
-{
-       int err;
-       char *xattr_name;
-       size_t size = 0;
-       char *value = NULL;
-
-       hfs_dbg(ACL_MOD, "[%s]: ino %lu\n", __func__, inode->i_ino);
-
-       switch (type) {
-       case ACL_TYPE_ACCESS:
-               xattr_name = XATTR_NAME_POSIX_ACL_ACCESS;
-               break;
-
-       case ACL_TYPE_DEFAULT:
-               xattr_name = XATTR_NAME_POSIX_ACL_DEFAULT;
-               if (!S_ISDIR(inode->i_mode))
-                       return acl ? -EACCES : 0;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       if (acl) {
-               size = posix_acl_xattr_size(acl->a_count);
-               if (unlikely(size > HFSPLUS_MAX_INLINE_DATA_SIZE))
-                       return -ENOMEM;
-               value = (char *)hfsplus_alloc_attr_entry();
-               if (unlikely(!value))
-                       return -ENOMEM;
-               err = posix_acl_to_xattr(&init_user_ns, acl, value, size);
-               if (unlikely(err < 0))
-                       goto end_set_acl;
-       }
-
-       err = __hfsplus_setxattr(inode, xattr_name, value, size, 0);
-
-end_set_acl:
-       hfsplus_destroy_attr_entry((hfsplus_attr_entry *)value);
-
-       if (!err)
-               set_cached_acl(inode, type, acl);
-
-       return err;
-}
-
-int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl, int type)
-{
-       int err;
-
-       if (type == ACL_TYPE_ACCESS && acl) {
-               err = posix_acl_update_mode(inode, &inode->i_mode, &acl);
-               if (err)
-                       return err;
-       }
-       return __hfsplus_set_posix_acl(inode, acl, type);
-}
-
-int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir)
-{
-       int err = 0;
-       struct posix_acl *default_acl, *acl;
-
-       hfs_dbg(ACL_MOD,
-               "[%s]: ino %lu, dir->ino %lu\n",
-               __func__, inode->i_ino, dir->i_ino);
-
-       if (S_ISLNK(inode->i_mode))
-               return 0;
-
-       err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
-       if (err)
-               return err;
-
-       if (default_acl) {
-               err = __hfsplus_set_posix_acl(inode, default_acl,
-                                             ACL_TYPE_DEFAULT);
-               posix_acl_release(default_acl);
-       }
-
-       if (acl) {
-               if (!err)
-                       err = __hfsplus_set_posix_acl(inode, acl,
-                                                     ACL_TYPE_ACCESS);
-               posix_acl_release(acl);
-       }
-       return err;
-}
index a6c0f54c48c30f25315865f8080d412fb428c00a..eb4535eba95d9a5e13dfda5fb196849a069bda64 100644 (file)
@@ -524,8 +524,10 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
                goto out_put_root;
        if (!hfs_brec_read(&fd, &entry, sizeof(entry))) {
                hfs_find_exit(&fd);
-               if (entry.type != cpu_to_be16(HFSPLUS_FOLDER))
+               if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) {
+                       err = -EINVAL;
                        goto out_put_root;
+               }
                inode = hfsplus_iget(sb, be32_to_cpu(entry.folder.id));
                if (IS_ERR(inode)) {
                        err = PTR_ERR(inode);
@@ -562,8 +564,8 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
                                goto out_put_hidden_dir;
                        }
 
-                       err = hfsplus_init_inode_security(sbi->hidden_dir,
-                                                               root, &str);
+                       err = hfsplus_init_security(sbi->hidden_dir,
+                                                       root, &str);
                        if (err == -EOPNOTSUPP)
                                err = 0; /* Operation is not supported. */
                        else if (err) {
index dfa90c21948f82a34b6eedfab2bfdd8b1c996ef3..c8d1b2be7854ea5a829dfe6749121d0a70182903 100644 (file)
@@ -272,8 +272,8 @@ static inline int asc2unichar(struct super_block *sb, const char *astr, int len,
        return size;
 }
 
-/* Decomposes a single unicode character. */
-static inline u16 *decompose_unichar(wchar_t uc, int *size)
+/* Decomposes a non-Hangul unicode character. */
+static u16 *hfsplus_decompose_nonhangul(wchar_t uc, int *size)
 {
        int off;
 
@@ -296,6 +296,51 @@ static inline u16 *decompose_unichar(wchar_t uc, int *size)
        return hfsplus_decompose_table + (off / 4);
 }
 
+/*
+ * Try to decompose a unicode character as Hangul. Return 0 if @uc is not
+ * precomposed Hangul, otherwise return the length of the decomposition.
+ *
+ * This function was adapted from sample code from the Unicode Standard
+ * Annex #15: Unicode Normalization Forms, version 3.2.0.
+ *
+ * Copyright (C) 1991-2018 Unicode, Inc.  All rights reserved.  Distributed
+ * under the Terms of Use in http://www.unicode.org/copyright.html.
+ */
+static int hfsplus_try_decompose_hangul(wchar_t uc, u16 *result)
+{
+       int index;
+       int l, v, t;
+
+       index = uc - Hangul_SBase;
+       if (index < 0 || index >= Hangul_SCount)
+               return 0;
+
+       l = Hangul_LBase + index / Hangul_NCount;
+       v = Hangul_VBase + (index % Hangul_NCount) / Hangul_TCount;
+       t = Hangul_TBase + index % Hangul_TCount;
+
+       result[0] = l;
+       result[1] = v;
+       if (t != Hangul_TBase) {
+               result[2] = t;
+               return 3;
+       }
+       return 2;
+}
+
+/* Decomposes a single unicode character. */
+static u16 *decompose_unichar(wchar_t uc, int *size, u16 *hangul_buffer)
+{
+       u16 *result;
+
+       /* Hangul is handled separately */
+       result = hangul_buffer;
+       *size = hfsplus_try_decompose_hangul(uc, result);
+       if (*size == 0)
+               result = hfsplus_decompose_nonhangul(uc, size);
+       return result;
+}
+
 int hfsplus_asc2uni(struct super_block *sb,
                    struct hfsplus_unistr *ustr, int max_unistr_len,
                    const char *astr, int len)
@@ -303,13 +348,14 @@ int hfsplus_asc2uni(struct super_block *sb,
        int size, dsize, decompose;
        u16 *dstr, outlen = 0;
        wchar_t c;
+       u16 dhangul[3];
 
        decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
        while (outlen < max_unistr_len && len > 0) {
                size = asc2unichar(sb, astr, len, &c);
 
                if (decompose)
-                       dstr = decompose_unichar(c, &dsize);
+                       dstr = decompose_unichar(c, &dsize, dhangul);
                else
                        dstr = NULL;
                if (dstr) {
@@ -344,6 +390,7 @@ int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str)
        unsigned long hash;
        wchar_t c;
        u16 c2;
+       u16 dhangul[3];
 
        casefold = test_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);
        decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
@@ -357,7 +404,7 @@ int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str)
                len -= size;
 
                if (decompose)
-                       dstr = decompose_unichar(c, &dsize);
+                       dstr = decompose_unichar(c, &dsize, dhangul);
                else
                        dstr = NULL;
                if (dstr) {
@@ -396,6 +443,7 @@ int hfsplus_compare_dentry(const struct dentry *dentry,
        const char *astr1, *astr2;
        u16 c1, c2;
        wchar_t c;
+       u16 dhangul_1[3], dhangul_2[3];
 
        casefold = test_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);
        decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
@@ -413,7 +461,8 @@ int hfsplus_compare_dentry(const struct dentry *dentry,
                        len1 -= size;
 
                        if (decompose)
-                               dstr1 = decompose_unichar(c, &dsize1);
+                               dstr1 = decompose_unichar(c, &dsize1,
+                                                         dhangul_1);
                        if (!decompose || !dstr1) {
                                c1 = c;
                                dstr1 = &c1;
@@ -427,7 +476,8 @@ int hfsplus_compare_dentry(const struct dentry *dentry,
                        len2 -= size;
 
                        if (decompose)
-                               dstr2 = decompose_unichar(c, &dsize2);
+                               dstr2 = decompose_unichar(c, &dsize2,
+                                                         dhangul_2);
                        if (!decompose || !dstr2) {
                                c2 = c;
                                dstr2 = &c2;
index e538b758c448bef6beaaf8d7558b20ef04f82eaf..d5403b4004c97ffd4e3b7d8e59fd3b61051217b4 100644 (file)
@@ -8,10 +8,8 @@
  */
 
 #include "hfsplus_fs.h"
-#include <linux/posix_acl_xattr.h>
 #include <linux/nls.h>
 #include "xattr.h"
-#include "acl.h"
 
 static int hfsplus_removexattr(struct inode *inode, const char *name);
 
@@ -19,10 +17,6 @@ const struct xattr_handler *hfsplus_xattr_handlers[] = {
        &hfsplus_xattr_osx_handler,
        &hfsplus_xattr_user_handler,
        &hfsplus_xattr_trusted_handler,
-#ifdef CONFIG_HFSPLUS_FS_POSIX_ACL
-       &posix_acl_access_xattr_handler,
-       &posix_acl_default_xattr_handler,
-#endif
        &hfsplus_xattr_security_handler,
        NULL
 };
index a4e611d697104ba0b0e81bbf4884bb4aeb8dd1f4..d14e362b3ebaf7a4a13639067526eb910c03909e 100644 (file)
@@ -38,7 +38,4 @@ ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size);
 int hfsplus_init_security(struct inode *inode, struct inode *dir,
                                const struct qstr *qstr);
 
-int hfsplus_init_inode_security(struct inode *inode, struct inode *dir,
-                               const struct qstr *qstr);
-
 #endif
index f5550b006e8810bd43d5c2680bf80f55b3fcd511..cfbe6a3bfb1ee2e0c4123009e53d253c9bd2a5ec 100644 (file)
@@ -12,7 +12,6 @@
 
 #include "hfsplus_fs.h"
 #include "xattr.h"
-#include "acl.h"
 
 static int hfsplus_security_getxattr(const struct xattr_handler *handler,
                                     struct dentry *unused, struct inode *inode,
@@ -72,18 +71,6 @@ int hfsplus_init_security(struct inode *inode, struct inode *dir,
                                        &hfsplus_initxattrs, NULL);
 }
 
-int hfsplus_init_inode_security(struct inode *inode,
-                                               struct inode *dir,
-                                               const struct qstr *qstr)
-{
-       int err;
-
-       err = hfsplus_init_posix_acl(inode, dir);
-       if (!err)
-               err = hfsplus_init_security(inode, dir, qstr);
-       return err;
-}
-
 const struct xattr_handler hfsplus_xattr_security_handler = {
        .prefix = XATTR_SECURITY_PREFIX,
        .get    = hfsplus_security_getxattr,
index 082b7c76dd0c91cc245f842b77becd520e1fb84c..1aee39160ac5b14d49c3cb604aafede94aa4e1ae 100644 (file)
@@ -565,7 +565,7 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                        err = -EFSERROR;
                        goto end1;
                }
-               err = r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0;
+               err = -ENOSPC;
                goto end1;
        }
 
index 346a146c7617d10ab34ae8eb1bb5d6641e734d88..32920a10100e23fc60f53cf36c882278ae972cee 100644 (file)
@@ -410,7 +410,6 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
        int i, freed = 0;
        bool truncate_op = (lend == LLONG_MAX);
 
-       memset(&pseudo_vma, 0, sizeof(struct vm_area_struct));
        vma_init(&pseudo_vma, current->mm);
        pseudo_vma.vm_flags = (VM_HUGETLB | VM_MAYSHARE | VM_SHARED);
        pagevec_init(&pvec);
@@ -595,7 +594,6 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset,
         * allocation routines.  If NUMA is configured, use page index
         * as input to create an allocation policy.
         */
-       memset(&pseudo_vma, 0, sizeof(struct vm_area_struct));
        vma_init(&pseudo_vma, mm);
        pseudo_vma.vm_flags = (VM_HUGETLB | VM_MAYSHARE | VM_SHARED);
        pseudo_vma.vm_file = file;
index a06de44542325a2848a3882774df0959d1dfa17b..42f6d25f32a52048199bdcf138bc23a698e69666 100644 (file)
@@ -1595,50 +1595,17 @@ sector_t bmap(struct inode *inode, sector_t block)
 }
 EXPORT_SYMBOL(bmap);
 
-/*
- * Update times in overlayed inode from underlying real inode
- */
-static void update_ovl_inode_times(struct dentry *dentry, struct inode *inode,
-                              bool rcu)
-{
-       struct dentry *upperdentry;
-
-       /*
-        * Nothing to do if in rcu or if non-overlayfs
-        */
-       if (rcu || likely(!(dentry->d_flags & DCACHE_OP_REAL)))
-               return;
-
-       upperdentry = d_real(dentry, NULL, 0, D_REAL_UPPER);
-
-       /*
-        * If file is on lower then we can't update atime, so no worries about
-        * stale mtime/ctime.
-        */
-       if (upperdentry) {
-               struct inode *realinode = d_inode(upperdentry);
-
-               if ((!timespec64_equal(&inode->i_mtime, &realinode->i_mtime) ||
-                    !timespec64_equal(&inode->i_ctime, &realinode->i_ctime))) {
-                       inode->i_mtime = realinode->i_mtime;
-                       inode->i_ctime = realinode->i_ctime;
-               }
-       }
-}
-
 /*
  * With relative atime, only update atime if the previous atime is
  * earlier than either the ctime or mtime or if at least a day has
  * passed since the last atime update.
  */
-static int relatime_need_update(const struct path *path, struct inode *inode,
-                               struct timespec now, bool rcu)
+static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
+                            struct timespec now)
 {
 
-       if (!(path->mnt->mnt_flags & MNT_RELATIME))
+       if (!(mnt->mnt_flags & MNT_RELATIME))
                return 1;
-
-       update_ovl_inode_times(path->dentry, inode, rcu);
        /*
         * Is mtime younger than atime? If yes, update atime:
         */
@@ -1709,8 +1676,7 @@ static int update_time(struct inode *inode, struct timespec64 *time, int flags)
  *     This function automatically handles read only file systems and media,
  *     as well as the "noatime" flag and inode specific "noatime" markers.
  */
-bool __atime_needs_update(const struct path *path, struct inode *inode,
-                         bool rcu)
+bool atime_needs_update(const struct path *path, struct inode *inode)
 {
        struct vfsmount *mnt = path->mnt;
        struct timespec64 now;
@@ -1736,7 +1702,7 @@ bool __atime_needs_update(const struct path *path, struct inode *inode,
 
        now = current_time(inode);
 
-       if (!relatime_need_update(path, inode, timespec64_to_timespec(now), rcu))
+       if (!relatime_need_update(mnt, inode, timespec64_to_timespec(now)))
                return false;
 
        if (timespec64_equal(&inode->i_atime, &now))
@@ -1751,7 +1717,7 @@ void touch_atime(const struct path *path)
        struct inode *inode = d_inode(path->dentry);
        struct timespec64 now;
 
-       if (!__atime_needs_update(path, inode, false))
+       if (!atime_needs_update(path, inode))
                return;
 
        if (!sb_start_write_trylock(inode->i_sb))
index 50a28fc71300667838c692f601f9787e2acd8759..d410186bc369f9625d492387e3a99e6bcbb99703 100644 (file)
@@ -82,10 +82,8 @@ extern void __init mnt_init(void);
 
 extern int __mnt_want_write(struct vfsmount *);
 extern int __mnt_want_write_file(struct file *);
-extern int mnt_want_write_file_path(struct file *);
 extern void __mnt_drop_write(struct vfsmount *);
 extern void __mnt_drop_write_file(struct file *);
-extern void mnt_drop_write_file_path(struct file *);
 
 /*
  * fs_struct.c
@@ -96,6 +94,7 @@ extern void chroot_fs_refs(const struct path *, const struct path *);
  * file_table.c
  */
 extern struct file *alloc_empty_file(int, const struct cred *);
+extern struct file *alloc_empty_file_noaccount(int, const struct cred *);
 
 /*
  * super.c
@@ -136,13 +135,6 @@ extern long prune_icache_sb(struct super_block *sb, struct shrink_control *sc);
 extern void inode_add_lru(struct inode *inode);
 extern int dentry_needs_remove_privs(struct dentry *dentry);
 
-extern bool __atime_needs_update(const struct path *, struct inode *, bool);
-static inline bool atime_needs_update_rcu(const struct path *path,
-                                         struct inode *inode)
-{
-       return __atime_needs_update(path, inode, true);
-}
-
 /*
  * fs-writeback.c
  */
@@ -185,7 +177,6 @@ extern const struct dentry_operations ns_dentry_operations;
  */
 extern int do_vfs_ioctl(struct file *file, unsigned int fd, unsigned int cmd,
                    unsigned long arg);
-extern long vfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 
 /*
  * iomap support:
index b445b13fc59bd99cea023dc5835674833da4bd6e..3212c29235ce34d21dedc26ea569978d45462706 100644 (file)
@@ -49,6 +49,7 @@ long vfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  out:
        return error;
 }
+EXPORT_SYMBOL(vfs_ioctl);
 
 static int ioctl_fibmap(struct file *filp, int __user *p)
 {
index 009071e73bc0bb46e368f792859d492a93cbd366..74762b1ec233f9e9ab1f5da47116271143a344db 100644 (file)
@@ -290,7 +290,7 @@ iomap_readpage_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
        sector_t sector;
 
        if (iomap->type == IOMAP_INLINE) {
-               WARN_ON_ONCE(poff);
+               WARN_ON_ONCE(pos);
                iomap_read_inline_data(inode, page, iomap);
                return PAGE_SIZE;
        }
index ec3fba7d492f483e14accbfd98d5b63550f2591c..488a9e7f8f66020f4424b322db62eacdcbbdd057 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/mpage.h>
 #include <linux/user_namespace.h>
 #include <linux/seq_file.h>
+#include <linux/blkdev.h>
 
 #include "isofs.h"
 #include "zisofs.h"
@@ -653,6 +654,12 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
        /*
         * What if bugger tells us to go beyond page size?
         */
+       if (bdev_logical_block_size(s->s_bdev) > 2048) {
+               printk(KERN_WARNING
+                      "ISOFS: unsupported/invalid hardware sector size %d\n",
+                       bdev_logical_block_size(s->s_bdev));
+               goto out_freesbi;
+       }
        opt.blocksize = sb_min_blocksize(s, opt.blocksize);
 
        sbi->s_high_sierra = 0; /* default is iso9660 */
index 96c1d14c18f12fd6d61e74344c6d28d3e6cf2730..c2a128678e6e596ffebdc43db0989bbbd83ee1f4 100644 (file)
@@ -187,7 +187,7 @@ __be32 nlmclnt_grant(const struct sockaddr *addr, const struct nlm_lock *lock)
                        continue;
                if (!rpc_cmp_addr(nlm_addr(block->b_host), addr))
                        continue;
-               if (nfs_compare_fh(NFS_FH(file_inode(fl_blocked->fl_file)) ,fh) != 0)
+               if (nfs_compare_fh(NFS_FH(locks_inode(fl_blocked->fl_file)), fh) != 0)
                        continue;
                /* Alright, we found a lock. Set the return status
                 * and wake up the caller
index a2c0dfc6fdc0017c2e9f41d3dc4d6dd0d6b4fce0..d20b92f271c2341bbd323de93d76da0c65d904d7 100644 (file)
@@ -128,7 +128,7 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl)
        char *nodename = req->a_host->h_rpcclnt->cl_nodename;
 
        nlmclnt_next_cookie(&argp->cookie);
-       memcpy(&lock->fh, NFS_FH(file_inode(fl->fl_file)), sizeof(struct nfs_fh));
+       memcpy(&lock->fh, NFS_FH(locks_inode(fl->fl_file)), sizeof(struct nfs_fh));
        lock->caller  = nodename;
        lock->oh.data = req->a_owner;
        lock->oh.len  = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s",
index 3701bccab478638be018a0dfe9840915c78ccbb3..74330daeab7177149c8a85b5b3e9eb0593e3a126 100644 (file)
@@ -405,8 +405,8 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
        __be32                  ret;
 
        dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n",
-                               file_inode(file->f_file)->i_sb->s_id,
-                               file_inode(file->f_file)->i_ino,
+                               locks_inode(file->f_file)->i_sb->s_id,
+                               locks_inode(file->f_file)->i_ino,
                                lock->fl.fl_type, lock->fl.fl_pid,
                                (long long)lock->fl.fl_start,
                                (long long)lock->fl.fl_end,
@@ -511,8 +511,8 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
        __be32                  ret;
 
        dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
-                               file_inode(file->f_file)->i_sb->s_id,
-                               file_inode(file->f_file)->i_ino,
+                               locks_inode(file->f_file)->i_sb->s_id,
+                               locks_inode(file->f_file)->i_ino,
                                lock->fl.fl_type,
                                (long long)lock->fl.fl_start,
                                (long long)lock->fl.fl_end);
@@ -566,8 +566,8 @@ nlmsvc_unlock(struct net *net, struct nlm_file *file, struct nlm_lock *lock)
        int     error;
 
        dprintk("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n",
-                               file_inode(file->f_file)->i_sb->s_id,
-                               file_inode(file->f_file)->i_ino,
+                               locks_inode(file->f_file)->i_sb->s_id,
+                               locks_inode(file->f_file)->i_ino,
                                lock->fl.fl_pid,
                                (long long)lock->fl.fl_start,
                                (long long)lock->fl.fl_end);
@@ -595,8 +595,8 @@ nlmsvc_cancel_blocked(struct net *net, struct nlm_file *file, struct nlm_lock *l
        int status = 0;
 
        dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n",
-                               file_inode(file->f_file)->i_sb->s_id,
-                               file_inode(file->f_file)->i_ino,
+                               locks_inode(file->f_file)->i_sb->s_id,
+                               locks_inode(file->f_file)->i_ino,
                                lock->fl.fl_pid,
                                (long long)lock->fl.fl_start,
                                (long long)lock->fl.fl_end);
index 4ec3d6e03e76dc0909c25fd90b4c9e2ee0dd33a8..899360ba3b8486857db0654ee329eb6ba05563fb 100644 (file)
@@ -44,7 +44,7 @@ static inline void nlm_debug_print_fh(char *msg, struct nfs_fh *f)
 
 static inline void nlm_debug_print_file(char *msg, struct nlm_file *file)
 {
-       struct inode *inode = file_inode(file->f_file);
+       struct inode *inode = locks_inode(file->f_file);
 
        dprintk("lockd: %s %s/%ld\n",
                msg, inode->i_sb->s_id, inode->i_ino);
@@ -414,7 +414,7 @@ nlmsvc_match_sb(void *datap, struct nlm_file *file)
 {
        struct super_block *sb = datap;
 
-       return sb == file_inode(file->f_file)->i_sb;
+       return sb == locks_inode(file->f_file)->i_sb;
 }
 
 /**
index bc047a7edc476e96d6e6a729de2884c292f4dc72..2ecb4db8c840ec7d2174422ceebf9a88dc4706a3 100644 (file)
 #define IS_OFDLCK(fl)  (fl->fl_flags & FL_OFDLCK)
 #define IS_REMOTELCK(fl)       (fl->fl_pid <= 0)
 
-static inline bool is_remote_lock(struct file *filp)
-{
-       return likely(!(filp->f_path.dentry->d_sb->s_flags & SB_NOREMOTELOCK));
-}
-
 static bool lease_breaking(struct file_lock *fl)
 {
        return fl->fl_flags & (FL_UNLOCK_PENDING | FL_DOWNGRADE_PENDING);
@@ -542,7 +537,7 @@ lease_setup(struct file_lock *fl, void **priv)
        if (!fasync_insert_entry(fa->fa_fd, filp, &fl->fl_fasync, fa))
                *priv = NULL;
 
-       __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
+       __f_setown(filp, task_pid(current), PIDTYPE_TGID, 0);
 }
 
 static const struct lock_manager_operations lease_manager_ops = {
@@ -1651,8 +1646,7 @@ check_conflicting_open(const struct dentry *dentry, const long arg, int flags)
        if (flags & FL_LAYOUT)
                return 0;
 
-       if ((arg == F_RDLCK) &&
-           (atomic_read(&d_real_inode(dentry)->i_writecount) > 0))
+       if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
                return -EAGAIN;
 
        if ((arg == F_WRLCK) && ((d_count(dentry) > 1) ||
@@ -1873,7 +1867,7 @@ EXPORT_SYMBOL(generic_setlease);
 int
 vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv)
 {
-       if (filp->f_op->setlease && is_remote_lock(filp))
+       if (filp->f_op->setlease)
                return filp->f_op->setlease(filp, arg, lease, priv);
        else
                return generic_setlease(filp, arg, lease, priv);
@@ -2020,7 +2014,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
        if (error)
                goto out_free;
 
-       if (f.file->f_op->flock && is_remote_lock(f.file))
+       if (f.file->f_op->flock)
                error = f.file->f_op->flock(f.file,
                                          (can_sleep) ? F_SETLKW : F_SETLK,
                                          lock);
@@ -2046,7 +2040,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
  */
 int vfs_test_lock(struct file *filp, struct file_lock *fl)
 {
-       if (filp->f_op->lock && is_remote_lock(filp))
+       if (filp->f_op->lock)
                return filp->f_op->lock(filp, F_GETLK, fl);
        posix_test_lock(filp, fl);
        return 0;
@@ -2196,7 +2190,7 @@ out:
  */
 int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf)
 {
-       if (filp->f_op->lock && is_remote_lock(filp))
+       if (filp->f_op->lock)
                return filp->f_op->lock(filp, cmd, fl);
        else
                return posix_lock_file(filp, fl, conf);
@@ -2518,7 +2512,7 @@ locks_remove_flock(struct file *filp, struct file_lock_context *flctx)
        if (list_empty(&flctx->flc_flock))
                return;
 
-       if (filp->f_op->flock && is_remote_lock(filp))
+       if (filp->f_op->flock)
                filp->f_op->flock(filp, F_SETLKW, &fl);
        else
                flock_lock_inode(inode, &fl);
@@ -2605,7 +2599,7 @@ EXPORT_SYMBOL(posix_unblock_lock);
  */
 int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
 {
-       if (filp->f_op->lock && is_remote_lock(filp))
+       if (filp->f_op->lock)
                return filp->f_op->lock(filp, F_CANCELLK, fl);
        return 0;
 }
index 3cd396277cd3986a6f5c2d6da7de7d123de4cff6..0cab6494978c1295b965f503422bdbeacff6ccc4 100644 (file)
@@ -887,6 +887,8 @@ static inline void put_link(struct nameidata *nd)
 
 int sysctl_protected_symlinks __read_mostly = 0;
 int sysctl_protected_hardlinks __read_mostly = 0;
+int sysctl_protected_fifos __read_mostly;
+int sysctl_protected_regular __read_mostly;
 
 /**
  * may_follow_link - Check symlink following for unsafe situations
@@ -1003,6 +1005,45 @@ static int may_linkat(struct path *link)
        return -EPERM;
 }
 
+/**
+ * may_create_in_sticky - Check whether an O_CREAT open in a sticky directory
+ *                       should be allowed, or not, on files that already
+ *                       exist.
+ * @dir: the sticky parent directory
+ * @inode: the inode of the file to open
+ *
+ * Block an O_CREAT open of a FIFO (or a regular file) when:
+ *   - sysctl_protected_fifos (or sysctl_protected_regular) is enabled
+ *   - the file already exists
+ *   - we are in a sticky directory
+ *   - we don't own the file
+ *   - the owner of the directory doesn't own the file
+ *   - the directory is world writable
+ * If the sysctl_protected_fifos (or sysctl_protected_regular) is set to 2
+ * the directory doesn't have to be world writable: being group writable will
+ * be enough.
+ *
+ * Returns 0 if the open is allowed, -ve on error.
+ */
+static int may_create_in_sticky(struct dentry * const dir,
+                               struct inode * const inode)
+{
+       if ((!sysctl_protected_fifos && S_ISFIFO(inode->i_mode)) ||
+           (!sysctl_protected_regular && S_ISREG(inode->i_mode)) ||
+           likely(!(dir->d_inode->i_mode & S_ISVTX)) ||
+           uid_eq(inode->i_uid, dir->d_inode->i_uid) ||
+           uid_eq(current_fsuid(), inode->i_uid))
+               return 0;
+
+       if (likely(dir->d_inode->i_mode & 0002) ||
+           (dir->d_inode->i_mode & 0020 &&
+            ((sysctl_protected_fifos >= 2 && S_ISFIFO(inode->i_mode)) ||
+             (sysctl_protected_regular >= 2 && S_ISREG(inode->i_mode))))) {
+               return -EACCES;
+       }
+       return 0;
+}
+
 static __always_inline
 const char *get_link(struct nameidata *nd)
 {
@@ -1015,7 +1056,7 @@ const char *get_link(struct nameidata *nd)
        if (!(nd->flags & LOOKUP_RCU)) {
                touch_atime(&last->link);
                cond_resched();
-       } else if (atime_needs_update_rcu(&last->link, inode)) {
+       } else if (atime_needs_update(&last->link, inode)) {
                if (unlikely(unlazy_walk(nd)))
                        return ERR_PTR(-ECHILD);
                touch_atime(&last->link);
@@ -3348,9 +3389,15 @@ finish_open:
        if (error)
                return error;
        audit_inode(nd->name, nd->path.dentry, 0);
-       error = -EISDIR;
-       if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry))
-               goto out;
+       if (open_flag & O_CREAT) {
+               error = -EISDIR;
+               if (d_is_dir(nd->path.dentry))
+                       goto out;
+               error = may_create_in_sticky(dir,
+                                            d_backing_inode(nd->path.dentry));
+               if (unlikely(error))
+                       goto out;
+       }
        error = -ENOTDIR;
        if ((nd->flags & LOOKUP_DIRECTORY) && !d_can_lookup(nd->path.dentry))
                goto out;
index bd2f4c68506afb79023c4423abebe392397c53ea..99186556f8d34ecfc89f27fb329b35dc2e42d114 100644 (file)
@@ -61,9 +61,6 @@ __setup("mphash_entries=", set_mphash_entries);
 static u64 event;
 static DEFINE_IDA(mnt_id_ida);
 static DEFINE_IDA(mnt_group_ida);
-static DEFINE_SPINLOCK(mnt_id_lock);
-static int mnt_id_start = 0;
-static int mnt_group_start = 1;
 
 static struct hlist_head *mount_hashtable __read_mostly;
 static struct hlist_head *mountpoint_hashtable __read_mostly;
@@ -101,50 +98,30 @@ static inline struct hlist_head *mp_hash(struct dentry *dentry)
 
 static int mnt_alloc_id(struct mount *mnt)
 {
-       int res;
+       int res = ida_alloc(&mnt_id_ida, GFP_KERNEL);
 
-retry:
-       ida_pre_get(&mnt_id_ida, GFP_KERNEL);
-       spin_lock(&mnt_id_lock);
-       res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id);
-       if (!res)
-               mnt_id_start = mnt->mnt_id + 1;
-       spin_unlock(&mnt_id_lock);
-       if (res == -EAGAIN)
-               goto retry;
-
-       return res;
+       if (res < 0)
+               return res;
+       mnt->mnt_id = res;
+       return 0;
 }
 
 static void mnt_free_id(struct mount *mnt)
 {
-       int id = mnt->mnt_id;
-       spin_lock(&mnt_id_lock);
-       ida_remove(&mnt_id_ida, id);
-       if (mnt_id_start > id)
-               mnt_id_start = id;
-       spin_unlock(&mnt_id_lock);
+       ida_free(&mnt_id_ida, mnt->mnt_id);
 }
 
 /*
  * Allocate a new peer group ID
- *
- * mnt_group_ida is protected by namespace_sem
  */
 static int mnt_alloc_group_id(struct mount *mnt)
 {
-       int res;
+       int res = ida_alloc_min(&mnt_group_ida, 1, GFP_KERNEL);
 
-       if (!ida_pre_get(&mnt_group_ida, GFP_KERNEL))
-               return -ENOMEM;
-
-       res = ida_get_new_above(&mnt_group_ida,
-                               mnt_group_start,
-                               &mnt->mnt_group_id);
-       if (!res)
-               mnt_group_start = mnt->mnt_group_id + 1;
-
-       return res;
+       if (res < 0)
+               return res;
+       mnt->mnt_group_id = res;
+       return 0;
 }
 
 /*
@@ -152,10 +129,7 @@ static int mnt_alloc_group_id(struct mount *mnt)
  */
 void mnt_release_group_id(struct mount *mnt)
 {
-       int id = mnt->mnt_group_id;
-       ida_remove(&mnt_group_ida, id);
-       if (mnt_group_start > id)
-               mnt_group_start = id;
+       ida_free(&mnt_group_ida, mnt->mnt_group_id);
        mnt->mnt_group_id = 0;
 }
 
@@ -430,75 +404,21 @@ int __mnt_want_write_file(struct file *file)
                return mnt_clone_write(file->f_path.mnt);
 }
 
-/**
- * mnt_want_write_file_path - get write access to a file's mount
- * @file: the file who's mount on which to take a write
- *
- * This is like mnt_want_write, but it takes a file and can
- * do some optimisations if the file is open for write already
- *
- * Called by the vfs for cases when we have an open file at hand, but will do an
- * inode operation on it (important distinction for files opened on overlayfs,
- * since the file operations will come from the real underlying file, while
- * inode operations come from the overlay).
- */
-int mnt_want_write_file_path(struct file *file)
-{
-       int ret;
-
-       sb_start_write(file->f_path.mnt->mnt_sb);
-       ret = __mnt_want_write_file(file);
-       if (ret)
-               sb_end_write(file->f_path.mnt->mnt_sb);
-       return ret;
-}
-
-static inline int may_write_real(struct file *file)
-{
-       struct dentry *dentry = file->f_path.dentry;
-       struct dentry *upperdentry;
-
-       /* Writable file? */
-       if (file->f_mode & FMODE_WRITER)
-               return 0;
-
-       /* Not overlayfs? */
-       if (likely(!(dentry->d_flags & DCACHE_OP_REAL)))
-               return 0;
-
-       /* File refers to upper, writable layer? */
-       upperdentry = d_real(dentry, NULL, 0, D_REAL_UPPER);
-       if (upperdentry &&
-           (file_inode(file) == d_inode(upperdentry) ||
-            file_inode(file) == d_inode(dentry)))
-               return 0;
-
-       /* Lower layer: can't write to real file, sorry... */
-       return -EPERM;
-}
-
 /**
  * mnt_want_write_file - get write access to a file's mount
  * @file: the file who's mount on which to take a write
  *
  * This is like mnt_want_write, but it takes a file and can
  * do some optimisations if the file is open for write already
- *
- * Mostly called by filesystems from their ioctl operation before performing
- * modification.  On overlayfs this needs to check if the file is on a read-only
- * lower layer and deny access in that case.
  */
 int mnt_want_write_file(struct file *file)
 {
        int ret;
 
-       ret = may_write_real(file);
-       if (!ret) {
-               sb_start_write(file_inode(file)->i_sb);
-               ret = __mnt_want_write_file(file);
-               if (ret)
-                       sb_end_write(file_inode(file)->i_sb);
-       }
+       sb_start_write(file_inode(file)->i_sb);
+       ret = __mnt_want_write_file(file);
+       if (ret)
+               sb_end_write(file_inode(file)->i_sb);
        return ret;
 }
 EXPORT_SYMBOL_GPL(mnt_want_write_file);
@@ -538,14 +458,9 @@ void __mnt_drop_write_file(struct file *file)
        __mnt_drop_write(file->f_path.mnt);
 }
 
-void mnt_drop_write_file_path(struct file *file)
-{
-       mnt_drop_write(file->f_path.mnt);
-}
-
 void mnt_drop_write_file(struct file *file)
 {
-       __mnt_drop_write(file->f_path.mnt);
+       __mnt_drop_write_file(file);
        sb_end_write(file_inode(file)->i_sb);
 }
 EXPORT_SYMBOL(mnt_drop_write_file);
index 7cb5c38c19e4f7386902740f9575a070bd15687b..06cb0c1d9aee37dff885f511fa4f8da6f5ec1914 100644 (file)
@@ -753,6 +753,7 @@ out:
        case -ENODEV:
                /* Our extent block devices are unavailable */
                set_bit(NFS_LSEG_UNAVAILABLE, &lseg->pls_flags);
+               /* Fall through */
        case 0:
                return lseg;
        default:
index a7efd83779d229400dc6ebe94d959b9895ef5b71..dec5880ac6de28aa393406e931c4a2f70d2a5fda 100644 (file)
@@ -204,7 +204,7 @@ static bool bl_map_stripe(struct pnfs_block_dev *dev, u64 offset,
        chunk = div_u64(offset, dev->chunk_size);
        div_u64_rem(chunk, dev->nr_children, &chunk_idx);
 
-       if (chunk_idx > dev->nr_children) {
+       if (chunk_idx >= dev->nr_children) {
                dprintk("%s: invalid chunk idx %d (%lld/%lld)\n",
                        __func__, chunk_idx, offset, dev->chunk_size);
                /* error, should not happen */
index a20a0bce40a48885453375cb3ab0c0ca5a3c3e53..8f34daf85f7036a1573f78d8e95f27347cd7c639 100644 (file)
@@ -184,6 +184,18 @@ struct cb_notify_lock_args {
 extern __be32 nfs4_callback_notify_lock(void *argp, void *resp,
                                         struct cb_process_state *cps);
 #endif /* CONFIG_NFS_V4_1 */
+#ifdef CONFIG_NFS_V4_2
+struct cb_offloadargs {
+       struct nfs_fh           coa_fh;
+       nfs4_stateid            coa_stateid;
+       uint32_t                error;
+       uint64_t                wr_count;
+       struct nfs_writeverf    wr_writeverf;
+};
+
+extern __be32 nfs4_callback_offload(void *args, void *dummy,
+                                   struct cb_process_state *cps);
+#endif /* CONFIG_NFS_V4_2 */
 extern int check_gss_callback_principal(struct nfs_client *, struct svc_rqst *);
 extern __be32 nfs4_callback_getattr(void *argp, void *resp,
                                    struct cb_process_state *cps);
index 64c214fb9da67d5ba0ce6fb732a6c3df963823cf..fa515d5ea5ba12e0e47fb0c6e3c67ea898bc0003 100644 (file)
@@ -215,9 +215,9 @@ static u32 pnfs_check_callback_stateid(struct pnfs_layout_hdr *lo,
 {
        u32 oldseq, newseq;
 
-       /* Is the stateid still not initialised? */
+       /* Is the stateid not initialised? */
        if (!pnfs_layout_is_valid(lo))
-               return NFS4ERR_DELAY;
+               return NFS4ERR_NOMATCHING_LAYOUT;
 
        /* Mismatched stateid? */
        if (!nfs4_stateid_match_other(&lo->plh_stateid, new))
@@ -273,7 +273,6 @@ static u32 initiate_file_draining(struct nfs_client *clp,
        rv = pnfs_check_callback_stateid(lo, &args->cbl_stateid);
        if (rv != NFS_OK)
                goto unlock;
-       pnfs_set_layout_stateid(lo, &args->cbl_stateid, true);
 
        /*
         * Enforce RFC5661 Section 12.5.5.2.1.5 (Bulk Recall and Return)
@@ -283,19 +282,23 @@ static u32 initiate_file_draining(struct nfs_client *clp,
                goto unlock;
        }
 
-       if (pnfs_mark_matching_lsegs_return(lo, &free_me_list,
+       pnfs_set_layout_stateid(lo, &args->cbl_stateid, true);
+       switch (pnfs_mark_matching_lsegs_return(lo, &free_me_list,
                                &args->cbl_range,
                                be32_to_cpu(args->cbl_stateid.seqid))) {
+       case 0:
+       case -EBUSY:
+               /* There are layout segments that need to be returned */
                rv = NFS4_OK;
-               goto unlock;
-       }
-
-       /* Embrace your forgetfulness! */
-       rv = NFS4ERR_NOMATCHING_LAYOUT;
+               break;
+       case -ENOENT:
+               /* Embrace your forgetfulness! */
+               rv = NFS4ERR_NOMATCHING_LAYOUT;
 
-       if (NFS_SERVER(ino)->pnfs_curr_ld->return_range) {
-               NFS_SERVER(ino)->pnfs_curr_ld->return_range(lo,
-                       &args->cbl_range);
+               if (NFS_SERVER(ino)->pnfs_curr_ld->return_range) {
+                       NFS_SERVER(ino)->pnfs_curr_ld->return_range(lo,
+                               &args->cbl_range);
+               }
        }
 unlock:
        spin_unlock(&ino->i_lock);
@@ -328,8 +331,6 @@ static u32 initiate_bulk_draining(struct nfs_client *clp,
 static u32 do_callback_layoutrecall(struct nfs_client *clp,
                                    struct cb_layoutrecallargs *args)
 {
-       write_seqcount_begin(&clp->cl_callback_count);
-       write_seqcount_end(&clp->cl_callback_count);
        if (args->cbl_recall_type == RETURN_FILE)
                return initiate_file_draining(clp, args);
        return initiate_bulk_draining(clp, args);
@@ -441,11 +442,14 @@ validate_seqid(const struct nfs4_slot_table *tbl, const struct nfs4_slot *slot,
  * a match.  If the slot is in use and the sequence numbers match, the
  * client is still waiting for a response to the original request.
  */
-static bool referring_call_exists(struct nfs_client *clp,
+static int referring_call_exists(struct nfs_client *clp,
                                  uint32_t nrclists,
-                                 struct referring_call_list *rclists)
+                                 struct referring_call_list *rclists,
+                                 spinlock_t *lock)
+       __releases(lock)
+       __acquires(lock)
 {
-       bool status = false;
+       int status = 0;
        int i, j;
        struct nfs4_session *session;
        struct nfs4_slot_table *tbl;
@@ -468,8 +472,10 @@ static bool referring_call_exists(struct nfs_client *clp,
 
                for (j = 0; j < rclist->rcl_nrefcalls; j++) {
                        ref = &rclist->rcl_refcalls[j];
+                       spin_unlock(lock);
                        status = nfs4_slot_wait_on_seqid(tbl, ref->rc_slotid,
                                        ref->rc_sequenceid, HZ >> 1) < 0;
+                       spin_lock(lock);
                        if (status)
                                goto out;
                }
@@ -546,7 +552,8 @@ __be32 nfs4_callback_sequence(void *argp, void *resp,
         * related callback was received before the response to the original
         * call.
         */
-       if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists)) {
+       if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists,
+                               &tbl->slot_tbl_lock) < 0) {
                status = htonl(NFS4ERR_DELAY);
                goto out_unlock;
        }
@@ -660,3 +667,57 @@ __be32 nfs4_callback_notify_lock(void *argp, void *resp,
        return htonl(NFS4_OK);
 }
 #endif /* CONFIG_NFS_V4_1 */
+#ifdef CONFIG_NFS_V4_2
+static void nfs4_copy_cb_args(struct nfs4_copy_state *cp_state,
+                               struct cb_offloadargs *args)
+{
+       cp_state->count = args->wr_count;
+       cp_state->error = args->error;
+       if (!args->error) {
+               cp_state->verf.committed = args->wr_writeverf.committed;
+               memcpy(&cp_state->verf.verifier.data[0],
+                       &args->wr_writeverf.verifier.data[0],
+                       NFS4_VERIFIER_SIZE);
+       }
+}
+
+__be32 nfs4_callback_offload(void *data, void *dummy,
+                            struct cb_process_state *cps)
+{
+       struct cb_offloadargs *args = data;
+       struct nfs_server *server;
+       struct nfs4_copy_state *copy;
+       bool found = false;
+
+       spin_lock(&cps->clp->cl_lock);
+       rcu_read_lock();
+       list_for_each_entry_rcu(server, &cps->clp->cl_superblocks,
+                               client_link) {
+               list_for_each_entry(copy, &server->ss_copies, copies) {
+                       if (memcmp(args->coa_stateid.other,
+                                       copy->stateid.other,
+                                       sizeof(args->coa_stateid.other)))
+                               continue;
+                       nfs4_copy_cb_args(copy, args);
+                       complete(&copy->completion);
+                       found = true;
+                       goto out;
+               }
+       }
+out:
+       rcu_read_unlock();
+       if (!found) {
+               copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_NOFS);
+               if (!copy) {
+                       spin_unlock(&cps->clp->cl_lock);
+                       return htonl(NFS4ERR_SERVERFAULT);
+               }
+               memcpy(&copy->stateid, &args->coa_stateid, NFS4_STATEID_SIZE);
+               nfs4_copy_cb_args(copy, args);
+               list_add_tail(&copy->copies, &cps->clp->pending_cb_stateids);
+       }
+       spin_unlock(&cps->clp->cl_lock);
+
+       return 0;
+}
+#endif /* CONFIG_NFS_V4_2 */
index a813979b5be0c7b6491d3ca0843f6c63945ac959..a87a562734077c221884edaf7962086af6e7a643 100644 (file)
@@ -38,6 +38,9 @@
 #define CB_OP_RECALLSLOT_RES_MAXSZ     (CB_OP_HDR_RES_MAXSZ)
 #define CB_OP_NOTIFY_LOCK_RES_MAXSZ    (CB_OP_HDR_RES_MAXSZ)
 #endif /* CONFIG_NFS_V4_1 */
+#ifdef CONFIG_NFS_V4_2
+#define CB_OP_OFFLOAD_RES_MAXSZ                (CB_OP_HDR_RES_MAXSZ)
+#endif /* CONFIG_NFS_V4_2 */
 
 #define NFSDBG_FACILITY NFSDBG_CALLBACK
 
@@ -527,7 +530,72 @@ static __be32 decode_notify_lock_args(struct svc_rqst *rqstp,
 }
 
 #endif /* CONFIG_NFS_V4_1 */
+#ifdef CONFIG_NFS_V4_2
+static __be32 decode_write_response(struct xdr_stream *xdr,
+                                       struct cb_offloadargs *args)
+{
+       __be32 *p;
+
+       /* skip the always zero field */
+       p = read_buf(xdr, 4);
+       if (unlikely(!p))
+               goto out;
+       p++;
+
+       /* decode count, stable_how, verifier */
+       p = xdr_inline_decode(xdr, 8 + 4);
+       if (unlikely(!p))
+               goto out;
+       p = xdr_decode_hyper(p, &args->wr_count);
+       args->wr_writeverf.committed = be32_to_cpup(p);
+       p = xdr_inline_decode(xdr, NFS4_VERIFIER_SIZE);
+       if (likely(p)) {
+               memcpy(&args->wr_writeverf.verifier.data[0], p,
+                       NFS4_VERIFIER_SIZE);
+               return 0;
+       }
+out:
+       return htonl(NFS4ERR_RESOURCE);
+}
+
+static __be32 decode_offload_args(struct svc_rqst *rqstp,
+                                       struct xdr_stream *xdr,
+                                       void *data)
+{
+       struct cb_offloadargs *args = data;
+       __be32 *p;
+       __be32 status;
+
+       /* decode fh */
+       status = decode_fh(xdr, &args->coa_fh);
+       if (unlikely(status != 0))
+               return status;
 
+       /* decode stateid */
+       status = decode_stateid(xdr, &args->coa_stateid);
+       if (unlikely(status != 0))
+               return status;
+
+       /* decode status */
+       p = read_buf(xdr, 4);
+       if (unlikely(!p))
+               goto out;
+       args->error = ntohl(*p++);
+       if (!args->error) {
+               status = decode_write_response(xdr, args);
+               if (unlikely(status != 0))
+                       return status;
+       } else {
+               p = xdr_inline_decode(xdr, 8);
+               if (unlikely(!p))
+                       goto out;
+               p = xdr_decode_hyper(p, &args->wr_count);
+       }
+       return 0;
+out:
+       return htonl(NFS4ERR_RESOURCE);
+}
+#endif /* CONFIG_NFS_V4_2 */
 static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
 {
        if (unlikely(xdr_stream_encode_opaque(xdr, str, len) < 0))
@@ -773,7 +841,10 @@ preprocess_nfs42_op(int nop, unsigned int op_nr, struct callback_op **op)
        if (status != htonl(NFS4ERR_OP_ILLEGAL))
                return status;
 
-       if (op_nr == OP_CB_OFFLOAD)
+       if (op_nr == OP_CB_OFFLOAD) {
+               *op = &callback_ops[op_nr];
+               return htonl(NFS_OK);
+       } else
                return htonl(NFS4ERR_NOTSUPP);
        return htonl(NFS4ERR_OP_ILLEGAL);
 }
@@ -883,16 +954,21 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp)
 
        if (hdr_arg.minorversion == 0) {
                cps.clp = nfs4_find_client_ident(SVC_NET(rqstp), hdr_arg.cb_ident);
-               if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp))
+               if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp)) {
+                       if (cps.clp)
+                               nfs_put_client(cps.clp);
                        goto out_invalidcred;
+               }
        }
 
        cps.minorversion = hdr_arg.minorversion;
        hdr_res.taglen = hdr_arg.taglen;
        hdr_res.tag = hdr_arg.tag;
-       if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0)
+       if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0) {
+               if (cps.clp)
+                       nfs_put_client(cps.clp);
                return rpc_system_err;
-
+       }
        while (status == 0 && nops != hdr_arg.nops) {
                status = process_op(nops, rqstp, &xdr_in,
                                    rqstp->rq_argp, &xdr_out, rqstp->rq_resp,
@@ -969,6 +1045,13 @@ static struct callback_op callback_ops[] = {
                .res_maxsize = CB_OP_NOTIFY_LOCK_RES_MAXSZ,
        },
 #endif /* CONFIG_NFS_V4_1 */
+#ifdef CONFIG_NFS_V4_2
+       [OP_CB_OFFLOAD] = {
+               .process_op = nfs4_callback_offload,
+               .decode_args = decode_offload_args,
+               .res_maxsize = CB_OP_OFFLOAD_RES_MAXSZ,
+       },
+#endif /* CONFIG_NFS_V4_2 */
 };
 
 /*
index 377a61654a887401da3a97b942599eb494dbf3d6..96d5f8135eb99bd84a05ea95962dd37500da8a57 100644 (file)
@@ -886,6 +886,7 @@ struct nfs_server *nfs_alloc_server(void)
        INIT_LIST_HEAD(&server->delegations);
        INIT_LIST_HEAD(&server->layouts);
        INIT_LIST_HEAD(&server->state_owners_lru);
+       INIT_LIST_HEAD(&server->ss_copies);
 
        atomic_set(&server->active, 0);
 
index d7f158c3efc8a18b78f9b592a1466dc7be28b7b6..8bfaa658b2c190ddfa61f8a52acb4895b9f63b1d 100644 (file)
@@ -904,23 +904,29 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int whence)
        dfprintk(FILE, "NFS: llseek dir(%pD2, %lld, %d)\n",
                        filp, offset, whence);
 
-       inode_lock(inode);
        switch (whence) {
-               case 1:
-                       offset += filp->f_pos;
-               case 0:
-                       if (offset >= 0)
-                               break;
-               default:
-                       offset = -EINVAL;
-                       goto out;
+       default:
+               return -EINVAL;
+       case SEEK_SET:
+               if (offset < 0)
+                       return -EINVAL;
+               inode_lock(inode);
+               break;
+       case SEEK_CUR:
+               if (offset == 0)
+                       return filp->f_pos;
+               inode_lock(inode);
+               offset += filp->f_pos;
+               if (offset < 0) {
+                       inode_unlock(inode);
+                       return -EINVAL;
+               }
        }
        if (offset != filp->f_pos) {
                filp->f_pos = offset;
                dir_ctx->dir_cookie = 0;
                dir_ctx->duped = 0;
        }
-out:
        inode_unlock(inode);
        return offset;
 }
@@ -1032,7 +1038,7 @@ int nfs_lookup_verify_inode(struct inode *inode, unsigned int flags)
        if (flags & LOOKUP_REVAL)
                goto out_force;
 out:
-       return (inode->i_nlink == 0) ? -ENOENT : 0;
+       return (inode->i_nlink == 0) ? -ESTALE : 0;
 out_force:
        if (flags & LOOKUP_RCU)
                return -ECHILD;
@@ -2499,7 +2505,9 @@ static int nfs_execute_ok(struct inode *inode, int mask)
        struct nfs_server *server = NFS_SERVER(inode);
        int ret = 0;
 
-       if (nfs_check_cache_invalid(inode, NFS_INO_INVALID_ACCESS)) {
+       if (S_ISDIR(inode->i_mode))
+               return 0;
+       if (nfs_check_cache_invalid(inode, NFS_INO_INVALID_OTHER)) {
                if (mask & MAY_NOT_BLOCK)
                        return -ECHILD;
                ret = __nfs_revalidate_inode(server, inode);
index 621c517b325c664a81a609483ab7b9830f12e25a..aa12c3063baec60bad7483004379c2edd7800f5e 100644 (file)
@@ -758,7 +758,7 @@ static void nfs_direct_write_schedule_work(struct work_struct *work)
 
 static void nfs_direct_write_complete(struct nfs_direct_req *dreq)
 {
-       schedule_work(&dreq->work); /* Calls nfs_direct_write_schedule_work */
+       queue_work(nfsiod_workqueue, &dreq->work); /* Calls nfs_direct_write_schedule_work */
 }
 
 static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
index 81cca49a837506a5abff4d25447e4f4a9484b3b3..29553fdba8af7ec61c11a19bfaeb8be4a7b0ddb4 100644 (file)
@@ -532,13 +532,13 @@ const struct address_space_operations nfs_file_aops = {
  * writable, implying that someone is about to modify the page through a
  * shared-writable mapping
  */
-static int nfs_vm_page_mkwrite(struct vm_fault *vmf)
+static vm_fault_t nfs_vm_page_mkwrite(struct vm_fault *vmf)
 {
        struct page *page = vmf->page;
        struct file *filp = vmf->vma->vm_file;
        struct inode *inode = file_inode(filp);
        unsigned pagelen;
-       int ret = VM_FAULT_NOPAGE;
+       vm_fault_t ret = VM_FAULT_NOPAGE;
        struct address_space *mapping;
 
        dfprintk(PAGECACHE, "NFS: vm_page_mkwrite(%pD2(%lu), offset %lld)\n",
index 8f003792ccde1c24c3bcd444a609b888a629340f..cae43333ef16035e11c78c4ab30ba08832396c1f 100644 (file)
@@ -812,7 +812,6 @@ ff_layout_pg_get_read(struct nfs_pageio_descriptor *pgio,
                      struct nfs_page *req,
                      bool strict_iomode)
 {
-retry_strict:
        pnfs_put_lseg(pgio->pg_lseg);
        pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
                                           req->wb_context,
@@ -825,16 +824,6 @@ retry_strict:
                pgio->pg_error = PTR_ERR(pgio->pg_lseg);
                pgio->pg_lseg = NULL;
        }
-
-       /* If we don't have checking, do get a IOMODE_RW
-        * segment, and the server wants to avoid READs
-        * there, then retry!
-        */
-       if (pgio->pg_lseg && !strict_iomode &&
-           ff_layout_avoid_read_on_rw(pgio->pg_lseg)) {
-               strict_iomode = true;
-               goto retry_strict;
-       }
 }
 
 static void
@@ -849,14 +838,16 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
 retry:
        pnfs_generic_pg_check_layout(pgio);
        /* Use full layout for now */
-       if (!pgio->pg_lseg)
+       if (!pgio->pg_lseg) {
                ff_layout_pg_get_read(pgio, req, false);
-       else if (ff_layout_avoid_read_on_rw(pgio->pg_lseg))
+               if (!pgio->pg_lseg)
+                       goto out_nolseg;
+       }
+       if (ff_layout_avoid_read_on_rw(pgio->pg_lseg)) {
                ff_layout_pg_get_read(pgio, req, true);
-
-       /* If no lseg, fall back to read through mds */
-       if (pgio->pg_lseg == NULL)
-               goto out_mds;
+               if (!pgio->pg_lseg)
+                       goto out_nolseg;
+       }
 
        ds = ff_layout_choose_best_ds_for_read(pgio->pg_lseg, 0, &ds_idx);
        if (!ds) {
@@ -878,6 +869,9 @@ retry:
        pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].rsize;
 
        return;
+out_nolseg:
+       if (pgio->pg_error < 0)
+               return;
 out_mds:
        pnfs_put_lseg(pgio->pg_lseg);
        pgio->pg_lseg = NULL;
@@ -1323,6 +1317,7 @@ static void ff_layout_read_record_layoutstats_done(struct rpc_task *task,
                        FF_LAYOUT_COMP(hdr->lseg, hdr->pgio_mirror_idx),
                        hdr->args.count,
                        hdr->res.count);
+       set_bit(NFS_LSEG_LAYOUTRETURN, &hdr->lseg->pls_flags);
 }
 
 static int ff_layout_read_prepare_common(struct rpc_task *task,
@@ -1507,6 +1502,7 @@ static void ff_layout_write_record_layoutstats_done(struct rpc_task *task,
                        FF_LAYOUT_COMP(hdr->lseg, hdr->pgio_mirror_idx),
                        hdr->args.count, hdr->res.count,
                        hdr->res.verf->committed);
+       set_bit(NFS_LSEG_LAYOUTRETURN, &hdr->lseg->pls_flags);
 }
 
 static int ff_layout_write_prepare_common(struct rpc_task *task,
@@ -1615,6 +1611,7 @@ static void ff_layout_commit_record_layoutstats_done(struct rpc_task *task,
        nfs4_ff_layout_stat_io_end_write(task,
                        FF_LAYOUT_COMP(cdata->lseg, cdata->ds_commit_index),
                        count, count, NFS_FILE_SYNC);
+       set_bit(NFS_LSEG_LAYOUTRETURN, &cdata->lseg->pls_flags);
 }
 
 static void ff_layout_commit_prepare_common(struct rpc_task *task,
index 7173a4ee862cb87af4cbab0314032c412a6bf3e8..9fce18548f7e848be7fa395766fb2c488dd724af 100644 (file)
@@ -108,6 +108,7 @@ struct posix_acl *nfs3_get_acl(struct inode *inode, int type)
                case -EPROTONOSUPPORT:
                        dprintk("NFS_V3_ACL extension not supported; disabling\n");
                        server->caps &= ~NFS_CAP_ACLS;
+                       /* fall through */
                case -ENOTSUPP:
                        status = -EOPNOTSUPP;
                default:
@@ -229,6 +230,7 @@ static int __nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
                        dprintk("NFS_V3_ACL SETACL RPC not supported"
                                        "(will not retry)\n");
                        server->caps &= ~NFS_CAP_ACLS;
+                       /* fall through */
                case -ENOTSUPP:
                        status = -EOPNOTSUPP;
        }
index 5f59b6f65a421911fb35d196636dd7d0a7488053..ac5b784a1de05c864958f1a16646fac034b402d5 100644 (file)
@@ -17,6 +17,7 @@
 #include "internal.h"
 
 #define NFSDBG_FACILITY NFSDBG_PROC
+static int nfs42_do_offload_cancel_async(struct file *dst, nfs4_stateid *std);
 
 static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
                struct nfs_lock_context *lock, loff_t offset, loff_t len)
@@ -130,6 +131,91 @@ out_unlock:
        return err;
 }
 
+static int handle_async_copy(struct nfs42_copy_res *res,
+                            struct nfs_server *server,
+                            struct file *src,
+                            struct file *dst,
+                            nfs4_stateid *src_stateid)
+{
+       struct nfs4_copy_state *copy;
+       int status = NFS4_OK;
+       bool found_pending = false;
+       struct nfs_open_context *ctx = nfs_file_open_context(dst);
+
+       spin_lock(&server->nfs_client->cl_lock);
+       list_for_each_entry(copy, &server->nfs_client->pending_cb_stateids,
+                               copies) {
+               if (memcmp(&res->write_res.stateid, &copy->stateid,
+                               NFS4_STATEID_SIZE))
+                       continue;
+               found_pending = true;
+               list_del(&copy->copies);
+               break;
+       }
+       if (found_pending) {
+               spin_unlock(&server->nfs_client->cl_lock);
+               goto out;
+       }
+
+       copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_NOFS);
+       if (!copy) {
+               spin_unlock(&server->nfs_client->cl_lock);
+               return -ENOMEM;
+       }
+       memcpy(&copy->stateid, &res->write_res.stateid, NFS4_STATEID_SIZE);
+       init_completion(&copy->completion);
+       copy->parent_state = ctx->state;
+
+       list_add_tail(&copy->copies, &server->ss_copies);
+       spin_unlock(&server->nfs_client->cl_lock);
+
+       status = wait_for_completion_interruptible(&copy->completion);
+       spin_lock(&server->nfs_client->cl_lock);
+       list_del_init(&copy->copies);
+       spin_unlock(&server->nfs_client->cl_lock);
+       if (status == -ERESTARTSYS) {
+               goto out_cancel;
+       } else if (copy->flags) {
+               status = -EAGAIN;
+               goto out_cancel;
+       }
+out:
+       res->write_res.count = copy->count;
+       memcpy(&res->write_res.verifier, &copy->verf, sizeof(copy->verf));
+       status = -copy->error;
+
+       kfree(copy);
+       return status;
+out_cancel:
+       nfs42_do_offload_cancel_async(dst, &copy->stateid);
+       kfree(copy);
+       return status;
+}
+
+static int process_copy_commit(struct file *dst, loff_t pos_dst,
+                              struct nfs42_copy_res *res)
+{
+       struct nfs_commitres cres;
+       int status = -ENOMEM;
+
+       cres.verf = kzalloc(sizeof(struct nfs_writeverf), GFP_NOFS);
+       if (!cres.verf)
+               goto out;
+
+       status = nfs4_proc_commit(dst, pos_dst, res->write_res.count, &cres);
+       if (status)
+               goto out_free;
+       if (nfs_write_verifier_cmp(&res->write_res.verifier.verifier,
+                                   &cres.verf->verifier)) {
+               dprintk("commit verf differs from copy verf\n");
+               status = -EAGAIN;
+       }
+out_free:
+       kfree(cres.verf);
+out:
+       return status;
+}
+
 static ssize_t _nfs42_proc_copy(struct file *src,
                                struct nfs_lock_context *src_lock,
                                struct file *dst,
@@ -168,9 +254,16 @@ static ssize_t _nfs42_proc_copy(struct file *src,
        if (status)
                return status;
 
-       res->commit_res.verf = kzalloc(sizeof(struct nfs_writeverf), GFP_NOFS);
-       if (!res->commit_res.verf)
-               return -ENOMEM;
+       res->commit_res.verf = NULL;
+       if (args->sync) {
+               res->commit_res.verf =
+                       kzalloc(sizeof(struct nfs_writeverf), GFP_NOFS);
+               if (!res->commit_res.verf)
+                       return -ENOMEM;
+       }
+       set_bit(NFS_CLNT_DST_SSC_COPY_STATE,
+               &dst_lock->open_context->state->flags);
+
        status = nfs4_call_sync(server->client, server, &msg,
                                &args->seq_args, &res->seq_res, 0);
        if (status == -ENOTSUPP)
@@ -178,18 +271,34 @@ static ssize_t _nfs42_proc_copy(struct file *src,
        if (status)
                goto out;
 
-       if (nfs_write_verifier_cmp(&res->write_res.verifier.verifier,
+       if (args->sync &&
+               nfs_write_verifier_cmp(&res->write_res.verifier.verifier,
                                    &res->commit_res.verf->verifier)) {
                status = -EAGAIN;
                goto out;
        }
 
+       if (!res->synchronous) {
+               status = handle_async_copy(res, server, src, dst,
+                               &args->src_stateid);
+               if (status)
+                       return status;
+       }
+
+       if ((!res->synchronous || !args->sync) &&
+                       res->write_res.verifier.committed != NFS_FILE_SYNC) {
+               status = process_copy_commit(dst, pos_dst, res);
+               if (status)
+                       return status;
+       }
+
        truncate_pagecache_range(dst_inode, pos_dst,
                                 pos_dst + res->write_res.count);
 
        status = res->write_res.count;
 out:
-       kfree(res->commit_res.verf);
+       if (args->sync)
+               kfree(res->commit_res.verf);
        return status;
 }
 
@@ -206,6 +315,7 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
                .dst_fh         = NFS_FH(file_inode(dst)),
                .dst_pos        = pos_dst,
                .count          = count,
+               .sync           = false,
        };
        struct nfs42_copy_res res;
        struct nfs4_exception src_exception = {
@@ -247,7 +357,11 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
                if (err == -ENOTSUPP) {
                        err = -EOPNOTSUPP;
                        break;
-               } if (err == -EAGAIN) {
+               } else if (err == -EAGAIN) {
+                       dst_exception.retry = 1;
+                       continue;
+               } else if (err == -NFS4ERR_OFFLOAD_NO_REQS && !args.sync) {
+                       args.sync = true;
                        dst_exception.retry = 1;
                        continue;
                }
@@ -264,6 +378,89 @@ out_put_src_lock:
        return err;
 }
 
+struct nfs42_offloadcancel_data {
+       struct nfs_server *seq_server;
+       struct nfs42_offload_status_args args;
+       struct nfs42_offload_status_res res;
+};
+
+static void nfs42_offload_cancel_prepare(struct rpc_task *task, void *calldata)
+{
+       struct nfs42_offloadcancel_data *data = calldata;
+
+       nfs4_setup_sequence(data->seq_server->nfs_client,
+                               &data->args.osa_seq_args,
+                               &data->res.osr_seq_res, task);
+}
+
+static void nfs42_offload_cancel_done(struct rpc_task *task, void *calldata)
+{
+       struct nfs42_offloadcancel_data *data = calldata;
+
+       nfs41_sequence_done(task, &data->res.osr_seq_res);
+       if (task->tk_status &&
+               nfs4_async_handle_error(task, data->seq_server, NULL,
+                       NULL) == -EAGAIN)
+               rpc_restart_call_prepare(task);
+}
+
+static void nfs42_free_offloadcancel_data(void *data)
+{
+       kfree(data);
+}
+
+static const struct rpc_call_ops nfs42_offload_cancel_ops = {
+       .rpc_call_prepare = nfs42_offload_cancel_prepare,
+       .rpc_call_done = nfs42_offload_cancel_done,
+       .rpc_release = nfs42_free_offloadcancel_data,
+};
+
+static int nfs42_do_offload_cancel_async(struct file *dst,
+                                        nfs4_stateid *stateid)
+{
+       struct nfs_server *dst_server = NFS_SERVER(file_inode(dst));
+       struct nfs42_offloadcancel_data *data = NULL;
+       struct nfs_open_context *ctx = nfs_file_open_context(dst);
+       struct rpc_task *task;
+       struct rpc_message msg = {
+               .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OFFLOAD_CANCEL],
+               .rpc_cred = ctx->cred,
+       };
+       struct rpc_task_setup task_setup_data = {
+               .rpc_client = dst_server->client,
+               .rpc_message = &msg,
+               .callback_ops = &nfs42_offload_cancel_ops,
+               .workqueue = nfsiod_workqueue,
+               .flags = RPC_TASK_ASYNC,
+       };
+       int status;
+
+       if (!(dst_server->caps & NFS_CAP_OFFLOAD_CANCEL))
+               return -EOPNOTSUPP;
+
+       data = kzalloc(sizeof(struct nfs42_offloadcancel_data), GFP_NOFS);
+       if (data == NULL)
+               return -ENOMEM;
+
+       data->seq_server = dst_server;
+       data->args.osa_src_fh = NFS_FH(file_inode(dst));
+       memcpy(&data->args.osa_stateid, stateid,
+               sizeof(data->args.osa_stateid));
+       msg.rpc_argp = &data->args;
+       msg.rpc_resp = &data->res;
+       task_setup_data.callback_data = data;
+       nfs4_init_sequence(&data->args.osa_seq_args, &data->res.osr_seq_res,
+                          1, 0);
+       task = rpc_run_task(&task_setup_data);
+       if (IS_ERR(task))
+               return PTR_ERR(task);
+       status = rpc_wait_for_completion_task(task);
+       if (status == -ENOTSUPP)
+               dst_server->caps &= ~NFS_CAP_OFFLOAD_CANCEL;
+       rpc_put_task(task);
+       return status;
+}
+
 static loff_t _nfs42_proc_llseek(struct file *filep,
                struct nfs_lock_context *lock, loff_t offset, int whence)
 {
index 5966e1e7b1f51d059e54f4b3a5506d033ed5cc22..69f72ed2bf879310f0ece97fab1e4cccea75a402 100644 (file)
@@ -26,6 +26,9 @@
                                         NFS42_WRITE_RES_SIZE + \
                                         1 /* cr_consecutive */ + \
                                         1 /* cr_synchronous */)
+#define encode_offload_cancel_maxsz    (op_encode_hdr_maxsz + \
+                                        XDR_QUADLEN(NFS4_STATEID_SIZE))
+#define decode_offload_cancel_maxsz    (op_decode_hdr_maxsz)
 #define encode_deallocate_maxsz                (op_encode_hdr_maxsz + \
                                         encode_fallocate_maxsz)
 #define decode_deallocate_maxsz                (op_decode_hdr_maxsz)
                                         decode_putfh_maxsz + \
                                         decode_copy_maxsz + \
                                         decode_commit_maxsz)
+#define NFS4_enc_offload_cancel_sz     (compound_encode_hdr_maxsz + \
+                                        encode_putfh_maxsz + \
+                                        encode_offload_cancel_maxsz)
+#define NFS4_dec_offload_cancel_sz     (compound_decode_hdr_maxsz + \
+                                        decode_putfh_maxsz + \
+                                        decode_offload_cancel_maxsz)
 #define NFS4_enc_deallocate_sz         (compound_encode_hdr_maxsz + \
                                         encode_putfh_maxsz + \
                                         encode_deallocate_maxsz + \
@@ -141,10 +150,18 @@ static void encode_copy(struct xdr_stream *xdr,
        encode_uint64(xdr, args->count);
 
        encode_uint32(xdr, 1); /* consecutive = true */
-       encode_uint32(xdr, 1); /* synchronous = true */
+       encode_uint32(xdr, args->sync);
        encode_uint32(xdr, 0); /* src server list */
 }
 
+static void encode_offload_cancel(struct xdr_stream *xdr,
+                                 const struct nfs42_offload_status_args *args,
+                                 struct compound_hdr *hdr)
+{
+       encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr);
+       encode_nfs4_stateid(xdr, &args->osa_stateid);
+}
+
 static void encode_deallocate(struct xdr_stream *xdr,
                              const struct nfs42_falloc_args *args,
                              struct compound_hdr *hdr)
@@ -256,7 +273,27 @@ static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
        encode_savefh(xdr, &hdr);
        encode_putfh(xdr, args->dst_fh, &hdr);
        encode_copy(xdr, args, &hdr);
-       encode_copy_commit(xdr, args, &hdr);
+       if (args->sync)
+               encode_copy_commit(xdr, args, &hdr);
+       encode_nops(&hdr);
+}
+
+/*
+ * Encode OFFLOAD_CANEL request
+ */
+static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
+                                       struct xdr_stream *xdr,
+                                       const void *data)
+{
+       const struct nfs42_offload_status_args *args = data;
+       struct compound_hdr hdr = {
+               .minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
+       };
+
+       encode_compound_hdr(xdr, req, &hdr);
+       encode_sequence(xdr, &args->osa_seq_args, &hdr);
+       encode_putfh(xdr, args->osa_src_fh, &hdr);
+       encode_offload_cancel(xdr, args, &hdr);
        encode_nops(&hdr);
 }
 
@@ -353,21 +390,23 @@ static int decode_write_response(struct xdr_stream *xdr,
                                 struct nfs42_write_res *res)
 {
        __be32 *p;
+       int status, count;
 
-       p = xdr_inline_decode(xdr, 4 + 8 + 4);
+       p = xdr_inline_decode(xdr, 4);
        if (unlikely(!p))
                goto out_overflow;
-
-       /*
-        * We never use asynchronous mode, so warn if a server returns
-        * a stateid.
-        */
-       if (unlikely(*p != 0)) {
-               pr_err_once("%s: server has set unrequested "
-                               "asynchronous mode\n", __func__);
+       count = be32_to_cpup(p);
+       if (count > 1)
                return -EREMOTEIO;
+       else if (count == 1) {
+               status = decode_opaque_fixed(xdr, &res->stateid,
+                               NFS4_STATEID_SIZE);
+               if (unlikely(status))
+                       goto out_overflow;
        }
-       p++;
+       p = xdr_inline_decode(xdr, 8 + 4);
+       if (unlikely(!p))
+               goto out_overflow;
        p = xdr_decode_hyper(p, &res->count);
        res->verifier.committed = be32_to_cpup(p);
        return decode_verifier(xdr, &res->verifier.verifier);
@@ -413,6 +452,12 @@ static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
        return decode_copy_requirements(xdr, res);
 }
 
+static int decode_offload_cancel(struct xdr_stream *xdr,
+                                struct nfs42_offload_status_res *res)
+{
+       return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
+}
+
 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
 {
        return decode_op_hdr(xdr, OP_DEALLOCATE);
@@ -507,7 +552,34 @@ static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
        status = decode_copy(xdr, res);
        if (status)
                goto out;
-       status = decode_commit(xdr, &res->commit_res);
+       if (res->commit_res.verf)
+               status = decode_commit(xdr, &res->commit_res);
+out:
+       return status;
+}
+
+/*
+ * Decode OFFLOAD_CANCEL response
+ */
+static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
+                                      struct xdr_stream *xdr,
+                                      void *data)
+{
+       struct nfs42_offload_status_res *res = data;
+       struct compound_hdr hdr;
+       int status;
+
+       status = decode_compound_hdr(xdr, &hdr);
+       if (status)
+               goto out;
+       status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
+       if (status)
+               goto out;
+       status = decode_putfh(xdr);
+       if (status)
+               goto out;
+       status = decode_offload_cancel(xdr, res);
+
 out:
        return status;
 }
index 51beb6e38c9009e486344ac430c533a9f7e5bc3a..3a6904173214c6ce4399de30f007d479b7983174 100644 (file)
@@ -163,6 +163,9 @@ enum {
        NFS_STATE_RECOVERY_FAILED,      /* OPEN stateid state recovery failed */
        NFS_STATE_MAY_NOTIFY_LOCK,      /* server may CB_NOTIFY_LOCK */
        NFS_STATE_CHANGE_WAIT,          /* A state changing operation is outstanding */
+#ifdef CONFIG_NFS_V4_2
+       NFS_CLNT_DST_SSC_COPY_STATE,    /* dst server open state on client*/
+#endif /* CONFIG_NFS_V4_2 */
 };
 
 struct nfs4_state {
@@ -273,6 +276,9 @@ int nfs4_replace_transport(struct nfs_server *server,
 
 /* nfs4proc.c */
 extern int nfs4_handle_exception(struct nfs_server *, int, struct nfs4_exception *);
+extern int nfs4_async_handle_error(struct rpc_task *task,
+                                  struct nfs_server *server,
+                                  struct nfs4_state *state, long *timeout);
 extern int nfs4_call_sync(struct rpc_clnt *, struct nfs_server *,
                          struct rpc_message *, struct nfs4_sequence_args *,
                          struct nfs4_sequence_res *, int);
@@ -505,7 +511,7 @@ extern int nfs4_sequence_done(struct rpc_task *task,
                              struct nfs4_sequence_res *res);
 
 extern void nfs4_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp);
-
+extern int nfs4_proc_commit(struct file *dst, __u64 offset, __u32 count, struct nfs_commitres *res);
 extern const nfs4_stateid zero_stateid;
 extern const nfs4_stateid invalid_stateid;
 
index 979631411a0e4ea5a7eedc3c668d36a57c20ced6..146e3086223478d79501564a185e9dd8aa488d03 100644 (file)
@@ -156,9 +156,23 @@ nfs4_shutdown_ds_clients(struct nfs_client *clp)
        }
 }
 
+static void
+nfs4_cleanup_callback(struct nfs_client *clp)
+{
+       struct nfs4_copy_state *cp_state;
+
+       while (!list_empty(&clp->pending_cb_stateids)) {
+               cp_state = list_entry(clp->pending_cb_stateids.next,
+                                       struct nfs4_copy_state, copies);
+               list_del(&cp_state->copies);
+               kfree(cp_state);
+       }
+}
+
 void nfs41_shutdown_client(struct nfs_client *clp)
 {
        if (nfs4_has_session(clp)) {
+               nfs4_cleanup_callback(clp);
                nfs4_shutdown_ds_clients(clp);
                nfs4_destroy_session(clp->cl_session);
                nfs4_destroy_clientid(clp);
@@ -202,6 +216,7 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
 #if IS_ENABLED(CONFIG_NFS_V4_1)
        init_waitqueue_head(&clp->cl_lock_waitq);
 #endif
+       INIT_LIST_HEAD(&clp->pending_cb_stateids);
        return clp;
 
 error:
@@ -1127,7 +1142,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
        nfs_server_copy_userdata(server, parent_server);
 
        /* Get a client representation */
-#ifdef CONFIG_SUNRPC_XPRT_RDMA
+#if IS_ENABLED(CONFIG_SUNRPC_XPRT_RDMA)
        rpc_set_port(data->addr, NFS_RDMA_PORT);
        error = nfs4_set_client(server, data->hostname,
                                data->addr,
@@ -1139,7 +1154,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
                                parent_client->cl_net);
        if (!error)
                goto init_server;
-#endif /* CONFIG_SUNRPC_XPRT_RDMA */
+#endif /* IS_ENABLED(CONFIG_SUNRPC_XPRT_RDMA) */
 
        rpc_set_port(data->addr, NFS_PORT);
        error = nfs4_set_client(server, data->hostname,
@@ -1153,7 +1168,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
        if (error < 0)
                goto error;
 
-#ifdef CONFIG_SUNRPC_XPRT_RDMA
+#if IS_ENABLED(CONFIG_SUNRPC_XPRT_RDMA)
 init_server:
 #endif
        error = nfs_init_server_rpcclient(server, parent_server->client->cl_timeout, data->authflavor);
index 6b3b372b59b9d85b240c10203f2aeb58c9cc4e7b..4288a6ecaf756361bf134af1b790cb15fd9c02d6 100644 (file)
@@ -133,10 +133,15 @@ static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in,
                                    struct file *file_out, loff_t pos_out,
                                    size_t count, unsigned int flags)
 {
+       ssize_t ret;
+
        if (file_inode(file_in) == file_inode(file_out))
                return -EINVAL;
-
-       return nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count);
+retry:
+       ret = nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count);
+       if (ret == -EAGAIN)
+               goto retry;
+       return ret;
 }
 
 static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence)
@@ -149,6 +154,7 @@ static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence)
                ret = nfs42_proc_llseek(filep, offset, whence);
                if (ret != -ENOTSUPP)
                        return ret;
+               /* Fall through */
        default:
                return nfs_file_llseek(filep, offset, whence);
        }
index b6f9d84ba19b1a1002cbc22760ab4d84bd396006..3f23b6840547e71ebd4c228c15412ad62dfab600 100644 (file)
@@ -506,6 +506,7 @@ static int nfs_idmap_prepare_message(char *desc, struct idmap *idmap,
        switch (token) {
        case Opt_find_uid:
                im->im_type = IDMAP_TYPE_USER;
+               /* Fall through */
        case Opt_find_gid:
                im->im_conv = IDMAP_CONV_NAMETOID;
                ret = match_strlcpy(im->im_name, &substr, IDMAP_NAMESZ);
@@ -513,9 +514,12 @@ static int nfs_idmap_prepare_message(char *desc, struct idmap *idmap,
 
        case Opt_find_user:
                im->im_type = IDMAP_TYPE_USER;
+               /* Fall through */
        case Opt_find_group:
                im->im_conv = IDMAP_CONV_IDTONAME;
                ret = match_int(&substr, &im->im_id);
+               if (ret)
+                       goto out;
                break;
 
        default:
index b790976d39135de899c1b70a08f75059247e2236..34830f6457ea252a2b56b9ef379b6ca3551f4f46 100644 (file)
@@ -449,6 +449,7 @@ static int nfs4_do_handle_exception(struct nfs_server *server,
                                                stateid);
                                goto wait_on_recovery;
                        }
+                       /* Fall through */
                case -NFS4ERR_OPENMODE:
                        if (inode) {
                                int err;
@@ -501,8 +502,10 @@ static int nfs4_do_handle_exception(struct nfs_server *server,
                                ret = -EBUSY;
                                break;
                        }
+                       /* Fall through */
                case -NFS4ERR_DELAY:
                        nfs_inc_server_stats(server, NFSIOS_DELAY);
+                       /* Fall through */
                case -NFS4ERR_GRACE:
                case -NFS4ERR_LAYOUTTRYLATER:
                case -NFS4ERR_RECALLCONFLICT:
@@ -581,12 +584,19 @@ nfs4_async_handle_exception(struct rpc_task *task, struct nfs_server *server,
                ret = -EIO;
        return ret;
 out_retry:
-       if (ret == 0)
+       if (ret == 0) {
                exception->retry = 1;
+               /*
+                * For NFS4ERR_MOVED, the client transport will need to
+                * be recomputed after migration recovery has completed.
+                */
+               if (errorcode == -NFS4ERR_MOVED)
+                       rpc_task_release_transport(task);
+       }
        return ret;
 }
 
-static int
+int
 nfs4_async_handle_error(struct rpc_task *task, struct nfs_server *server,
                        struct nfs4_state *state, long *timeout)
 {
@@ -1071,15 +1081,30 @@ int nfs4_call_sync(struct rpc_clnt *clnt,
        return nfs4_call_sync_sequence(clnt, server, msg, args, res);
 }
 
-static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo,
-               unsigned long timestamp)
+static void
+nfs4_inc_nlink_locked(struct inode *inode)
+{
+       NFS_I(inode)->cache_validity |= NFS_INO_INVALID_OTHER;
+       inc_nlink(inode);
+}
+
+static void
+nfs4_dec_nlink_locked(struct inode *inode)
+{
+       NFS_I(inode)->cache_validity |= NFS_INO_INVALID_OTHER;
+       drop_nlink(inode);
+}
+
+static void
+update_changeattr_locked(struct inode *dir, struct nfs4_change_info *cinfo,
+               unsigned long timestamp, unsigned long cache_validity)
 {
        struct nfs_inode *nfsi = NFS_I(dir);
 
-       spin_lock(&dir->i_lock);
        nfsi->cache_validity |= NFS_INO_INVALID_CTIME
                | NFS_INO_INVALID_MTIME
-               | NFS_INO_INVALID_DATA;
+               | NFS_INO_INVALID_DATA
+               | cache_validity;
        if (cinfo->atomic && cinfo->before == inode_peek_iversion_raw(dir)) {
                nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
                nfsi->attrtimeo_timestamp = jiffies;
@@ -1092,7 +1117,16 @@ static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo,
        inode_set_iversion_raw(dir, cinfo->after);
        nfsi->read_cache_jiffies = timestamp;
        nfsi->attr_gencount = nfs_inc_attr_generation_counter();
+       nfsi->cache_validity &= ~NFS_INO_INVALID_CHANGE;
        nfs_fscache_invalidate(dir);
+}
+
+static void
+update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo,
+               unsigned long timestamp, unsigned long cache_validity)
+{
+       spin_lock(&dir->i_lock);
+       update_changeattr_locked(dir, cinfo, timestamp, cache_validity);
        spin_unlock(&dir->i_lock);
 }
 
@@ -1354,6 +1388,7 @@ static int can_open_delegated(struct nfs_delegation *delegation, fmode_t fmode,
        case NFS4_OPEN_CLAIM_PREVIOUS:
                if (!test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags))
                        break;
+               /* Fall through */
        default:
                return 0;
        }
@@ -1773,6 +1808,10 @@ nfs4_opendata_check_deleg(struct nfs4_opendata *data, struct nfs4_state *state)
                                data->o_res.delegation_type,
                                &data->o_res.delegation,
                                data->o_res.pagemod_limit);
+
+       if (data->o_res.do_recall)
+               nfs_async_inode_return_delegation(state->inode,
+                                                 &data->o_res.delegation);
 }
 
 /*
@@ -2119,6 +2158,7 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx,
                err = nfs4_open_recover_helper(opendata, FMODE_WRITE);
                if (err)
                        break;
+               /* Fall through */
        case FMODE_READ:
                err = nfs4_open_recover_helper(opendata, FMODE_READ);
        }
@@ -2248,6 +2288,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
        case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
        case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
                data->o_arg.open_bitmap = &nfs4_open_noattr_bitmap[0];
+               /* Fall through */
        case NFS4_OPEN_CLAIM_FH:
                task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
        }
@@ -2481,7 +2522,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data,
                if (data->file_created ||
                    inode_peek_iversion_raw(dir) != o_res->cinfo.after)
                        update_changeattr(dir, &o_res->cinfo,
-                                       o_res->f_attr->time_start);
+                                       o_res->f_attr->time_start, 0);
        }
        if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0)
                server->caps &= ~NFS_CAP_POSIX_LOCK;
@@ -2843,6 +2884,9 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
                                nfs_save_change_attribute(d_inode(opendata->dir)));
        }
 
+       /* Parse layoutget results before we check for access */
+       pnfs_parse_lgopen(state->inode, opendata->lgp, ctx);
+
        ret = nfs4_opendata_access(sp->so_cred, opendata, state, fmode, flags);
        if (ret != 0)
                goto out;
@@ -2851,8 +2895,6 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
                nfs_inode_attach_open_context(ctx);
                if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
                        nfs4_schedule_stateid_recovery(server, state);
-               else
-                       pnfs_parse_lgopen(state->inode, opendata->lgp, ctx);
        }
 
 out:
@@ -3220,7 +3262,8 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
                        calldata->res.lr_res = NULL;
                        break;
                case -NFS4ERR_OLD_STATEID:
-                       if (nfs4_refresh_layout_stateid(&calldata->arg.lr_args->stateid,
+                       if (nfs4_layoutreturn_refresh_stateid(&calldata->arg.lr_args->stateid,
+                                               &calldata->arg.lr_args->range,
                                                calldata->inode))
                                goto lr_restart;
                        /* Fallthrough */
@@ -4236,7 +4279,8 @@ out:
        return status;
 }
 
-static int _nfs4_proc_remove(struct inode *dir, const struct qstr *name)
+static int
+_nfs4_proc_remove(struct inode *dir, const struct qstr *name, u32 ftype)
 {
        struct nfs_server *server = NFS_SERVER(dir);
        struct nfs_removeargs args = {
@@ -4255,8 +4299,14 @@ static int _nfs4_proc_remove(struct inode *dir, const struct qstr *name)
        int status;
 
        status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 1);
-       if (status == 0)
-               update_changeattr(dir, &res.cinfo, timestamp);
+       if (status == 0) {
+               spin_lock(&dir->i_lock);
+               update_changeattr_locked(dir, &res.cinfo, timestamp, 0);
+               /* Removing a directory decrements nlink in the parent */
+               if (ftype == NF4DIR && dir->i_nlink > 2)
+                       nfs4_dec_nlink_locked(dir);
+               spin_unlock(&dir->i_lock);
+       }
        return status;
 }
 
@@ -4273,7 +4323,7 @@ static int nfs4_proc_remove(struct inode *dir, struct dentry *dentry)
                        nfs4_inode_make_writeable(inode);
        }
        do {
-               err = _nfs4_proc_remove(dir, &dentry->d_name);
+               err = _nfs4_proc_remove(dir, &dentry->d_name, NF4REG);
                trace_nfs4_remove(dir, &dentry->d_name, err);
                err = nfs4_handle_exception(NFS_SERVER(dir), err,
                                &exception);
@@ -4287,7 +4337,7 @@ static int nfs4_proc_rmdir(struct inode *dir, const struct qstr *name)
        int err;
 
        do {
-               err = _nfs4_proc_remove(dir, name);
+               err = _nfs4_proc_remove(dir, name, NF4DIR);
                trace_nfs4_remove(dir, name, err);
                err = nfs4_handle_exception(NFS_SERVER(dir), err,
                                &exception);
@@ -4331,7 +4381,8 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
                                    &data->timeout) == -EAGAIN)
                return 0;
        if (task->tk_status == 0)
-               update_changeattr(dir, &res->cinfo, res->dir_attr->time_start);
+               update_changeattr(dir, &res->cinfo,
+                               res->dir_attr->time_start, 0);
        return 1;
 }
 
@@ -4373,9 +4424,18 @@ static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
                return 0;
 
        if (task->tk_status == 0) {
-               update_changeattr(old_dir, &res->old_cinfo, res->old_fattr->time_start);
-               if (new_dir != old_dir)
-                       update_changeattr(new_dir, &res->new_cinfo, res->new_fattr->time_start);
+               if (new_dir != old_dir) {
+                       /* Note: If we moved a directory, nlink will change */
+                       update_changeattr(old_dir, &res->old_cinfo,
+                                       res->old_fattr->time_start,
+                                       NFS_INO_INVALID_OTHER);
+                       update_changeattr(new_dir, &res->new_cinfo,
+                                       res->new_fattr->time_start,
+                                       NFS_INO_INVALID_OTHER);
+               } else
+                       update_changeattr(old_dir, &res->old_cinfo,
+                                       res->old_fattr->time_start,
+                                       0);
        }
        return 1;
 }
@@ -4416,7 +4476,7 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, const struct
 
        status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
        if (!status) {
-               update_changeattr(dir, &res.cinfo, res.fattr->time_start);
+               update_changeattr(dir, &res.cinfo, res.fattr->time_start, 0);
                status = nfs_post_op_update_inode(inode, res.fattr);
                if (!status)
                        nfs_setsecurity(inode, res.fattr, res.label);
@@ -4491,8 +4551,13 @@ static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_
        int status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &data->msg,
                                    &data->arg.seq_args, &data->res.seq_res, 1);
        if (status == 0) {
-               update_changeattr(dir, &data->res.dir_cinfo,
-                               data->res.fattr->time_start);
+               spin_lock(&dir->i_lock);
+               update_changeattr_locked(dir, &data->res.dir_cinfo,
+                               data->res.fattr->time_start, 0);
+               /* Creating a directory bumps nlink in the parent */
+               if (data->arg.ftype == NF4DIR)
+                       nfs4_inc_nlink_locked(dir);
+               spin_unlock(&dir->i_lock);
                status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, data->res.label);
        }
        return status;
@@ -5073,6 +5138,40 @@ static void nfs4_proc_commit_setup(struct nfs_commit_data *data, struct rpc_mess
        nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_COMMIT, clnt, msg);
 }
 
+static int _nfs4_proc_commit(struct file *dst, struct nfs_commitargs *args,
+                               struct nfs_commitres *res)
+{
+       struct inode *dst_inode = file_inode(dst);
+       struct nfs_server *server = NFS_SERVER(dst_inode);
+       struct rpc_message msg = {
+               .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT],
+               .rpc_argp = args,
+               .rpc_resp = res,
+       };
+
+       args->fh = NFS_FH(dst_inode);
+       return nfs4_call_sync(server->client, server, &msg,
+                       &args->seq_args, &res->seq_res, 1);
+}
+
+int nfs4_proc_commit(struct file *dst, __u64 offset, __u32 count, struct nfs_commitres *res)
+{
+       struct nfs_commitargs args = {
+               .offset = offset,
+               .count = count,
+       };
+       struct nfs_server *dst_server = NFS_SERVER(file_inode(dst));
+       struct nfs4_exception exception = { };
+       int status;
+
+       do {
+               status = _nfs4_proc_commit(dst, &args, res);
+               status = nfs4_handle_exception(dst_server, status, &exception);
+       } while (exception.retry);
+
+       return status;
+}
+
 struct nfs4_renewdata {
        struct nfs_client       *client;
        unsigned long           timestamp;
@@ -5902,7 +6001,8 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
                        data->res.lr_res = NULL;
                        break;
                case -NFS4ERR_OLD_STATEID:
-                       if (nfs4_refresh_layout_stateid(&data->args.lr_args->stateid,
+                       if (nfs4_layoutreturn_refresh_stateid(&data->args.lr_args->stateid,
+                                               &data->args.lr_args->range,
                                                data->inode))
                                goto lr_restart;
                        /* Fallthrough */
@@ -6209,11 +6309,13 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
                        if (nfs4_update_lock_stateid(calldata->lsp,
                                        &calldata->res.stateid))
                                break;
+                       /* Fall through */
                case -NFS4ERR_ADMIN_REVOKED:
                case -NFS4ERR_EXPIRED:
                        nfs4_free_revoked_stateid(calldata->server,
                                        &calldata->arg.stateid,
                                        task->tk_msg.rpc_cred);
+                       /* Fall through */
                case -NFS4ERR_BAD_STATEID:
                case -NFS4ERR_OLD_STATEID:
                case -NFS4ERR_STALE_STATEID:
@@ -7727,7 +7829,7 @@ static int nfs4_sp4_select_mode(struct nfs_client *clp,
        }
 out:
        clp->cl_sp4_flags = flags;
-       return 0;
+       return ret;
 }
 
 struct nfs41_exchange_id_data {
@@ -8168,7 +8270,7 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args,
        args->bc_attrs.max_resp_sz = max_bc_payload;
        args->bc_attrs.max_resp_sz_cached = 0;
        args->bc_attrs.max_ops = NFS4_MAX_BACK_CHANNEL_OPS;
-       args->bc_attrs.max_reqs = min_t(unsigned short, max_session_cb_slots, 1);
+       args->bc_attrs.max_reqs = max_t(unsigned short, max_session_cb_slots, 1);
 
        dprintk("%s: Back Channel : max_rqst_sz=%u max_resp_sz=%u "
                "max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n",
@@ -8851,7 +8953,8 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
        server = NFS_SERVER(lrp->args.inode);
        switch (task->tk_status) {
        case -NFS4ERR_OLD_STATEID:
-               if (nfs4_refresh_layout_stateid(&lrp->args.stateid,
+               if (nfs4_layoutreturn_refresh_stateid(&lrp->args.stateid,
+                                       &lrp->args.range,
                                        lrp->args.inode))
                        goto out_restart;
                /* Fallthrough */
@@ -9554,6 +9657,7 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
                | NFS_CAP_LGOPEN
                | NFS_CAP_ALLOCATE
                | NFS_CAP_COPY
+               | NFS_CAP_OFFLOAD_CANCEL
                | NFS_CAP_DEALLOCATE
                | NFS_CAP_SEEK
                | NFS_CAP_LAYOUTSTATS
index 2bf2eaa08ca7de5397e0099786b672a757543242..3df0eb52da1c97d3802c34702068a36f31f02d69 100644 (file)
@@ -274,7 +274,7 @@ static int nfs4_drain_slot_tbl(struct nfs4_slot_table *tbl)
 static int nfs4_begin_drain_session(struct nfs_client *clp)
 {
        struct nfs4_session *ses = clp->cl_session;
-       int ret = 0;
+       int ret;
 
        if (clp->cl_slot_tbl)
                return nfs4_drain_slot_tbl(clp->cl_slot_tbl);
@@ -1525,6 +1525,7 @@ restart:
                default:
                        pr_err("NFS: %s: unhandled error %d\n",
                                        __func__, status);
+                       /* Fall through */
                case -ENOMEM:
                case -NFS4ERR_DENIED:
                case -NFS4ERR_RECLAIM_BAD:
@@ -1588,6 +1589,22 @@ restart:
                                }
                                clear_bit(NFS_STATE_RECLAIM_NOGRACE,
                                        &state->flags);
+#ifdef CONFIG_NFS_V4_2
+                               if (test_bit(NFS_CLNT_DST_SSC_COPY_STATE, &state->flags)) {
+                                       struct nfs4_copy_state *copy;
+
+                                       spin_lock(&sp->so_server->nfs_client->cl_lock);
+                                       list_for_each_entry(copy, &sp->so_server->ss_copies, copies) {
+                                               if (memcmp(&state->stateid.other, &copy->parent_state->stateid.other, NFS4_STATEID_SIZE))
+                                                       continue;
+                                               copy->flags = 1;
+                                               complete(&copy->completion);
+                                               printk("AGLO: server rebooted waking up the copy\n");
+                                               break;
+                                       }
+                                       spin_unlock(&sp->so_server->nfs_client->cl_lock);
+                               }
+#endif /* CONFIG_NFS_V4_2 */
                                nfs4_put_open_state(state);
                                spin_lock(&sp->so_lock);
                                goto restart;
@@ -1597,6 +1614,7 @@ restart:
                        default:
                                printk(KERN_ERR "NFS: %s: unhandled error %d\n",
                                        __func__, status);
+                               /* Fall through */
                        case -ENOENT:
                        case -ENOMEM:
                        case -EACCES:
@@ -1608,6 +1626,7 @@ restart:
                                break;
                        case -EAGAIN:
                                ssleep(1);
+                               /* Fall through */
                        case -NFS4ERR_ADMIN_REVOKED:
                        case -NFS4ERR_STALE_STATEID:
                        case -NFS4ERR_OLD_STATEID:
@@ -1939,7 +1958,9 @@ static int nfs4_establish_lease(struct nfs_client *clp)
                clp->cl_mvops->reboot_recovery_ops;
        int status;
 
-       nfs4_begin_drain_session(clp);
+       status = nfs4_begin_drain_session(clp);
+       if (status != 0)
+               return status;
        cred = nfs4_get_clid_cred(clp);
        if (cred == NULL)
                return -ENOENT;
@@ -2027,7 +2048,9 @@ static int nfs4_try_migration(struct nfs_server *server, struct rpc_cred *cred)
                goto out;
        }
 
-       nfs4_begin_drain_session(clp);
+       status = nfs4_begin_drain_session(clp);
+       if (status != 0)
+               return status;
 
        status = nfs4_replace_transport(server, locations);
        if (status != 0) {
@@ -2190,9 +2213,11 @@ again:
        case -ETIMEDOUT:
                if (clnt->cl_softrtry)
                        break;
+               /* Fall through */
        case -NFS4ERR_DELAY:
        case -EAGAIN:
                ssleep(1);
+               /* Fall through */
        case -NFS4ERR_STALE_CLIENTID:
                dprintk("NFS: %s after status %d, retrying\n",
                        __func__, status);
@@ -2204,6 +2229,7 @@ again:
                }
                if (clnt->cl_auth->au_flavor == RPC_AUTH_UNIX)
                        break;
+               /* Fall through */
        case -NFS4ERR_CLID_INUSE:
        case -NFS4ERR_WRONGSEC:
                /* No point in retrying if we already used RPC_AUTH_UNIX */
@@ -2374,7 +2400,9 @@ static int nfs4_reset_session(struct nfs_client *clp)
 
        if (!nfs4_has_session(clp))
                return 0;
-       nfs4_begin_drain_session(clp);
+       status = nfs4_begin_drain_session(clp);
+       if (status != 0)
+               return status;
        cred = nfs4_get_clid_cred(clp);
        status = nfs4_proc_destroy_session(clp->cl_session, cred);
        switch (status) {
@@ -2417,7 +2445,9 @@ static int nfs4_bind_conn_to_session(struct nfs_client *clp)
 
        if (!nfs4_has_session(clp))
                return 0;
-       nfs4_begin_drain_session(clp);
+       ret = nfs4_begin_drain_session(clp);
+       if (ret != 0)
+               return ret;
        cred = nfs4_get_clid_cred(clp);
        ret = nfs4_proc_bind_conn_to_session(clp, cred);
        if (cred)
index cd41d2577a049b489496b24a05ec2e28b959ee9d..b7bde12d8cd518ce7b8da11d7ae3b6239ca3292f 100644 (file)
@@ -7789,6 +7789,7 @@ const struct rpc_procinfo nfs4_procedures[] = {
        PROC42(LAYOUTSTATS,     enc_layoutstats,        dec_layoutstats),
        PROC42(CLONE,           enc_clone,              dec_clone),
        PROC42(COPY,            enc_copy,               dec_copy),
+       PROC42(OFFLOAD_CANCEL,  enc_offload_cancel,     dec_offload_cancel),
        PROC(LOOKUPP,           enc_lookupp,            dec_lookupp),
 };
 
index 67d19cd92e44235d1c0ec81630efa79bd902616f..bb5476a6d264278aae9d549835b6f9b5bc2dbfc7 100644 (file)
@@ -561,6 +561,7 @@ static void nfs_pgio_rpcsetup(struct nfs_pgio_header *hdr,
        case FLUSH_COND_STABLE:
                if (nfs_reqs_to_commit(cinfo))
                        break;
+               /* fall through */
        default:
                hdr->args.stable = NFS_FILE_SYNC;
        }
index bcc3addec3c5376436f55f4d7cabad564bc41ea7..e8f232de484f4d591666c6789b9932404e6fc5cb 100644 (file)
@@ -361,18 +361,32 @@ pnfs_clear_lseg_state(struct pnfs_layout_segment *lseg,
 /*
  * Update the seqid of a layout stateid
  */
-bool nfs4_refresh_layout_stateid(nfs4_stateid *dst, struct inode *inode)
+bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst,
+               struct pnfs_layout_range *dst_range,
+               struct inode *inode)
 {
        struct pnfs_layout_hdr *lo;
+       struct pnfs_layout_range range = {
+               .iomode = IOMODE_ANY,
+               .offset = 0,
+               .length = NFS4_MAX_UINT64,
+       };
        bool ret = false;
+       LIST_HEAD(head);
+       int err;
 
        spin_lock(&inode->i_lock);
        lo = NFS_I(inode)->layout;
        if (lo && nfs4_stateid_match_other(dst, &lo->plh_stateid)) {
-               dst->seqid = lo->plh_stateid.seqid;
-               ret = true;
+               err = pnfs_mark_matching_lsegs_return(lo, &head, &range, 0);
+               if (err != -EBUSY) {
+                       dst->seqid = lo->plh_stateid.seqid;
+                       *dst_range = range;
+                       ret = true;
+               }
        }
        spin_unlock(&inode->i_lock);
+       pnfs_free_lseg_list(&head);
        return ret;
 }
 
@@ -1018,7 +1032,6 @@ pnfs_alloc_init_layoutget_args(struct inode *ino,
        nfs4_stateid_copy(&lgp->args.stateid, stateid);
        lgp->gfp_flags = gfp_flags;
        lgp->cred = get_rpccred(ctx->cred);
-       lgp->callback_count = raw_seqcount_begin(&server->nfs_client->cl_callback_count);
        return lgp;
 }
 
@@ -1160,12 +1173,21 @@ static bool
 pnfs_layout_need_return(struct pnfs_layout_hdr *lo)
 {
        struct pnfs_layout_segment *s;
+       enum pnfs_iomode iomode;
+       u32 seq;
 
        if (!test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags))
                return false;
 
-       /* Defer layoutreturn until all lsegs are done */
+       seq = lo->plh_return_seq;
+       iomode = lo->plh_return_iomode;
+
+       /* Defer layoutreturn until all recalled lsegs are done */
        list_for_each_entry(s, &lo->plh_segs, pls_list) {
+               if (seq && pnfs_seqid_is_newer(s->pls_seq, seq))
+                       continue;
+               if (iomode != IOMODE_ANY && s->pls_range.iomode != iomode)
+                       continue;
                if (test_bit(NFS_LSEG_LAYOUTRETURN, &s->pls_flags))
                        return false;
        }
@@ -1609,7 +1631,7 @@ pnfs_lseg_range_match(const struct pnfs_layout_range *ls_range,
            (range->iomode != ls_range->iomode &&
             strict_iomode) ||
            !pnfs_lseg_range_intersecting(ls_range, range))
-               return 0;
+               return false;
 
        /* range1 covers only the first byte in the range */
        range1 = *range;
@@ -1631,7 +1653,6 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo,
 
        list_for_each_entry(lseg, &lo->plh_segs, pls_list) {
                if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags) &&
-                   !test_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags) &&
                    pnfs_lseg_range_match(&lseg->pls_range, range,
                                          strict_iomode)) {
                        ret = pnfs_get_lseg(lseg);
@@ -1731,6 +1752,17 @@ static bool pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo)
                                   TASK_UNINTERRUPTIBLE);
 }
 
+static void nfs_layoutget_begin(struct pnfs_layout_hdr *lo)
+{
+       atomic_inc(&lo->plh_outstanding);
+}
+
+static void nfs_layoutget_end(struct pnfs_layout_hdr *lo)
+{
+       if (atomic_dec_and_test(&lo->plh_outstanding))
+               wake_up_var(&lo->plh_outstanding);
+}
+
 static void pnfs_clear_first_layoutget(struct pnfs_layout_hdr *lo)
 {
        unsigned long *bitlock = &lo->plh_flags;
@@ -1791,12 +1823,6 @@ pnfs_update_layout(struct inode *ino,
                goto out;
        }
 
-       if (iomode == IOMODE_READ && i_size_read(ino) == 0) {
-               trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
-                                PNFS_UPDATE_LAYOUT_RD_ZEROLEN);
-               goto out;
-       }
-
        if (pnfs_within_mdsthreshold(ctx, ino, iomode)) {
                trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
                                 PNFS_UPDATE_LAYOUT_MDSTHRESH);
@@ -1830,6 +1856,21 @@ lookup_again:
                goto out_unlock;
        }
 
+       /*
+        * If the layout segment list is empty, but there are outstanding
+        * layoutget calls, then they might be subject to a layoutrecall.
+        */
+       if (list_empty(&lo->plh_segs) &&
+           atomic_read(&lo->plh_outstanding) != 0) {
+               spin_unlock(&ino->i_lock);
+               if (wait_var_event_killable(&lo->plh_outstanding,
+                                       atomic_read(&lo->plh_outstanding) == 0
+                                       || !list_empty(&lo->plh_segs)))
+                       goto out_put_layout_hdr;
+               pnfs_put_layout_hdr(lo);
+               goto lookup_again;
+       }
+
        lseg = pnfs_find_lseg(lo, &arg, strict_iomode);
        if (lseg) {
                trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
@@ -1903,7 +1944,7 @@ lookup_again:
                                PNFS_UPDATE_LAYOUT_BLOCKED);
                goto out_unlock;
        }
-       atomic_inc(&lo->plh_outstanding);
+       nfs_layoutget_begin(lo);
        spin_unlock(&ino->i_lock);
 
        _add_to_server_list(lo, server);
@@ -1920,14 +1961,14 @@ lookup_again:
        if (!lgp) {
                trace_pnfs_update_layout(ino, pos, count, iomode, lo, NULL,
                                         PNFS_UPDATE_LAYOUT_NOMEM);
-               atomic_dec(&lo->plh_outstanding);
+               nfs_layoutget_end(lo);
                goto out_put_layout_hdr;
        }
 
        lseg = nfs4_proc_layoutget(lgp, &timeout);
        trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
                                 PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET);
-       atomic_dec(&lo->plh_outstanding);
+       nfs_layoutget_end(lo);
        if (IS_ERR(lseg)) {
                switch(PTR_ERR(lseg)) {
                case -EBUSY:
@@ -1935,15 +1976,6 @@ lookup_again:
                                lseg = NULL;
                        break;
                case -ERECALLCONFLICT:
-                       /* Huh? We hold no layouts, how is there a recall? */
-                       if (first) {
-                               lseg = NULL;
-                               break;
-                       }
-                       /* Destroy the existing layout and start over */
-                       if (time_after(jiffies, giveup))
-                               pnfs_destroy_layout(NFS_I(ino));
-                       /* Fallthrough */
                case -EAGAIN:
                        break;
                default:
@@ -2022,7 +2054,7 @@ _pnfs_grab_empty_layout(struct inode *ino, struct nfs_open_context *ctx)
                goto out_unlock;
        if (test_and_set_bit(NFS_LAYOUT_FIRST_LAYOUTGET, &lo->plh_flags))
                goto out_unlock;
-       atomic_inc(&lo->plh_outstanding);
+       nfs_layoutget_begin(lo);
        spin_unlock(&ino->i_lock);
        _add_to_server_list(lo, NFS_SERVER(ino));
        return lo;
@@ -2146,9 +2178,6 @@ void pnfs_parse_lgopen(struct inode *ino, struct nfs4_layoutget *lgp,
        } else
                lo = NFS_I(lgp->args.inode)->layout;
 
-       if (read_seqcount_retry(&srv->nfs_client->cl_callback_count,
-                               lgp->callback_count))
-               return;
        lseg = pnfs_layout_process(lgp);
        if (!IS_ERR(lseg)) {
                iomode = lgp->args.range.iomode;
@@ -2163,8 +2192,8 @@ void nfs4_lgopen_release(struct nfs4_layoutget *lgp)
                struct inode *inode = lgp->args.inode;
                if (inode) {
                        struct pnfs_layout_hdr *lo = NFS_I(inode)->layout;
-                       atomic_dec(&lo->plh_outstanding);
                        pnfs_clear_first_layoutget(lo);
+                       nfs_layoutget_end(lo);
                }
                pnfs_layoutget_free(lgp);
        }
@@ -2238,15 +2267,31 @@ out_forget:
        return ERR_PTR(-EAGAIN);
 }
 
+static int
+mark_lseg_invalid_or_return(struct pnfs_layout_segment *lseg,
+               struct list_head *tmp_list)
+{
+       if (!mark_lseg_invalid(lseg, tmp_list))
+               return 0;
+       pnfs_cache_lseg_for_layoutreturn(lseg->pls_layout, lseg);
+       return 1;
+}
+
 /**
  * pnfs_mark_matching_lsegs_return - Free or return matching layout segments
  * @lo: pointer to layout header
  * @tmp_list: list header to be used with pnfs_free_lseg_list()
  * @return_range: describe layout segment ranges to be returned
+ * @seq: stateid seqid to match
  *
  * This function is mainly intended for use by layoutrecall. It attempts
  * to free the layout segment immediately, or else to mark it for return
  * as soon as its reference count drops to zero.
+ *
+ * Returns
+ * - 0: a layoutreturn needs to be scheduled.
+ * - EBUSY: there are layout segment that are still in use.
+ * - ENOENT: there are no layout segments that need to be returned.
  */
 int
 pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
@@ -2259,9 +2304,6 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
 
        dprintk("%s:Begin lo %p\n", __func__, lo);
 
-       if (list_empty(&lo->plh_segs))
-               return 0;
-
        assert_spin_locked(&lo->plh_inode->i_lock);
 
        list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
@@ -2271,16 +2313,23 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
                                lseg, lseg->pls_range.iomode,
                                lseg->pls_range.offset,
                                lseg->pls_range.length);
-                       if (mark_lseg_invalid(lseg, tmp_list))
+                       if (mark_lseg_invalid_or_return(lseg, tmp_list))
                                continue;
                        remaining++;
                        set_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags);
                }
 
-       if (remaining)
+       if (remaining) {
                pnfs_set_plh_return_info(lo, return_range->iomode, seq);
+               return -EBUSY;
+       }
 
-       return remaining;
+       if (!list_empty(&lo->plh_return_segs)) {
+               pnfs_set_plh_return_info(lo, return_range->iomode, seq);
+               return 0;
+       }
+
+       return -ENOENT;
 }
 
 void pnfs_error_mark_layout_for_return(struct inode *inode,
@@ -2305,7 +2354,7 @@ void pnfs_error_mark_layout_for_return(struct inode *inode,
         * segments at hand when sending layoutreturn. See pnfs_put_lseg()
         * for how it works.
         */
-       if (!pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs, &range, 0)) {
+       if (pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs, &range, 0) != -EBUSY) {
                nfs4_stateid stateid;
                enum pnfs_iomode iomode;
 
index 3fe81424337d07b5b19ab77d08825fb27bf523b0..ece367ebde6928204418e51321401e06bc4fe9aa 100644 (file)
@@ -259,7 +259,9 @@ int pnfs_destroy_layouts_byfsid(struct nfs_client *clp,
                bool is_recall);
 int pnfs_destroy_layouts_byclid(struct nfs_client *clp,
                bool is_recall);
-bool nfs4_refresh_layout_stateid(nfs4_stateid *dst, struct inode *inode);
+bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst,
+               struct pnfs_layout_range *dst_range,
+               struct inode *inode);
 void pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo);
 void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo,
                             const nfs4_stateid *new,
@@ -780,7 +782,8 @@ static inline void nfs4_pnfs_v3_ds_connect_unload(void)
 {
 }
 
-static inline bool nfs4_refresh_layout_stateid(nfs4_stateid *dst,
+static inline bool nfs4_layoutreturn_refresh_stateid(nfs4_stateid *dst,
+               struct pnfs_layout_range *dst_range,
                struct inode *inode)
 {
        return false;
index 32ba2d47185303419270acf6891fc28ead9f8e8e..d5e4d3cd8c7f15762ef11de727a2fbcdb10c3f7a 100644 (file)
@@ -61,7 +61,7 @@ EXPORT_SYMBOL_GPL(pnfs_generic_commit_release);
 
 /* The generic layer is about to remove the req from the commit list.
  * If this will make the bucket empty, it will need to put the lseg reference.
- * Note this must be called holding i_lock
+ * Note this must be called holding nfsi->commit_mutex
  */
 void
 pnfs_generic_clear_request_commit(struct nfs_page *req,
@@ -149,9 +149,7 @@ restart:
                if (list_empty(&b->written)) {
                        freeme = b->wlseg;
                        b->wlseg = NULL;
-                       spin_unlock(&cinfo->inode->i_lock);
                        pnfs_put_lseg(freeme);
-                       spin_lock(&cinfo->inode->i_lock);
                        goto restart;
                }
        }
@@ -167,7 +165,7 @@ static void pnfs_generic_retry_commit(struct nfs_commit_info *cinfo, int idx)
        LIST_HEAD(pages);
        int i;
 
-       spin_lock(&cinfo->inode->i_lock);
+       mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
        for (i = idx; i < fl_cinfo->nbuckets; i++) {
                bucket = &fl_cinfo->buckets[i];
                if (list_empty(&bucket->committing))
@@ -177,12 +175,12 @@ static void pnfs_generic_retry_commit(struct nfs_commit_info *cinfo, int idx)
                list_for_each(pos, &bucket->committing)
                        cinfo->ds->ncommitting--;
                list_splice_init(&bucket->committing, &pages);
-               spin_unlock(&cinfo->inode->i_lock);
+               mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
                nfs_retry_commit(&pages, freeme, cinfo, i);
                pnfs_put_lseg(freeme);
-               spin_lock(&cinfo->inode->i_lock);
+               mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
        }
-       spin_unlock(&cinfo->inode->i_lock);
+       mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
 }
 
 static unsigned int
@@ -222,13 +220,13 @@ void pnfs_fetch_commit_bucket_list(struct list_head *pages,
        struct list_head *pos;
 
        bucket = &cinfo->ds->buckets[data->ds_commit_index];
-       spin_lock(&cinfo->inode->i_lock);
+       mutex_lock(&NFS_I(cinfo->inode)->commit_mutex);
        list_for_each(pos, &bucket->committing)
                cinfo->ds->ncommitting--;
        list_splice_init(&bucket->committing, pages);
        data->lseg = bucket->clseg;
        bucket->clseg = NULL;
-       spin_unlock(&cinfo->inode->i_lock);
+       mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex);
 
 }
 
index 5e470e233c83d242856322bb27c86e50d206cfe8..ac4b2f005778c05df1bb68117f66fd407f20a529 100644 (file)
@@ -884,7 +884,7 @@ int nfs_show_stats(struct seq_file *m, struct dentry *root)
 #endif
        seq_printf(m, "\n");
 
-       rpc_print_iostats(m, nfss->client);
+       rpc_clnt_show_stats(m, nfss->client);
 
        return 0;
 }
@@ -2899,7 +2899,7 @@ static int param_set_portnr(const char *val, const struct kernel_param *kp)
        if (!val)
                return -EINVAL;
        ret = kstrtoul(val, 0, &num);
-       if (ret == -EINVAL || num > NFS_CALLBACK_MAXPORTNR)
+       if (ret || num > NFS_CALLBACK_MAXPORTNR)
                return -EINVAL;
        *((unsigned int *)kp->arg) = num;
        return 0;
index a057b4f45a468dd695202f5462787cfd8d2dc0fa..586726a590d88149fa0fe769de37fa7aa14033a2 100644 (file)
@@ -1406,6 +1406,8 @@ static void nfs_async_write_error(struct list_head *head)
 static void nfs_async_write_reschedule_io(struct nfs_pgio_header *hdr)
 {
        nfs_async_write_error(&hdr->pages);
+       filemap_fdatawrite_range(hdr->inode->i_mapping, hdr->args.offset,
+                       hdr->args.offset + hdr->args.count - 1);
 }
 
 static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops = {
index 36358d435cb044a3a740756ff8e247e77020bfac..426f550056974d9d58b2868239fce3a74d0fc383 100644 (file)
@@ -102,6 +102,7 @@ struct nfsd_net {
 
        time_t nfsd4_lease;
        time_t nfsd4_grace;
+       bool somebody_reclaimed;
 
        bool nfsd_net_up;
        bool lockd_up;
index 6259a4b8579faddce80cecdf133b4515d1e558de..9eb8086ea841e6a787adc94f90b9cf0816696011 100644 (file)
@@ -202,7 +202,8 @@ nfsd3_proc_write(struct svc_rqst *rqstp)
 
        fh_copy(&resp->fh, &argp->fh);
        resp->committed = argp->stable;
-       nvecs = svc_fill_write_vector(rqstp, &argp->first, cnt);
+       nvecs = svc_fill_write_vector(rqstp, rqstp->rq_arg.pages,
+                                     &argp->first, cnt);
        if (!nvecs)
                RETURN_STATUS(nfserr_io);
        nfserr = nfsd_write(rqstp, &resp->fh, argp->offset,
@@ -289,6 +290,7 @@ nfsd3_proc_symlink(struct svc_rqst *rqstp)
                RETURN_STATUS(nfserr_nametoolong);
 
        argp->tname = svc_fill_symlink_pathname(rqstp, &argp->first,
+                                               page_address(rqstp->rq_arg.pages[0]),
                                                argp->tlen);
        if (IS_ERR(argp->tname))
                RETURN_STATUS(nfserrno(PTR_ERR(argp->tname)));
@@ -302,6 +304,7 @@ nfsd3_proc_symlink(struct svc_rqst *rqstp)
        fh_init(&resp->fh, NFS3_FHSIZE);
        nfserr = nfsd_symlink(rqstp, &resp->dirfh, argp->fname, argp->flen,
                                                   argp->tname, &resp->fh);
+       kfree(argp->tname);
        RETURN_STATUS(nfserr);
 }
 
index 1f04d2a70d257c436960abbdb0eef2ee0648cadf..601bf33c26a0bbdc036bb7b2a195fc07ccfc7fe8 100644 (file)
@@ -746,30 +746,17 @@ static int max_cb_time(struct net *net)
        return max(nn->nfsd4_lease/10, (time_t)1) * HZ;
 }
 
-static struct rpc_cred *callback_cred;
-
-int set_callback_cred(void)
-{
-       if (callback_cred)
-               return 0;
-       callback_cred = rpc_lookup_machine_cred("nfs");
-       if (!callback_cred)
-               return -ENOMEM;
-       return 0;
-}
-
-void cleanup_callback_cred(void)
-{
-       if (callback_cred) {
-               put_rpccred(callback_cred);
-               callback_cred = NULL;
-       }
-}
-
 static struct rpc_cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc_clnt *client, struct nfsd4_session *ses)
 {
        if (clp->cl_minorversion == 0) {
-               return get_rpccred(callback_cred);
+               char *principal = clp->cl_cred.cr_targ_princ ?
+                                       clp->cl_cred.cr_targ_princ : "nfs";
+               struct rpc_cred *cred;
+
+               cred = rpc_lookup_machine_cred(principal);
+               if (!IS_ERR(cred))
+                       get_rpccred(cred);
+               return cred;
        } else {
                struct rpc_auth *auth = client->cl_auth;
                struct auth_cred acred = {};
@@ -980,6 +967,7 @@ static bool nfsd4_cb_sequence_done(struct rpc_task *task, struct nfsd4_callback
                break;
        case -ESERVERFAULT:
                ++session->se_cb_seq_nr;
+               /* Fall through */
        case 1:
        case -NFS4ERR_BADSESSION:
                nfsd4_mark_cb_fault(cb->cb_clp, cb->cb_seq_status);
index 228faf00a5945397f79c2e97f0566394d6830987..2b36aa037ce03a70e598aea2e0f387168b3806e1 100644 (file)
@@ -133,27 +133,20 @@ void nfsd4_setup_layout_type(struct svc_export *exp)
        if (!(exp->ex_flags & NFSEXP_PNFS))
                return;
 
-       /*
-        * If flex file is configured, use it by default. Otherwise
-        * check if the file system supports exporting a block-like layout.
-        * If the block device supports reservations prefer the SCSI layout,
-        * otherwise advertise the block layout.
-        */
 #ifdef CONFIG_NFSD_FLEXFILELAYOUT
        exp->ex_layout_types |= 1 << LAYOUT_FLEX_FILES;
 #endif
 #ifdef CONFIG_NFSD_BLOCKLAYOUT
-       /* overwrite flex file layout selection if needed */
        if (sb->s_export_op->get_uuid &&
            sb->s_export_op->map_blocks &&
            sb->s_export_op->commit_blocks)
                exp->ex_layout_types |= 1 << LAYOUT_BLOCK_VOLUME;
 #endif
 #ifdef CONFIG_NFSD_SCSILAYOUT
-       /* overwrite block layout selection if needed */
        if (sb->s_export_op->map_blocks &&
            sb->s_export_op->commit_blocks &&
-           sb->s_bdev && sb->s_bdev->bd_disk->fops->pr_ops)
+           sb->s_bdev && sb->s_bdev->bd_disk->fops->pr_ops &&
+               blk_queue_scsi_passthrough(sb->s_bdev->bd_disk->queue))
                exp->ex_layout_types |= 1 << LAYOUT_SCSI;
 #endif
 }
index 5d99e8810b85a59bd05df3016a4c52baf48b83dc..b7bc6e1a85ac3d1472b7867ccd75b5819126f2c8 100644 (file)
@@ -354,6 +354,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        struct svc_fh *resfh = NULL;
        struct net *net = SVC_NET(rqstp);
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
+       bool reclaim = false;
 
        dprintk("NFSD: nfsd4_open filename %.*s op_openowner %p\n",
                (int)open->op_fname.len, open->op_fname.data,
@@ -424,6 +425,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                        if (status)
                                goto out;
                        open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
+                       reclaim = true;
                case NFS4_OPEN_CLAIM_FH:
                case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
                        status = do_open_fhandle(rqstp, cstate, open);
@@ -452,6 +454,8 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        WARN(status && open->op_created,
             "nfsd4_process_open2 failed to open newly-created file! status=%u\n",
             be32_to_cpu(status));
+       if (reclaim && !status)
+               nn->somebody_reclaimed = true;
 out:
        if (resfh && resfh != &cstate->current_fh) {
                fh_dup2(&cstate->current_fh, resfh);
@@ -982,24 +986,6 @@ out:
        return status;
 }
 
-static int fill_in_write_vector(struct kvec *vec, struct nfsd4_write *write)
-{
-        int i = 1;
-        int buflen = write->wr_buflen;
-
-        vec[0].iov_base = write->wr_head.iov_base;
-        vec[0].iov_len = min_t(int, buflen, write->wr_head.iov_len);
-        buflen -= vec[0].iov_len;
-
-        while (buflen) {
-                vec[i].iov_base = page_address(write->wr_pagelist[i - 1]);
-                vec[i].iov_len = min_t(int, PAGE_SIZE, buflen);
-                buflen -= vec[i].iov_len;
-                i++;
-        }
-        return i;
-}
-
 static __be32
 nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
            union nfsd4_op_u *u)
@@ -1027,7 +1013,10 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        write->wr_how_written = write->wr_stable_how;
        gen_boot_verifier(&write->wr_verifier, SVC_NET(rqstp));
 
-       nvecs = fill_in_write_vector(rqstp->rq_vec, write);
+       nvecs = svc_fill_write_vector(rqstp, write->wr_pagelist,
+                                     &write->wr_head, write->wr_buflen);
+       if (!nvecs)
+               return nfserr_io;
        WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec));
 
        status = nfsd_vfs_write(rqstp, &cstate->current_fh, filp,
@@ -1599,7 +1588,7 @@ static const char *nfsd4_op_name(unsigned opnum);
  */
 static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args)
 {
-       struct nfsd4_op *op = &args->ops[0];
+       struct nfsd4_op *first_op = &args->ops[0];
 
        /* These ordering requirements don't apply to NFSv4.0: */
        if (args->minorversion == 0)
@@ -1607,12 +1596,17 @@ static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args)
        /* This is weird, but OK, not our problem: */
        if (args->opcnt == 0)
                return nfs_ok;
-       if (op->status == nfserr_op_illegal)
+       if (first_op->status == nfserr_op_illegal)
                return nfs_ok;
-       if (!(nfsd4_ops[op->opnum].op_flags & ALLOWED_AS_FIRST_OP))
+       if (!(nfsd4_ops[first_op->opnum].op_flags & ALLOWED_AS_FIRST_OP))
                return nfserr_op_not_in_session;
-       if (op->opnum == OP_SEQUENCE)
+       if (first_op->opnum == OP_SEQUENCE)
                return nfs_ok;
+       /*
+        * So first_op is something allowed outside a session, like
+        * EXCHANGE_ID; but then it has to be the only op in the
+        * compound:
+        */
        if (args->opcnt != 1)
                return nfserr_not_only_op;
        return nfs_ok;
@@ -1726,6 +1720,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
        if (status) {
                op = &args->ops[0];
                op->status = status;
+               resp->opcnt = 1;
                goto encode_op;
        }
 
index 857141446d6b378cbdfcb09c8ec5b2df5c319d6d..b0ca0efd287510417387fe916ea9668c587ddec1 100644 (file)
@@ -1979,8 +1979,10 @@ static int copy_cred(struct svc_cred *target, struct svc_cred *source)
        target->cr_principal = kstrdup(source->cr_principal, GFP_KERNEL);
        target->cr_raw_principal = kstrdup(source->cr_raw_principal,
                                                                GFP_KERNEL);
-       if ((source->cr_principal && ! target->cr_principal) ||
-           (source->cr_raw_principal && ! target->cr_raw_principal))
+       target->cr_targ_princ = kstrdup(source->cr_targ_princ, GFP_KERNEL);
+       if ((source->cr_principal && !target->cr_principal) ||
+           (source->cr_raw_principal && !target->cr_raw_principal) ||
+           (source->cr_targ_princ && !target->cr_targ_princ))
                return -ENOMEM;
 
        target->cr_flavor = source->cr_flavor;
@@ -2057,6 +2059,7 @@ same_creds(struct svc_cred *cr1, struct svc_cred *cr2)
                || (!gid_eq(cr1->cr_gid, cr2->cr_gid))
                || !groups_equal(cr1->cr_group_info, cr2->cr_group_info))
                return false;
+       /* XXX: check that cr_targ_princ fields match ? */
        if (cr1->cr_principal == cr2->cr_principal)
                return true;
        if (!cr1->cr_principal || !cr2->cr_principal)
@@ -2956,18 +2959,18 @@ out_no_session:
        return status;
 }
 
-static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid)
+static bool nfsd4_compound_in_session(struct nfsd4_compound_state *cstate, struct nfs4_sessionid *sid)
 {
-       if (!session)
+       if (!cstate->session)
                return false;
-       return !memcmp(sid, &session->se_sessionid, sizeof(*sid));
+       return !memcmp(sid, &cstate->session->se_sessionid, sizeof(*sid));
 }
 
 __be32
 nfsd4_destroy_session(struct svc_rqst *r, struct nfsd4_compound_state *cstate,
                union nfsd4_op_u *u)
 {
-       struct nfsd4_destroy_session *sessionid = &u->destroy_session;
+       struct nfs4_sessionid *sessionid = &u->destroy_session.sessionid;
        struct nfsd4_session *ses;
        __be32 status;
        int ref_held_by_me = 0;
@@ -2975,14 +2978,14 @@ nfsd4_destroy_session(struct svc_rqst *r, struct nfsd4_compound_state *cstate,
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 
        status = nfserr_not_only_op;
-       if (nfsd4_compound_in_session(cstate->session, &sessionid->sessionid)) {
+       if (nfsd4_compound_in_session(cstatesessionid)) {
                if (!nfsd4_last_compound_op(r))
                        goto out;
                ref_held_by_me++;
        }
-       dump_sessionid(__func__, &sessionid->sessionid);
+       dump_sessionid(__func__, sessionid);
        spin_lock(&nn->client_lock);
-       ses = find_in_sessionid_hashtbl(&sessionid->sessionid, net, &status);
+       ses = find_in_sessionid_hashtbl(sessionid, net, &status);
        if (!ses)
                goto out_client_lock;
        status = nfserr_wrong_cred;
@@ -3945,9 +3948,9 @@ static void nfsd_break_one_deleg(struct nfs4_delegation *dp)
        /*
         * We're assuming the state code never drops its reference
         * without first removing the lease.  Since we're in this lease
-        * callback (and since the lease code is serialized by the kernel
-        * lock) we know the server hasn't removed the lease yet, we know
-        * it's safe to take a reference.
+        * callback (and since the lease code is serialized by the
+        * i_lock) we know the server hasn't removed the lease yet, and
+        * we know it's safe to take a reference.
         */
        refcount_inc(&dp->dl_stid.sc_count);
        nfsd4_run_cb(&dp->dl_recall);
@@ -4693,6 +4696,28 @@ nfsd4_end_grace(struct nfsd_net *nn)
         */
 }
 
+/*
+ * If we've waited a lease period but there are still clients trying to
+ * reclaim, wait a little longer to give them a chance to finish.
+ */
+static bool clients_still_reclaiming(struct nfsd_net *nn)
+{
+       unsigned long now = get_seconds();
+       unsigned long double_grace_period_end = nn->boot_time +
+                                               2 * nn->nfsd4_lease;
+
+       if (!nn->somebody_reclaimed)
+               return false;
+       nn->somebody_reclaimed = false;
+       /*
+        * If we've given them *two* lease times to reclaim, and they're
+        * still not done, give up:
+        */
+       if (time_after(now, double_grace_period_end))
+               return false;
+       return true;
+}
+
 static time_t
 nfs4_laundromat(struct nfsd_net *nn)
 {
@@ -4706,6 +4731,11 @@ nfs4_laundromat(struct nfsd_net *nn)
        time_t t, new_timeo = nn->nfsd4_lease;
 
        dprintk("NFSD: laundromat service - starting\n");
+
+       if (clients_still_reclaiming(nn)) {
+               new_timeo = 0;
+               goto out;
+       }
        nfsd4_end_grace(nn);
        INIT_LIST_HEAD(&reaplist);
        spin_lock(&nn->client_lock);
@@ -4803,7 +4833,7 @@ nfs4_laundromat(struct nfsd_net *nn)
                posix_unblock_lock(&nbl->nbl_lock);
                free_blocked_lock(nbl);
        }
-
+out:
        new_timeo = max_t(time_t, new_timeo, NFSD_LAUNDROMAT_MINTIMEOUT);
        return new_timeo;
 }
@@ -6053,6 +6083,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        case 0: /* success! */
                nfs4_inc_and_copy_stateid(&lock->lk_resp_stateid, &lock_stp->st_stid);
                status = 0;
+               if (lock->lk_reclaim)
+                       nn->somebody_reclaimed = true;
                break;
        case FILE_LOCK_DEFERRED:
                nbl = NULL;
@@ -6293,7 +6325,7 @@ check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner)
                return status;
        }
 
-       inode = file_inode(filp);
+       inode = locks_inode(filp);
        flctx = inode->i_flctx;
 
        if (flctx && !list_empty_careful(&flctx->flc_posix)) {
@@ -7199,14 +7231,10 @@ nfs4_state_start(void)
 {
        int ret;
 
-       ret = set_callback_cred();
-       if (ret)
-               return ret;
-
        laundry_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, "nfsd4");
        if (laundry_wq == NULL) {
                ret = -ENOMEM;
-               goto out_cleanup_cred;
+               goto out;
        }
        ret = nfsd4_create_callback_queue();
        if (ret)
@@ -7217,8 +7245,7 @@ nfs4_state_start(void)
 
 out_free_laundry:
        destroy_workqueue(laundry_wq);
-out_cleanup_cred:
-       cleanup_callback_cred();
+out:
        return ret;
 }
 
@@ -7255,7 +7282,6 @@ nfs4_state_shutdown(void)
 {
        destroy_workqueue(laundry_wq);
        nfsd4_destroy_callback_queue();
-       cleanup_callback_cred();
 }
 
 static void
index a96843c59fc146f1abb8c3a623984f29a083fefb..418fa9c78186b6b6f5d36ced347d1255ce2505fe 100644 (file)
@@ -1390,10 +1390,8 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
                        p += XDR_QUADLEN(dummy);
                }
 
-               /* ssp_window and ssp_num_gss_handles */
+               /* ignore ssp_window and ssp_num_gss_handles: */
                READ_BUF(8);
-               dummy = be32_to_cpup(p++);
-               dummy = be32_to_cpup(p++);
                break;
        default:
                goto xdr_error;
@@ -2006,6 +2004,31 @@ static __be32 *encode_change(__be32 *p, struct kstat *stat, struct inode *inode,
        return p;
 }
 
+/*
+ * ctime (in NFSv4, time_metadata) is not writeable, and the client
+ * doesn't really care what resolution could theoretically be stored by
+ * the filesystem.
+ *
+ * The client cares how close together changes can be while still
+ * guaranteeing ctime changes.  For most filesystems (which have
+ * timestamps with nanosecond fields) that is limited by the resolution
+ * of the time returned from current_time() (which I'm assuming to be
+ * 1/HZ).
+ */
+static __be32 *encode_time_delta(__be32 *p, struct inode *inode)
+{
+       struct timespec ts;
+       u32 ns;
+
+       ns = max_t(u32, NSEC_PER_SEC/HZ, inode->i_sb->s_time_gran);
+       ts = ns_to_timespec(ns);
+
+       p = xdr_encode_hyper(p, ts.tv_sec);
+       *p++ = cpu_to_be32(ts.tv_nsec);
+
+       return p;
+}
+
 static __be32 *encode_cinfo(__be32 *p, struct nfsd4_change_info *c)
 {
        *p++ = cpu_to_be32(c->atomic);
@@ -2797,9 +2820,7 @@ out_acl:
                p = xdr_reserve_space(xdr, 12);
                if (!p)
                        goto out_resource;
-               *p++ = cpu_to_be32(0);
-               *p++ = cpu_to_be32(1);
-               *p++ = cpu_to_be32(0);
+               p = encode_time_delta(p, d_inode(dentry));
        }
        if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
                p = xdr_reserve_space(xdr, 12);
@@ -2868,6 +2889,16 @@ out_acl:
                        goto out;
        }
 
+       if (bmval2 & FATTR4_WORD2_CHANGE_ATTR_TYPE) {
+               p = xdr_reserve_space(xdr, 4);
+               if (!p)
+                       goto out_resource;
+               if (IS_I_VERSION(d_inode(dentry)))
+                       *p++ = cpu_to_be32(NFS4_CHANGE_TYPE_IS_MONOTONIC_INCR);
+               else
+                       *p++ = cpu_to_be32(NFS4_CHANGE_TYPE_IS_TIME_METADATA);
+       }
+
        if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
                status = nfsd4_encode_security_label(xdr, rqstp, context,
                                                                contextlen);
index d107b4426f7eb15443188e8538c4b6e8e99d4fa8..7fb9f7c667b11077adc4afacb20d5c75319c5841 100644 (file)
@@ -73,7 +73,7 @@ static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
 static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size);
 #endif
 
-static ssize_t (*write_op[])(struct file *, char *, size_t) = {
+static ssize_t (*const write_op[])(struct file *, char *, size_t) = {
        [NFSD_Fh] = write_filehandle,
        [NFSD_FO_UnlockIP] = write_unlock_ip,
        [NFSD_FO_UnlockFS] = write_unlock_fs,
@@ -1237,8 +1237,9 @@ static __net_init int nfsd_init_net(struct net *net)
        retval = nfsd_idmap_init(net);
        if (retval)
                goto out_idmap_error;
-       nn->nfsd4_lease = 90;   /* default lease time */
-       nn->nfsd4_grace = 90;
+       nn->nfsd4_lease = 45;   /* default lease time */
+       nn->nfsd4_grace = 45;
+       nn->somebody_reclaimed = false;
        nn->clverifier_counter = prandom_u32();
        nn->clientid_counter = prandom_u32();
 
index 3fce905d036502987d4ebb9560800a28fd37ad98..066899929863c020f8a87a94f0399b770c46eb78 100644 (file)
@@ -360,6 +360,7 @@ void                nfsd_lockd_shutdown(void);
 
 #define NFSD4_2_SUPPORTED_ATTRS_WORD2 \
        (NFSD4_1_SUPPORTED_ATTRS_WORD2 | \
+       FATTR4_WORD2_CHANGE_ATTR_TYPE | \
        FATTR4_WORD2_MODE_UMASK | \
        NFSD4_2_SECURITY_ATTRS)
 
index a008e7634181a17001d995f3a20b5ac2a63e6cbf..b319080288c36c8f77dee284ea37db1b84aa3866 100644 (file)
@@ -451,7 +451,7 @@ static bool fsid_type_ok_for_exp(u8 fsid_type, struct svc_export *exp)
        switch (fsid_type) {
        case FSID_DEV:
                if (!old_valid_dev(exp_sb(exp)->s_dev))
-                       return 0;
+                       return false;
                /* FALL THROUGH */
        case FSID_MAJOR_MINOR:
        case FSID_ENCODE_DEV:
@@ -461,13 +461,13 @@ static bool fsid_type_ok_for_exp(u8 fsid_type, struct svc_export *exp)
        case FSID_UUID8:
        case FSID_UUID16:
                if (!is_root_export(exp))
-                       return 0;
+                       return false;
                /* fall through */
        case FSID_UUID4_INUM:
        case FSID_UUID16_INUM:
                return exp->ex_uuid != NULL;
        }
-       return 1;
+       return true;
 }
 
 
index f107f9fa8e158e611d185dc14329ea2ce1fcaa47..0d20fd161225a3d97b7a7a046bb4cc8d53f404f4 100644 (file)
@@ -218,7 +218,8 @@ nfsd_proc_write(struct svc_rqst *rqstp)
                SVCFH_fmt(&argp->fh),
                argp->len, argp->offset);
 
-       nvecs = svc_fill_write_vector(rqstp, &argp->first, cnt);
+       nvecs = svc_fill_write_vector(rqstp, rqstp->rq_arg.pages,
+                                     &argp->first, cnt);
        if (!nvecs)
                return nfserr_io;
        nfserr = nfsd_write(rqstp, fh_copy(&resp->fh, &argp->fh),
@@ -453,6 +454,7 @@ nfsd_proc_symlink(struct svc_rqst *rqstp)
                return nfserr_nametoolong;
 
        argp->tname = svc_fill_symlink_pathname(rqstp, &argp->first,
+                                               page_address(rqstp->rq_arg.pages[0]),
                                                argp->tlen);
        if (IS_ERR(argp->tname))
                return nfserrno(PTR_ERR(argp->tname));
@@ -465,6 +467,7 @@ nfsd_proc_symlink(struct svc_rqst *rqstp)
        nfserr = nfsd_symlink(rqstp, &argp->ffh, argp->fname, argp->flen,
                                                 argp->tname, &newfh);
 
+       kfree(argp->tname);
        fh_put(&argp->ffh);
        fh_put(&newfh);
        return nfserr;
index f3772ea8ba0d394f95c302584093d57fc19e37d7..0b15dac7e609716ce032d4fa6873eefe8e2d4690 100644 (file)
@@ -617,8 +617,6 @@ extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir,
                                                        struct nfsd_net *nn);
 extern __be32 nfs4_check_open_reclaim(clientid_t *clid,
                struct nfsd4_compound_state *cstate, struct nfsd_net *nn);
-extern int set_callback_cred(void);
-extern void cleanup_callback_cred(void);
 extern void nfsd4_probe_callback(struct nfs4_client *clp);
 extern void nfsd4_probe_callback_sync(struct nfs4_client *clp);
 extern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *);
index 03b8ba933eb2a3dcc781eaf9e57594da5a40f48b..235b959fc2b3a706866fd9e96447764641d94536 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * alloc.c - NILFS dat/inode allocator
  *
  * Copyright (C) 2006-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Originally written by Koji Sato.
  * Two allocators were unified by Ryusuke Konishi and Amagai Yoshiji.
  */
index 05149e606a78a8dfd8f4a701863eccddb0e4979e..0303c3968cee06d37c25fa18c9a958aa69dea27a 100644 (file)
@@ -1,18 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * alloc.h - persistent object (dat entry/disk inode) allocator/deallocator
  *
  * Copyright (C) 2006-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Originally written by Koji Sato.
  * Two allocators were unified by Ryusuke Konishi and Amagai Yoshiji.
  */
index 01fb1831ca250b43172c7b046a2447b590feda0e..fb5a9a8a13cf7d734c0c13f38df097786c5ba5a1 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * bmap.c - NILFS block mapping.
  *
  * Copyright (C) 2006-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Koji Sato.
  */
 
index 2b6ffbe5997a2f8bc77e80621999d4f1d651e02f..2c63858e81c9ce089820e9803a7a98f6121c524b 100644 (file)
@@ -1,18 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * bmap.h - NILFS block mapping.
  *
  * Copyright (C) 2006-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Koji Sato.
  */
 
index dec98cab729dd90fdb491e5ac770c8bf99867aec..ebb24a314f43129fce712b87ee5d44e9e38e2979 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * btnode.c - NILFS B-tree node cache
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Originally written by Seiji Kihara.
  * Fully revised by Ryusuke Konishi for stabilization and simplification.
  *
index 4e8aaa1aeb65db70bc1f7fcc9faae7a81f96d09c..0f88dbc9bcb3ef4536ff13a28321d432070a8413 100644 (file)
@@ -1,18 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * btnode.h - NILFS B-tree node cache
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Seiji Kihara.
  * Revised by Ryusuke Konishi.
  */
index 16a7a67a11c9e2098dde76c6eecee10fb1838b47..23e043eca237bd2e760882f5783b28a51558ae64 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * btree.c - NILFS B-tree.
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Koji Sato.
  */
 
index 2184e47fa4bf6ff297feea6caa7fce3fc761d31c..d1421b646ce46bbc4afd851e7b01175f5b8d53be 100644 (file)
@@ -1,18 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * btree.h - NILFS B-tree.
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Koji Sato.
  */
 
index a15a1601e931dab6139a9f8dcee0428f06e1f485..8d41311b5db4b45b5a1536a10c90015e9e60e01e 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * cpfile.c - NILFS checkpoint file.
  *
  * Copyright (C) 2006-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Koji Sato.
  */
 
index 6eca972f9673cc676e9469b848567727f1fb61b2..6336222df24a8fee683afca437db55a9c29b3e4c 100644 (file)
@@ -1,18 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * cpfile.h - NILFS checkpoint file.
  *
  * Copyright (C) 2006-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Koji Sato.
  */
 
index dffedb2f88179a321b13ea3901c9fe7efd03ea22..6f4066636be9a3eba91d78852246edabdffcff0d 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * dat.c - NILFS disk address translation.
  *
  * Copyright (C) 2006-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Koji Sato.
  */
 
index 57dc6cf466d02d3d082fb85125b37338ebfad94c..b17ee34580ae69dc4898785552cca5c83fe56535 100644 (file)
@@ -1,18 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * dat.h - NILFS disk address translation.
  *
  * Copyright (C) 2006-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Koji Sato.
  */
 
index 582831ab3eb95dee645907bf4be2402f62087748..81394e22d0a09a1ee88ac45850e5d63e98301001 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * dir.c - NILFS directory entry operations
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Modified for NILFS by Amagai Yoshiji.
  */
 /*
index 96e3ed0d9652b67de00717f0e9a9042b3106620d..533e24ea3a88d208e8e39bf1a14a53852accb907 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * direct.c - NILFS direct block pointer.
  *
  * Copyright (C) 2006-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Koji Sato.
  */
 
index cfe85e848bba1e9e07aea1ea93dad3b3d520b342..ec9a23c77994e76954ef0921c7607c550dc91215 100644 (file)
@@ -1,18 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * direct.h - NILFS direct block pointer.
  *
  * Copyright (C) 2006-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Koji Sato.
  */
 
index c5fa3dee72fc0b962dec9d3134d8c0d723422134..64bc81363c6cc0437dd4c757615af395c85b0475 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * file.c - NILFS regular file handling primitives including fsync().
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Amagai Yoshiji and Ryusuke Konishi.
  */
 
@@ -51,7 +42,7 @@ int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
        return err;
 }
 
-static int nilfs_page_mkwrite(struct vm_fault *vmf)
+static vm_fault_t nilfs_page_mkwrite(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
        struct page *page = vmf->page;
index 853a831dcde0890481d45fdfadf89ff8a35b7671..aa3c328ee189c4409c1c4fe497677b2278c12553 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * gcinode.c - dummy inodes to buffer blocks for garbage collection
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Seiji Kihara, Amagai Yoshiji, and Ryusuke Konishi.
  * Revised by Ryusuke Konishi.
  *
index b8fa45c20c63fdbded97c3474ac68438529cfca6..4140d232cadc04dbf65aa6a76b4660f9d30c3537 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * ifile.c - NILFS inode file
  *
  * Copyright (C) 2006-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Amagai Yoshiji.
  * Revised by Ryusuke Konishi.
  *
index 188b94fe0ec5fe3f313160b0c8568e269b582253..a1e1e5711a054fd2fc9472234c34dbd88163adb0 100644 (file)
@@ -1,18 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * ifile.h - NILFS inode file
  *
  * Copyright (C) 2006-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Amagai Yoshiji.
  * Revised by Ryusuke Konishi.
  *
index 6a612d832e7de41f1273805fd8db2ad0f0433221..671085512e0fde9e8be3274629db21e8c0561b96 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * inode.c - NILFS inode operations.
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Ryusuke Konishi.
  *
  */
index 1d2c3d7711feb94dea6ce3a0a1540a41a1bef1d2..9b96d79eea6c81247380142fb9db0ef1ad0c51cb 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * ioctl.c - NILFS ioctl operations.
  *
  * Copyright (C) 2007, 2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Koji Sato.
  */
 
index c6bc1033e7d2ccf3795bde38b18a5787e2644d1d..700870a92bc4a1a2499e2ffef381613f8bad6e1a 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * mdt.c - meta data file for NILFS
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Ryusuke Konishi.
  */
 
index 3f67f3932097b408fd6d7161a90e62170992a71a..e77aea4bb921c37c212558b11137022e796a5bae 100644 (file)
@@ -1,18 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * mdt.h - NILFS meta data file prototype and definitions
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Ryusuke Konishi.
  */
 
index dd52d3f82e8d673bd43dd99dfdfff6658b959357..9fe6d4ab74f01ef3d7055d4bb1ace9a73e441ad7 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * namei.c - NILFS pathname lookup operations.
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Modified for NILFS by Amagai Yoshiji and Ryusuke Konishi.
  */
 /*
index 33f8c8fc96e8e772bbe163da521e7ca2e7fa65a0..a2f247b6a209ec250cb7da2c1cbede10c14cf03f 100644 (file)
@@ -1,18 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * nilfs.h - NILFS local header file.
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Koji Sato and Ryusuke Konishi.
  */
 
index 4cb850a6f1c2c64794449e922c6e40f69aa585b6..329a056b73b178958e71308c35b945a0c39de834 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * page.c - buffer/page management specific to NILFS
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Ryusuke Konishi and Seiji Kihara.
  */
 
index f3687c958fa848c20a3d17cab71b5a0da77de5d1..62b9bb469e92f3e58bd2378a8da979acb8364466 100644 (file)
@@ -1,18 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * page.h - buffer/page management specific to NILFS
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Ryusuke Konishi and Seiji Kihara.
  */
 
index 5139efed1888294a425499ceba313f3747567b56..140b663e91c7fbf826702e9a27fce936ac80333f 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * recovery.c - NILFS recovery logic
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Ryusuke Konishi.
  */
 
index 68cb9e4740b4e818836a56dcdc24a05d6e3e5f51..20c479b5e41b8c7a9bbd09d309cf33aa51e3a90d 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * segbuf.c - NILFS segment buffer
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Ryusuke Konishi.
  *
  */
index 10e16935fff655c914c34055d526eccc172b409b..9bea1bd59041e0e0b69a379398f6877face96b3b 100644 (file)
@@ -1,18 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * segbuf.h - NILFS Segment buffer prototypes and definitions
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Ryusuke Konishi.
  *
  */
index 0953635e7d48e7915b35cd63c44ff1b6bfcc8e68..445eef41bfaf00a948b5c29f3041703bba369dfa 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * segment.c - NILFS segment constructor.
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Ryusuke Konishi.
  *
  */
index 04634e3e3d583af75d1dd77329582c9f8bd309fc..f5cf5308f3fcad1be6f0863c560ad30e04059c59 100644 (file)
@@ -1,18 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * segment.h - NILFS Segment constructor prototypes and definitions
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Ryusuke Konishi.
  *
  */
index c7fa139d50e8287e481586fe177df2c03ef9e6de..bf3f8f05c89b3dbb10849111e7a0815b2a3786e5 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * sufile.c - NILFS segment usage file.
  *
  * Copyright (C) 2006-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Koji Sato.
  * Revised by Ryusuke Konishi.
  */
index 673a891350f49599e30a5666afd85973a5419522..c4e2c7a7add1d5d1d5f89948507810c468c0b403 100644 (file)
@@ -1,18 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * sufile.h - NILFS segment usage file.
  *
  * Copyright (C) 2006-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Koji Sato.
  */
 
index 6ffeca84d7c3c10830687601daaea788d9ef5415..26290aa1023f31950017cdba5c31fb589934e701 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * super.c - NILFS module and super block management.
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Ryusuke Konishi.
  */
 /*
@@ -834,7 +825,7 @@ static int nilfs_setup_super(struct super_block *sb, int is_mount)
                sbp[0]->s_max_mnt_count = cpu_to_le16(NILFS_DFL_MAX_MNT_COUNT);
 
        sbp[0]->s_mnt_count = cpu_to_le16(mnt_count + 1);
-       sbp[0]->s_mtime = cpu_to_le64(get_seconds());
+       sbp[0]->s_mtime = cpu_to_le64(ktime_get_real_seconds());
 
 skip_mount_setup:
        sbp[0]->s_state =
index 4b25837e77245902dee4a3674206adf1262c83b9..e60be7bb55b0b870e99d7844f6e3495d7d17e365 100644 (file)
@@ -1,19 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * sysfs.c - sysfs support implementation.
  *
  * Copyright (C) 2005-2014 Nippon Telegraph and Telephone Corporation.
  * Copyright (C) 2014 HGST, Inc., a Western Digital Company.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
  * Written by Vyacheslav Dubeyko <Vyacheslav.Dubeyko@hgst.com>
  */
 
index 648cedf9c06ec75c3e783d0d5e6f5b91ae1891d9..d001eb862daece4420aacc6fa450a8a35d64d7f9 100644 (file)
@@ -1,19 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * sysfs.h - sysfs support declarations.
  *
  * Copyright (C) 2005-2014 Nippon Telegraph and Telephone Corporation.
  * Copyright (C) 2014 HGST, Inc., a Western Digital Company.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
  * Written by Vyacheslav Dubeyko <Vyacheslav.Dubeyko@hgst.com>
  */
 
index 1a85317e83f0f751332118daf559fc9ba79fb560..484785cdf96e220525a57222190ac3fe0bca7f71 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * the_nilfs.c - the_nilfs shared structure.
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Ryusuke Konishi.
  *
  */
index 36da1779f9766f1e32bc8f8c2de6a7d93413403f..380a543c5b19bd424782e8393ecc285af648396e 100644 (file)
@@ -1,18 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * the_nilfs.h - the_nilfs shared structure.
  *
  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone 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; 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.
- *
  * Written by Ryusuke Konishi.
  *
  */
index a6365e6bc04704fd8f0735a1a90af5e72658b6ba..58d77dc696eb5b804a228b8ba8f74758c3bc164d 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/fs.h>
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/sched/signal.h>
 #include <linux/dnotify.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
@@ -353,7 +354,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
                goto out;
        }
 
-       __f_setown(filp, task_pid(current), PIDTYPE_PID, 0);
+       __f_setown(filp, task_pid(current), PIDTYPE_TGID, 0);
 
        error = attach_dn(dn, dn_mark, id, fd, filp, mask);
        /* !error means that we attached the dn to the dn_mark, so don't free it */
index eb4e75175cfb77bac8490e1a7c5a713aaeebc594..94b52157bf8db41371077c91d068b5fb9b3d64bc 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/mount.h>
 #include <linux/sched.h>
 #include <linux/sched/user.h>
+#include <linux/sched/signal.h>
 #include <linux/types.h>
 #include <linux/wait.h>
 #include <linux/audit.h>
index f174397b63a046f32ca24a7be30080c4ff5fe009..ababdbfab537ef259b20079cd74d7f036e293fc7 100644 (file)
@@ -351,16 +351,9 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
 
        iter_info.srcu_idx = srcu_read_lock(&fsnotify_mark_srcu);
 
-       if ((mask & FS_MODIFY) ||
-           (test_mask & to_tell->i_fsnotify_mask)) {
-               iter_info.marks[FSNOTIFY_OBJ_TYPE_INODE] =
-                       fsnotify_first_mark(&to_tell->i_fsnotify_marks);
-       }
-
-       if (mnt && ((mask & FS_MODIFY) ||
-                   (test_mask & mnt->mnt_fsnotify_mask))) {
-               iter_info.marks[FSNOTIFY_OBJ_TYPE_INODE] =
-                       fsnotify_first_mark(&to_tell->i_fsnotify_marks);
+       iter_info.marks[FSNOTIFY_OBJ_TYPE_INODE] =
+               fsnotify_first_mark(&to_tell->i_fsnotify_marks);
+       if (mnt) {
                iter_info.marks[FSNOTIFY_OBJ_TYPE_VFSMOUNT] =
                        fsnotify_first_mark(&mnt->mnt_fsnotify_marks);
        }
index 05506d60131c69d546f574e9633f7d01039c70c6..59cdb27826defe2ddac7023438132c1b80a49c29 100644 (file)
@@ -132,13 +132,13 @@ static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
        struct fsnotify_mark *mark;
 
        assert_spin_locked(&conn->lock);
+       /* We can get detached connector here when inode is getting unlinked. */
+       if (!fsnotify_valid_obj_type(conn->type))
+               return;
        hlist_for_each_entry(mark, &conn->list, obj_list) {
                if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)
                        new_mask |= mark->mask;
        }
-       if (WARN_ON(!fsnotify_valid_obj_type(conn->type)))
-               return;
-
        *fsnotify_conn_mask_p(conn) = new_mask;
 }
 
index 255f758af03a0998dd2e233397dde23fc6740760..9fa35cb6f6e0b5b38023f45512fc75200be4c694 100644 (file)
@@ -2537,19 +2537,14 @@ static int ocfs2_file_clone_range(struct file *file_in,
                                         len, false);
 }
 
-static ssize_t ocfs2_file_dedupe_range(struct file *src_file,
-                                      u64 loff,
-                                      u64 len,
-                                      struct file *dst_file,
-                                      u64 dst_loff)
+static int ocfs2_file_dedupe_range(struct file *file_in,
+                                  loff_t pos_in,
+                                  struct file *file_out,
+                                  loff_t pos_out,
+                                  u64 len)
 {
-       int error;
-
-       error = ocfs2_reflink_remap_range(src_file, loff, dst_file, dst_loff,
+       return ocfs2_reflink_remap_range(file_in, pos_in, file_out, pos_out,
                                          len, true);
-       if (error)
-               return error;
-       return len;
 }
 
 const struct inode_operations ocfs2_file_iops = {
index d98e19239bb71eb0a19c3dbfe94fa122e4d75dec..0285ce7dbd515c8c7bfd9e63f0211cabfb818801 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -68,7 +68,6 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
 long vfs_truncate(const struct path *path, loff_t length)
 {
        struct inode *inode;
-       struct dentry *upperdentry;
        long error;
 
        inode = path->dentry->d_inode;
@@ -91,17 +90,7 @@ long vfs_truncate(const struct path *path, loff_t length)
        if (IS_APPEND(inode))
                goto mnt_drop_write_and_out;
 
-       /*
-        * If this is an overlayfs then do as if opening the file so we get
-        * write access on the upper inode, not on the overlay inode.  For
-        * non-overlay filesystems d_real() is an identity function.
-        */
-       upperdentry = d_real(path->dentry, NULL, O_WRONLY, 0);
-       error = PTR_ERR(upperdentry);
-       if (IS_ERR(upperdentry))
-               goto mnt_drop_write_and_out;
-
-       error = get_write_access(upperdentry->d_inode);
+       error = get_write_access(inode);
        if (error)
                goto mnt_drop_write_and_out;
 
@@ -120,7 +109,7 @@ long vfs_truncate(const struct path *path, loff_t length)
                error = do_truncate(path->dentry, length, 0, NULL);
 
 put_write_and_out:
-       put_write_access(upperdentry->d_inode);
+       put_write_access(inode);
 mnt_drop_write_and_out:
        mnt_drop_write(path->mnt);
 out:
@@ -707,12 +696,12 @@ int ksys_fchown(unsigned int fd, uid_t user, gid_t group)
        if (!f.file)
                goto out;
 
-       error = mnt_want_write_file_path(f.file);
+       error = mnt_want_write_file(f.file);
        if (error)
                goto out_fput;
        audit_file(f.file);
        error = chown_common(&f.file->f_path, user, group);
-       mnt_drop_write_file_path(f.file);
+       mnt_drop_write_file(f.file);
 out_fput:
        fdput(f);
 out:
@@ -887,13 +876,8 @@ EXPORT_SYMBOL(file_path);
  */
 int vfs_open(const struct path *path, struct file *file)
 {
-       struct dentry *dentry = d_real(path->dentry, NULL, file->f_flags, 0);
-
-       if (IS_ERR(dentry))
-               return PTR_ERR(dentry);
-
        file->f_path = *path;
-       return do_dentry_open(file, d_backing_inode(dentry), NULL);
+       return do_dentry_open(file, d_backing_inode(path->dentry), NULL);
 }
 
 struct file *dentry_open(const struct path *path, int flags,
@@ -919,6 +903,24 @@ struct file *dentry_open(const struct path *path, int flags,
 }
 EXPORT_SYMBOL(dentry_open);
 
+struct file *open_with_fake_path(const struct path *path, int flags,
+                               struct inode *inode, const struct cred *cred)
+{
+       struct file *f = alloc_empty_file_noaccount(flags, cred);
+       if (!IS_ERR(f)) {
+               int error;
+
+               f->f_path = *path;
+               error = do_dentry_open(f, inode, NULL);
+               if (error) {
+                       fput(f);
+                       f = ERR_PTR(error);
+               }
+       }
+       return f;
+}
+EXPORT_SYMBOL(open_with_fake_path);
+
 static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op)
 {
        int lookup_flags = 0;
index 9384164253ac6e825c0174e66039088f5a0931a3..2ef91be2a04ee1a3a13581a8c9cb1309267f2786 100644 (file)
@@ -64,6 +64,7 @@ config OVERLAY_FS_NFS_EXPORT
        bool "Overlayfs: turn on NFS export feature by default"
        depends on OVERLAY_FS
        depends on OVERLAY_FS_INDEX
+       depends on !OVERLAY_FS_METACOPY
        help
          If this config option is enabled then overlay filesystems will use
          the index directory to decode overlay NFS file handles by default.
@@ -103,3 +104,21 @@ config OVERLAY_FS_XINO_AUTO
          For more information, see Documentation/filesystems/overlayfs.txt
 
          If unsure, say N.
+
+config OVERLAY_FS_METACOPY
+       bool "Overlayfs: turn on metadata only copy up feature by default"
+       depends on OVERLAY_FS
+       select OVERLAY_FS_REDIRECT_DIR
+       help
+         If this config option is enabled then overlay filesystems will
+         copy up only metadata where appropriate and data copy up will
+         happen when a file is opened for WRITE operation. It is still
+         possible to turn off this feature globally with the "metacopy=off"
+         module option or on a filesystem instance basis with the
+         "metacopy=off" mount option.
+
+         Note, that this feature is not backward compatible.  That is,
+         mounting an overlay which has metacopy only inodes on a kernel
+         that doesn't support this feature will have unexpected results.
+
+         If unsure, say N.
index 30802347a0204b4adcd680c898ceca135132f07d..46e1ff8ac0564c323ca6e200a321da0d76e536d0 100644 (file)
@@ -4,5 +4,5 @@
 
 obj-$(CONFIG_OVERLAY_FS) += overlay.o
 
-overlay-objs := super.o namei.o util.o inode.o dir.o readdir.o copy_up.o \
-               export.o
+overlay-objs := super.o namei.o util.o inode.o file.o dir.o readdir.o \
+               copy_up.o export.o
index ddaddb4ce4c3dfe515b438fd6aafc51885eba362..296037afecdb4e689d458b54ffc597ed2265bbf9 100644 (file)
 
 #define OVL_COPY_UP_CHUNK_SIZE (1 << 20)
 
-static bool __read_mostly ovl_check_copy_up;
-module_param_named(check_copy_up, ovl_check_copy_up, bool,
-                  S_IWUSR | S_IRUGO);
-MODULE_PARM_DESC(ovl_check_copy_up,
-                "Warn on copy-up when causing process also has a R/O fd open");
-
-static int ovl_check_fd(const void *data, struct file *f, unsigned int fd)
+static int ovl_ccup_set(const char *buf, const struct kernel_param *param)
 {
-       const struct dentry *dentry = data;
-
-       if (file_inode(f) == d_inode(dentry))
-               pr_warn_ratelimited("overlayfs: Warning: Copying up %pD, but open R/O on fd %u which will cease to be coherent [pid=%d %s]\n",
-                                   f, fd, current->pid, current->comm);
+       pr_warn("overlayfs: \"check_copy_up\" module option is obsolete\n");
        return 0;
 }
 
-/*
- * Check the fds open by this process and warn if something like the following
- * scenario is about to occur:
- *
- *     fd1 = open("foo", O_RDONLY);
- *     fd2 = open("foo", O_RDWR);
- */
-static void ovl_do_check_copy_up(struct dentry *dentry)
+static int ovl_ccup_get(char *buf, const struct kernel_param *param)
 {
-       if (ovl_check_copy_up)
-               iterate_fd(current->files, 0, ovl_check_fd, dentry);
+       return sprintf(buf, "N\n");
 }
 
+module_param_call(check_copy_up, ovl_ccup_set, ovl_ccup_get, NULL, 0644);
+MODULE_PARM_DESC(ovl_check_copy_up, "Obsolete; does nothing");
+
 int ovl_copy_xattr(struct dentry *old, struct dentry *new)
 {
        ssize_t list_size, size, value_size = 0;
@@ -195,6 +180,16 @@ out_fput:
        return error;
 }
 
+static int ovl_set_size(struct dentry *upperdentry, struct kstat *stat)
+{
+       struct iattr attr = {
+               .ia_valid = ATTR_SIZE,
+               .ia_size = stat->size,
+       };
+
+       return notify_change(upperdentry, &attr, NULL);
+}
+
 static int ovl_set_timestamps(struct dentry *upperdentry, struct kstat *stat)
 {
        struct iattr attr = {
@@ -403,6 +398,7 @@ struct ovl_copy_up_ctx {
        bool tmpfile;
        bool origin;
        bool indexed;
+       bool metacopy;
 };
 
 static int ovl_link_up(struct ovl_copy_up_ctx *c)
@@ -505,28 +501,10 @@ static int ovl_copy_up_inode(struct ovl_copy_up_ctx *c, struct dentry *temp)
 {
        int err;
 
-       if (S_ISREG(c->stat.mode)) {
-               struct path upperpath;
-
-               ovl_path_upper(c->dentry, &upperpath);
-               BUG_ON(upperpath.dentry != NULL);
-               upperpath.dentry = temp;
-
-               err = ovl_copy_up_data(&c->lowerpath, &upperpath, c->stat.size);
-               if (err)
-                       return err;
-       }
-
        err = ovl_copy_xattr(c->lowerpath.dentry, temp);
        if (err)
                return err;
 
-       inode_lock(temp->d_inode);
-       err = ovl_set_attr(temp, &c->stat);
-       inode_unlock(temp->d_inode);
-       if (err)
-               return err;
-
        /*
         * Store identifier of lower inode in upper inode xattr to
         * allow lookup of the copy up origin inode.
@@ -540,7 +518,34 @@ static int ovl_copy_up_inode(struct ovl_copy_up_ctx *c, struct dentry *temp)
                        return err;
        }
 
-       return 0;
+       if (S_ISREG(c->stat.mode) && !c->metacopy) {
+               struct path upperpath, datapath;
+
+               ovl_path_upper(c->dentry, &upperpath);
+               BUG_ON(upperpath.dentry != NULL);
+               upperpath.dentry = temp;
+
+               ovl_path_lowerdata(c->dentry, &datapath);
+               err = ovl_copy_up_data(&datapath, &upperpath, c->stat.size);
+               if (err)
+                       return err;
+       }
+
+       if (c->metacopy) {
+               err = ovl_check_setxattr(c->dentry, temp, OVL_XATTR_METACOPY,
+                                        NULL, 0, -EOPNOTSUPP);
+               if (err)
+                       return err;
+       }
+
+       inode_lock(temp->d_inode);
+       if (c->metacopy)
+               err = ovl_set_size(temp, &c->stat);
+       if (!err)
+               err = ovl_set_attr(temp, &c->stat);
+       inode_unlock(temp->d_inode);
+
+       return err;
 }
 
 static int ovl_copy_up_locked(struct ovl_copy_up_ctx *c)
@@ -575,6 +580,8 @@ static int ovl_copy_up_locked(struct ovl_copy_up_ctx *c)
        if (err)
                goto out;
 
+       if (!c->metacopy)
+               ovl_set_upperdata(d_inode(c->dentry));
        inode = d_inode(c->dentry);
        ovl_inode_update(inode, newdentry);
        if (S_ISDIR(inode->i_mode))
@@ -677,6 +684,49 @@ out:
        return err;
 }
 
+static bool ovl_need_meta_copy_up(struct dentry *dentry, umode_t mode,
+                                 int flags)
+{
+       struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
+
+       if (!ofs->config.metacopy)
+               return false;
+
+       if (!S_ISREG(mode))
+               return false;
+
+       if (flags && ((OPEN_FMODE(flags) & FMODE_WRITE) || (flags & O_TRUNC)))
+               return false;
+
+       return true;
+}
+
+/* Copy up data of an inode which was copied up metadata only in the past. */
+static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c)
+{
+       struct path upperpath, datapath;
+       int err;
+
+       ovl_path_upper(c->dentry, &upperpath);
+       if (WARN_ON(upperpath.dentry == NULL))
+               return -EIO;
+
+       ovl_path_lowerdata(c->dentry, &datapath);
+       if (WARN_ON(datapath.dentry == NULL))
+               return -EIO;
+
+       err = ovl_copy_up_data(&datapath, &upperpath, c->stat.size);
+       if (err)
+               return err;
+
+       err = vfs_removexattr(upperpath.dentry, OVL_XATTR_METACOPY);
+       if (err)
+               return err;
+
+       ovl_set_upperdata(d_inode(c->dentry));
+       return err;
+}
+
 static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
                           int flags)
 {
@@ -698,6 +748,8 @@ static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
        if (err)
                return err;
 
+       ctx.metacopy = ovl_need_meta_copy_up(dentry, ctx.stat.mode, flags);
+
        if (parent) {
                ovl_path_upper(parent, &parentpath);
                ctx.destdir = parentpath.dentry;
@@ -719,9 +771,8 @@ static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
                if (IS_ERR(ctx.link))
                        return PTR_ERR(ctx.link);
        }
-       ovl_do_check_copy_up(ctx.lowerpath.dentry);
 
-       err = ovl_copy_up_start(dentry);
+       err = ovl_copy_up_start(dentry, flags);
        /* err < 0: interrupted, err > 0: raced with another copy-up */
        if (unlikely(err)) {
                if (err > 0)
@@ -731,6 +782,8 @@ static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
                        err = ovl_do_copy_up(&ctx);
                if (!err && parent && !ovl_dentry_has_upper_alias(dentry))
                        err = ovl_link_up(&ctx);
+               if (!err && ovl_dentry_needs_data_copy_up_locked(dentry, flags))
+                       err = ovl_copy_up_meta_inode_data(&ctx);
                ovl_copy_up_end(dentry);
        }
        do_delayed_call(&done);
@@ -756,21 +809,7 @@ int ovl_copy_up_flags(struct dentry *dentry, int flags)
                struct dentry *next;
                struct dentry *parent = NULL;
 
-               /*
-                * Check if copy-up has happened as well as for upper alias (in
-                * case of hard links) is there.
-                *
-                * Both checks are lockless:
-                *  - false negatives: will recheck under oi->lock
-                *  - false positives:
-                *    + ovl_dentry_upper() uses memory barriers to ensure the
-                *      upper dentry is up-to-date
-                *    + ovl_dentry_has_upper_alias() relies on locking of
-                *      upper parent i_rwsem to prevent reordering copy-up
-                *      with rename.
-                */
-               if (ovl_dentry_upper(dentry) &&
-                   (ovl_dentry_has_upper_alias(dentry) || disconnected))
+               if (ovl_already_copied_up(dentry, flags))
                        break;
 
                next = dget(dentry);
@@ -795,6 +834,41 @@ int ovl_copy_up_flags(struct dentry *dentry, int flags)
        return err;
 }
 
+static bool ovl_open_need_copy_up(struct dentry *dentry, int flags)
+{
+       /* Copy up of disconnected dentry does not set upper alias */
+       if (ovl_already_copied_up(dentry, flags))
+               return false;
+
+       if (special_file(d_inode(dentry)->i_mode))
+               return false;
+
+       if (!ovl_open_flags_need_copy_up(flags))
+               return false;
+
+       return true;
+}
+
+int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags)
+{
+       int err = 0;
+
+       if (ovl_open_need_copy_up(dentry, file_flags)) {
+               err = ovl_want_write(dentry);
+               if (!err) {
+                       err = ovl_copy_up_flags(dentry, file_flags);
+                       ovl_drop_write(dentry);
+               }
+       }
+
+       return err;
+}
+
+int ovl_copy_up_with_data(struct dentry *dentry)
+{
+       return ovl_copy_up_flags(dentry, O_WRONLY);
+}
+
 int ovl_copy_up(struct dentry *dentry)
 {
        return ovl_copy_up_flags(dentry, 0);
index f480b1a2cd2e5ada2a7a3c978b00d541839b635a..276914ae3c60aaf297747f03b58d4582df335ec9 100644 (file)
@@ -24,6 +24,8 @@ module_param_named(redirect_max, ovl_redirect_max, ushort, 0644);
 MODULE_PARM_DESC(ovl_redirect_max,
                 "Maximum length of absolute redirect xattr value");
 
+static int ovl_set_redirect(struct dentry *dentry, bool samedir);
+
 int ovl_cleanup(struct inode *wdir, struct dentry *wdentry)
 {
        int err;
@@ -242,7 +244,7 @@ static int ovl_instantiate(struct dentry *dentry, struct inode *inode,
                .newinode = inode,
        };
 
-       ovl_dentry_version_inc(dentry->d_parent, false);
+       ovl_dir_modified(dentry->d_parent, false);
        ovl_dentry_set_upper_alias(dentry);
        if (!hardlink) {
                /*
@@ -601,6 +603,10 @@ static int ovl_create_object(struct dentry *dentry, int mode, dev_t rdev,
        if (!inode)
                goto out_drop_write;
 
+       spin_lock(&inode->i_lock);
+       inode->i_state |= I_CREATING;
+       spin_unlock(&inode->i_lock);
+
        inode_init_owner(inode, dentry->d_parent->d_inode, mode);
        attr.mode = inode->i_mode;
 
@@ -657,6 +663,12 @@ static int ovl_link(struct dentry *old, struct inode *newdir,
        if (err)
                goto out_drop_write;
 
+       if (ovl_is_metacopy_dentry(old)) {
+               err = ovl_set_redirect(old, false);
+               if (err)
+                       goto out_drop_write;
+       }
+
        err = ovl_nlink_start(old, &locked);
        if (err)
                goto out_drop_write;
@@ -722,7 +734,7 @@ static int ovl_remove_and_whiteout(struct dentry *dentry,
        if (err)
                goto out_d_drop;
 
-       ovl_dentry_version_inc(dentry->d_parent, true);
+       ovl_dir_modified(dentry->d_parent, true);
 out_d_drop:
        d_drop(dentry);
 out_dput_upper:
@@ -767,7 +779,7 @@ static int ovl_remove_upper(struct dentry *dentry, bool is_dir,
                err = vfs_rmdir(dir, upper);
        else
                err = vfs_unlink(dir, upper, NULL);
-       ovl_dentry_version_inc(dentry->d_parent, ovl_type_origin(dentry));
+       ovl_dir_modified(dentry->d_parent, ovl_type_origin(dentry));
 
        /*
         * Keeping this dentry hashed would mean having to release
@@ -797,6 +809,7 @@ static int ovl_do_remove(struct dentry *dentry, bool is_dir)
        int err;
        bool locked = false;
        const struct cred *old_cred;
+       struct dentry *upperdentry;
        bool lower_positive = ovl_lower_positive(dentry);
        LIST_HEAD(list);
 
@@ -832,6 +845,17 @@ static int ovl_do_remove(struct dentry *dentry, bool is_dir)
                        drop_nlink(dentry->d_inode);
        }
        ovl_nlink_end(dentry, locked);
+
+       /*
+        * Copy ctime
+        *
+        * Note: we fail to update ctime if there was no copy-up, only a
+        * whiteout
+        */
+       upperdentry = ovl_dentry_upper(dentry);
+       if (upperdentry)
+               ovl_copyattr(d_inode(upperdentry), d_inode(dentry));
+
 out_drop_write:
        ovl_drop_write(dentry);
 out:
@@ -862,13 +886,13 @@ static bool ovl_can_move(struct dentry *dentry)
                !d_is_dir(dentry) || !ovl_type_merge_or_lower(dentry);
 }
 
-static char *ovl_get_redirect(struct dentry *dentry, bool samedir)
+static char *ovl_get_redirect(struct dentry *dentry, bool abs_redirect)
 {
        char *buf, *ret;
        struct dentry *d, *tmp;
        int buflen = ovl_redirect_max + 1;
 
-       if (samedir) {
+       if (!abs_redirect) {
                ret = kstrndup(dentry->d_name.name, dentry->d_name.len,
                               GFP_KERNEL);
                goto out;
@@ -922,15 +946,43 @@ out:
        return ret ? ret : ERR_PTR(-ENOMEM);
 }
 
+static bool ovl_need_absolute_redirect(struct dentry *dentry, bool samedir)
+{
+       struct dentry *lowerdentry;
+
+       if (!samedir)
+               return true;
+
+       if (d_is_dir(dentry))
+               return false;
+
+       /*
+        * For non-dir hardlinked files, we need absolute redirects
+        * in general as two upper hardlinks could be in different
+        * dirs. We could put a relative redirect now and convert
+        * it to absolute redirect later. But when nlink > 1 and
+        * indexing is on, that means relative redirect needs to be
+        * converted to absolute during copy up of another lower
+        * hardllink as well.
+        *
+        * So without optimizing too much, just check if lower is
+        * a hard link or not. If lower is hard link, put absolute
+        * redirect.
+        */
+       lowerdentry = ovl_dentry_lower(dentry);
+       return (d_inode(lowerdentry)->i_nlink > 1);
+}
+
 static int ovl_set_redirect(struct dentry *dentry, bool samedir)
 {
        int err;
        const char *redirect = ovl_dentry_get_redirect(dentry);
+       bool absolute_redirect = ovl_need_absolute_redirect(dentry, samedir);
 
-       if (redirect && (samedir || redirect[0] == '/'))
+       if (redirect && (!absolute_redirect || redirect[0] == '/'))
                return 0;
 
-       redirect = ovl_get_redirect(dentry, samedir);
+       redirect = ovl_get_redirect(dentry, absolute_redirect);
        if (IS_ERR(redirect))
                return PTR_ERR(redirect);
 
@@ -1106,22 +1158,20 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
                goto out_dput;
 
        err = 0;
-       if (is_dir) {
-               if (ovl_type_merge_or_lower(old))
-                       err = ovl_set_redirect(old, samedir);
-               else if (!old_opaque && ovl_type_merge(new->d_parent))
-                       err = ovl_set_opaque_xerr(old, olddentry, -EXDEV);
-               if (err)
-                       goto out_dput;
-       }
-       if (!overwrite && new_is_dir) {
-               if (ovl_type_merge_or_lower(new))
-                       err = ovl_set_redirect(new, samedir);
-               else if (!new_opaque && ovl_type_merge(old->d_parent))
-                       err = ovl_set_opaque_xerr(new, newdentry, -EXDEV);
-               if (err)
-                       goto out_dput;
-       }
+       if (ovl_type_merge_or_lower(old))
+               err = ovl_set_redirect(old, samedir);
+       else if (is_dir && !old_opaque && ovl_type_merge(new->d_parent))
+               err = ovl_set_opaque_xerr(old, olddentry, -EXDEV);
+       if (err)
+               goto out_dput;
+
+       if (!overwrite && ovl_type_merge_or_lower(new))
+               err = ovl_set_redirect(new, samedir);
+       else if (!overwrite && new_is_dir && !new_opaque &&
+                ovl_type_merge(old->d_parent))
+               err = ovl_set_opaque_xerr(new, newdentry, -EXDEV);
+       if (err)
+               goto out_dput;
 
        err = ovl_do_rename(old_upperdir->d_inode, olddentry,
                            new_upperdir->d_inode, newdentry, flags);
@@ -1138,10 +1188,15 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
                        drop_nlink(d_inode(new));
        }
 
-       ovl_dentry_version_inc(old->d_parent, ovl_type_origin(old) ||
-                              (!overwrite && ovl_type_origin(new)));
-       ovl_dentry_version_inc(new->d_parent, ovl_type_origin(old) ||
-                              (d_inode(new) && ovl_type_origin(new)));
+       ovl_dir_modified(old->d_parent, ovl_type_origin(old) ||
+                        (!overwrite && ovl_type_origin(new)));
+       ovl_dir_modified(new->d_parent, ovl_type_origin(old) ||
+                        (d_inode(new) && ovl_type_origin(new)));
+
+       /* copy ctime: */
+       ovl_copyattr(d_inode(olddentry), d_inode(old));
+       if (d_inode(new) && ovl_dentry_upper(new))
+               ovl_copyattr(d_inode(newdentry), d_inode(new));
 
 out_dput:
        dput(newdentry);
index 9941ece61a14bcc096cec0514e8c2f9ec9ca9ed0..8fa37cd7818adfe5272027ad31c24e764837a1c0 100644 (file)
@@ -317,6 +317,9 @@ static struct dentry *ovl_obtain_alias(struct super_block *sb,
                return ERR_CAST(inode);
        }
 
+       if (upper)
+               ovl_set_flag(OVL_UPPERDATA, inode);
+
        dentry = d_find_any_alias(inode);
        if (!dentry) {
                dentry = d_alloc_anon(inode->i_sb);
diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
new file mode 100644 (file)
index 0000000..32e9282
--- /dev/null
@@ -0,0 +1,511 @@
+/*
+ * Copyright (C) 2017 Red Hat, 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/cred.h>
+#include <linux/file.h>
+#include <linux/mount.h>
+#include <linux/xattr.h>
+#include <linux/uio.h>
+#include "overlayfs.h"
+
+static char ovl_whatisit(struct inode *inode, struct inode *realinode)
+{
+       if (realinode != ovl_inode_upper(inode))
+               return 'l';
+       if (ovl_has_upperdata(inode))
+               return 'u';
+       else
+               return 'm';
+}
+
+static struct file *ovl_open_realfile(const struct file *file,
+                                     struct inode *realinode)
+{
+       struct inode *inode = file_inode(file);
+       struct file *realfile;
+       const struct cred *old_cred;
+
+       old_cred = ovl_override_creds(inode->i_sb);
+       realfile = open_with_fake_path(&file->f_path, file->f_flags | O_NOATIME,
+                                      realinode, current_cred());
+       revert_creds(old_cred);
+
+       pr_debug("open(%p[%pD2/%c], 0%o) -> (%p, 0%o)\n",
+                file, file, ovl_whatisit(inode, realinode), file->f_flags,
+                realfile, IS_ERR(realfile) ? 0 : realfile->f_flags);
+
+       return realfile;
+}
+
+#define OVL_SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT)
+
+static int ovl_change_flags(struct file *file, unsigned int flags)
+{
+       struct inode *inode = file_inode(file);
+       int err;
+
+       /* No atime modificaton on underlying */
+       flags |= O_NOATIME;
+
+       /* If some flag changed that cannot be changed then something's amiss */
+       if (WARN_ON((file->f_flags ^ flags) & ~OVL_SETFL_MASK))
+               return -EIO;
+
+       flags &= OVL_SETFL_MASK;
+
+       if (((flags ^ file->f_flags) & O_APPEND) && IS_APPEND(inode))
+               return -EPERM;
+
+       if (flags & O_DIRECT) {
+               if (!file->f_mapping->a_ops ||
+                   !file->f_mapping->a_ops->direct_IO)
+                       return -EINVAL;
+       }
+
+       if (file->f_op->check_flags) {
+               err = file->f_op->check_flags(flags);
+               if (err)
+                       return err;
+       }
+
+       spin_lock(&file->f_lock);
+       file->f_flags = (file->f_flags & ~OVL_SETFL_MASK) | flags;
+       spin_unlock(&file->f_lock);
+
+       return 0;
+}
+
+static int ovl_real_fdget_meta(const struct file *file, struct fd *real,
+                              bool allow_meta)
+{
+       struct inode *inode = file_inode(file);
+       struct inode *realinode;
+
+       real->flags = 0;
+       real->file = file->private_data;
+
+       if (allow_meta)
+               realinode = ovl_inode_real(inode);
+       else
+               realinode = ovl_inode_realdata(inode);
+
+       /* Has it been copied up since we'd opened it? */
+       if (unlikely(file_inode(real->file) != realinode)) {
+               real->flags = FDPUT_FPUT;
+               real->file = ovl_open_realfile(file, realinode);
+
+               return PTR_ERR_OR_ZERO(real->file);
+       }
+
+       /* Did the flags change since open? */
+       if (unlikely((file->f_flags ^ real->file->f_flags) & ~O_NOATIME))
+               return ovl_change_flags(real->file, file->f_flags);
+
+       return 0;
+}
+
+static int ovl_real_fdget(const struct file *file, struct fd *real)
+{
+       return ovl_real_fdget_meta(file, real, false);
+}
+
+static int ovl_open(struct inode *inode, struct file *file)
+{
+       struct dentry *dentry = file_dentry(file);
+       struct file *realfile;
+       int err;
+
+       err = ovl_open_maybe_copy_up(dentry, file->f_flags);
+       if (err)
+               return err;
+
+       /* No longer need these flags, so don't pass them on to underlying fs */
+       file->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
+
+       realfile = ovl_open_realfile(file, ovl_inode_realdata(inode));
+       if (IS_ERR(realfile))
+               return PTR_ERR(realfile);
+
+       /* For O_DIRECT dentry_open() checks f_mapping->a_ops->direct_IO */
+       file->f_mapping = realfile->f_mapping;
+
+       file->private_data = realfile;
+
+       return 0;
+}
+
+static int ovl_release(struct inode *inode, struct file *file)
+{
+       fput(file->private_data);
+
+       return 0;
+}
+
+static loff_t ovl_llseek(struct file *file, loff_t offset, int whence)
+{
+       struct inode *realinode = ovl_inode_real(file_inode(file));
+
+       return generic_file_llseek_size(file, offset, whence,
+                                       realinode->i_sb->s_maxbytes,
+                                       i_size_read(realinode));
+}
+
+static void ovl_file_accessed(struct file *file)
+{
+       struct inode *inode, *upperinode;
+
+       if (file->f_flags & O_NOATIME)
+               return;
+
+       inode = file_inode(file);
+       upperinode = ovl_inode_upper(inode);
+
+       if (!upperinode)
+               return;
+
+       if ((!timespec64_equal(&inode->i_mtime, &upperinode->i_mtime) ||
+            !timespec64_equal(&inode->i_ctime, &upperinode->i_ctime))) {
+               inode->i_mtime = upperinode->i_mtime;
+               inode->i_ctime = upperinode->i_ctime;
+       }
+
+       touch_atime(&file->f_path);
+}
+
+static rwf_t ovl_iocb_to_rwf(struct kiocb *iocb)
+{
+       int ifl = iocb->ki_flags;
+       rwf_t flags = 0;
+
+       if (ifl & IOCB_NOWAIT)
+               flags |= RWF_NOWAIT;
+       if (ifl & IOCB_HIPRI)
+               flags |= RWF_HIPRI;
+       if (ifl & IOCB_DSYNC)
+               flags |= RWF_DSYNC;
+       if (ifl & IOCB_SYNC)
+               flags |= RWF_SYNC;
+
+       return flags;
+}
+
+static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
+{
+       struct file *file = iocb->ki_filp;
+       struct fd real;
+       const struct cred *old_cred;
+       ssize_t ret;
+
+       if (!iov_iter_count(iter))
+               return 0;
+
+       ret = ovl_real_fdget(file, &real);
+       if (ret)
+               return ret;
+
+       old_cred = ovl_override_creds(file_inode(file)->i_sb);
+       ret = vfs_iter_read(real.file, iter, &iocb->ki_pos,
+                           ovl_iocb_to_rwf(iocb));
+       revert_creds(old_cred);
+
+       ovl_file_accessed(file);
+
+       fdput(real);
+
+       return ret;
+}
+
+static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
+{
+       struct file *file = iocb->ki_filp;
+       struct inode *inode = file_inode(file);
+       struct fd real;
+       const struct cred *old_cred;
+       ssize_t ret;
+
+       if (!iov_iter_count(iter))
+               return 0;
+
+       inode_lock(inode);
+       /* Update mode */
+       ovl_copyattr(ovl_inode_real(inode), inode);
+       ret = file_remove_privs(file);
+       if (ret)
+               goto out_unlock;
+
+       ret = ovl_real_fdget(file, &real);
+       if (ret)
+               goto out_unlock;
+
+       old_cred = ovl_override_creds(file_inode(file)->i_sb);
+       ret = vfs_iter_write(real.file, iter, &iocb->ki_pos,
+                            ovl_iocb_to_rwf(iocb));
+       revert_creds(old_cred);
+
+       /* Update size */
+       ovl_copyattr(ovl_inode_real(inode), inode);
+
+       fdput(real);
+
+out_unlock:
+       inode_unlock(inode);
+
+       return ret;
+}
+
+static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
+{
+       struct fd real;
+       const struct cred *old_cred;
+       int ret;
+
+       ret = ovl_real_fdget_meta(file, &real, !datasync);
+       if (ret)
+               return ret;
+
+       /* Don't sync lower file for fear of receiving EROFS error */
+       if (file_inode(real.file) == ovl_inode_upper(file_inode(file))) {
+               old_cred = ovl_override_creds(file_inode(file)->i_sb);
+               ret = vfs_fsync_range(real.file, start, end, datasync);
+               revert_creds(old_cred);
+       }
+
+       fdput(real);
+
+       return ret;
+}
+
+static int ovl_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       struct file *realfile = file->private_data;
+       const struct cred *old_cred;
+       int ret;
+
+       if (!realfile->f_op->mmap)
+               return -ENODEV;
+
+       if (WARN_ON(file != vma->vm_file))
+               return -EIO;
+
+       vma->vm_file = get_file(realfile);
+
+       old_cred = ovl_override_creds(file_inode(file)->i_sb);
+       ret = call_mmap(vma->vm_file, vma);
+       revert_creds(old_cred);
+
+       if (ret) {
+               /* Drop reference count from new vm_file value */
+               fput(realfile);
+       } else {
+               /* Drop reference count from previous vm_file value */
+               fput(file);
+       }
+
+       ovl_file_accessed(file);
+
+       return ret;
+}
+
+static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
+{
+       struct inode *inode = file_inode(file);
+       struct fd real;
+       const struct cred *old_cred;
+       int ret;
+
+       ret = ovl_real_fdget(file, &real);
+       if (ret)
+               return ret;
+
+       old_cred = ovl_override_creds(file_inode(file)->i_sb);
+       ret = vfs_fallocate(real.file, mode, offset, len);
+       revert_creds(old_cred);
+
+       /* Update size */
+       ovl_copyattr(ovl_inode_real(inode), inode);
+
+       fdput(real);
+
+       return ret;
+}
+
+static long ovl_real_ioctl(struct file *file, unsigned int cmd,
+                          unsigned long arg)
+{
+       struct fd real;
+       const struct cred *old_cred;
+       long ret;
+
+       ret = ovl_real_fdget(file, &real);
+       if (ret)
+               return ret;
+
+       old_cred = ovl_override_creds(file_inode(file)->i_sb);
+       ret = vfs_ioctl(real.file, cmd, arg);
+       revert_creds(old_cred);
+
+       fdput(real);
+
+       return ret;
+}
+
+static long ovl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       long ret;
+       struct inode *inode = file_inode(file);
+
+       switch (cmd) {
+       case FS_IOC_GETFLAGS:
+               ret = ovl_real_ioctl(file, cmd, arg);
+               break;
+
+       case FS_IOC_SETFLAGS:
+               if (!inode_owner_or_capable(inode))
+                       return -EACCES;
+
+               ret = mnt_want_write_file(file);
+               if (ret)
+                       return ret;
+
+               ret = ovl_copy_up_with_data(file_dentry(file));
+               if (!ret) {
+                       ret = ovl_real_ioctl(file, cmd, arg);
+
+                       inode_lock(inode);
+                       ovl_copyflags(ovl_inode_real(inode), inode);
+                       inode_unlock(inode);
+               }
+
+               mnt_drop_write_file(file);
+               break;
+
+       default:
+               ret = -ENOTTY;
+       }
+
+       return ret;
+}
+
+static long ovl_compat_ioctl(struct file *file, unsigned int cmd,
+                            unsigned long arg)
+{
+       switch (cmd) {
+       case FS_IOC32_GETFLAGS:
+               cmd = FS_IOC_GETFLAGS;
+               break;
+
+       case FS_IOC32_SETFLAGS:
+               cmd = FS_IOC_SETFLAGS;
+               break;
+
+       default:
+               return -ENOIOCTLCMD;
+       }
+
+       return ovl_ioctl(file, cmd, arg);
+}
+
+enum ovl_copyop {
+       OVL_COPY,
+       OVL_CLONE,
+       OVL_DEDUPE,
+};
+
+static ssize_t ovl_copyfile(struct file *file_in, loff_t pos_in,
+                           struct file *file_out, loff_t pos_out,
+                           u64 len, unsigned int flags, enum ovl_copyop op)
+{
+       struct inode *inode_out = file_inode(file_out);
+       struct fd real_in, real_out;
+       const struct cred *old_cred;
+       ssize_t ret;
+
+       ret = ovl_real_fdget(file_out, &real_out);
+       if (ret)
+               return ret;
+
+       ret = ovl_real_fdget(file_in, &real_in);
+       if (ret) {
+               fdput(real_out);
+               return ret;
+       }
+
+       old_cred = ovl_override_creds(file_inode(file_out)->i_sb);
+       switch (op) {
+       case OVL_COPY:
+               ret = vfs_copy_file_range(real_in.file, pos_in,
+                                         real_out.file, pos_out, len, flags);
+               break;
+
+       case OVL_CLONE:
+               ret = vfs_clone_file_range(real_in.file, pos_in,
+                                          real_out.file, pos_out, len);
+               break;
+
+       case OVL_DEDUPE:
+               ret = vfs_dedupe_file_range_one(real_in.file, pos_in,
+                                               real_out.file, pos_out, len);
+               break;
+       }
+       revert_creds(old_cred);
+
+       /* Update size */
+       ovl_copyattr(ovl_inode_real(inode_out), inode_out);
+
+       fdput(real_in);
+       fdput(real_out);
+
+       return ret;
+}
+
+static ssize_t ovl_copy_file_range(struct file *file_in, loff_t pos_in,
+                                  struct file *file_out, loff_t pos_out,
+                                  size_t len, unsigned int flags)
+{
+       return ovl_copyfile(file_in, pos_in, file_out, pos_out, len, flags,
+                           OVL_COPY);
+}
+
+static int ovl_clone_file_range(struct file *file_in, loff_t pos_in,
+                               struct file *file_out, loff_t pos_out, u64 len)
+{
+       return ovl_copyfile(file_in, pos_in, file_out, pos_out, len, 0,
+                           OVL_CLONE);
+}
+
+static int ovl_dedupe_file_range(struct file *file_in, loff_t pos_in,
+                                struct file *file_out, loff_t pos_out, u64 len)
+{
+       /*
+        * Don't copy up because of a dedupe request, this wouldn't make sense
+        * most of the time (data would be duplicated instead of deduplicated).
+        */
+       if (!ovl_inode_upper(file_inode(file_in)) ||
+           !ovl_inode_upper(file_inode(file_out)))
+               return -EPERM;
+
+       return ovl_copyfile(file_in, pos_in, file_out, pos_out, len, 0,
+                           OVL_DEDUPE);
+}
+
+const struct file_operations ovl_file_operations = {
+       .open           = ovl_open,
+       .release        = ovl_release,
+       .llseek         = ovl_llseek,
+       .read_iter      = ovl_read_iter,
+       .write_iter     = ovl_write_iter,
+       .fsync          = ovl_fsync,
+       .mmap           = ovl_mmap,
+       .fallocate      = ovl_fallocate,
+       .unlocked_ioctl = ovl_ioctl,
+       .compat_ioctl   = ovl_compat_ioctl,
+
+       .copy_file_range        = ovl_copy_file_range,
+       .clone_file_range       = ovl_clone_file_range,
+       .dedupe_file_range      = ovl_dedupe_file_range,
+};
index ed16a898caeb8d59ef3daad075c96774a7648db7..e0bb217c01e2a6c8389bf9ec2dfb2f56f0fab7c8 100644 (file)
 int ovl_setattr(struct dentry *dentry, struct iattr *attr)
 {
        int err;
+       bool full_copy_up = false;
        struct dentry *upperdentry;
        const struct cred *old_cred;
 
-       /*
-        * Check for permissions before trying to copy-up.  This is redundant
-        * since it will be rechecked later by ->setattr() on upper dentry.  But
-        * without this, copy-up can be triggered by just about anybody.
-        *
-        * We don't initialize inode->size, which just means that
-        * inode_newsize_ok() will always check against MAX_LFS_FILESIZE and not
-        * check for a swapfile (which this won't be anyway).
-        */
        err = setattr_prepare(dentry, attr);
        if (err)
                return err;
@@ -39,10 +31,33 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
        if (err)
                goto out;
 
-       err = ovl_copy_up(dentry);
+       if (attr->ia_valid & ATTR_SIZE) {
+               struct inode *realinode = d_inode(ovl_dentry_real(dentry));
+
+               err = -ETXTBSY;
+               if (atomic_read(&realinode->i_writecount) < 0)
+                       goto out_drop_write;
+
+               /* Truncate should trigger data copy up as well */
+               full_copy_up = true;
+       }
+
+       if (!full_copy_up)
+               err = ovl_copy_up(dentry);
+       else
+               err = ovl_copy_up_with_data(dentry);
        if (!err) {
+               struct inode *winode = NULL;
+
                upperdentry = ovl_dentry_upper(dentry);
 
+               if (attr->ia_valid & ATTR_SIZE) {
+                       winode = d_inode(upperdentry);
+                       err = get_write_access(winode);
+                       if (err)
+                               goto out_drop_write;
+               }
+
                if (attr->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
                        attr->ia_valid &= ~ATTR_MODE;
 
@@ -53,7 +68,11 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
                if (!err)
                        ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
                inode_unlock(upperdentry->d_inode);
+
+               if (winode)
+                       put_write_access(winode);
        }
+out_drop_write:
        ovl_drop_write(dentry);
 out:
        return err;
@@ -133,6 +152,9 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
        bool samefs = ovl_same_sb(dentry->d_sb);
        struct ovl_layer *lower_layer = NULL;
        int err;
+       bool metacopy_blocks = false;
+
+       metacopy_blocks = ovl_is_metacopy_dentry(dentry);
 
        type = ovl_path_real(dentry, &realpath);
        old_cred = ovl_override_creds(dentry->d_sb);
@@ -154,7 +176,8 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
                        lower_layer = ovl_layer_lower(dentry);
                } else if (OVL_TYPE_ORIGIN(type)) {
                        struct kstat lowerstat;
-                       u32 lowermask = STATX_INO | (!is_dir ? STATX_NLINK : 0);
+                       u32 lowermask = STATX_INO | STATX_BLOCKS |
+                                       (!is_dir ? STATX_NLINK : 0);
 
                        ovl_path_lower(dentry, &realpath);
                        err = vfs_getattr(&realpath, &lowerstat,
@@ -183,6 +206,35 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
                                stat->ino = lowerstat.ino;
                                lower_layer = ovl_layer_lower(dentry);
                        }
+
+                       /*
+                        * If we are querying a metacopy dentry and lower
+                        * dentry is data dentry, then use the blocks we
+                        * queried just now. We don't have to do additional
+                        * vfs_getattr(). If lower itself is metacopy, then
+                        * additional vfs_getattr() is unavoidable.
+                        */
+                       if (metacopy_blocks &&
+                           realpath.dentry == ovl_dentry_lowerdata(dentry)) {
+                               stat->blocks = lowerstat.blocks;
+                               metacopy_blocks = false;
+                       }
+               }
+
+               if (metacopy_blocks) {
+                       /*
+                        * If lower is not same as lowerdata or if there was
+                        * no origin on upper, we can end up here.
+                        */
+                       struct kstat lowerdatastat;
+                       u32 lowermask = STATX_BLOCKS;
+
+                       ovl_path_lowerdata(dentry, &realpath);
+                       err = vfs_getattr(&realpath, &lowerdatastat,
+                                         lowermask, flags);
+                       if (err)
+                               goto out;
+                       stat->blocks = lowerdatastat.blocks;
                }
        }
 
@@ -304,6 +356,9 @@ int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name,
        }
        revert_creds(old_cred);
 
+       /* copy c/mtime */
+       ovl_copyattr(d_inode(realdentry), inode);
+
 out_drop_write:
        ovl_drop_write(dentry);
 out:
@@ -384,38 +439,6 @@ struct posix_acl *ovl_get_acl(struct inode *inode, int type)
        return acl;
 }
 
-static bool ovl_open_need_copy_up(struct dentry *dentry, int flags)
-{
-       /* Copy up of disconnected dentry does not set upper alias */
-       if (ovl_dentry_upper(dentry) &&
-           (ovl_dentry_has_upper_alias(dentry) ||
-            (dentry->d_flags & DCACHE_DISCONNECTED)))
-               return false;
-
-       if (special_file(d_inode(dentry)->i_mode))
-               return false;
-
-       if (!(OPEN_FMODE(flags) & FMODE_WRITE) && !(flags & O_TRUNC))
-               return false;
-
-       return true;
-}
-
-int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags)
-{
-       int err = 0;
-
-       if (ovl_open_need_copy_up(dentry, file_flags)) {
-               err = ovl_want_write(dentry);
-               if (!err) {
-                       err = ovl_copy_up_flags(dentry, file_flags);
-                       ovl_drop_write(dentry);
-               }
-       }
-
-       return err;
-}
-
 int ovl_update_time(struct inode *inode, struct timespec64 *ts, int flags)
 {
        if (flags & S_ATIME) {
@@ -433,6 +456,23 @@ int ovl_update_time(struct inode *inode, struct timespec64 *ts, int flags)
        return 0;
 }
 
+static int ovl_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+                     u64 start, u64 len)
+{
+       int err;
+       struct inode *realinode = ovl_inode_real(inode);
+       const struct cred *old_cred;
+
+       if (!realinode->i_op->fiemap)
+               return -EOPNOTSUPP;
+
+       old_cred = ovl_override_creds(inode->i_sb);
+       err = realinode->i_op->fiemap(realinode, fieinfo, start, len);
+       revert_creds(old_cred);
+
+       return err;
+}
+
 static const struct inode_operations ovl_file_inode_operations = {
        .setattr        = ovl_setattr,
        .permission     = ovl_permission,
@@ -440,6 +480,7 @@ static const struct inode_operations ovl_file_inode_operations = {
        .listxattr      = ovl_listxattr,
        .get_acl        = ovl_get_acl,
        .update_time    = ovl_update_time,
+       .fiemap         = ovl_fiemap,
 };
 
 static const struct inode_operations ovl_symlink_inode_operations = {
@@ -450,6 +491,15 @@ static const struct inode_operations ovl_symlink_inode_operations = {
        .update_time    = ovl_update_time,
 };
 
+static const struct inode_operations ovl_special_inode_operations = {
+       .setattr        = ovl_setattr,
+       .permission     = ovl_permission,
+       .getattr        = ovl_getattr,
+       .listxattr      = ovl_listxattr,
+       .get_acl        = ovl_get_acl,
+       .update_time    = ovl_update_time,
+};
+
 /*
  * It is possible to stack overlayfs instance on top of another
  * overlayfs instance as lower layer. We need to annonate the
@@ -520,6 +570,7 @@ static void ovl_fill_inode(struct inode *inode, umode_t mode, dev_t rdev,
        switch (mode & S_IFMT) {
        case S_IFREG:
                inode->i_op = &ovl_file_inode_operations;
+               inode->i_fop = &ovl_file_operations;
                break;
 
        case S_IFDIR:
@@ -532,7 +583,7 @@ static void ovl_fill_inode(struct inode *inode, umode_t mode, dev_t rdev,
                break;
 
        default:
-               inode->i_op = &ovl_file_inode_operations;
+               inode->i_op = &ovl_special_inode_operations;
                init_special_inode(inode, mode, rdev);
                break;
        }
@@ -769,8 +820,9 @@ struct inode *ovl_get_inode(struct super_block *sb,
        bool bylower = ovl_hash_bylower(sb, upperdentry, lowerdentry,
                                        oip->index);
        int fsid = bylower ? oip->lowerpath->layer->fsid : 0;
-       bool is_dir;
+       bool is_dir, metacopy = false;
        unsigned long ino = 0;
+       int err = -ENOMEM;
 
        if (!realinode)
                realinode = d_inode(lowerdentry);
@@ -787,7 +839,7 @@ struct inode *ovl_get_inode(struct super_block *sb,
 
                inode = ovl_iget5(sb, oip->newinode, key);
                if (!inode)
-                       goto out_nomem;
+                       goto out_err;
                if (!(inode->i_state & I_NEW)) {
                        /*
                         * Verify that the underlying files stored in the inode
@@ -796,11 +848,12 @@ struct inode *ovl_get_inode(struct super_block *sb,
                        if (!ovl_verify_inode(inode, lowerdentry, upperdentry,
                                              true)) {
                                iput(inode);
-                               inode = ERR_PTR(-ESTALE);
-                               goto out;
+                               err = -ESTALE;
+                               goto out_err;
                        }
 
                        dput(upperdentry);
+                       kfree(oip->redirect);
                        goto out;
                }
 
@@ -812,11 +865,13 @@ struct inode *ovl_get_inode(struct super_block *sb,
        } else {
                /* Lower hardlink that will be broken on copy up */
                inode = new_inode(sb);
-               if (!inode)
-                       goto out_nomem;
+               if (!inode) {
+                       err = -ENOMEM;
+                       goto out_err;
+               }
        }
        ovl_fill_inode(inode, realinode->i_mode, realinode->i_rdev, ino, fsid);
-       ovl_inode_init(inode, upperdentry, lowerdentry);
+       ovl_inode_init(inode, upperdentry, lowerdentry, oip->lowerdata);
 
        if (upperdentry && ovl_is_impuredir(upperdentry))
                ovl_set_flag(OVL_IMPURE, inode);
@@ -824,6 +879,20 @@ struct inode *ovl_get_inode(struct super_block *sb,
        if (oip->index)
                ovl_set_flag(OVL_INDEX, inode);
 
+       if (upperdentry) {
+               err = ovl_check_metacopy_xattr(upperdentry);
+               if (err < 0)
+                       goto out_err;
+               metacopy = err;
+               if (!metacopy)
+                       ovl_set_flag(OVL_UPPERDATA, inode);
+       }
+
+       OVL_I(inode)->redirect = oip->redirect;
+
+       if (bylower)
+               ovl_set_flag(OVL_CONST_INO, inode);
+
        /* Check for non-merge dir that may have whiteouts */
        if (is_dir) {
                if (((upperdentry && lowerdentry) || oip->numlower > 1) ||
@@ -837,7 +906,7 @@ struct inode *ovl_get_inode(struct super_block *sb,
 out:
        return inode;
 
-out_nomem:
-       inode = ERR_PTR(-ENOMEM);
+out_err:
+       inode = ERR_PTR(err);
        goto out;
 }
index c993dd8db739df44572fb4c0dcf7882b20ea2eab..f28711846dd6ebad2cca1ad5fc3a4ef95f3806b7 100644 (file)
@@ -24,38 +24,20 @@ struct ovl_lookup_data {
        bool stop;
        bool last;
        char *redirect;
+       bool metacopy;
 };
 
 static int ovl_check_redirect(struct dentry *dentry, struct ovl_lookup_data *d,
                              size_t prelen, const char *post)
 {
        int res;
-       char *s, *next, *buf = NULL;
+       char *buf;
 
-       res = vfs_getxattr(dentry, OVL_XATTR_REDIRECT, NULL, 0);
-       if (res < 0) {
-               if (res == -ENODATA || res == -EOPNOTSUPP)
-                       return 0;
-               goto fail;
-       }
-       buf = kzalloc(prelen + res + strlen(post) + 1, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
+       buf = ovl_get_redirect_xattr(dentry, prelen + strlen(post));
+       if (IS_ERR_OR_NULL(buf))
+               return PTR_ERR(buf);
 
-       if (res == 0)
-               goto invalid;
-
-       res = vfs_getxattr(dentry, OVL_XATTR_REDIRECT, buf, res);
-       if (res < 0)
-               goto fail;
-       if (res == 0)
-               goto invalid;
        if (buf[0] == '/') {
-               for (s = buf; *s++ == '/'; s = next) {
-                       next = strchrnul(s, '/');
-                       if (s == next)
-                               goto invalid;
-               }
                /*
                 * One of the ancestor path elements in an absolute path
                 * lookup in ovl_lookup_layer() could have been opaque and
@@ -66,9 +48,7 @@ static int ovl_check_redirect(struct dentry *dentry, struct ovl_lookup_data *d,
                 */
                d->stop = false;
        } else {
-               if (strchr(buf, '/') != NULL)
-                       goto invalid;
-
+               res = strlen(buf) + 1;
                memmove(buf + prelen, buf, res);
                memcpy(buf, d->name.name, prelen);
        }
@@ -80,16 +60,6 @@ static int ovl_check_redirect(struct dentry *dentry, struct ovl_lookup_data *d,
        d->name.len = strlen(d->redirect);
 
        return 0;
-
-err_free:
-       kfree(buf);
-       return 0;
-fail:
-       pr_warn_ratelimited("overlayfs: failed to get redirect (%i)\n", res);
-       goto err_free;
-invalid:
-       pr_warn_ratelimited("overlayfs: invalid redirect (%s)\n", buf);
-       goto err_free;
 }
 
 static int ovl_acceptable(void *ctx, struct dentry *dentry)
@@ -252,28 +222,39 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
                d->stop = d->opaque = true;
                goto put_and_out;
        }
-       if (!d_can_lookup(this)) {
+       /*
+        * This dentry should be a regular file if previous layer lookup
+        * found a metacopy dentry.
+        */
+       if (last_element && d->metacopy && !d_is_reg(this)) {
                d->stop = true;
-               if (d->is_dir)
-                       goto put_and_out;
-
-               /*
-                * NB: handle failure to lookup non-last element when non-dir
-                * redirects become possible
-                */
-               WARN_ON(!last_element);
-               goto out;
+               goto put_and_out;
        }
-       if (last_element)
-               d->is_dir = true;
-       if (d->last)
-               goto out;
+       if (!d_can_lookup(this)) {
+               if (d->is_dir || !last_element) {
+                       d->stop = true;
+                       goto put_and_out;
+               }
+               err = ovl_check_metacopy_xattr(this);
+               if (err < 0)
+                       goto out_err;
 
-       if (ovl_is_opaquedir(this)) {
-               d->stop = true;
+               d->metacopy = err;
+               d->stop = !d->metacopy;
+               if (!d->metacopy || d->last)
+                       goto out;
+       } else {
                if (last_element)
-                       d->opaque = true;
-               goto out;
+                       d->is_dir = true;
+               if (d->last)
+                       goto out;
+
+               if (ovl_is_opaquedir(this)) {
+                       d->stop = true;
+                       if (last_element)
+                               d->opaque = true;
+                       goto out;
+               }
        }
        err = ovl_check_redirect(this, d, prelen, post);
        if (err)
@@ -823,7 +804,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
        struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
        struct ovl_entry *poe = dentry->d_parent->d_fsdata;
        struct ovl_entry *roe = dentry->d_sb->s_root->d_fsdata;
-       struct ovl_path *stack = NULL;
+       struct ovl_path *stack = NULL, *origin_path = NULL;
        struct dentry *upperdir, *upperdentry = NULL;
        struct dentry *origin = NULL;
        struct dentry *index = NULL;
@@ -834,6 +815,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
        struct dentry *this;
        unsigned int i;
        int err;
+       bool metacopy = false;
        struct ovl_lookup_data d = {
                .name = dentry->d_name,
                .is_dir = false,
@@ -841,6 +823,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                .stop = false,
                .last = ofs->config.redirect_follow ? false : !poe->numlower,
                .redirect = NULL,
+               .metacopy = false,
        };
 
        if (dentry->d_name.len > ofs->namelen)
@@ -859,7 +842,8 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                        goto out;
                }
                if (upperdentry && !d.is_dir) {
-                       BUG_ON(!d.stop || d.redirect);
+                       unsigned int origin_ctr = 0;
+
                        /*
                         * Lookup copy up origin by decoding origin file handle.
                         * We may get a disconnected dentry, which is fine,
@@ -870,9 +854,13 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                         * number - it's the same as if we held a reference
                         * to a dentry in lower layer that was moved under us.
                         */
-                       err = ovl_check_origin(ofs, upperdentry, &stack, &ctr);
+                       err = ovl_check_origin(ofs, upperdentry, &origin_path,
+                                              &origin_ctr);
                        if (err)
                                goto out_put_upper;
+
+                       if (d.metacopy)
+                               metacopy = true;
                }
 
                if (d.redirect) {
@@ -913,7 +901,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                 * If no origin fh is stored in upper of a merge dir, store fh
                 * of lower dir and set upper parent "impure".
                 */
-               if (upperdentry && !ctr && !ofs->noxattr) {
+               if (upperdentry && !ctr && !ofs->noxattr && d.is_dir) {
                        err = ovl_fix_origin(dentry, this, upperdentry);
                        if (err) {
                                dput(this);
@@ -925,18 +913,35 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                 * When "verify_lower" feature is enabled, do not merge with a
                 * lower dir that does not match a stored origin xattr. In any
                 * case, only verified origin is used for index lookup.
+                *
+                * For non-dir dentry, if index=on, then ensure origin
+                * matches the dentry found using path based lookup,
+                * otherwise error out.
                 */
-               if (upperdentry && !ctr && ovl_verify_lower(dentry->d_sb)) {
+               if (upperdentry && !ctr &&
+                   ((d.is_dir && ovl_verify_lower(dentry->d_sb)) ||
+                    (!d.is_dir && ofs->config.index && origin_path))) {
                        err = ovl_verify_origin(upperdentry, this, false);
                        if (err) {
                                dput(this);
-                               break;
+                               if (d.is_dir)
+                                       break;
+                               goto out_put;
                        }
-
-                       /* Bless lower dir as verified origin */
                        origin = this;
                }
 
+               if (d.metacopy)
+                       metacopy = true;
+               /*
+                * Do not store intermediate metacopy dentries in chain,
+                * except top most lower metacopy dentry
+                */
+               if (d.metacopy && ctr) {
+                       dput(this);
+                       continue;
+               }
+
                stack[ctr].dentry = this;
                stack[ctr].layer = lower.layer;
                ctr++;
@@ -968,13 +973,48 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                }
        }
 
+       if (metacopy) {
+               /*
+                * Found a metacopy dentry but did not find corresponding
+                * data dentry
+                */
+               if (d.metacopy) {
+                       err = -EIO;
+                       goto out_put;
+               }
+
+               err = -EPERM;
+               if (!ofs->config.metacopy) {
+                       pr_warn_ratelimited("overlay: refusing to follow metacopy origin for (%pd2)\n",
+                                           dentry);
+                       goto out_put;
+               }
+       } else if (!d.is_dir && upperdentry && !ctr && origin_path) {
+               if (WARN_ON(stack != NULL)) {
+                       err = -EIO;
+                       goto out_put;
+               }
+               stack = origin_path;
+               ctr = 1;
+               origin_path = NULL;
+       }
+
        /*
         * Lookup index by lower inode and verify it matches upper inode.
         * We only trust dir index if we verified that lower dir matches
         * origin, otherwise dir index entries may be inconsistent and we
-        * ignore them. Always lookup index of non-dir and non-upper.
+        * ignore them.
+        *
+        * For non-dir upper metacopy dentry, we already set "origin" if we
+        * verified that lower matched upper origin. If upper origin was
+        * not present (because lower layer did not support fh encode/decode),
+        * or indexing is not enabled, do not set "origin" and skip looking up
+        * index. This case should be handled in same way as a non-dir upper
+        * without ORIGIN is handled.
+        *
+        * Always lookup index of non-dir non-metacopy and non-upper.
         */
-       if (ctr && (!upperdentry || !d.is_dir))
+       if (ctr && (!upperdentry || (!d.is_dir && !metacopy)))
                origin = stack[0].dentry;
 
        if (origin && ovl_indexdir(dentry->d_sb) &&
@@ -1000,8 +1040,15 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
 
        if (upperdentry)
                ovl_dentry_set_upper_alias(dentry);
-       else if (index)
+       else if (index) {
                upperdentry = dget(index);
+               upperredirect = ovl_get_redirect_xattr(upperdentry, 0);
+               if (IS_ERR(upperredirect)) {
+                       err = PTR_ERR(upperredirect);
+                       upperredirect = NULL;
+                       goto out_free_oe;
+               }
+       }
 
        if (upperdentry || ctr) {
                struct ovl_inode_params oip = {
@@ -1009,22 +1056,22 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                        .lowerpath = stack,
                        .index = index,
                        .numlower = ctr,
+                       .redirect = upperredirect,
+                       .lowerdata = (ctr > 1 && !d.is_dir) ?
+                                     stack[ctr - 1].dentry : NULL,
                };
 
                inode = ovl_get_inode(dentry->d_sb, &oip);
                err = PTR_ERR(inode);
                if (IS_ERR(inode))
                        goto out_free_oe;
-
-               /*
-                * NB: handle redirected hard links when non-dir redirects
-                * become possible
-                */
-               WARN_ON(OVL_I(inode)->redirect);
-               OVL_I(inode)->redirect = upperredirect;
        }
 
        revert_creds(old_cred);
+       if (origin_path) {
+               dput(origin_path->dentry);
+               kfree(origin_path);
+       }
        dput(index);
        kfree(stack);
        kfree(d.redirect);
@@ -1039,6 +1086,10 @@ out_put:
                dput(stack[i].dentry);
        kfree(stack);
 out_put_upper:
+       if (origin_path) {
+               dput(origin_path->dentry);
+               kfree(origin_path);
+       }
        dput(upperdentry);
        kfree(upperredirect);
 out:
index 7538b9b56237b46f6cb3f8ed00dc36cecd4b5c94..f61839e1054c6b40872a6bf3dc89e3a7da7b6f52 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/kernel.h>
 #include <linux/uuid.h>
+#include <linux/fs.h>
 #include "ovl_entry.h"
 
 enum ovl_path_type {
@@ -28,6 +29,7 @@ enum ovl_path_type {
 #define OVL_XATTR_IMPURE OVL_XATTR_PREFIX "impure"
 #define OVL_XATTR_NLINK OVL_XATTR_PREFIX "nlink"
 #define OVL_XATTR_UPPER OVL_XATTR_PREFIX "upper"
+#define OVL_XATTR_METACOPY OVL_XATTR_PREFIX "metacopy"
 
 enum ovl_inode_flag {
        /* Pure upper dir that may contain non pure upper entries */
@@ -35,6 +37,9 @@ enum ovl_inode_flag {
        /* Non-merge dir that may contain whiteout entries */
        OVL_WHITEOUTS,
        OVL_INDEX,
+       OVL_UPPERDATA,
+       /* Inode number will remain constant over copy up. */
+       OVL_CONST_INO,
 };
 
 enum ovl_entry_flag {
@@ -190,6 +195,14 @@ static inline struct dentry *ovl_do_tmpfile(struct dentry *dentry, umode_t mode)
        return ret;
 }
 
+static inline bool ovl_open_flags_need_copy_up(int flags)
+{
+       if (!flags)
+               return false;
+
+       return ((OPEN_FMODE(flags) & FMODE_WRITE) || (flags & O_TRUNC));
+}
+
 /* util.c */
 int ovl_want_write(struct dentry *dentry);
 void ovl_drop_write(struct dentry *dentry);
@@ -206,15 +219,19 @@ bool ovl_dentry_weird(struct dentry *dentry);
 enum ovl_path_type ovl_path_type(struct dentry *dentry);
 void ovl_path_upper(struct dentry *dentry, struct path *path);
 void ovl_path_lower(struct dentry *dentry, struct path *path);
+void ovl_path_lowerdata(struct dentry *dentry, struct path *path);
 enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path);
 struct dentry *ovl_dentry_upper(struct dentry *dentry);
 struct dentry *ovl_dentry_lower(struct dentry *dentry);
+struct dentry *ovl_dentry_lowerdata(struct dentry *dentry);
 struct ovl_layer *ovl_layer_lower(struct dentry *dentry);
 struct dentry *ovl_dentry_real(struct dentry *dentry);
 struct dentry *ovl_i_dentry_upper(struct inode *inode);
 struct inode *ovl_inode_upper(struct inode *inode);
 struct inode *ovl_inode_lower(struct inode *inode);
+struct inode *ovl_inode_lowerdata(struct inode *inode);
 struct inode *ovl_inode_real(struct inode *inode);
+struct inode *ovl_inode_realdata(struct inode *inode);
 struct ovl_dir_cache *ovl_dir_cache(struct inode *inode);
 void ovl_set_dir_cache(struct inode *inode, struct ovl_dir_cache *cache);
 void ovl_dentry_set_flag(unsigned long flag, struct dentry *dentry);
@@ -225,18 +242,23 @@ bool ovl_dentry_is_whiteout(struct dentry *dentry);
 void ovl_dentry_set_opaque(struct dentry *dentry);
 bool ovl_dentry_has_upper_alias(struct dentry *dentry);
 void ovl_dentry_set_upper_alias(struct dentry *dentry);
+bool ovl_dentry_needs_data_copy_up(struct dentry *dentry, int flags);
+bool ovl_dentry_needs_data_copy_up_locked(struct dentry *dentry, int flags);
+bool ovl_has_upperdata(struct inode *inode);
+void ovl_set_upperdata(struct inode *inode);
 bool ovl_redirect_dir(struct super_block *sb);
 const char *ovl_dentry_get_redirect(struct dentry *dentry);
 void ovl_dentry_set_redirect(struct dentry *dentry, const char *redirect);
 void ovl_inode_init(struct inode *inode, struct dentry *upperdentry,
-                   struct dentry *lowerdentry);
+                   struct dentry *lowerdentry, struct dentry *lowerdata);
 void ovl_inode_update(struct inode *inode, struct dentry *upperdentry);
-void ovl_dentry_version_inc(struct dentry *dentry, bool impurity);
+void ovl_dir_modified(struct dentry *dentry, bool impurity);
 u64 ovl_dentry_version_get(struct dentry *dentry);
 bool ovl_is_whiteout(struct dentry *dentry);
 struct file *ovl_path_open(struct path *path, int flags);
-int ovl_copy_up_start(struct dentry *dentry);
+int ovl_copy_up_start(struct dentry *dentry, int flags);
 void ovl_copy_up_end(struct dentry *dentry);
+bool ovl_already_copied_up(struct dentry *dentry, int flags);
 bool ovl_check_origin_xattr(struct dentry *dentry);
 bool ovl_check_dir_xattr(struct dentry *dentry, const char *name);
 int ovl_check_setxattr(struct dentry *dentry, struct dentry *upperdentry,
@@ -252,6 +274,9 @@ bool ovl_need_index(struct dentry *dentry);
 int ovl_nlink_start(struct dentry *dentry, bool *locked);
 void ovl_nlink_end(struct dentry *dentry, bool locked);
 int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir);
+int ovl_check_metacopy_xattr(struct dentry *dentry);
+bool ovl_is_metacopy_dentry(struct dentry *dentry);
+char *ovl_get_redirect_xattr(struct dentry *dentry, int padding);
 
 static inline bool ovl_is_impuredir(struct dentry *dentry)
 {
@@ -324,7 +349,6 @@ int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name,
                  void *value, size_t size);
 ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
 struct posix_acl *ovl_get_acl(struct inode *inode, int type);
-int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags);
 int ovl_update_time(struct inode *inode, struct timespec64 *ts, int flags);
 bool ovl_is_private_xattr(const char *name);
 
@@ -334,6 +358,8 @@ struct ovl_inode_params {
        struct ovl_path *lowerpath;
        struct dentry *index;
        unsigned int numlower;
+       char *redirect;
+       struct dentry *lowerdata;
 };
 struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, dev_t rdev);
 struct inode *ovl_lookup_inode(struct super_block *sb, struct dentry *real,
@@ -348,6 +374,14 @@ static inline void ovl_copyattr(struct inode *from, struct inode *to)
        to->i_atime = from->i_atime;
        to->i_mtime = from->i_mtime;
        to->i_ctime = from->i_ctime;
+       i_size_write(to, i_size_read(from));
+}
+
+static inline void ovl_copyflags(struct inode *from, struct inode *to)
+{
+       unsigned int mask = S_SYNC | S_IMMUTABLE | S_APPEND | S_NOATIME;
+
+       inode_set_flags(to, from->i_flags & mask, mask);
 }
 
 /* dir.c */
@@ -368,9 +402,14 @@ struct dentry *ovl_create_real(struct inode *dir, struct dentry *newdentry,
 int ovl_cleanup(struct inode *dir, struct dentry *dentry);
 struct dentry *ovl_create_temp(struct dentry *workdir, struct ovl_cattr *attr);
 
+/* file.c */
+extern const struct file_operations ovl_file_operations;
+
 /* copy_up.c */
 int ovl_copy_up(struct dentry *dentry);
+int ovl_copy_up_with_data(struct dentry *dentry);
 int ovl_copy_up_flags(struct dentry *dentry, int flags);
+int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags);
 int ovl_copy_xattr(struct dentry *old, struct dentry *new);
 int ovl_set_attr(struct dentry *upper, struct kstat *stat);
 struct ovl_fh *ovl_encode_real_fh(struct dentry *real, bool is_upper);
index 41655a7d68947068e2e13b57739aa1bd7a1279eb..ec237035333afcbb8ffab21951a172e384a6597a 100644 (file)
@@ -19,6 +19,7 @@ struct ovl_config {
        bool index;
        bool nfs_export;
        int xino;
+       bool metacopy;
 };
 
 struct ovl_sb {
@@ -88,7 +89,10 @@ static inline struct ovl_entry *OVL_E(struct dentry *dentry)
 }
 
 struct ovl_inode {
-       struct ovl_dir_cache *cache;
+       union {
+               struct ovl_dir_cache *cache;    /* directory */
+               struct inode *lowerdata;        /* regular file */
+       };
        const char *redirect;
        u64 version;
        unsigned long flags;
index ef1fe42ff7bb3a4e38e1d75714a1ef1bad4acf42..cc8303a806b4a1fbdb73c89872850f59f22c1eb6 100644 (file)
@@ -668,6 +668,21 @@ static int ovl_fill_real(struct dir_context *ctx, const char *name,
        return orig_ctx->actor(orig_ctx, name, namelen, offset, ino, d_type);
 }
 
+static bool ovl_is_impure_dir(struct file *file)
+{
+       struct ovl_dir_file *od = file->private_data;
+       struct inode *dir = d_inode(file->f_path.dentry);
+
+       /*
+        * Only upper dir can be impure, but if we are in the middle of
+        * iterating a lower real dir, dir could be copied up and marked
+        * impure. We only want the impure cache if we started iterating
+        * a real upper dir to begin with.
+        */
+       return od->is_upper && ovl_test_flag(OVL_IMPURE, dir);
+
+}
+
 static int ovl_iterate_real(struct file *file, struct dir_context *ctx)
 {
        int err;
@@ -696,7 +711,7 @@ static int ovl_iterate_real(struct file *file, struct dir_context *ctx)
                rdt.parent_ino = stat.ino;
        }
 
-       if (ovl_test_flag(OVL_IMPURE, d_inode(dir))) {
+       if (ovl_is_impure_dir(file)) {
                rdt.cache = ovl_cache_get_impure(&file->f_path);
                if (IS_ERR(rdt.cache))
                        return PTR_ERR(rdt.cache);
@@ -727,7 +742,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx)
                 */
                if (ovl_xino_bits(dentry->d_sb) ||
                    (ovl_same_sb(dentry->d_sb) &&
-                    (ovl_test_flag(OVL_IMPURE, d_inode(dentry)) ||
+                    (ovl_is_impure_dir(file) ||
                      OVL_TYPE_MERGE(ovl_path_type(dentry->d_parent))))) {
                        return ovl_iterate_real(file, ctx);
                }
index 704b373114671cca9d8136a9bbed769b0a75dd69..2e0fc93c2c06646ccf5c67c43836f9d4989da501 100644 (file)
@@ -64,6 +64,11 @@ static void ovl_entry_stack_free(struct ovl_entry *oe)
                dput(oe->lowerstack[i].dentry);
 }
 
+static bool ovl_metacopy_def = IS_ENABLED(CONFIG_OVERLAY_FS_METACOPY);
+module_param_named(metacopy, ovl_metacopy_def, bool, 0644);
+MODULE_PARM_DESC(ovl_metacopy_def,
+                "Default to on or off for the metadata only copy up feature");
+
 static void ovl_dentry_release(struct dentry *dentry)
 {
        struct ovl_entry *oe = dentry->d_fsdata;
@@ -74,31 +79,14 @@ static void ovl_dentry_release(struct dentry *dentry)
        }
 }
 
-static int ovl_check_append_only(struct inode *inode, int flag)
-{
-       /*
-        * This test was moot in vfs may_open() because overlay inode does
-        * not have the S_APPEND flag, so re-check on real upper inode
-        */
-       if (IS_APPEND(inode)) {
-               if  ((flag & O_ACCMODE) != O_RDONLY && !(flag & O_APPEND))
-                       return -EPERM;
-               if (flag & O_TRUNC)
-                       return -EPERM;
-       }
-
-       return 0;
-}
-
 static struct dentry *ovl_d_real(struct dentry *dentry,
-                                const struct inode *inode,
-                                unsigned int open_flags, unsigned int flags)
+                                const struct inode *inode)
 {
        struct dentry *real;
-       int err;
 
-       if (flags & D_REAL_UPPER)
-               return ovl_dentry_upper(dentry);
+       /* It's an overlay file */
+       if (inode && d_inode(dentry) == inode)
+               return dentry;
 
        if (!d_is_reg(dentry)) {
                if (!inode || inode == d_inode(dentry))
@@ -106,28 +94,19 @@ static struct dentry *ovl_d_real(struct dentry *dentry,
                goto bug;
        }
 
-       if (open_flags) {
-               err = ovl_open_maybe_copy_up(dentry, open_flags);
-               if (err)
-                       return ERR_PTR(err);
-       }
-
        real = ovl_dentry_upper(dentry);
-       if (real && (!inode || inode == d_inode(real))) {
-               if (!inode) {
-                       err = ovl_check_append_only(d_inode(real), open_flags);
-                       if (err)
-                               return ERR_PTR(err);
-               }
+       if (real && (inode == d_inode(real)))
+               return real;
+
+       if (real && !inode && ovl_has_upperdata(d_inode(dentry)))
                return real;
-       }
 
-       real = ovl_dentry_lower(dentry);
+       real = ovl_dentry_lowerdata(dentry);
        if (!real)
                goto bug;
 
        /* Handle recursion */
-       real = d_real(real, inode, open_flags, 0);
+       real = d_real(real, inode);
 
        if (!inode || inode == d_inode(real))
                return real;
@@ -205,6 +184,7 @@ static struct inode *ovl_alloc_inode(struct super_block *sb)
        oi->flags = 0;
        oi->__upperdentry = NULL;
        oi->lower = NULL;
+       oi->lowerdata = NULL;
        mutex_init(&oi->lock);
 
        return &oi->vfs_inode;
@@ -223,8 +203,11 @@ static void ovl_destroy_inode(struct inode *inode)
 
        dput(oi->__upperdentry);
        iput(oi->lower);
+       if (S_ISDIR(inode->i_mode))
+               ovl_dir_cache_free(inode);
+       else
+               iput(oi->lowerdata);
        kfree(oi->redirect);
-       ovl_dir_cache_free(inode);
        mutex_destroy(&oi->lock);
 
        call_rcu(&inode->i_rcu, ovl_i_callback);
@@ -376,6 +359,9 @@ static int ovl_show_options(struct seq_file *m, struct dentry *dentry)
                                                "on" : "off");
        if (ofs->config.xino != ovl_xino_def())
                seq_printf(m, ",xino=%s", ovl_xino_str[ofs->config.xino]);
+       if (ofs->config.metacopy != ovl_metacopy_def)
+               seq_printf(m, ",metacopy=%s",
+                          ofs->config.metacopy ? "on" : "off");
        return 0;
 }
 
@@ -413,6 +399,8 @@ enum {
        OPT_XINO_ON,
        OPT_XINO_OFF,
        OPT_XINO_AUTO,
+       OPT_METACOPY_ON,
+       OPT_METACOPY_OFF,
        OPT_ERR,
 };
 
@@ -429,6 +417,8 @@ static const match_table_t ovl_tokens = {
        {OPT_XINO_ON,                   "xino=on"},
        {OPT_XINO_OFF,                  "xino=off"},
        {OPT_XINO_AUTO,                 "xino=auto"},
+       {OPT_METACOPY_ON,               "metacopy=on"},
+       {OPT_METACOPY_OFF,              "metacopy=off"},
        {OPT_ERR,                       NULL}
 };
 
@@ -481,6 +471,7 @@ static int ovl_parse_redirect_mode(struct ovl_config *config, const char *mode)
 static int ovl_parse_opt(char *opt, struct ovl_config *config)
 {
        char *p;
+       int err;
 
        config->redirect_mode = kstrdup(ovl_redirect_mode_def(), GFP_KERNEL);
        if (!config->redirect_mode)
@@ -555,6 +546,14 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
                        config->xino = OVL_XINO_AUTO;
                        break;
 
+               case OPT_METACOPY_ON:
+                       config->metacopy = true;
+                       break;
+
+               case OPT_METACOPY_OFF:
+                       config->metacopy = false;
+                       break;
+
                default:
                        pr_err("overlayfs: unrecognized mount option \"%s\" or missing value\n", p);
                        return -EINVAL;
@@ -569,7 +568,20 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
                config->workdir = NULL;
        }
 
-       return ovl_parse_redirect_mode(config, config->redirect_mode);
+       err = ovl_parse_redirect_mode(config, config->redirect_mode);
+       if (err)
+               return err;
+
+       /* metacopy feature with upper requires redirect_dir=on */
+       if (config->upperdir && config->metacopy && !config->redirect_dir) {
+               pr_warn("overlayfs: metadata only copy up requires \"redirect_dir=on\", falling back to metacopy=off.\n");
+               config->metacopy = false;
+       } else if (config->metacopy && !config->redirect_follow) {
+               pr_warn("overlayfs: metadata only copy up requires \"redirect_dir=follow\" on non-upper mount, falling back to metacopy=off.\n");
+               config->metacopy = false;
+       }
+
+       return 0;
 }
 
 #define OVL_WORKDIR_NAME "work"
@@ -1042,7 +1054,8 @@ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath)
        if (err) {
                ofs->noxattr = true;
                ofs->config.index = false;
-               pr_warn("overlayfs: upper fs does not support xattr, falling back to index=off.\n");
+               ofs->config.metacopy = false;
+               pr_warn("overlayfs: upper fs does not support xattr, falling back to index=off and metacopy=off.\n");
                err = 0;
        } else {
                vfs_removexattr(ofs->workdir, OVL_XATTR_OPAQUE);
@@ -1064,7 +1077,6 @@ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath)
                pr_warn("overlayfs: NFS export requires \"index=on\", falling back to nfs_export=off.\n");
                ofs->config.nfs_export = false;
        }
-
 out:
        mnt_drop_write(mnt);
        return err;
@@ -1375,6 +1387,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
        ofs->config.index = ovl_index_def;
        ofs->config.nfs_export = ovl_nfs_export_def;
        ofs->config.xino = ovl_xino_def();
+       ofs->config.metacopy = ovl_metacopy_def;
        err = ovl_parse_opt((char *) data, &ofs->config);
        if (err)
                goto out_err;
@@ -1445,6 +1458,11 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
                }
        }
 
+       if (ofs->config.metacopy && ofs->config.nfs_export) {
+               pr_warn("overlayfs: NFS export is not supported with metadata only copy up, falling back to nfs_export=off.\n");
+               ofs->config.nfs_export = false;
+       }
+
        if (ofs->config.nfs_export)
                sb->s_export_op = &ovl_export_operations;
 
@@ -1455,7 +1473,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_op = &ovl_super_operations;
        sb->s_xattr = ovl_xattr_handlers;
        sb->s_fs_info = ofs;
-       sb->s_flags |= SB_POSIXACL | SB_NOREMOTELOCK;
+       sb->s_flags |= SB_POSIXACL;
 
        err = -ENOMEM;
        root_dentry = d_make_root(ovl_new_inode(sb, S_IFDIR, 0));
@@ -1474,8 +1492,9 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
        /* Root is always merge -> can have whiteouts */
        ovl_set_flag(OVL_WHITEOUTS, d_inode(root_dentry));
        ovl_dentry_set_flag(OVL_E_CONNECTED, root_dentry);
+       ovl_set_upperdata(d_inode(root_dentry));
        ovl_inode_init(d_inode(root_dentry), upperpath.dentry,
-                      ovl_dentry_lower(root_dentry));
+                      ovl_dentry_lower(root_dentry), NULL);
 
        sb->s_root = root_dentry;
 
index 6f1078028c66b4aced7c94f04959a754b293645c..8cfb62cc86728029e271df468fe3b8415de1fc46 100644 (file)
@@ -133,8 +133,10 @@ enum ovl_path_type ovl_path_type(struct dentry *dentry)
                 * Non-dir dentry can hold lower dentry of its copy up origin.
                 */
                if (oe->numlower) {
-                       type |= __OVL_PATH_ORIGIN;
-                       if (d_is_dir(dentry))
+                       if (ovl_test_flag(OVL_CONST_INO, d_inode(dentry)))
+                               type |= __OVL_PATH_ORIGIN;
+                       if (d_is_dir(dentry) ||
+                           !ovl_has_upperdata(d_inode(dentry)))
                                type |= __OVL_PATH_MERGE;
                }
        } else {
@@ -164,6 +166,18 @@ void ovl_path_lower(struct dentry *dentry, struct path *path)
        }
 }
 
+void ovl_path_lowerdata(struct dentry *dentry, struct path *path)
+{
+       struct ovl_entry *oe = dentry->d_fsdata;
+
+       if (oe->numlower) {
+               path->mnt = oe->lowerstack[oe->numlower - 1].layer->mnt;
+               path->dentry = oe->lowerstack[oe->numlower - 1].dentry;
+       } else {
+               *path = (struct path) { };
+       }
+}
+
 enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path)
 {
        enum ovl_path_type type = ovl_path_type(dentry);
@@ -195,6 +209,19 @@ struct ovl_layer *ovl_layer_lower(struct dentry *dentry)
        return oe->numlower ? oe->lowerstack[0].layer : NULL;
 }
 
+/*
+ * ovl_dentry_lower() could return either a data dentry or metacopy dentry
+ * dependig on what is stored in lowerstack[0]. At times we need to find
+ * lower dentry which has data (and not metacopy dentry). This helper
+ * returns the lower data dentry.
+ */
+struct dentry *ovl_dentry_lowerdata(struct dentry *dentry)
+{
+       struct ovl_entry *oe = dentry->d_fsdata;
+
+       return oe->numlower ? oe->lowerstack[oe->numlower - 1].dentry : NULL;
+}
+
 struct dentry *ovl_dentry_real(struct dentry *dentry)
 {
        return ovl_dentry_upper(dentry) ?: ovl_dentry_lower(dentry);
@@ -222,6 +249,26 @@ struct inode *ovl_inode_real(struct inode *inode)
        return ovl_inode_upper(inode) ?: ovl_inode_lower(inode);
 }
 
+/* Return inode which contains lower data. Do not return metacopy */
+struct inode *ovl_inode_lowerdata(struct inode *inode)
+{
+       if (WARN_ON(!S_ISREG(inode->i_mode)))
+               return NULL;
+
+       return OVL_I(inode)->lowerdata ?: ovl_inode_lower(inode);
+}
+
+/* Return real inode which contains data. Does not return metacopy inode */
+struct inode *ovl_inode_realdata(struct inode *inode)
+{
+       struct inode *upperinode;
+
+       upperinode = ovl_inode_upper(inode);
+       if (upperinode && ovl_has_upperdata(inode))
+               return upperinode;
+
+       return ovl_inode_lowerdata(inode);
+}
 
 struct ovl_dir_cache *ovl_dir_cache(struct inode *inode)
 {
@@ -279,6 +326,62 @@ void ovl_dentry_set_upper_alias(struct dentry *dentry)
        ovl_dentry_set_flag(OVL_E_UPPER_ALIAS, dentry);
 }
 
+static bool ovl_should_check_upperdata(struct inode *inode)
+{
+       if (!S_ISREG(inode->i_mode))
+               return false;
+
+       if (!ovl_inode_lower(inode))
+               return false;
+
+       return true;
+}
+
+bool ovl_has_upperdata(struct inode *inode)
+{
+       if (!ovl_should_check_upperdata(inode))
+               return true;
+
+       if (!ovl_test_flag(OVL_UPPERDATA, inode))
+               return false;
+       /*
+        * Pairs with smp_wmb() in ovl_set_upperdata(). Main user of
+        * ovl_has_upperdata() is ovl_copy_up_meta_inode_data(). Make sure
+        * if setting of OVL_UPPERDATA is visible, then effects of writes
+        * before that are visible too.
+        */
+       smp_rmb();
+       return true;
+}
+
+void ovl_set_upperdata(struct inode *inode)
+{
+       /*
+        * Pairs with smp_rmb() in ovl_has_upperdata(). Make sure
+        * if OVL_UPPERDATA flag is visible, then effects of write operations
+        * before it are visible as well.
+        */
+       smp_wmb();
+       ovl_set_flag(OVL_UPPERDATA, inode);
+}
+
+/* Caller should hold ovl_inode->lock */
+bool ovl_dentry_needs_data_copy_up_locked(struct dentry *dentry, int flags)
+{
+       if (!ovl_open_flags_need_copy_up(flags))
+               return false;
+
+       return !ovl_test_flag(OVL_UPPERDATA, d_inode(dentry));
+}
+
+bool ovl_dentry_needs_data_copy_up(struct dentry *dentry, int flags)
+{
+       if (!ovl_open_flags_need_copy_up(flags))
+               return false;
+
+       return !ovl_has_upperdata(d_inode(dentry));
+}
+
 bool ovl_redirect_dir(struct super_block *sb)
 {
        struct ovl_fs *ofs = sb->s_fs_info;
@@ -300,7 +403,7 @@ void ovl_dentry_set_redirect(struct dentry *dentry, const char *redirect)
 }
 
 void ovl_inode_init(struct inode *inode, struct dentry *upperdentry,
-                   struct dentry *lowerdentry)
+                   struct dentry *lowerdentry, struct dentry *lowerdata)
 {
        struct inode *realinode = d_inode(upperdentry ?: lowerdentry);
 
@@ -308,8 +411,11 @@ void ovl_inode_init(struct inode *inode, struct dentry *upperdentry,
                OVL_I(inode)->__upperdentry = upperdentry;
        if (lowerdentry)
                OVL_I(inode)->lower = igrab(d_inode(lowerdentry));
+       if (lowerdata)
+               OVL_I(inode)->lowerdata = igrab(d_inode(lowerdata));
 
        ovl_copyattr(realinode, inode);
+       ovl_copyflags(realinode, inode);
        if (!inode->i_ino)
                inode->i_ino = realinode->i_ino;
 }
@@ -333,7 +439,7 @@ void ovl_inode_update(struct inode *inode, struct dentry *upperdentry)
        }
 }
 
-void ovl_dentry_version_inc(struct dentry *dentry, bool impurity)
+static void ovl_dentry_version_inc(struct dentry *dentry, bool impurity)
 {
        struct inode *inode = d_inode(dentry);
 
@@ -348,6 +454,14 @@ void ovl_dentry_version_inc(struct dentry *dentry, bool impurity)
                OVL_I(inode)->version++;
 }
 
+void ovl_dir_modified(struct dentry *dentry, bool impurity)
+{
+       /* Copy mtime/ctime */
+       ovl_copyattr(d_inode(ovl_dentry_upper(dentry)), d_inode(dentry));
+
+       ovl_dentry_version_inc(dentry, impurity);
+}
+
 u64 ovl_dentry_version_get(struct dentry *dentry)
 {
        struct inode *inode = d_inode(dentry);
@@ -368,13 +482,51 @@ struct file *ovl_path_open(struct path *path, int flags)
        return dentry_open(path, flags | O_NOATIME, current_cred());
 }
 
-int ovl_copy_up_start(struct dentry *dentry)
+/* Caller should hold ovl_inode->lock */
+static bool ovl_already_copied_up_locked(struct dentry *dentry, int flags)
+{
+       bool disconnected = dentry->d_flags & DCACHE_DISCONNECTED;
+
+       if (ovl_dentry_upper(dentry) &&
+           (ovl_dentry_has_upper_alias(dentry) || disconnected) &&
+           !ovl_dentry_needs_data_copy_up_locked(dentry, flags))
+               return true;
+
+       return false;
+}
+
+bool ovl_already_copied_up(struct dentry *dentry, int flags)
+{
+       bool disconnected = dentry->d_flags & DCACHE_DISCONNECTED;
+
+       /*
+        * Check if copy-up has happened as well as for upper alias (in
+        * case of hard links) is there.
+        *
+        * Both checks are lockless:
+        *  - false negatives: will recheck under oi->lock
+        *  - false positives:
+        *    + ovl_dentry_upper() uses memory barriers to ensure the
+        *      upper dentry is up-to-date
+        *    + ovl_dentry_has_upper_alias() relies on locking of
+        *      upper parent i_rwsem to prevent reordering copy-up
+        *      with rename.
+        */
+       if (ovl_dentry_upper(dentry) &&
+           (ovl_dentry_has_upper_alias(dentry) || disconnected) &&
+           !ovl_dentry_needs_data_copy_up(dentry, flags))
+               return true;
+
+       return false;
+}
+
+int ovl_copy_up_start(struct dentry *dentry, int flags)
 {
        struct ovl_inode *oi = OVL_I(d_inode(dentry));
        int err;
 
        err = mutex_lock_interruptible(&oi->lock);
-       if (!err && ovl_dentry_has_upper_alias(dentry)) {
+       if (!err && ovl_already_copied_up_locked(dentry, flags)) {
                err = 1; /* Already copied up */
                mutex_unlock(&oi->lock);
        }
@@ -675,3 +827,91 @@ err:
        pr_err("overlayfs: failed to lock workdir+upperdir\n");
        return -EIO;
 }
+
+/* err < 0, 0 if no metacopy xattr, 1 if metacopy xattr found */
+int ovl_check_metacopy_xattr(struct dentry *dentry)
+{
+       int res;
+
+       /* Only regular files can have metacopy xattr */
+       if (!S_ISREG(d_inode(dentry)->i_mode))
+               return 0;
+
+       res = vfs_getxattr(dentry, OVL_XATTR_METACOPY, NULL, 0);
+       if (res < 0) {
+               if (res == -ENODATA || res == -EOPNOTSUPP)
+                       return 0;
+               goto out;
+       }
+
+       return 1;
+out:
+       pr_warn_ratelimited("overlayfs: failed to get metacopy (%i)\n", res);
+       return res;
+}
+
+bool ovl_is_metacopy_dentry(struct dentry *dentry)
+{
+       struct ovl_entry *oe = dentry->d_fsdata;
+
+       if (!d_is_reg(dentry))
+               return false;
+
+       if (ovl_dentry_upper(dentry)) {
+               if (!ovl_has_upperdata(d_inode(dentry)))
+                       return true;
+               return false;
+       }
+
+       return (oe->numlower > 1);
+}
+
+char *ovl_get_redirect_xattr(struct dentry *dentry, int padding)
+{
+       int res;
+       char *s, *next, *buf = NULL;
+
+       res = vfs_getxattr(dentry, OVL_XATTR_REDIRECT, NULL, 0);
+       if (res < 0) {
+               if (res == -ENODATA || res == -EOPNOTSUPP)
+                       return NULL;
+               goto fail;
+       }
+
+       buf = kzalloc(res + padding + 1, GFP_KERNEL);
+       if (!buf)
+               return ERR_PTR(-ENOMEM);
+
+       if (res == 0)
+               goto invalid;
+
+       res = vfs_getxattr(dentry, OVL_XATTR_REDIRECT, buf, res);
+       if (res < 0)
+               goto fail;
+       if (res == 0)
+               goto invalid;
+
+       if (buf[0] == '/') {
+               for (s = buf; *s++ == '/'; s = next) {
+                       next = strchrnul(s, '/');
+                       if (s == next)
+                               goto invalid;
+               }
+       } else {
+               if (strchr(buf, '/') != NULL)
+                       goto invalid;
+       }
+
+       return buf;
+
+err_free:
+       kfree(buf);
+       return ERR_PTR(res);
+fail:
+       pr_warn_ratelimited("overlayfs: failed to get redirect (%i)\n", res);
+       goto err_free;
+invalid:
+       pr_warn_ratelimited("overlayfs: invalid redirect (%s)\n", buf);
+       res = -EINVAL;
+       goto err_free;
+}
index 0eaeb41453f566f600e6f97d9d1c69faacd89d1e..817c02b13b1d549675997df79ba363cdb319105d 100644 (file)
@@ -31,6 +31,7 @@ config PROC_FS
 config PROC_KCORE
        bool "/proc/kcore support" if !ARM
        depends on PROC_FS && MMU
+       select CRASH_CORE
        help
          Provides a virtual ELF core file of the live kernel.  This can
          be read with gdb and other ELF tools.  No modifications can be
index aaffc0c302162db0fc9d682c071469f55326dc1d..ccf86f16d9f0190c18e7f4345b7ca0960709eb05 100644 (file)
@@ -463,7 +463,7 @@ static int lstats_show_proc(struct seq_file *m, void *v)
        if (!task)
                return -ESRCH;
        seq_puts(m, "Latency Top version : v0.1\n");
-       for (i = 0; i < 32; i++) {
+       for (i = 0; i < LT_SAVECOUNT; i++) {
                struct latency_record *lr = &task->latency_record[i];
                if (lr->backtrace[0]) {
                        int q;
@@ -1366,10 +1366,8 @@ static ssize_t proc_fail_nth_read(struct file *file, char __user *buf,
        if (!task)
                return -ESRCH;
        len = snprintf(numbuf, sizeof(numbuf), "%u\n", task->fail_nth);
-       len = simple_read_from_buffer(buf, count, ppos, numbuf, len);
        put_task_struct(task);
-
-       return len;
+       return simple_read_from_buffer(buf, count, ppos, numbuf, len);
 }
 
 static const struct file_operations proc_fail_nth_operations = {
@@ -2519,47 +2517,47 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
                                   size_t count, loff_t *ppos)
 {
        struct inode * inode = file_inode(file);
+       struct task_struct *task;
        void *page;
-       ssize_t length;
-       struct task_struct *task = get_proc_task(inode);
-
-       length = -ESRCH;
-       if (!task)
-               goto out_no_task;
+       int rv;
 
+       rcu_read_lock();
+       task = pid_task(proc_pid(inode), PIDTYPE_PID);
+       if (!task) {
+               rcu_read_unlock();
+               return -ESRCH;
+       }
        /* A task may only write its own attributes. */
-       length = -EACCES;
-       if (current != task)
-               goto out;
+       if (current != task) {
+               rcu_read_unlock();
+               return -EACCES;
+       }
+       rcu_read_unlock();
 
        if (count > PAGE_SIZE)
                count = PAGE_SIZE;
 
        /* No partial writes. */
-       length = -EINVAL;
        if (*ppos != 0)
-               goto out;
+               return -EINVAL;
 
        page = memdup_user(buf, count);
        if (IS_ERR(page)) {
-               length = PTR_ERR(page);
+               rv = PTR_ERR(page);
                goto out;
        }
 
        /* Guard against adverse ptrace interaction */
-       length = mutex_lock_interruptible(&current->signal->cred_guard_mutex);
-       if (length < 0)
+       rv = mutex_lock_interruptible(&current->signal->cred_guard_mutex);
+       if (rv < 0)
                goto out_free;
 
-       length = security_setprocattr(file->f_path.dentry->d_name.name,
-                                     page, count);
+       rv = security_setprocattr(file->f_path.dentry->d_name.name, page, count);
        mutex_unlock(&current->signal->cred_guard_mutex);
 out_free:
        kfree(page);
 out:
-       put_task_struct(task);
-out_no_task:
-       return length;
+       return rv;
 }
 
 static const struct file_operations proc_pid_attr_operations = {
@@ -3309,12 +3307,12 @@ static const struct pid_entry tid_base_stuff[] = {
        REG("cmdline",   S_IRUGO, proc_pid_cmdline_ops),
        ONE("stat",      S_IRUGO, proc_tid_stat),
        ONE("statm",     S_IRUGO, proc_pid_statm),
-       REG("maps",      S_IRUGO, proc_tid_maps_operations),
+       REG("maps",      S_IRUGO, proc_pid_maps_operations),
 #ifdef CONFIG_PROC_CHILDREN
        REG("children",  S_IRUGO, proc_tid_children_operations),
 #endif
 #ifdef CONFIG_NUMA
-       REG("numa_maps", S_IRUGO, proc_tid_numa_maps_operations),
+       REG("numa_maps", S_IRUGO, proc_pid_numa_maps_operations),
 #endif
        REG("mem",       S_IRUSR|S_IWUSR, proc_mem_operations),
        LNK("cwd",       proc_cwd_link),
@@ -3324,7 +3322,7 @@ static const struct pid_entry tid_base_stuff[] = {
        REG("mountinfo",  S_IRUGO, proc_mountinfo_operations),
 #ifdef CONFIG_PROC_PAGE_MONITOR
        REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
-       REG("smaps",     S_IRUGO, proc_tid_smaps_operations),
+       REG("smaps",     S_IRUGO, proc_pid_smaps_operations),
        REG("smaps_rollup", S_IRUGO, proc_pid_smaps_rollup_operations),
        REG("pagemap",    S_IRUSR, proc_pagemap_operations),
 #endif
index bb1c1625b158d03f5c8685f55e370267e1cc76fb..8ae109429a883939ed0241c1e122db7ba857ac1a 100644 (file)
@@ -286,9 +286,9 @@ int proc_readdir_de(struct file *file, struct dir_context *ctx,
        if (!dir_emit_dots(file, ctx))
                return 0;
 
+       i = ctx->pos - 2;
        read_lock(&proc_subdir_lock);
        de = pde_subdir_first(de);
-       i = ctx->pos - 2;
        for (;;) {
                if (!de) {
                        read_unlock(&proc_subdir_lock);
@@ -309,8 +309,8 @@ int proc_readdir_de(struct file *file, struct dir_context *ctx,
                        pde_put(de);
                        return 0;
                }
-               read_lock(&proc_subdir_lock);
                ctx->pos++;
+               read_lock(&proc_subdir_lock);
                next = pde_subdir_next(de);
                pde_put(de);
                de = next;
index 85ffbd27f2883a8e6fb3dfe8275c2e1a36ac3ffe..fc5306a31a1d8b489dc16483d79cf83b6445f387 100644 (file)
@@ -105,8 +105,10 @@ void __init proc_init_kmemcache(void)
                kmem_cache_create("pde_opener", sizeof(struct pde_opener), 0,
                                  SLAB_ACCOUNT|SLAB_PANIC, NULL);
        proc_dir_entry_cache = kmem_cache_create_usercopy(
-               "proc_dir_entry", SIZEOF_PDE_SLOT, 0, SLAB_PANIC,
-               OFFSETOF_PDE_NAME, SIZEOF_PDE_INLINE_NAME, NULL);
+               "proc_dir_entry", SIZEOF_PDE, 0, SLAB_PANIC,
+               offsetof(struct proc_dir_entry, inline_name),
+               SIZEOF_PDE_INLINE_NAME, NULL);
+       BUILD_BUG_ON(sizeof(struct proc_dir_entry) >= SIZEOF_PDE);
 }
 
 static int proc_show_options(struct seq_file *seq, struct dentry *root)
index da3dbfa09e79c2f82a4f601f2eb103c00f716a23..5185d7f6a51ee845fc12c6d49d4497d766af6c23 100644 (file)
@@ -65,16 +65,13 @@ struct proc_dir_entry {
        char inline_name[];
 } __randomize_layout;
 
-#define OFFSETOF_PDE_NAME offsetof(struct proc_dir_entry, inline_name)
-#define SIZEOF_PDE_SLOT                                        \
-       (OFFSETOF_PDE_NAME + 34 <= 64 ? 64 :            \
-        OFFSETOF_PDE_NAME + 34 <= 128 ? 128 :          \
-        OFFSETOF_PDE_NAME + 34 <= 192 ? 192 :          \
-        OFFSETOF_PDE_NAME + 34 <= 256 ? 256 :          \
-        OFFSETOF_PDE_NAME + 34 <= 512 ? 512 :          \
-        0)
-
-#define SIZEOF_PDE_INLINE_NAME (SIZEOF_PDE_SLOT - OFFSETOF_PDE_NAME)
+#define SIZEOF_PDE     (                               \
+       sizeof(struct proc_dir_entry) < 128 ? 128 :     \
+       sizeof(struct proc_dir_entry) < 192 ? 192 :     \
+       sizeof(struct proc_dir_entry) < 256 ? 256 :     \
+       sizeof(struct proc_dir_entry) < 512 ? 512 :     \
+       0)
+#define SIZEOF_PDE_INLINE_NAME (SIZEOF_PDE - sizeof(struct proc_dir_entry))
 
 extern struct kmem_cache *proc_dir_entry_cache;
 void pde_free(struct proc_dir_entry *pde);
@@ -116,12 +113,12 @@ static inline void *__PDE_DATA(const struct inode *inode)
        return PDE(inode)->data;
 }
 
-static inline struct pid *proc_pid(struct inode *inode)
+static inline struct pid *proc_pid(const struct inode *inode)
 {
        return PROC_I(inode)->pid;
 }
 
-static inline struct task_struct *get_proc_task(struct inode *inode)
+static inline struct task_struct *get_proc_task(const struct inode *inode)
 {
        return get_pid_task(proc_pid(inode), PIDTYPE_PID);
 }
@@ -285,7 +282,6 @@ struct proc_maps_private {
        struct inode *inode;
        struct task_struct *task;
        struct mm_struct *mm;
-       struct mem_size_stats *rollup;
 #ifdef CONFIG_MMU
        struct vm_area_struct *tail_vma;
 #endif
@@ -297,12 +293,9 @@ struct proc_maps_private {
 struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode);
 
 extern const struct file_operations proc_pid_maps_operations;
-extern const struct file_operations proc_tid_maps_operations;
 extern const struct file_operations proc_pid_numa_maps_operations;
-extern const struct file_operations proc_tid_numa_maps_operations;
 extern const struct file_operations proc_pid_smaps_operations;
 extern const struct file_operations proc_pid_smaps_rollup_operations;
-extern const struct file_operations proc_tid_smaps_operations;
 extern const struct file_operations proc_clear_refs_operations;
 extern const struct file_operations proc_pagemap_operations;
 
index e64ecb9f272090bf6b23772a0d36e56b63b8106a..ad72261ee3fe8d1959038fa0ee9bf6d0ff276449 100644 (file)
@@ -10,6 +10,7 @@
  *     Safe accesses to vmalloc/direct-mapped discontiguous areas, Kanoj Sarcar <kanoj@sgi.com>
  */
 
+#include <linux/crash_core.h>
 #include <linux/mm.h>
 #include <linux/proc_fs.h>
 #include <linux/kcore.h>
@@ -49,32 +50,23 @@ static struct proc_dir_entry *proc_root_kcore;
 #define        kc_offset_to_vaddr(o) ((o) + PAGE_OFFSET)
 #endif
 
-/* An ELF note in memory */
-struct memelfnote
-{
-       const char *name;
-       int type;
-       unsigned int datasz;
-       void *data;
-};
-
 static LIST_HEAD(kclist_head);
-static DEFINE_RWLOCK(kclist_lock);
+static DECLARE_RWSEM(kclist_lock);
 static int kcore_need_update = 1;
 
-void
-kclist_add(struct kcore_list *new, void *addr, size_t size, int type)
+/* This doesn't grab kclist_lock, so it should only be used at init time. */
+void __init kclist_add(struct kcore_list *new, void *addr, size_t size,
+                      int type)
 {
        new->addr = (unsigned long)addr;
        new->size = size;
        new->type = type;
 
-       write_lock(&kclist_lock);
        list_add_tail(&new->list, &kclist_head);
-       write_unlock(&kclist_lock);
 }
 
-static size_t get_kcore_size(int *nphdr, size_t *elf_buflen)
+static size_t get_kcore_size(int *nphdr, size_t *phdrs_len, size_t *notes_len,
+                            size_t *data_offset)
 {
        size_t try, size;
        struct kcore_list *m;
@@ -88,53 +80,19 @@ static size_t get_kcore_size(int *nphdr, size_t *elf_buflen)
                        size = try;
                *nphdr = *nphdr + 1;
        }
-       *elf_buflen =   sizeof(struct elfhdr) + 
-                       (*nphdr + 2)*sizeof(struct elf_phdr) + 
-                       3 * ((sizeof(struct elf_note)) +
-                            roundup(sizeof(CORE_STR), 4)) +
-                       roundup(sizeof(struct elf_prstatus), 4) +
-                       roundup(sizeof(struct elf_prpsinfo), 4) +
-                       roundup(arch_task_struct_size, 4);
-       *elf_buflen = PAGE_ALIGN(*elf_buflen);
-       return size + *elf_buflen;
-}
-
-static void free_kclist_ents(struct list_head *head)
-{
-       struct kcore_list *tmp, *pos;
 
-       list_for_each_entry_safe(pos, tmp, head, list) {
-               list_del(&pos->list);
-               kfree(pos);
-       }
+       *phdrs_len = *nphdr * sizeof(struct elf_phdr);
+       *notes_len = (4 * sizeof(struct elf_note) +
+                     3 * ALIGN(sizeof(CORE_STR), 4) +
+                     VMCOREINFO_NOTE_NAME_BYTES +
+                     ALIGN(sizeof(struct elf_prstatus), 4) +
+                     ALIGN(sizeof(struct elf_prpsinfo), 4) +
+                     ALIGN(arch_task_struct_size, 4) +
+                     ALIGN(vmcoreinfo_size, 4));
+       *data_offset = PAGE_ALIGN(sizeof(struct elfhdr) + *phdrs_len +
+                                 *notes_len);
+       return *data_offset + size;
 }
-/*
- * Replace all KCORE_RAM/KCORE_VMEMMAP information with passed list.
- */
-static void __kcore_update_ram(struct list_head *list)
-{
-       int nphdr;
-       size_t size;
-       struct kcore_list *tmp, *pos;
-       LIST_HEAD(garbage);
-
-       write_lock(&kclist_lock);
-       if (kcore_need_update) {
-               list_for_each_entry_safe(pos, tmp, &kclist_head, list) {
-                       if (pos->type == KCORE_RAM
-                               || pos->type == KCORE_VMEMMAP)
-                               list_move(&pos->list, &garbage);
-               }
-               list_splice_tail(list, &kclist_head);
-       } else
-               list_splice(list, &garbage);
-       kcore_need_update = 0;
-       proc_root_kcore->size = get_kcore_size(&nphdr, &size);
-       write_unlock(&kclist_lock);
-
-       free_kclist_ents(&garbage);
-}
-
 
 #ifdef CONFIG_HIGHMEM
 /*
@@ -142,11 +100,9 @@ static void __kcore_update_ram(struct list_head *list)
  * because memory hole is not as big as !HIGHMEM case.
  * (HIGHMEM is special because part of memory is _invisible_ from the kernel.)
  */
-static int kcore_update_ram(void)
+static int kcore_ram_list(struct list_head *head)
 {
-       LIST_HEAD(head);
        struct kcore_list *ent;
-       int ret = 0;
 
        ent = kmalloc(sizeof(*ent), GFP_KERNEL);
        if (!ent)
@@ -154,9 +110,8 @@ static int kcore_update_ram(void)
        ent->addr = (unsigned long)__va(0);
        ent->size = max_low_pfn << PAGE_SHIFT;
        ent->type = KCORE_RAM;
-       list_add(&ent->list, &head);
-       __kcore_update_ram(&head);
-       return ret;
+       list_add(&ent->list, head);
+       return 0;
 }
 
 #else /* !CONFIG_HIGHMEM */
@@ -255,11 +210,10 @@ free_out:
        return 1;
 }
 
-static int kcore_update_ram(void)
+static int kcore_ram_list(struct list_head *list)
 {
        int nid, ret;
        unsigned long end_pfn;
-       LIST_HEAD(head);
 
        /* Not inialized....update now */
        /* find out "max pfn" */
@@ -271,258 +225,258 @@ static int kcore_update_ram(void)
                        end_pfn = node_end;
        }
        /* scan 0 to max_pfn */
-       ret = walk_system_ram_range(0, end_pfn, &head, kclist_add_private);
-       if (ret) {
-               free_kclist_ents(&head);
+       ret = walk_system_ram_range(0, end_pfn, list, kclist_add_private);
+       if (ret)
                return -ENOMEM;
-       }
-       __kcore_update_ram(&head);
-       return ret;
+       return 0;
 }
 #endif /* CONFIG_HIGHMEM */
 
-/*****************************************************************************/
-/*
- * determine size of ELF note
- */
-static int notesize(struct memelfnote *en)
-{
-       int sz;
-
-       sz = sizeof(struct elf_note);
-       sz += roundup((strlen(en->name) + 1), 4);
-       sz += roundup(en->datasz, 4);
-
-       return sz;
-} /* end notesize() */
-
-/*****************************************************************************/
-/*
- * store a note in the header buffer
- */
-static char *storenote(struct memelfnote *men, char *bufp)
+static int kcore_update_ram(void)
 {
-       struct elf_note en;
-
-#define DUMP_WRITE(addr,nr) do { memcpy(bufp,addr,nr); bufp += nr; } while(0)
-
-       en.n_namesz = strlen(men->name) + 1;
-       en.n_descsz = men->datasz;
-       en.n_type = men->type;
-
-       DUMP_WRITE(&en, sizeof(en));
-       DUMP_WRITE(men->name, en.n_namesz);
-
-       /* XXX - cast from long long to long to avoid need for libgcc.a */
-       bufp = (char*) roundup((unsigned long)bufp,4);
-       DUMP_WRITE(men->data, men->datasz);
-       bufp = (char*) roundup((unsigned long)bufp,4);
-
-#undef DUMP_WRITE
-
-       return bufp;
-} /* end storenote() */
+       LIST_HEAD(list);
+       LIST_HEAD(garbage);
+       int nphdr;
+       size_t phdrs_len, notes_len, data_offset;
+       struct kcore_list *tmp, *pos;
+       int ret = 0;
 
-/*
- * store an ELF coredump header in the supplied buffer
- * nphdr is the number of elf_phdr to insert
- */
-static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff)
-{
-       struct elf_prstatus prstatus;   /* NT_PRSTATUS */
-       struct elf_prpsinfo prpsinfo;   /* NT_PRPSINFO */
-       struct elf_phdr *nhdr, *phdr;
-       struct elfhdr *elf;
-       struct memelfnote notes[3];
-       off_t offset = 0;
-       struct kcore_list *m;
+       down_write(&kclist_lock);
+       if (!xchg(&kcore_need_update, 0))
+               goto out;
 
-       /* setup ELF header */
-       elf = (struct elfhdr *) bufp;
-       bufp += sizeof(struct elfhdr);
-       offset += sizeof(struct elfhdr);
-       memcpy(elf->e_ident, ELFMAG, SELFMAG);
-       elf->e_ident[EI_CLASS]  = ELF_CLASS;
-       elf->e_ident[EI_DATA]   = ELF_DATA;
-       elf->e_ident[EI_VERSION]= EV_CURRENT;
-       elf->e_ident[EI_OSABI] = ELF_OSABI;
-       memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
-       elf->e_type     = ET_CORE;
-       elf->e_machine  = ELF_ARCH;
-       elf->e_version  = EV_CURRENT;
-       elf->e_entry    = 0;
-       elf->e_phoff    = sizeof(struct elfhdr);
-       elf->e_shoff    = 0;
-       elf->e_flags    = ELF_CORE_EFLAGS;
-       elf->e_ehsize   = sizeof(struct elfhdr);
-       elf->e_phentsize= sizeof(struct elf_phdr);
-       elf->e_phnum    = nphdr;
-       elf->e_shentsize= 0;
-       elf->e_shnum    = 0;
-       elf->e_shstrndx = 0;
-
-       /* setup ELF PT_NOTE program header */
-       nhdr = (struct elf_phdr *) bufp;
-       bufp += sizeof(struct elf_phdr);
-       offset += sizeof(struct elf_phdr);
-       nhdr->p_type    = PT_NOTE;
-       nhdr->p_offset  = 0;
-       nhdr->p_vaddr   = 0;
-       nhdr->p_paddr   = 0;
-       nhdr->p_filesz  = 0;
-       nhdr->p_memsz   = 0;
-       nhdr->p_flags   = 0;
-       nhdr->p_align   = 0;
-
-       /* setup ELF PT_LOAD program header for every area */
-       list_for_each_entry(m, &kclist_head, list) {
-               phdr = (struct elf_phdr *) bufp;
-               bufp += sizeof(struct elf_phdr);
-               offset += sizeof(struct elf_phdr);
-
-               phdr->p_type    = PT_LOAD;
-               phdr->p_flags   = PF_R|PF_W|PF_X;
-               phdr->p_offset  = kc_vaddr_to_offset(m->addr) + dataoff;
-               phdr->p_vaddr   = (size_t)m->addr;
-               if (m->type == KCORE_RAM || m->type == KCORE_TEXT)
-                       phdr->p_paddr   = __pa(m->addr);
-               else
-                       phdr->p_paddr   = (elf_addr_t)-1;
-               phdr->p_filesz  = phdr->p_memsz = m->size;
-               phdr->p_align   = PAGE_SIZE;
+       ret = kcore_ram_list(&list);
+       if (ret) {
+               /* Couldn't get the RAM list, try again next time. */
+               WRITE_ONCE(kcore_need_update, 1);
+               list_splice_tail(&list, &garbage);
+               goto out;
        }
 
-       /*
-        * Set up the notes in similar form to SVR4 core dumps made
-        * with info from their /proc.
-        */
-       nhdr->p_offset  = offset;
-
-       /* set up the process status */
-       notes[0].name = CORE_STR;
-       notes[0].type = NT_PRSTATUS;
-       notes[0].datasz = sizeof(struct elf_prstatus);
-       notes[0].data = &prstatus;
-
-       memset(&prstatus, 0, sizeof(struct elf_prstatus));
-
-       nhdr->p_filesz  = notesize(&notes[0]);
-       bufp = storenote(&notes[0], bufp);
-
-       /* set up the process info */
-       notes[1].name   = CORE_STR;
-       notes[1].type   = NT_PRPSINFO;
-       notes[1].datasz = sizeof(struct elf_prpsinfo);
-       notes[1].data   = &prpsinfo;
-
-       memset(&prpsinfo, 0, sizeof(struct elf_prpsinfo));
-       prpsinfo.pr_state       = 0;
-       prpsinfo.pr_sname       = 'R';
-       prpsinfo.pr_zomb        = 0;
-
-       strcpy(prpsinfo.pr_fname, "vmlinux");
-       strlcpy(prpsinfo.pr_psargs, saved_command_line, sizeof(prpsinfo.pr_psargs));
-
-       nhdr->p_filesz  += notesize(&notes[1]);
-       bufp = storenote(&notes[1], bufp);
+       list_for_each_entry_safe(pos, tmp, &kclist_head, list) {
+               if (pos->type == KCORE_RAM || pos->type == KCORE_VMEMMAP)
+                       list_move(&pos->list, &garbage);
+       }
+       list_splice_tail(&list, &kclist_head);
 
-       /* set up the task structure */
-       notes[2].name   = CORE_STR;
-       notes[2].type   = NT_TASKSTRUCT;
-       notes[2].datasz = arch_task_struct_size;
-       notes[2].data   = current;
+       proc_root_kcore->size = get_kcore_size(&nphdr, &phdrs_len, &notes_len,
+                                              &data_offset);
 
-       nhdr->p_filesz  += notesize(&notes[2]);
-       bufp = storenote(&notes[2], bufp);
+out:
+       up_write(&kclist_lock);
+       list_for_each_entry_safe(pos, tmp, &garbage, list) {
+               list_del(&pos->list);
+               kfree(pos);
+       }
+       return ret;
+}
 
-} /* end elf_kcore_store_hdr() */
+static void append_kcore_note(char *notes, size_t *i, const char *name,
+                             unsigned int type, const void *desc,
+                             size_t descsz)
+{
+       struct elf_note *note = (struct elf_note *)&notes[*i];
+
+       note->n_namesz = strlen(name) + 1;
+       note->n_descsz = descsz;
+       note->n_type = type;
+       *i += sizeof(*note);
+       memcpy(&notes[*i], name, note->n_namesz);
+       *i = ALIGN(*i + note->n_namesz, 4);
+       memcpy(&notes[*i], desc, descsz);
+       *i = ALIGN(*i + descsz, 4);
+}
 
-/*****************************************************************************/
-/*
- * read from the ELF header and then kernel memory
- */
 static ssize_t
 read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
 {
        char *buf = file->private_data;
-       ssize_t acc = 0;
-       size_t size, tsz;
-       size_t elf_buflen;
+       size_t phdrs_offset, notes_offset, data_offset;
+       size_t phdrs_len, notes_len;
+       struct kcore_list *m;
+       size_t tsz;
        int nphdr;
        unsigned long start;
+       size_t orig_buflen = buflen;
+       int ret = 0;
 
-       read_lock(&kclist_lock);
-       size = get_kcore_size(&nphdr, &elf_buflen);
+       down_read(&kclist_lock);
+
+       get_kcore_size(&nphdr, &phdrs_len, &notes_len, &data_offset);
+       phdrs_offset = sizeof(struct elfhdr);
+       notes_offset = phdrs_offset + phdrs_len;
+
+       /* ELF file header. */
+       if (buflen && *fpos < sizeof(struct elfhdr)) {
+               struct elfhdr ehdr = {
+                       .e_ident = {
+                               [EI_MAG0] = ELFMAG0,
+                               [EI_MAG1] = ELFMAG1,
+                               [EI_MAG2] = ELFMAG2,
+                               [EI_MAG3] = ELFMAG3,
+                               [EI_CLASS] = ELF_CLASS,
+                               [EI_DATA] = ELF_DATA,
+                               [EI_VERSION] = EV_CURRENT,
+                               [EI_OSABI] = ELF_OSABI,
+                       },
+                       .e_type = ET_CORE,
+                       .e_machine = ELF_ARCH,
+                       .e_version = EV_CURRENT,
+                       .e_phoff = sizeof(struct elfhdr),
+                       .e_flags = ELF_CORE_EFLAGS,
+                       .e_ehsize = sizeof(struct elfhdr),
+                       .e_phentsize = sizeof(struct elf_phdr),
+                       .e_phnum = nphdr,
+               };
+
+               tsz = min_t(size_t, buflen, sizeof(struct elfhdr) - *fpos);
+               if (copy_to_user(buffer, (char *)&ehdr + *fpos, tsz)) {
+                       ret = -EFAULT;
+                       goto out;
+               }
 
-       if (buflen == 0 || *fpos >= size) {
-               read_unlock(&kclist_lock);
-               return 0;
+               buffer += tsz;
+               buflen -= tsz;
+               *fpos += tsz;
        }
 
-       /* trim buflen to not go beyond EOF */
-       if (buflen > size - *fpos)
-               buflen = size - *fpos;
-
-       /* construct an ELF core header if we'll need some of it */
-       if (*fpos < elf_buflen) {
-               char * elf_buf;
-
-               tsz = elf_buflen - *fpos;
-               if (buflen < tsz)
-                       tsz = buflen;
-               elf_buf = kzalloc(elf_buflen, GFP_ATOMIC);
-               if (!elf_buf) {
-                       read_unlock(&kclist_lock);
-                       return -ENOMEM;
+       /* ELF program headers. */
+       if (buflen && *fpos < phdrs_offset + phdrs_len) {
+               struct elf_phdr *phdrs, *phdr;
+
+               phdrs = kzalloc(phdrs_len, GFP_KERNEL);
+               if (!phdrs) {
+                       ret = -ENOMEM;
+                       goto out;
                }
-               elf_kcore_store_hdr(elf_buf, nphdr, elf_buflen);
-               read_unlock(&kclist_lock);
-               if (copy_to_user(buffer, elf_buf + *fpos, tsz)) {
-                       kfree(elf_buf);
-                       return -EFAULT;
+
+               phdrs[0].p_type = PT_NOTE;
+               phdrs[0].p_offset = notes_offset;
+               phdrs[0].p_filesz = notes_len;
+
+               phdr = &phdrs[1];
+               list_for_each_entry(m, &kclist_head, list) {
+                       phdr->p_type = PT_LOAD;
+                       phdr->p_flags = PF_R | PF_W | PF_X;
+                       phdr->p_offset = kc_vaddr_to_offset(m->addr) + data_offset;
+                       if (m->type == KCORE_REMAP)
+                               phdr->p_vaddr = (size_t)m->vaddr;
+                       else
+                               phdr->p_vaddr = (size_t)m->addr;
+                       if (m->type == KCORE_RAM || m->type == KCORE_REMAP)
+                               phdr->p_paddr = __pa(m->addr);
+                       else if (m->type == KCORE_TEXT)
+                               phdr->p_paddr = __pa_symbol(m->addr);
+                       else
+                               phdr->p_paddr = (elf_addr_t)-1;
+                       phdr->p_filesz = phdr->p_memsz = m->size;
+                       phdr->p_align = PAGE_SIZE;
+                       phdr++;
                }
-               kfree(elf_buf);
+
+               tsz = min_t(size_t, buflen, phdrs_offset + phdrs_len - *fpos);
+               if (copy_to_user(buffer, (char *)phdrs + *fpos - phdrs_offset,
+                                tsz)) {
+                       kfree(phdrs);
+                       ret = -EFAULT;
+                       goto out;
+               }
+               kfree(phdrs);
+
+               buffer += tsz;
                buflen -= tsz;
                *fpos += tsz;
-               buffer += tsz;
-               acc += tsz;
+       }
+
+       /* ELF note segment. */
+       if (buflen && *fpos < notes_offset + notes_len) {
+               struct elf_prstatus prstatus = {};
+               struct elf_prpsinfo prpsinfo = {
+                       .pr_sname = 'R',
+                       .pr_fname = "vmlinux",
+               };
+               char *notes;
+               size_t i = 0;
+
+               strlcpy(prpsinfo.pr_psargs, saved_command_line,
+                       sizeof(prpsinfo.pr_psargs));
+
+               notes = kzalloc(notes_len, GFP_KERNEL);
+               if (!notes) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+
+               append_kcore_note(notes, &i, CORE_STR, NT_PRSTATUS, &prstatus,
+                                 sizeof(prstatus));
+               append_kcore_note(notes, &i, CORE_STR, NT_PRPSINFO, &prpsinfo,
+                                 sizeof(prpsinfo));
+               append_kcore_note(notes, &i, CORE_STR, NT_TASKSTRUCT, current,
+                                 arch_task_struct_size);
+               /*
+                * vmcoreinfo_size is mostly constant after init time, but it
+                * can be changed by crash_save_vmcoreinfo(). Racing here with a
+                * panic on another CPU before the machine goes down is insanely
+                * unlikely, but it's better to not leave potential buffer
+                * overflows lying around, regardless.
+                */
+               append_kcore_note(notes, &i, VMCOREINFO_NOTE_NAME, 0,
+                                 vmcoreinfo_data,
+                                 min(vmcoreinfo_size, notes_len - i));
+
+               tsz = min_t(size_t, buflen, notes_offset + notes_len - *fpos);
+               if (copy_to_user(buffer, notes + *fpos - notes_offset, tsz)) {
+                       kfree(notes);
+                       ret = -EFAULT;
+                       goto out;
+               }
+               kfree(notes);
 
-               /* leave now if filled buffer already */
-               if (buflen == 0)
-                       return acc;
-       } else
-               read_unlock(&kclist_lock);
+               buffer += tsz;
+               buflen -= tsz;
+               *fpos += tsz;
+       }
 
        /*
         * Check to see if our file offset matches with any of
         * the addresses in the elf_phdr on our list.
         */
-       start = kc_offset_to_vaddr(*fpos - elf_buflen);
+       start = kc_offset_to_vaddr(*fpos - data_offset);
        if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen)
                tsz = buflen;
-               
-       while (buflen) {
-               struct kcore_list *m;
 
-               read_lock(&kclist_lock);
-               list_for_each_entry(m, &kclist_head, list) {
-                       if (start >= m->addr && start < (m->addr+m->size))
-                               break;
+       m = NULL;
+       while (buflen) {
+               /*
+                * If this is the first iteration or the address is not within
+                * the previous entry, search for a matching entry.
+                */
+               if (!m || start < m->addr || start >= m->addr + m->size) {
+                       list_for_each_entry(m, &kclist_head, list) {
+                               if (start >= m->addr &&
+                                   start < m->addr + m->size)
+                                       break;
+                       }
                }
-               read_unlock(&kclist_lock);
 
                if (&m->list == &kclist_head) {
-                       if (clear_user(buffer, tsz))
-                               return -EFAULT;
+                       if (clear_user(buffer, tsz)) {
+                               ret = -EFAULT;
+                               goto out;
+                       }
                } else if (m->type == KCORE_VMALLOC) {
                        vread(buf, (char *)start, tsz);
                        /* we have to zero-fill user buffer even if no read */
-                       if (copy_to_user(buffer, buf, tsz))
-                               return -EFAULT;
+                       if (copy_to_user(buffer, buf, tsz)) {
+                               ret = -EFAULT;
+                               goto out;
+                       }
                } else if (m->type == KCORE_USER) {
                        /* User page is handled prior to normal kernel page: */
-                       if (copy_to_user(buffer, (char *)start, tsz))
-                               return -EFAULT;
+                       if (copy_to_user(buffer, (char *)start, tsz)) {
+                               ret = -EFAULT;
+                               goto out;
+                       }
                } else {
                        if (kern_addr_valid(start)) {
                                /*
@@ -530,29 +484,37 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
                                 * hardened user copy kernel text checks.
                                 */
                                if (probe_kernel_read(buf, (void *) start, tsz)) {
-                                       if (clear_user(buffer, tsz))
-                                               return -EFAULT;
+                                       if (clear_user(buffer, tsz)) {
+                                               ret = -EFAULT;
+                                               goto out;
+                                       }
                                } else {
-                                       if (copy_to_user(buffer, buf, tsz))
-                                               return -EFAULT;
+                                       if (copy_to_user(buffer, buf, tsz)) {
+                                               ret = -EFAULT;
+                                               goto out;
+                                       }
                                }
                        } else {
-                               if (clear_user(buffer, tsz))
-                                       return -EFAULT;
+                               if (clear_user(buffer, tsz)) {
+                                       ret = -EFAULT;
+                                       goto out;
+                               }
                        }
                }
                buflen -= tsz;
                *fpos += tsz;
                buffer += tsz;
-               acc += tsz;
                start += tsz;
                tsz = (buflen > PAGE_SIZE ? PAGE_SIZE : buflen);
        }
 
-       return acc;
+out:
+       up_read(&kclist_lock);
+       if (ret)
+               return ret;
+       return orig_buflen - buflen;
 }
 
-
 static int open_kcore(struct inode *inode, struct file *filp)
 {
        if (!capable(CAP_SYS_RAWIO))
@@ -592,9 +554,8 @@ static int __meminit kcore_callback(struct notifier_block *self,
        switch (action) {
        case MEM_ONLINE:
        case MEM_OFFLINE:
-               write_lock(&kclist_lock);
                kcore_need_update = 1;
-               write_unlock(&kclist_lock);
+               break;
        }
        return NOTIFY_OK;
 }
index 2fb04846ed11618666be529393732f5d706725d0..edda898714eb7bb23585241dc6631800c6ba1dfb 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/mman.h>
 #include <linux/mmzone.h>
 #include <linux/proc_fs.h>
+#include <linux/percpu.h>
 #include <linux/quicklist.h>
 #include <linux/seq_file.h>
 #include <linux/swap.h>
@@ -121,6 +122,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
                   (unsigned long)VMALLOC_TOTAL >> 10);
        show_val_kb(m, "VmallocUsed:    ", 0ul);
        show_val_kb(m, "VmallocChunk:   ", 0ul);
+       show_val_kb(m, "Percpu:         ", pcpu_nr_pages());
 
 #ifdef CONFIG_MEMORY_FAILURE
        seq_printf(m, "HardwareCorrupted: %5lu kB\n",
index 59749dfaef6743c270a00fdee97e378929a03899..535eda7857cfd5d16545edd40ce0c3cae0fb8f10 100644 (file)
@@ -183,7 +183,7 @@ static int show_stat(struct seq_file *p, void *v)
 
 static int stat_open(struct inode *inode, struct file *file)
 {
-       size_t size = 1024 + 128 * num_online_cpus();
+       unsigned int size = 1024 + 128 * num_online_cpus();
 
        /* minimum size to display an interrupt count : 2 bytes */
        size += 2 * nr_irqs;
index dfd73a4616ce565bfccb996a50f5eb549fe41fe8..5ea1d64cb0b4c19c185ad67d5990c0ce03e82561 100644 (file)
@@ -247,7 +247,6 @@ static int proc_map_release(struct inode *inode, struct file *file)
        if (priv->mm)
                mmdrop(priv->mm);
 
-       kfree(priv->rollup);
        return seq_release_private(inode, file);
 }
 
@@ -294,7 +293,7 @@ static void show_vma_header_prefix(struct seq_file *m,
 }
 
 static void
-show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
+show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
 {
        struct mm_struct *mm = vma->vm_mm;
        struct file *file = vma->vm_file;
@@ -357,35 +356,18 @@ done:
        seq_putc(m, '\n');
 }
 
-static int show_map(struct seq_file *m, void *v, int is_pid)
+static int show_map(struct seq_file *m, void *v)
 {
-       show_map_vma(m, v, is_pid);
+       show_map_vma(m, v);
        m_cache_vma(m, v);
        return 0;
 }
 
-static int show_pid_map(struct seq_file *m, void *v)
-{
-       return show_map(m, v, 1);
-}
-
-static int show_tid_map(struct seq_file *m, void *v)
-{
-       return show_map(m, v, 0);
-}
-
 static const struct seq_operations proc_pid_maps_op = {
        .start  = m_start,
        .next   = m_next,
        .stop   = m_stop,
-       .show   = show_pid_map
-};
-
-static const struct seq_operations proc_tid_maps_op = {
-       .start  = m_start,
-       .next   = m_next,
-       .stop   = m_stop,
-       .show   = show_tid_map
+       .show   = show_map
 };
 
 static int pid_maps_open(struct inode *inode, struct file *file)
@@ -393,11 +375,6 @@ static int pid_maps_open(struct inode *inode, struct file *file)
        return do_maps_open(inode, file, &proc_pid_maps_op);
 }
 
-static int tid_maps_open(struct inode *inode, struct file *file)
-{
-       return do_maps_open(inode, file, &proc_tid_maps_op);
-}
-
 const struct file_operations proc_pid_maps_operations = {
        .open           = pid_maps_open,
        .read           = seq_read,
@@ -405,13 +382,6 @@ const struct file_operations proc_pid_maps_operations = {
        .release        = proc_map_release,
 };
 
-const struct file_operations proc_tid_maps_operations = {
-       .open           = tid_maps_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = proc_map_release,
-};
-
 /*
  * Proportional Set Size(PSS): my share of RSS.
  *
@@ -433,7 +403,6 @@ const struct file_operations proc_tid_maps_operations = {
 
 #ifdef CONFIG_PROC_PAGE_MONITOR
 struct mem_size_stats {
-       bool first;
        unsigned long resident;
        unsigned long shared_clean;
        unsigned long shared_dirty;
@@ -447,7 +416,6 @@ struct mem_size_stats {
        unsigned long swap;
        unsigned long shared_hugetlb;
        unsigned long private_hugetlb;
-       unsigned long first_vma_start;
        u64 pss;
        u64 pss_locked;
        u64 swap_pss;
@@ -731,14 +699,9 @@ static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask,
 }
 #endif /* HUGETLB_PAGE */
 
-#define SEQ_PUT_DEC(str, val) \
-               seq_put_decimal_ull_width(m, str, (val) >> 10, 8)
-static int show_smap(struct seq_file *m, void *v, int is_pid)
+static void smap_gather_stats(struct vm_area_struct *vma,
+                            struct mem_size_stats *mss)
 {
-       struct proc_maps_private *priv = m->private;
-       struct vm_area_struct *vma = v;
-       struct mem_size_stats mss_stack;
-       struct mem_size_stats *mss;
        struct mm_walk smaps_walk = {
                .pmd_entry = smaps_pte_range,
 #ifdef CONFIG_HUGETLB_PAGE
@@ -746,23 +709,6 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
 #endif
                .mm = vma->vm_mm,
        };
-       int ret = 0;
-       bool rollup_mode;
-       bool last_vma;
-
-       if (priv->rollup) {
-               rollup_mode = true;
-               mss = priv->rollup;
-               if (mss->first) {
-                       mss->first_vma_start = vma->vm_start;
-                       mss->first = false;
-               }
-               last_vma = !m_next_vma(priv, vma);
-       } else {
-               rollup_mode = false;
-               memset(&mss_stack, 0, sizeof(mss_stack));
-               mss = &mss_stack;
-       }
 
        smaps_walk.private = mss;
 
@@ -794,79 +740,116 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
        walk_page_vma(vma, &smaps_walk);
        if (vma->vm_flags & VM_LOCKED)
                mss->pss_locked += mss->pss;
+}
 
-       if (!rollup_mode) {
-               show_map_vma(m, vma, is_pid);
-       } else if (last_vma) {
-               show_vma_header_prefix(
-                       m, mss->first_vma_start, vma->vm_end, 0, 0, 0, 0);
-               seq_pad(m, ' ');
-               seq_puts(m, "[rollup]\n");
-       } else {
-               ret = SEQ_SKIP;
-       }
-
-       if (!rollup_mode) {
-               SEQ_PUT_DEC("Size:           ", vma->vm_end - vma->vm_start);
-               SEQ_PUT_DEC(" kB\nKernelPageSize: ", vma_kernel_pagesize(vma));
-               SEQ_PUT_DEC(" kB\nMMUPageSize:    ", vma_mmu_pagesize(vma));
-               seq_puts(m, " kB\n");
-       }
+#define SEQ_PUT_DEC(str, val) \
+               seq_put_decimal_ull_width(m, str, (val) >> 10, 8)
 
-       if (!rollup_mode || last_vma) {
-               SEQ_PUT_DEC("Rss:            ", mss->resident);
-               SEQ_PUT_DEC(" kB\nPss:            ", mss->pss >> PSS_SHIFT);
-               SEQ_PUT_DEC(" kB\nShared_Clean:   ", mss->shared_clean);
-               SEQ_PUT_DEC(" kB\nShared_Dirty:   ", mss->shared_dirty);
-               SEQ_PUT_DEC(" kB\nPrivate_Clean:  ", mss->private_clean);
-               SEQ_PUT_DEC(" kB\nPrivate_Dirty:  ", mss->private_dirty);
-               SEQ_PUT_DEC(" kB\nReferenced:     ", mss->referenced);
-               SEQ_PUT_DEC(" kB\nAnonymous:      ", mss->anonymous);
-               SEQ_PUT_DEC(" kB\nLazyFree:       ", mss->lazyfree);
-               SEQ_PUT_DEC(" kB\nAnonHugePages:  ", mss->anonymous_thp);
-               SEQ_PUT_DEC(" kB\nShmemPmdMapped: ", mss->shmem_thp);
-               SEQ_PUT_DEC(" kB\nShared_Hugetlb: ", mss->shared_hugetlb);
-               seq_put_decimal_ull_width(m, " kB\nPrivate_Hugetlb: ",
-                                         mss->private_hugetlb >> 10, 7);
-               SEQ_PUT_DEC(" kB\nSwap:           ", mss->swap);
-               SEQ_PUT_DEC(" kB\nSwapPss:        ",
-                                               mss->swap_pss >> PSS_SHIFT);
-               SEQ_PUT_DEC(" kB\nLocked:         ",
-                                               mss->pss_locked >> PSS_SHIFT);
-               seq_puts(m, " kB\n");
-       }
-       if (!rollup_mode) {
-               if (arch_pkeys_enabled())
-                       seq_printf(m, "ProtectionKey:  %8u\n", vma_pkey(vma));
-               show_smap_vma_flags(m, vma);
-       }
-       m_cache_vma(m, vma);
-       return ret;
+/* Show the contents common for smaps and smaps_rollup */
+static void __show_smap(struct seq_file *m, const struct mem_size_stats *mss)
+{
+       SEQ_PUT_DEC("Rss:            ", mss->resident);
+       SEQ_PUT_DEC(" kB\nPss:            ", mss->pss >> PSS_SHIFT);
+       SEQ_PUT_DEC(" kB\nShared_Clean:   ", mss->shared_clean);
+       SEQ_PUT_DEC(" kB\nShared_Dirty:   ", mss->shared_dirty);
+       SEQ_PUT_DEC(" kB\nPrivate_Clean:  ", mss->private_clean);
+       SEQ_PUT_DEC(" kB\nPrivate_Dirty:  ", mss->private_dirty);
+       SEQ_PUT_DEC(" kB\nReferenced:     ", mss->referenced);
+       SEQ_PUT_DEC(" kB\nAnonymous:      ", mss->anonymous);
+       SEQ_PUT_DEC(" kB\nLazyFree:       ", mss->lazyfree);
+       SEQ_PUT_DEC(" kB\nAnonHugePages:  ", mss->anonymous_thp);
+       SEQ_PUT_DEC(" kB\nShmemPmdMapped: ", mss->shmem_thp);
+       SEQ_PUT_DEC(" kB\nShared_Hugetlb: ", mss->shared_hugetlb);
+       seq_put_decimal_ull_width(m, " kB\nPrivate_Hugetlb: ",
+                                 mss->private_hugetlb >> 10, 7);
+       SEQ_PUT_DEC(" kB\nSwap:           ", mss->swap);
+       SEQ_PUT_DEC(" kB\nSwapPss:        ",
+                                       mss->swap_pss >> PSS_SHIFT);
+       SEQ_PUT_DEC(" kB\nLocked:         ",
+                                       mss->pss_locked >> PSS_SHIFT);
+       seq_puts(m, " kB\n");
 }
-#undef SEQ_PUT_DEC
 
-static int show_pid_smap(struct seq_file *m, void *v)
+static int show_smap(struct seq_file *m, void *v)
 {
-       return show_smap(m, v, 1);
+       struct vm_area_struct *vma = v;
+       struct mem_size_stats mss;
+
+       memset(&mss, 0, sizeof(mss));
+
+       smap_gather_stats(vma, &mss);
+
+       show_map_vma(m, vma);
+
+       SEQ_PUT_DEC("Size:           ", vma->vm_end - vma->vm_start);
+       SEQ_PUT_DEC(" kB\nKernelPageSize: ", vma_kernel_pagesize(vma));
+       SEQ_PUT_DEC(" kB\nMMUPageSize:    ", vma_mmu_pagesize(vma));
+       seq_puts(m, " kB\n");
+
+       __show_smap(m, &mss);
+
+       if (arch_pkeys_enabled())
+               seq_printf(m, "ProtectionKey:  %8u\n", vma_pkey(vma));
+       show_smap_vma_flags(m, vma);
+
+       m_cache_vma(m, vma);
+
+       return 0;
 }
 
-static int show_tid_smap(struct seq_file *m, void *v)
+static int show_smaps_rollup(struct seq_file *m, void *v)
 {
-       return show_smap(m, v, 0);
+       struct proc_maps_private *priv = m->private;
+       struct mem_size_stats mss;
+       struct mm_struct *mm;
+       struct vm_area_struct *vma;
+       unsigned long last_vma_end = 0;
+       int ret = 0;
+
+       priv->task = get_proc_task(priv->inode);
+       if (!priv->task)
+               return -ESRCH;
+
+       mm = priv->mm;
+       if (!mm || !mmget_not_zero(mm)) {
+               ret = -ESRCH;
+               goto out_put_task;
+       }
+
+       memset(&mss, 0, sizeof(mss));
+
+       down_read(&mm->mmap_sem);
+       hold_task_mempolicy(priv);
+
+       for (vma = priv->mm->mmap; vma; vma = vma->vm_next) {
+               smap_gather_stats(vma, &mss);
+               last_vma_end = vma->vm_end;
+       }
+
+       show_vma_header_prefix(m, priv->mm->mmap->vm_start,
+                              last_vma_end, 0, 0, 0, 0);
+       seq_pad(m, ' ');
+       seq_puts(m, "[rollup]\n");
+
+       __show_smap(m, &mss);
+
+       release_task_mempolicy(priv);
+       up_read(&mm->mmap_sem);
+       mmput(mm);
+
+out_put_task:
+       put_task_struct(priv->task);
+       priv->task = NULL;
+
+       return ret;
 }
+#undef SEQ_PUT_DEC
 
 static const struct seq_operations proc_pid_smaps_op = {
        .start  = m_start,
        .next   = m_next,
        .stop   = m_stop,
-       .show   = show_pid_smap
-};
-
-static const struct seq_operations proc_tid_smaps_op = {
-       .start  = m_start,
-       .next   = m_next,
-       .stop   = m_stop,
-       .show   = show_tid_smap
+       .show   = show_smap
 };
 
 static int pid_smaps_open(struct inode *inode, struct file *file)
@@ -874,28 +857,45 @@ static int pid_smaps_open(struct inode *inode, struct file *file)
        return do_maps_open(inode, file, &proc_pid_smaps_op);
 }
 
-static int pid_smaps_rollup_open(struct inode *inode, struct file *file)
+static int smaps_rollup_open(struct inode *inode, struct file *file)
 {
-       struct seq_file *seq;
+       int ret;
        struct proc_maps_private *priv;
-       int ret = do_maps_open(inode, file, &proc_pid_smaps_op);
-
-       if (ret < 0)
-               return ret;
-       seq = file->private_data;
-       priv = seq->private;
-       priv->rollup = kzalloc(sizeof(*priv->rollup), GFP_KERNEL);
-       if (!priv->rollup) {
-               proc_map_release(inode, file);
+
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL_ACCOUNT);
+       if (!priv)
                return -ENOMEM;
+
+       ret = single_open(file, show_smaps_rollup, priv);
+       if (ret)
+               goto out_free;
+
+       priv->inode = inode;
+       priv->mm = proc_mem_open(inode, PTRACE_MODE_READ);
+       if (IS_ERR(priv->mm)) {
+               ret = PTR_ERR(priv->mm);
+
+               single_release(inode, file);
+               goto out_free;
        }
-       priv->rollup->first = true;
+
        return 0;
+
+out_free:
+       kfree(priv);
+       return ret;
 }
 
-static int tid_smaps_open(struct inode *inode, struct file *file)
+static int smaps_rollup_release(struct inode *inode, struct file *file)
 {
-       return do_maps_open(inode, file, &proc_tid_smaps_op);
+       struct seq_file *seq = file->private_data;
+       struct proc_maps_private *priv = seq->private;
+
+       if (priv->mm)
+               mmdrop(priv->mm);
+
+       kfree(priv);
+       return single_release(inode, file);
 }
 
 const struct file_operations proc_pid_smaps_operations = {
@@ -906,17 +906,10 @@ const struct file_operations proc_pid_smaps_operations = {
 };
 
 const struct file_operations proc_pid_smaps_rollup_operations = {
-       .open           = pid_smaps_rollup_open,
+       .open           = smaps_rollup_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
-       .release        = proc_map_release,
-};
-
-const struct file_operations proc_tid_smaps_operations = {
-       .open           = tid_smaps_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = proc_map_release,
+       .release        = smaps_rollup_release,
 };
 
 enum clear_refs_types {
@@ -1728,7 +1721,7 @@ static int gather_hugetlb_stats(pte_t *pte, unsigned long hmask,
 /*
  * Display pages allocated per node and memory policy via /proc.
  */
-static int show_numa_map(struct seq_file *m, void *v, int is_pid)
+static int show_numa_map(struct seq_file *m, void *v)
 {
        struct numa_maps_private *numa_priv = m->private;
        struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
@@ -1812,45 +1805,17 @@ out:
        return 0;
 }
 
-static int show_pid_numa_map(struct seq_file *m, void *v)
-{
-       return show_numa_map(m, v, 1);
-}
-
-static int show_tid_numa_map(struct seq_file *m, void *v)
-{
-       return show_numa_map(m, v, 0);
-}
-
 static const struct seq_operations proc_pid_numa_maps_op = {
        .start  = m_start,
        .next   = m_next,
        .stop   = m_stop,
-       .show   = show_pid_numa_map,
+       .show   = show_numa_map,
 };
 
-static const struct seq_operations proc_tid_numa_maps_op = {
-       .start  = m_start,
-       .next   = m_next,
-       .stop   = m_stop,
-       .show   = show_tid_numa_map,
-};
-
-static int numa_maps_open(struct inode *inode, struct file *file,
-                         const struct seq_operations *ops)
-{
-       return proc_maps_open(inode, file, ops,
-                               sizeof(struct numa_maps_private));
-}
-
 static int pid_numa_maps_open(struct inode *inode, struct file *file)
 {
-       return numa_maps_open(inode, file, &proc_pid_numa_maps_op);
-}
-
-static int tid_numa_maps_open(struct inode *inode, struct file *file)
-{
-       return numa_maps_open(inode, file, &proc_tid_numa_maps_op);
+       return proc_maps_open(inode, file, &proc_pid_numa_maps_op,
+                               sizeof(struct numa_maps_private));
 }
 
 const struct file_operations proc_pid_numa_maps_operations = {
@@ -1860,10 +1825,4 @@ const struct file_operations proc_pid_numa_maps_operations = {
        .release        = proc_map_release,
 };
 
-const struct file_operations proc_tid_numa_maps_operations = {
-       .open           = tid_numa_maps_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = proc_map_release,
-};
 #endif /* CONFIG_NUMA */
index 5b62f57bd9bceed80b386057b93fbce3a43602b3..0b63d68dedb2a018e716aa4cb4e93663a8b46992 100644 (file)
@@ -142,8 +142,7 @@ static int is_stack(struct vm_area_struct *vma)
 /*
  * display a single VMA to a sequenced file
  */
-static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
-                         int is_pid)
+static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
 {
        struct mm_struct *mm = vma->vm_mm;
        unsigned long ino = 0;
@@ -189,22 +188,11 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
 /*
  * display mapping lines for a particular process's /proc/pid/maps
  */
-static int show_map(struct seq_file *m, void *_p, int is_pid)
+static int show_map(struct seq_file *m, void *_p)
 {
        struct rb_node *p = _p;
 
-       return nommu_vma_show(m, rb_entry(p, struct vm_area_struct, vm_rb),
-                             is_pid);
-}
-
-static int show_pid_map(struct seq_file *m, void *_p)
-{
-       return show_map(m, _p, 1);
-}
-
-static int show_tid_map(struct seq_file *m, void *_p)
-{
-       return show_map(m, _p, 0);
+       return nommu_vma_show(m, rb_entry(p, struct vm_area_struct, vm_rb));
 }
 
 static void *m_start(struct seq_file *m, loff_t *pos)
@@ -260,14 +248,7 @@ static const struct seq_operations proc_pid_maps_ops = {
        .start  = m_start,
        .next   = m_next,
        .stop   = m_stop,
-       .show   = show_pid_map
-};
-
-static const struct seq_operations proc_tid_maps_ops = {
-       .start  = m_start,
-       .next   = m_next,
-       .stop   = m_stop,
-       .show   = show_tid_map
+       .show   = show_map
 };
 
 static int maps_open(struct inode *inode, struct file *file,
@@ -308,11 +289,6 @@ static int pid_maps_open(struct inode *inode, struct file *file)
        return maps_open(inode, file, &proc_pid_maps_ops);
 }
 
-static int tid_maps_open(struct inode *inode, struct file *file)
-{
-       return maps_open(inode, file, &proc_tid_maps_ops);
-}
-
 const struct file_operations proc_pid_maps_operations = {
        .open           = pid_maps_open,
        .read           = seq_read,
@@ -320,10 +296,3 @@ const struct file_operations proc_pid_maps_operations = {
        .release        = map_release,
 };
 
-const struct file_operations proc_tid_maps_operations = {
-       .open           = tid_maps_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = map_release,
-};
-
index 3f723cb478af31c721ec263b4db9fb3e9ac17054..a4c2791ab70baf8c5124a5e00d0e4a374652d13f 100644 (file)
@@ -9,7 +9,7 @@
 
 static int uptime_proc_show(struct seq_file *m, void *v)
 {
-       struct timespec uptime;
+       struct timespec64 uptime;
        struct timespec64 idle;
        u64 nsec;
        u32 rem;
@@ -19,7 +19,7 @@ static int uptime_proc_show(struct seq_file *m, void *v)
        for_each_possible_cpu(i)
                nsec += (__force u64) kcpustat_cpu(i).cpustat[CPUTIME_IDLE];
 
-       get_monotonic_boottime(&uptime);
+       ktime_get_boottime_ts64(&uptime);
        idle.tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
        idle.tv_nsec = rem;
        seq_printf(m, "%lu.%02lu %lu.%02lu\n",
index cfb6674331fded9083883df0d02a7e7f45c40d55..cbde728f8ac60958a8662367c47ee2afe02af25d 100644 (file)
@@ -225,6 +225,7 @@ out_unlock:
        return ret;
 }
 
+#ifdef CONFIG_MMU
 static int vmcoredd_mmap_dumps(struct vm_area_struct *vma, unsigned long dst,
                               u64 start, size_t size)
 {
@@ -259,6 +260,7 @@ out_unlock:
        mutex_unlock(&vmcoredd_mutex);
        return ret;
 }
+#endif /* CONFIG_MMU */
 #endif /* CONFIG_PROC_VMCORE_DEVICE_DUMP */
 
 /* Read from the ELF header and then the crash dump. On error, negative value is
@@ -379,7 +381,7 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer,
  * On s390 the fault handler is used for memory regions that can't be mapped
  * directly with remap_pfn_range().
  */
-static int mmap_vmcore_fault(struct vm_fault *vmf)
+static vm_fault_t mmap_vmcore_fault(struct vm_fault *vmf)
 {
 #ifdef CONFIG_S390
        struct address_space *mapping = vmf->vma->vm_file->f_mapping;
index 860bfbe7a07aa5b9a4491365b48655122fa5eb60..f0cbf58ad4dade2129c19d5dba42c8bb4eed276d 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/quotaops.h>
 #include <linux/types.h>
 #include <linux/writeback.h>
+#include <linux/nospec.h>
 
 static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
                                     qid_t id)
@@ -120,8 +121,6 @@ static int quota_getinfo(struct super_block *sb, int type, void __user *addr)
        struct if_dqinfo uinfo;
        int ret;
 
-       /* This checks whether qc_state has enough entries... */
-       BUILD_BUG_ON(MAXQUOTAS > XQM_MAXQUOTAS);
        if (!sb->s_qcop->get_state)
                return -ENOSYS;
        ret = sb->s_qcop->get_state(sb, &state);
@@ -354,10 +353,10 @@ static int quota_getstate(struct super_block *sb, struct fs_quota_stat *fqs)
         * GETXSTATE quotactl has space for just one set of time limits so
         * report them for the first enabled quota type
         */
-       for (type = 0; type < XQM_MAXQUOTAS; type++)
+       for (type = 0; type < MAXQUOTAS; type++)
                if (state.s_state[type].flags & QCI_ACCT_ENABLED)
                        break;
-       BUG_ON(type == XQM_MAXQUOTAS);
+       BUG_ON(type == MAXQUOTAS);
        fqs->qs_btimelimit = state.s_state[type].spc_timelimit;
        fqs->qs_itimelimit = state.s_state[type].ino_timelimit;
        fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit;
@@ -427,10 +426,10 @@ static int quota_getstatev(struct super_block *sb, struct fs_quota_statv *fqs)
         * GETXSTATV quotactl has space for just one set of time limits so
         * report them for the first enabled quota type
         */
-       for (type = 0; type < XQM_MAXQUOTAS; type++)
+       for (type = 0; type < MAXQUOTAS; type++)
                if (state.s_state[type].flags & QCI_ACCT_ENABLED)
                        break;
-       BUG_ON(type == XQM_MAXQUOTAS);
+       BUG_ON(type == MAXQUOTAS);
        fqs->qs_btimelimit = state.s_state[type].spc_timelimit;
        fqs->qs_itimelimit = state.s_state[type].ino_timelimit;
        fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit;
@@ -701,8 +700,9 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
 {
        int ret;
 
-       if (type >= (XQM_COMMAND(cmd) ? XQM_MAXQUOTAS : MAXQUOTAS))
+       if (type >= MAXQUOTAS)
                return -EINVAL;
+       type = array_index_nospec(type, MAXQUOTAS);
        /*
         * Quota not supported on this fs? Check this before s_quota_types
         * since they needn't be set if quota is not supported at all.
index 153f8f690490771208dbff66f458caaa9ec57d22..39b4a21dd9337a157927c1f8d0d741190de11e78 100644 (file)
@@ -1964,6 +1964,44 @@ out_error:
 }
 EXPORT_SYMBOL(vfs_dedupe_file_range_compare);
 
+int vfs_dedupe_file_range_one(struct file *src_file, loff_t src_pos,
+                             struct file *dst_file, loff_t dst_pos, u64 len)
+{
+       s64 ret;
+
+       ret = mnt_want_write_file(dst_file);
+       if (ret)
+               return ret;
+
+       ret = clone_verify_area(dst_file, dst_pos, len, true);
+       if (ret < 0)
+               goto out_drop_write;
+
+       ret = -EINVAL;
+       if (!(capable(CAP_SYS_ADMIN) || (dst_file->f_mode & FMODE_WRITE)))
+               goto out_drop_write;
+
+       ret = -EXDEV;
+       if (src_file->f_path.mnt != dst_file->f_path.mnt)
+               goto out_drop_write;
+
+       ret = -EISDIR;
+       if (S_ISDIR(file_inode(dst_file)->i_mode))
+               goto out_drop_write;
+
+       ret = -EINVAL;
+       if (!dst_file->f_op->dedupe_file_range)
+               goto out_drop_write;
+
+       ret = dst_file->f_op->dedupe_file_range(src_file, src_pos,
+                                               dst_file, dst_pos, len);
+out_drop_write:
+       mnt_drop_write_file(dst_file);
+
+       return ret;
+}
+EXPORT_SYMBOL(vfs_dedupe_file_range_one);
+
 int vfs_dedupe_file_range(struct file *file, struct file_dedupe_range *same)
 {
        struct file_dedupe_range_info *info;
@@ -1972,11 +2010,8 @@ int vfs_dedupe_file_range(struct file *file, struct file_dedupe_range *same)
        u64 len;
        int i;
        int ret;
-       bool is_admin = capable(CAP_SYS_ADMIN);
        u16 count = same->dest_count;
-       struct file *dst_file;
-       loff_t dst_off;
-       ssize_t deduped;
+       int deduped;
 
        if (!(file->f_mode & FMODE_READ))
                return -EINVAL;
@@ -2003,6 +2038,9 @@ int vfs_dedupe_file_range(struct file *file, struct file_dedupe_range *same)
        if (off + len > i_size_read(src))
                return -EINVAL;
 
+       /* Arbitrary 1G limit on a single dedupe request, can be raised. */
+       len = min_t(u64, len, 1 << 30);
+
        /* pre-format output fields to sane values */
        for (i = 0; i < count; i++) {
                same->info[i].bytes_deduped = 0ULL;
@@ -2010,54 +2048,28 @@ int vfs_dedupe_file_range(struct file *file, struct file_dedupe_range *same)
        }
 
        for (i = 0, info = same->info; i < count; i++, info++) {
-               struct inode *dst;
                struct fd dst_fd = fdget(info->dest_fd);
+               struct file *dst_file = dst_fd.file;
 
-               dst_file = dst_fd.file;
                if (!dst_file) {
                        info->status = -EBADF;
                        goto next_loop;
                }
-               dst = file_inode(dst_file);
-
-               ret = mnt_want_write_file(dst_file);
-               if (ret) {
-                       info->status = ret;
-                       goto next_fdput;
-               }
-
-               dst_off = info->dest_offset;
-               ret = clone_verify_area(dst_file, dst_off, len, true);
-               if (ret < 0) {
-                       info->status = ret;
-                       goto next_file;
-               }
-               ret = 0;
 
                if (info->reserved) {
                        info->status = -EINVAL;
-               } else if (!(is_admin || (dst_file->f_mode & FMODE_WRITE))) {
-                       info->status = -EINVAL;
-               } else if (file->f_path.mnt != dst_file->f_path.mnt) {
-                       info->status = -EXDEV;
-               } else if (S_ISDIR(dst->i_mode)) {
-                       info->status = -EISDIR;
-               } else if (dst_file->f_op->dedupe_file_range == NULL) {
-                       info->status = -EINVAL;
-               } else {
-                       deduped = dst_file->f_op->dedupe_file_range(file, off,
-                                                       len, dst_file,
-                                                       info->dest_offset);
-                       if (deduped == -EBADE)
-                               info->status = FILE_DEDUPE_RANGE_DIFFERS;
-                       else if (deduped < 0)
-                               info->status = deduped;
-                       else
-                               info->bytes_deduped += deduped;
+                       goto next_fdput;
                }
 
-next_file:
-               mnt_drop_write_file(dst_file);
+               deduped = vfs_dedupe_file_range_one(file, off, dst_file,
+                                                   info->dest_offset, len);
+               if (deduped == -EBADE)
+                       info->status = FILE_DEDUPE_RANGE_DIFFERS;
+               else if (deduped < 0)
+                       info->status = deduped;
+               else
+                       info->bytes_deduped = len;
+
 next_fdput:
                fdput(dst_fd);
 next_loop:
index e3c558d1b78c02c711ae9868fe409d349127103f..3a5a752d96c7bbfdb920193d9a5c427d08772423 100644 (file)
@@ -33,30 +33,22 @@ static int sd_is_left_mergeable(struct reiserfs_key *key, unsigned long bsize)
        return 0;
 }
 
-static char *print_time(time_t t)
-{
-       static char timebuf[256];
-
-       sprintf(timebuf, "%ld", t);
-       return timebuf;
-}
-
 static void sd_print_item(struct item_head *ih, char *item)
 {
        printk("\tmode | size | nlinks | first direct | mtime\n");
        if (stat_data_v1(ih)) {
                struct stat_data_v1 *sd = (struct stat_data_v1 *)item;
 
-               printk("\t0%-6o | %6u | %2u | %d | %s\n", sd_v1_mode(sd),
+               printk("\t0%-6o | %6u | %2u | %d | %u\n", sd_v1_mode(sd),
                       sd_v1_size(sd), sd_v1_nlink(sd),
                       sd_v1_first_direct_byte(sd),
-                      print_time(sd_v1_mtime(sd)));
+                      sd_v1_mtime(sd));
        } else {
                struct stat_data *sd = (struct stat_data *)item;
 
-               printk("\t0%-6o | %6llu | %2u | %d | %s\n", sd_v2_mode(sd),
+               printk("\t0%-6o | %6llu | %2u | %d | %u\n", sd_v2_mode(sd),
                       (unsigned long long)sd_v2_size(sd), sd_v2_nlink(sd),
-                      sd_v2_rdev(sd), print_time(sd_v2_mtime(sd)));
+                      sd_v2_rdev(sd), sd_v2_mtime(sd));
        }
 }
 
index 52eb5d293a343dc26a544c7f5d7b3fbec1de4b04..8a76f9d14bc661c5a6760d7815ac1e97352f8e0c 100644 (file)
@@ -2381,7 +2381,7 @@ static int journal_read(struct super_block *sb)
        struct reiserfs_journal_desc *desc;
        unsigned int oldest_trans_id = 0;
        unsigned int oldest_invalid_trans_id = 0;
-       time_t start;
+       time64_t start;
        unsigned long oldest_start = 0;
        unsigned long cur_dblock = 0;
        unsigned long newest_mount_id = 9;
@@ -2395,7 +2395,7 @@ static int journal_read(struct super_block *sb)
        cur_dblock = SB_ONDISK_JOURNAL_1st_BLOCK(sb);
        reiserfs_info(sb, "checking transaction log (%pg)\n",
                      journal->j_dev_bd);
-       start = get_seconds();
+       start = ktime_get_seconds();
 
        /*
         * step 1, read in the journal header block.  Check the transaction
@@ -2556,7 +2556,7 @@ start_log_replay:
        if (replay_count > 0) {
                reiserfs_info(sb,
                              "replayed %d transactions in %lu seconds\n",
-                             replay_count, get_seconds() - start);
+                             replay_count, ktime_get_seconds() - start);
        }
        /* needed to satisfy the locking in _update_journal_header_block */
        reiserfs_write_lock(sb);
@@ -2914,7 +2914,7 @@ int journal_transaction_should_end(struct reiserfs_transaction_handle *th,
                                   int new_alloc)
 {
        struct reiserfs_journal *journal = SB_JOURNAL(th->t_super);
-       time_t now = get_seconds();
+       time64_t now = ktime_get_seconds();
        /* cannot restart while nested */
        BUG_ON(!th->t_trans_id);
        if (th->t_refcount > 1)
@@ -3023,7 +3023,7 @@ static int do_journal_begin_r(struct reiserfs_transaction_handle *th,
                              struct super_block *sb, unsigned long nblocks,
                              int join)
 {
-       time_t now = get_seconds();
+       time64_t now = ktime_get_seconds();
        unsigned int old_trans_id;
        struct reiserfs_journal *journal = SB_JOURNAL(sb);
        struct reiserfs_transaction_handle myth;
@@ -3056,7 +3056,7 @@ relock:
                PROC_INFO_INC(sb, journal.journal_relock_writers);
                goto relock;
        }
-       now = get_seconds();
+       now = ktime_get_seconds();
 
        /*
         * if there is no room in the journal OR
@@ -3119,7 +3119,7 @@ relock:
        }
        /* we are the first writer, set trans_id */
        if (journal->j_trans_start_time == 0) {
-               journal->j_trans_start_time = get_seconds();
+               journal->j_trans_start_time = ktime_get_seconds();
        }
        atomic_inc(&journal->j_wcount);
        journal->j_len_alloc += nblocks;
@@ -3559,11 +3559,11 @@ static void flush_async_commits(struct work_struct *work)
  */
 void reiserfs_flush_old_commits(struct super_block *sb)
 {
-       time_t now;
+       time64_t now;
        struct reiserfs_transaction_handle th;
        struct reiserfs_journal *journal = SB_JOURNAL(sb);
 
-       now = get_seconds();
+       now = ktime_get_seconds();
        /*
         * safety check so we don't flush while we are replaying the log during
         * mount
@@ -3613,7 +3613,7 @@ void reiserfs_flush_old_commits(struct super_block *sb)
 static int check_journal_end(struct reiserfs_transaction_handle *th, int flags)
 {
 
-       time_t now;
+       time64_t now;
        int flush = flags & FLUSH_ALL;
        int commit_now = flags & COMMIT_NOW;
        int wait_on_commit = flags & WAIT;
@@ -3694,7 +3694,7 @@ static int check_journal_end(struct reiserfs_transaction_handle *th, int flags)
        }
 
        /* deal with old transactions where we are the last writers */
-       now = get_seconds();
+       now = ktime_get_seconds();
        if ((now - journal->j_trans_start_time) > journal->j_max_trans_age) {
                commit_now = 1;
                journal->j_next_async_flush = 1;
index e39b3910d24d981fb1eac72fbae8c809d9f3ae45..f2cf3441fdfc9f20ea6500ca2b8c6fddafb422fe 100644 (file)
@@ -297,6 +297,13 @@ static int show_oidmap(struct seq_file *m, void *unused)
        return 0;
 }
 
+static time64_t ktime_mono_to_real_seconds(time64_t mono)
+{
+       ktime_t kt = ktime_set(mono, NSEC_PER_SEC/2);
+
+       return ktime_divns(ktime_mono_to_real(kt), NSEC_PER_SEC);
+}
+
 static int show_journal(struct seq_file *m, void *unused)
 {
        struct super_block *sb = m->private;
@@ -325,7 +332,7 @@ static int show_journal(struct seq_file *m, void *unused)
                   "j_bcount: \t%lu\n"
                   "j_first_unflushed_offset: \t%lu\n"
                   "j_last_flush_trans_id: \t%u\n"
-                  "j_trans_start_time: \t%li\n"
+                  "j_trans_start_time: \t%lli\n"
                   "j_list_bitmap_index: \t%i\n"
                   "j_must_wait: \t%i\n"
                   "j_next_full_flush: \t%i\n"
@@ -366,7 +373,7 @@ static int show_journal(struct seq_file *m, void *unused)
                   JF(j_bcount),
                   JF(j_first_unflushed_offset),
                   JF(j_last_flush_trans_id),
-                  JF(j_trans_start_time),
+                  ktime_mono_to_real_seconds(JF(j_trans_start_time)),
                   JF(j_list_bitmap_index),
                   JF(j_must_wait),
                   JF(j_next_full_flush),
index ae4811fecc1fc793d531cbf6a709d8e89c9b2459..e5ca9ed79e54cda20606497abffa76470011d31d 100644 (file)
@@ -271,7 +271,7 @@ struct reiserfs_journal_list {
 
        struct mutex j_commit_mutex;
        unsigned int j_trans_id;
-       time_t j_timestamp;
+       time64_t j_timestamp; /* write-only but useful for crash dump analysis */
        struct reiserfs_list_bitmap *j_list_bitmap;
        struct buffer_head *j_commit_bh;        /* commit buffer head */
        struct reiserfs_journal_cnode *j_realblock;
@@ -331,7 +331,7 @@ struct reiserfs_journal {
 
        struct buffer_head *j_header_bh;
 
-       time_t j_trans_start_time;      /* time this transaction started */
+       time64_t j_trans_start_time;    /* time this transaction started */
        struct mutex j_mutex;
        struct mutex j_flush_mutex;
 
index ff94fad477e461435e335030dd7baf99c0783636..48cdfc81fe10641da6025849c27d8f307f968a50 100644 (file)
@@ -792,8 +792,10 @@ static int listxattr_filler(struct dir_context *ctx, const char *name,
                        return 0;
                size = namelen + 1;
                if (b->buf) {
-                       if (size > b->size)
+                       if (b->pos + size > b->size) {
+                               b->pos = -ERANGE;
                                return -ERANGE;
+                       }
                        memcpy(b->buf + b->pos, name, namelen);
                        b->buf[b->pos + namelen] = 0;
                }
index 7429588d6b4922574f05d43cbfbc6b5ad01ab648..f3a8c008e16430be1ba08d9f575c1df9faeb0f0a 100644 (file)
@@ -981,58 +981,42 @@ void emergency_thaw_all(void)
        }
 }
 
-/*
- * Unnamed block devices are dummy devices used by virtual
- * filesystems which don't use real block-devices.  -- jrs
- */
-
 static DEFINE_IDA(unnamed_dev_ida);
-static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */
-/* Many userspace utilities consider an FSID of 0 invalid.
- * Always return at least 1 from get_anon_bdev.
- */
-static int unnamed_dev_start = 1;
 
+/**
+ * get_anon_bdev - Allocate a block device for filesystems which don't have one.
+ * @p: Pointer to a dev_t.
+ *
+ * Filesystems which don't use real block devices can call this function
+ * to allocate a virtual block device.
+ *
+ * Context: Any context.  Frequently called while holding sb_lock.
+ * Return: 0 on success, -EMFILE if there are no anonymous bdevs left
+ * or -ENOMEM if memory allocation failed.
+ */
 int get_anon_bdev(dev_t *p)
 {
        int dev;
-       int error;
 
- retry:
-       if (ida_pre_get(&unnamed_dev_ida, GFP_ATOMIC) == 0)
-               return -ENOMEM;
-       spin_lock(&unnamed_dev_lock);
-       error = ida_get_new_above(&unnamed_dev_ida, unnamed_dev_start, &dev);
-       if (!error)
-               unnamed_dev_start = dev + 1;
-       spin_unlock(&unnamed_dev_lock);
-       if (error == -EAGAIN)
-               /* We raced and lost with another CPU. */
-               goto retry;
-       else if (error)
-               return -EAGAIN;
-
-       if (dev >= (1 << MINORBITS)) {
-               spin_lock(&unnamed_dev_lock);
-               ida_remove(&unnamed_dev_ida, dev);
-               if (unnamed_dev_start > dev)
-                       unnamed_dev_start = dev;
-               spin_unlock(&unnamed_dev_lock);
-               return -EMFILE;
-       }
-       *p = MKDEV(0, dev & MINORMASK);
+       /*
+        * Many userspace utilities consider an FSID of 0 invalid.
+        * Always return at least 1 from get_anon_bdev.
+        */
+       dev = ida_alloc_range(&unnamed_dev_ida, 1, (1 << MINORBITS) - 1,
+                       GFP_ATOMIC);
+       if (dev == -ENOSPC)
+               dev = -EMFILE;
+       if (dev < 0)
+               return dev;
+
+       *p = MKDEV(0, dev);
        return 0;
 }
 EXPORT_SYMBOL(get_anon_bdev);
 
 void free_anon_bdev(dev_t dev)
 {
-       int slot = MINOR(dev);
-       spin_lock(&unnamed_dev_lock);
-       ida_remove(&unnamed_dev_ida, slot);
-       if (slot < unnamed_dev_start)
-               unnamed_dev_start = slot;
-       spin_unlock(&unnamed_dev_lock);
+       ida_free(&unnamed_dev_ida, MINOR(dev));
 }
 EXPORT_SYMBOL(free_anon_bdev);
 
@@ -1040,7 +1024,6 @@ int set_anon_super(struct super_block *s, void *data)
 {
        return get_anon_bdev(&s->s_dev);
 }
-
 EXPORT_SYMBOL(set_anon_super);
 
 void kill_anon_super(struct super_block *sb)
@@ -1049,7 +1032,6 @@ void kill_anon_super(struct super_block *sb)
        generic_shutdown_super(sb);
        free_anon_bdev(dev);
 }
-
 EXPORT_SYMBOL(kill_anon_super);
 
 void kill_litter_super(struct super_block *sb)
@@ -1058,7 +1040,6 @@ void kill_litter_super(struct super_block *sb)
                d_genocide(sb->s_root);
        kill_anon_super(sb);
 }
-
 EXPORT_SYMBOL(kill_litter_super);
 
 static int ns_test_super(struct super_block *sb, void *data)
index bec9f79adb25a207dca39feeb924b7e946f664db..499a20a5a0107f3ca8942485a7a5b3bc58737793 100644 (file)
@@ -35,7 +35,7 @@
 static int sysv_sync_fs(struct super_block *sb, int wait)
 {
        struct sysv_sb_info *sbi = SYSV_SB(sb);
-       unsigned long time = get_seconds(), old_time;
+       u32 time = (u32)ktime_get_real_seconds(), old_time;
 
        mutex_lock(&sbi->s_lock);
 
@@ -46,8 +46,8 @@ static int sysv_sync_fs(struct super_block *sb, int wait)
         */
        old_time = fs32_to_cpu(sbi, *sbi->s_sb_time);
        if (sbi->s_type == FSTYPE_SYSV4) {
-               if (*sbi->s_sb_state == cpu_to_fs32(sbi, 0x7c269d38 - old_time))
-                       *sbi->s_sb_state = cpu_to_fs32(sbi, 0x7c269d38 - time);
+               if (*sbi->s_sb_state == cpu_to_fs32(sbi, 0x7c269d38u - old_time))
+                       *sbi->s_sb_state = cpu_to_fs32(sbi, 0x7c269d38u - time);
                *sbi->s_sb_time = cpu_to_fs32(sbi, time);
                mark_buffer_dirty(sbi->s_bh2);
        }
index bea8ad876bf9a407949008cc651d4559bcb67e60..7098c49f36934ec5859808313d6b803befc1ab22 100644 (file)
@@ -53,7 +53,7 @@ static const struct file_operations tracefs_file_operations = {
 static struct tracefs_dir_ops {
        int (*mkdir)(const char *name);
        int (*rmdir)(const char *name);
-} tracefs_ops;
+} tracefs_ops __ro_after_init;
 
 static char *get_dname(struct dentry *dentry)
 {
@@ -478,7 +478,8 @@ struct dentry *tracefs_create_dir(const char *name, struct dentry *parent)
  *
  * Returns the dentry of the instances directory.
  */
-struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *parent,
+__init struct dentry *tracefs_create_instance_dir(const char *name,
+                                         struct dentry *parent,
                                          int (*mkdir)(const char *name),
                                          int (*rmdir)(const char *name))
 {
index 83a961bf7280112f84a2567e2dd775f5679af3f3..bbc78549be4cc3f0536033624723666ab13ef0d0 100644 (file)
@@ -51,9 +51,20 @@ config UBIFS_ATIME_SUPPORT
 
          If unsure, say 'N'
 
+config UBIFS_FS_XATTR
+       bool "UBIFS XATTR support"
+       depends on UBIFS_FS
+       default y
+       help
+         Saying Y here includes support for extended attributes (xattrs).
+         Xattrs are name:value pairs associated with inodes by
+         the kernel or by users (see the attr(5) manual page).
+
+         If unsure, say Y.
+
 config UBIFS_FS_ENCRYPTION
        bool "UBIFS Encryption"
-       depends on UBIFS_FS && BLOCK
+       depends on UBIFS_FS && UBIFS_FS_XATTR && BLOCK
        select FS_ENCRYPTION
        default n
        help
@@ -64,7 +75,7 @@ config UBIFS_FS_ENCRYPTION
 
 config UBIFS_FS_SECURITY
        bool "UBIFS Security Labels"
-       depends on UBIFS_FS
+       depends on UBIFS_FS && UBIFS_FS_XATTR
        default y
        help
          Security labels provide an access control facility to support Linux
index 9758f709c73612dd59244817e7c4fae4dcb8335d..6197d7e539e42d872a07763e524e1aad284d7a82 100644 (file)
@@ -4,6 +4,7 @@ obj-$(CONFIG_UBIFS_FS) += ubifs.o
 ubifs-y += shrinker.o journal.o file.o dir.o super.o sb.o io.o
 ubifs-y += tnc.o master.o scan.o replay.o log.o commit.o gc.o orphan.o
 ubifs-y += budget.o find.o tnc_commit.o compress.o lpt.o lprops.o
-ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o xattr.o debug.o
+ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o debug.o
 ubifs-y += misc.o
 ubifs-$(CONFIG_UBIFS_FS_ENCRYPTION) += crypto.o
+ubifs-$(CONFIG_UBIFS_FS_XATTR) += xattr.o
index 11a11b32a2a9013dfcb3f9e5e12c80a8e503b864..7ef22baf9d150781e97381780be20a6d9dee6d81 100644 (file)
@@ -439,16 +439,16 @@ int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req)
 {
        int err, idx_growth, data_growth, dd_growth, retried = 0;
 
-       ubifs_assert(req->new_page <= 1);
-       ubifs_assert(req->dirtied_page <= 1);
-       ubifs_assert(req->new_dent <= 1);
-       ubifs_assert(req->mod_dent <= 1);
-       ubifs_assert(req->new_ino <= 1);
-       ubifs_assert(req->new_ino_d <= UBIFS_MAX_INO_DATA);
-       ubifs_assert(req->dirtied_ino <= 4);
-       ubifs_assert(req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4);
-       ubifs_assert(!(req->new_ino_d & 7));
-       ubifs_assert(!(req->dirtied_ino_d & 7));
+       ubifs_assert(c, req->new_page <= 1);
+       ubifs_assert(c, req->dirtied_page <= 1);
+       ubifs_assert(c, req->new_dent <= 1);
+       ubifs_assert(c, req->mod_dent <= 1);
+       ubifs_assert(c, req->new_ino <= 1);
+       ubifs_assert(c, req->new_ino_d <= UBIFS_MAX_INO_DATA);
+       ubifs_assert(c, req->dirtied_ino <= 4);
+       ubifs_assert(c, req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4);
+       ubifs_assert(c, !(req->new_ino_d & 7));
+       ubifs_assert(c, !(req->dirtied_ino_d & 7));
 
        data_growth = calc_data_growth(c, req);
        dd_growth = calc_dd_growth(c, req);
@@ -458,9 +458,9 @@ int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req)
 
 again:
        spin_lock(&c->space_lock);
-       ubifs_assert(c->bi.idx_growth >= 0);
-       ubifs_assert(c->bi.data_growth >= 0);
-       ubifs_assert(c->bi.dd_growth >= 0);
+       ubifs_assert(c, c->bi.idx_growth >= 0);
+       ubifs_assert(c, c->bi.data_growth >= 0);
+       ubifs_assert(c, c->bi.dd_growth >= 0);
 
        if (unlikely(c->bi.nospace) && (c->bi.nospace_rp || !can_use_rp(c))) {
                dbg_budg("no space");
@@ -526,20 +526,20 @@ again:
  */
 void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req)
 {
-       ubifs_assert(req->new_page <= 1);
-       ubifs_assert(req->dirtied_page <= 1);
-       ubifs_assert(req->new_dent <= 1);
-       ubifs_assert(req->mod_dent <= 1);
-       ubifs_assert(req->new_ino <= 1);
-       ubifs_assert(req->new_ino_d <= UBIFS_MAX_INO_DATA);
-       ubifs_assert(req->dirtied_ino <= 4);
-       ubifs_assert(req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4);
-       ubifs_assert(!(req->new_ino_d & 7));
-       ubifs_assert(!(req->dirtied_ino_d & 7));
+       ubifs_assert(c, req->new_page <= 1);
+       ubifs_assert(c, req->dirtied_page <= 1);
+       ubifs_assert(c, req->new_dent <= 1);
+       ubifs_assert(c, req->mod_dent <= 1);
+       ubifs_assert(c, req->new_ino <= 1);
+       ubifs_assert(c, req->new_ino_d <= UBIFS_MAX_INO_DATA);
+       ubifs_assert(c, req->dirtied_ino <= 4);
+       ubifs_assert(c, req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4);
+       ubifs_assert(c, !(req->new_ino_d & 7));
+       ubifs_assert(c, !(req->dirtied_ino_d & 7));
        if (!req->recalculate) {
-               ubifs_assert(req->idx_growth >= 0);
-               ubifs_assert(req->data_growth >= 0);
-               ubifs_assert(req->dd_growth >= 0);
+               ubifs_assert(c, req->idx_growth >= 0);
+               ubifs_assert(c, req->data_growth >= 0);
+               ubifs_assert(c, req->dd_growth >= 0);
        }
 
        if (req->recalculate) {
@@ -561,13 +561,13 @@ void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req)
        c->bi.dd_growth -= req->dd_growth;
        c->bi.min_idx_lebs = ubifs_calc_min_idx_lebs(c);
 
-       ubifs_assert(c->bi.idx_growth >= 0);
-       ubifs_assert(c->bi.data_growth >= 0);
-       ubifs_assert(c->bi.dd_growth >= 0);
-       ubifs_assert(c->bi.min_idx_lebs < c->main_lebs);
-       ubifs_assert(!(c->bi.idx_growth & 7));
-       ubifs_assert(!(c->bi.data_growth & 7));
-       ubifs_assert(!(c->bi.dd_growth & 7));
+       ubifs_assert(c, c->bi.idx_growth >= 0);
+       ubifs_assert(c, c->bi.data_growth >= 0);
+       ubifs_assert(c, c->bi.dd_growth >= 0);
+       ubifs_assert(c, c->bi.min_idx_lebs < c->main_lebs);
+       ubifs_assert(c, !(c->bi.idx_growth & 7));
+       ubifs_assert(c, !(c->bi.data_growth & 7));
+       ubifs_assert(c, !(c->bi.dd_growth & 7));
        spin_unlock(&c->space_lock);
 }
 
@@ -680,7 +680,7 @@ long long ubifs_get_free_space_nolock(struct ubifs_info *c)
        int rsvd_idx_lebs, lebs;
        long long available, outstanding, free;
 
-       ubifs_assert(c->bi.min_idx_lebs == ubifs_calc_min_idx_lebs(c));
+       ubifs_assert(c, c->bi.min_idx_lebs == ubifs_calc_min_idx_lebs(c));
        outstanding = c->bi.data_growth + c->bi.dd_growth;
        available = ubifs_calc_available(c, c->bi.min_idx_lebs);
 
index 63f56619991dd427c62bfd05ff7f5e7273d80d52..591f2c7a48f072f6c6ea6df736f3a8ec2eaafa7c 100644 (file)
@@ -91,9 +91,9 @@ static int nothing_to_commit(struct ubifs_info *c)
        if (c->nroot && test_bit(DIRTY_CNODE, &c->nroot->flags))
                return 0;
 
-       ubifs_assert(atomic_long_read(&c->dirty_zn_cnt) == 0);
-       ubifs_assert(c->dirty_pn_cnt == 0);
-       ubifs_assert(c->dirty_nn_cnt == 0);
+       ubifs_assert(c, atomic_long_read(&c->dirty_zn_cnt) == 0);
+       ubifs_assert(c, c->dirty_pn_cnt == 0);
+       ubifs_assert(c, c->dirty_nn_cnt == 0);
 
        return 1;
 }
@@ -113,7 +113,7 @@ static int do_commit(struct ubifs_info *c)
        struct ubifs_lp_stats lst;
 
        dbg_cmt("start");
-       ubifs_assert(!c->ro_media && !c->ro_mount);
+       ubifs_assert(c, !c->ro_media && !c->ro_mount);
 
        if (c->ro_error) {
                err = -EROFS;
index 55c508fe8131577e77aae83865cee6b4effc0513..4aaedf2d7f442237ec34e760f27e48c1736db5ed 100644 (file)
@@ -32,7 +32,7 @@ int ubifs_encrypt(const struct inode *inode, struct ubifs_data_node *dn,
        struct page *ret;
        unsigned int pad_len = round_up(in_len, UBIFS_CIPHER_BLOCK_SIZE);
 
-       ubifs_assert(pad_len <= *out_len);
+       ubifs_assert(c, pad_len <= *out_len);
        dn->compr_size = cpu_to_le16(in_len);
 
        /* pad to full block cipher length */
@@ -63,7 +63,7 @@ int ubifs_decrypt(const struct inode *inode, struct ubifs_data_node *dn,
                return -EINVAL;
        }
 
-       ubifs_assert(dlen <= UBIFS_BLOCK_SIZE);
+       ubifs_assert(c, dlen <= UBIFS_BLOCK_SIZE);
        err = fscrypt_decrypt_page(inode, virt_to_page(&dn->data), dlen,
                        offset_in_page(&dn->data), block);
        if (err) {
index 7cd8a7b95299c2b096c93d0d0fbfd7838f8dff2c..564e330d05b146df6d8c848742b08f02820b14c3 100644 (file)
@@ -134,7 +134,7 @@ const char *dbg_snprintf_key(const struct ubifs_info *c,
                }
        } else
                len -= snprintf(p, len, "bad key format %d", c->key_fmt);
-       ubifs_assert(len > 0);
+       ubifs_assert(c, len > 0);
        return p;
 }
 
@@ -276,7 +276,7 @@ void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode)
                return;
 
        pr_err("List of directory entries:\n");
-       ubifs_assert(!mutex_is_locked(&c->tnc_mutex));
+       ubifs_assert(c, !mutex_is_locked(&c->tnc_mutex));
 
        lowest_dent_key(c, &key, inode->i_ino);
        while (1) {
@@ -931,7 +931,7 @@ void ubifs_dump_tnc(struct ubifs_info *c)
 
        pr_err("\n");
        pr_err("(pid %d) start dumping TNC tree\n", current->pid);
-       znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL);
+       znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, NULL);
        level = znode->level;
        pr_err("== Level %d ==\n", level);
        while (znode) {
@@ -940,7 +940,7 @@ void ubifs_dump_tnc(struct ubifs_info *c)
                        pr_err("== Level %d ==\n", level);
                }
                ubifs_dump_znode(c, znode);
-               znode = ubifs_tnc_levelorder_next(c->zroot.znode, znode);
+               znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, znode);
        }
        pr_err("(pid %d) finish dumping TNC tree\n", current->pid);
 }
@@ -1183,7 +1183,7 @@ static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1,
        union ubifs_key key;
        char key_buf[DBG_KEY_BUF_LEN];
 
-       ubifs_assert(!keys_cmp(c, &zbr1->key, &zbr2->key));
+       ubifs_assert(c, !keys_cmp(c, &zbr1->key, &zbr2->key));
        dent1 = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS);
        if (!dent1)
                return -ENOMEM;
@@ -1479,7 +1479,7 @@ int dbg_check_tnc(struct ubifs_info *c, int extra)
        if (!dbg_is_chk_index(c))
                return 0;
 
-       ubifs_assert(mutex_is_locked(&c->tnc_mutex));
+       ubifs_assert(c, mutex_is_locked(&c->tnc_mutex));
        if (!c->zroot.znode)
                return 0;
 
@@ -1505,7 +1505,7 @@ int dbg_check_tnc(struct ubifs_info *c, int extra)
                }
 
                prev = znode;
-               znode = ubifs_tnc_postorder_next(znode);
+               znode = ubifs_tnc_postorder_next(c, znode);
                if (!znode)
                        break;
 
@@ -2036,7 +2036,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
                long long blk_offs;
                struct ubifs_data_node *dn = node;
 
-               ubifs_assert(zbr->len >= UBIFS_DATA_NODE_SZ);
+               ubifs_assert(c, zbr->len >= UBIFS_DATA_NODE_SZ);
 
                /*
                 * Search the inode node this data node belongs to and insert
@@ -2066,7 +2066,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
                struct ubifs_dent_node *dent = node;
                struct fsck_inode *fscki1;
 
-               ubifs_assert(zbr->len >= UBIFS_DENT_NODE_SZ);
+               ubifs_assert(c, zbr->len >= UBIFS_DENT_NODE_SZ);
 
                err = ubifs_validate_entry(c, dent);
                if (err)
@@ -2461,7 +2461,7 @@ static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
 {
        struct ubifs_debug_info *d = c->dbg;
 
-       ubifs_assert(dbg_is_tst_rcvry(c));
+       ubifs_assert(c, dbg_is_tst_rcvry(c));
 
        if (!d->pc_cnt) {
                /* First call - decide delay to the power cut */
@@ -3081,6 +3081,28 @@ void dbg_debugfs_exit(void)
                debugfs_remove_recursive(dfs_rootdir);
 }
 
+void ubifs_assert_failed(struct ubifs_info *c, const char *expr,
+                        const char *file, int line)
+{
+       ubifs_err(c, "UBIFS assert failed: %s, in %s:%u", expr, file, line);
+
+       switch (c->assert_action) {
+               case ASSACT_PANIC:
+               BUG();
+               break;
+
+               case ASSACT_RO:
+               ubifs_ro_mode(c, -EINVAL);
+               break;
+
+               case ASSACT_REPORT:
+               default:
+               dump_stack();
+               break;
+
+       }
+}
+
 /**
  * ubifs_debugging_init - initialize UBIFS debugging.
  * @c: UBIFS file-system description object
index e03d5179769ada74c6b1cb2c4aa2805ffa89dbdd..64c6977c189b932494f282a708a04101e4849878 100644 (file)
@@ -148,19 +148,21 @@ struct ubifs_global_debug_info {
        unsigned int tst_rcvry:1;
 };
 
-#define ubifs_assert(expr) do {                                                \
+void ubifs_assert_failed(struct ubifs_info *c, const char *expr,
+       const char *file, int line);
+
+#define ubifs_assert(c, expr) do {                                             \
        if (unlikely(!(expr))) {                                               \
-               pr_crit("UBIFS assert failed in %s at %u (pid %d)\n",          \
-                      __func__, __LINE__, current->pid);                      \
-               dump_stack();                                                  \
+               ubifs_assert_failed((struct ubifs_info *)c, #expr, __FILE__,   \
+                __LINE__);                                                    \
        }                                                                      \
 } while (0)
 
 #define ubifs_assert_cmt_locked(c) do {                                        \
        if (unlikely(down_write_trylock(&(c)->commit_sem))) {                  \
                up_write(&(c)->commit_sem);                                    \
-               pr_crit("commit lock is not locked!\n");                       \
-               ubifs_assert(0);                                               \
+               ubifs_err(c, "commit lock is not locked!\n");                  \
+               ubifs_assert(c, 0);                                            \
        }                                                                      \
 } while (0)
 
index 9da224d4f2da1d7de9f2bf292e7afa504a9668f3..5767b373a8ffbca6d1d06d3510dd5329ae71cc48 100644 (file)
@@ -240,8 +240,8 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
        }
 
        if (nm.hash) {
-               ubifs_assert(fname_len(&nm) == 0);
-               ubifs_assert(fname_name(&nm) == NULL);
+               ubifs_assert(c, fname_len(&nm) == 0);
+               ubifs_assert(c, fname_name(&nm) == NULL);
                dent_key_init_hash(c, &key, dir->i_ino, nm.hash);
                err = ubifs_tnc_lookup_dh(c, &key, dent, nm.minor_hash);
        } else {
@@ -404,7 +404,7 @@ static int do_tmpfile(struct inode *dir, struct dentry *dentry,
 
        if (whiteout) {
                init_special_inode(inode, inode->i_mode, WHITEOUT_DEV);
-               ubifs_assert(inode->i_op == &ubifs_file_inode_operations);
+               ubifs_assert(c, inode->i_op == &ubifs_file_inode_operations);
        }
 
        err = ubifs_init_security(dir, inode, &dentry->d_name);
@@ -421,7 +421,7 @@ static int do_tmpfile(struct inode *dir, struct dentry *dentry,
        } else {
                d_tmpfile(dentry, inode);
        }
-       ubifs_assert(ui->dirty);
+       ubifs_assert(c, ui->dirty);
 
        instantiated = 1;
        mutex_unlock(&ui->ui_mutex);
@@ -556,7 +556,7 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
 
        /* File positions 0 and 1 correspond to "." and ".." */
        if (ctx->pos < 2) {
-               ubifs_assert(!file->private_data);
+               ubifs_assert(c, !file->private_data);
                if (!dir_emit_dots(file, ctx)) {
                        if (encrypted)
                                fscrypt_fname_free_buffer(&fstr);
@@ -597,7 +597,7 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
                dbg_gen("ino %llu, new f_pos %#x",
                        (unsigned long long)le64_to_cpu(dent->inum),
                        key_hash_flash(c, &dent->key));
-               ubifs_assert(le64_to_cpu(dent->ch.sqnum) >
+               ubifs_assert(c, le64_to_cpu(dent->ch.sqnum) >
                             ubifs_inode(dir)->creat_sqnum);
 
                fname_len(&nm) = le16_to_cpu(dent->nlen);
@@ -716,8 +716,8 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
        dbg_gen("dent '%pd' to ino %lu (nlink %d) in dir ino %lu",
                dentry, inode->i_ino,
                inode->i_nlink, dir->i_ino);
-       ubifs_assert(inode_is_locked(dir));
-       ubifs_assert(inode_is_locked(inode));
+       ubifs_assert(c, inode_is_locked(dir));
+       ubifs_assert(c, inode_is_locked(inode));
 
        err = fscrypt_prepare_link(old_dentry, dir, dentry);
        if (err)
@@ -804,8 +804,8 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
 
        sz_change = CALC_DENT_SIZE(fname_len(&nm));
 
-       ubifs_assert(inode_is_locked(dir));
-       ubifs_assert(inode_is_locked(inode));
+       ubifs_assert(c, inode_is_locked(dir));
+       ubifs_assert(c, inode_is_locked(inode));
        err = dbg_check_synced_i_size(c, inode);
        if (err)
                goto out_fname;
@@ -896,8 +896,8 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
 
        dbg_gen("directory '%pd', ino %lu in dir ino %lu", dentry,
                inode->i_ino, dir->i_ino);
-       ubifs_assert(inode_is_locked(dir));
-       ubifs_assert(inode_is_locked(inode));
+       ubifs_assert(c, inode_is_locked(dir));
+       ubifs_assert(c, inode_is_locked(inode));
        err = ubifs_check_dir_empty(d_inode(dentry));
        if (err)
                return err;
@@ -1123,8 +1123,7 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
        struct ubifs_inode *ui;
        struct ubifs_inode *dir_ui = ubifs_inode(dir);
        struct ubifs_info *c = dir->i_sb->s_fs_info;
-       int err, len = strlen(symname);
-       int sz_change = CALC_DENT_SIZE(len);
+       int err, sz_change, len = strlen(symname);
        struct fscrypt_str disk_link;
        struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
                                        .new_ino_d = ALIGN(len, 8),
@@ -1151,6 +1150,8 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
        if (err)
                goto out_budg;
 
+       sz_change = CALC_DENT_SIZE(fname_len(&nm));
+
        inode = ubifs_new_inode(c, dir, S_IFLNK | S_IRWXUGO);
        if (IS_ERR(inode)) {
                err = PTR_ERR(inode);
@@ -1294,7 +1295,7 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
                new_dentry, new_dir->i_ino, flags);
 
        if (unlink)
-               ubifs_assert(inode_is_locked(new_inode));
+               ubifs_assert(c, inode_is_locked(new_inode));
 
        if (unlink && is_dir) {
                err = ubifs_check_dir_empty(new_inode);
@@ -1348,7 +1349,7 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
                whiteout_ui = ubifs_inode(whiteout);
                whiteout_ui->data = dev;
                whiteout_ui->data_len = ubifs_encode_dev(dev, MKDEV(0, 0));
-               ubifs_assert(!whiteout_ui->dirty);
+               ubifs_assert(c, !whiteout_ui->dirty);
        }
 
        lock_4_inodes(old_dir, new_dir, new_inode, whiteout);
@@ -1508,7 +1509,7 @@ static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry,
        int err;
        struct fscrypt_name fst_nm, snd_nm;
 
-       ubifs_assert(fst_inode && snd_inode);
+       ubifs_assert(c, fst_inode && snd_inode);
 
        err = fscrypt_setup_filename(old_dir, &old_dentry->d_name, 0, &fst_nm);
        if (err)
@@ -1555,12 +1556,13 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
                        unsigned int flags)
 {
        int err;
+       struct ubifs_info *c = old_dir->i_sb->s_fs_info;
 
        if (flags & ~(RENAME_NOREPLACE | RENAME_WHITEOUT | RENAME_EXCHANGE))
                return -EINVAL;
 
-       ubifs_assert(inode_is_locked(old_dir));
-       ubifs_assert(inode_is_locked(new_dir));
+       ubifs_assert(c, inode_is_locked(old_dir));
+       ubifs_assert(c, inode_is_locked(new_dir));
 
        err = fscrypt_prepare_rename(old_dir, old_dentry, new_dir, new_dentry,
                                     flags);
@@ -1647,7 +1649,9 @@ const struct inode_operations ubifs_dir_inode_operations = {
        .rename      = ubifs_rename,
        .setattr     = ubifs_setattr,
        .getattr     = ubifs_getattr,
+#ifdef CONFIG_UBIFS_FS_XATTR
        .listxattr   = ubifs_listxattr,
+#endif
 #ifdef CONFIG_UBIFS_ATIME_SUPPORT
        .update_time = ubifs_update_time,
 #endif
index fd7eb6fe90904fa9a57bd46711124f54af475849..1b78f2e09218bd3fcf44f2772c47af54347a1bc1 100644 (file)
@@ -71,7 +71,7 @@ static int read_block(struct inode *inode, void *addr, unsigned int block,
                return err;
        }
 
-       ubifs_assert(le64_to_cpu(dn->ch.sqnum) >
+       ubifs_assert(c, le64_to_cpu(dn->ch.sqnum) >
                     ubifs_inode(inode)->creat_sqnum);
        len = le32_to_cpu(dn->size);
        if (len <= 0 || len > UBIFS_BLOCK_SIZE)
@@ -115,12 +115,13 @@ static int do_readpage(struct page *page)
        unsigned int block, beyond;
        struct ubifs_data_node *dn;
        struct inode *inode = page->mapping->host;
+       struct ubifs_info *c = inode->i_sb->s_fs_info;
        loff_t i_size = i_size_read(inode);
 
        dbg_gen("ino %lu, pg %lu, i_size %lld, flags %#lx",
                inode->i_ino, page->index, i_size, page->flags);
-       ubifs_assert(!PageChecked(page));
-       ubifs_assert(!PagePrivate(page));
+       ubifs_assert(c, !PageChecked(page));
+       ubifs_assert(c, !PagePrivate(page));
 
        addr = kmap(page);
 
@@ -441,8 +442,8 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
        int skipped_read = 0;
        struct page *page;
 
-       ubifs_assert(ubifs_inode(inode)->ui_size == inode->i_size);
-       ubifs_assert(!c->ro_media && !c->ro_mount);
+       ubifs_assert(c, ubifs_inode(inode)->ui_size == inode->i_size);
+       ubifs_assert(c, !c->ro_media && !c->ro_mount);
 
        if (unlikely(c->ro_error))
                return -EROFS;
@@ -481,7 +482,7 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
 
        err = allocate_budget(c, page, ui, appending);
        if (unlikely(err)) {
-               ubifs_assert(err == -ENOSPC);
+               ubifs_assert(c, err == -ENOSPC);
                /*
                 * If we skipped reading the page because we were going to
                 * write all of it, then it is not up to date.
@@ -498,7 +499,7 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
                 * everything and fall-back to slow-path.
                 */
                if (appending) {
-                       ubifs_assert(mutex_is_locked(&ui->ui_mutex));
+                       ubifs_assert(c, mutex_is_locked(&ui->ui_mutex));
                        mutex_unlock(&ui->ui_mutex);
                }
                unlock_page(page);
@@ -595,7 +596,7 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping,
                 * '__set_page_dirty_nobuffers()'.
                 */
                __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
-               ubifs_assert(mutex_is_locked(&ui->ui_mutex));
+               ubifs_assert(c, mutex_is_locked(&ui->ui_mutex));
                mutex_unlock(&ui->ui_mutex);
        }
 
@@ -648,7 +649,7 @@ static int populate_page(struct ubifs_info *c, struct page *page,
 
                        dn = bu->buf + (bu->zbranch[nn].offs - offs);
 
-                       ubifs_assert(le64_to_cpu(dn->ch.sqnum) >
+                       ubifs_assert(c, le64_to_cpu(dn->ch.sqnum) >
                                     ubifs_inode(inode)->creat_sqnum);
 
                        len = le32_to_cpu(dn->size);
@@ -767,8 +768,8 @@ static int ubifs_do_bulk_read(struct ubifs_info *c, struct bu_info *bu,
                        bu->buf_len = bu->zbranch[bu->cnt - 1].offs +
                                      bu->zbranch[bu->cnt - 1].len -
                                      bu->zbranch[0].offs;
-                       ubifs_assert(bu->buf_len > 0);
-                       ubifs_assert(bu->buf_len <= c->leb_size);
+                       ubifs_assert(c, bu->buf_len > 0);
+                       ubifs_assert(c, bu->buf_len <= c->leb_size);
                        bu->buf = kmalloc(bu->buf_len, GFP_NOFS | __GFP_NOWARN);
                        if (!bu->buf)
                                goto out_bu_off;
@@ -920,7 +921,7 @@ static int do_writepage(struct page *page, int len)
 #ifdef UBIFS_DEBUG
        struct ubifs_inode *ui = ubifs_inode(inode);
        spin_lock(&ui->ui_lock);
-       ubifs_assert(page->index <= ui->synced_i_size >> PAGE_SHIFT);
+       ubifs_assert(c, page->index <= ui->synced_i_size >> PAGE_SHIFT);
        spin_unlock(&ui->ui_lock);
 #endif
 
@@ -949,7 +950,7 @@ static int do_writepage(struct page *page, int len)
                ubifs_ro_mode(c, err);
        }
 
-       ubifs_assert(PagePrivate(page));
+       ubifs_assert(c, PagePrivate(page));
        if (PageChecked(page))
                release_new_page_budget(c);
        else
@@ -1014,6 +1015,7 @@ static int do_writepage(struct page *page, int len)
 static int ubifs_writepage(struct page *page, struct writeback_control *wbc)
 {
        struct inode *inode = page->mapping->host;
+       struct ubifs_info *c = inode->i_sb->s_fs_info;
        struct ubifs_inode *ui = ubifs_inode(inode);
        loff_t i_size =  i_size_read(inode), synced_i_size;
        pgoff_t end_index = i_size >> PAGE_SHIFT;
@@ -1022,7 +1024,7 @@ static int ubifs_writepage(struct page *page, struct writeback_control *wbc)
 
        dbg_gen("ino %lu, pg %lu, pg flags %#lx",
                inode->i_ino, page->index, page->flags);
-       ubifs_assert(PagePrivate(page));
+       ubifs_assert(c, PagePrivate(page));
 
        /* Is the page fully outside @i_size? (truncate in progress) */
        if (page->index > end_index || (page->index == end_index && !len)) {
@@ -1167,7 +1169,7 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode,
                                 * 'ubifs_jnl_truncate()' will see an already
                                 * truncated (and up to date) data node.
                                 */
-                               ubifs_assert(PagePrivate(page));
+                               ubifs_assert(c, PagePrivate(page));
 
                                clear_page_dirty_for_io(page);
                                if (UBIFS_BLOCKS_PER_PAGE_SHIFT)
@@ -1303,7 +1305,7 @@ static void ubifs_invalidatepage(struct page *page, unsigned int offset,
        struct inode *inode = page->mapping->host;
        struct ubifs_info *c = inode->i_sb->s_fs_info;
 
-       ubifs_assert(PagePrivate(page));
+       ubifs_assert(c, PagePrivate(page));
        if (offset || length < PAGE_SIZE)
                /* Partial page remains dirty */
                return;
@@ -1365,11 +1367,10 @@ out:
  * granularity, they are not updated. This is an optimization.
  */
 static inline int mctime_update_needed(const struct inode *inode,
-                                      const struct timespec *now)
+                                      const struct timespec64 *now)
 {
-       struct timespec64 now64 = timespec_to_timespec64(*now);
-       if (!timespec64_equal(&inode->i_mtime, &now64) ||
-           !timespec64_equal(&inode->i_ctime, &now64))
+       if (!timespec64_equal(&inode->i_mtime, now) ||
+           !timespec64_equal(&inode->i_ctime, now))
                return 1;
        return 0;
 }
@@ -1425,7 +1426,7 @@ int ubifs_update_time(struct inode *inode, struct timespec64 *time,
  */
 static int update_mctime(struct inode *inode)
 {
-       struct timespec now = timespec64_to_timespec(current_time(inode));
+       struct timespec64 now = current_time(inode);
        struct ubifs_inode *ui = ubifs_inode(inode);
        struct ubifs_info *c = inode->i_sb->s_fs_info;
 
@@ -1462,13 +1463,15 @@ static ssize_t ubifs_write_iter(struct kiocb *iocb, struct iov_iter *from)
 static int ubifs_set_page_dirty(struct page *page)
 {
        int ret;
+       struct inode *inode = page->mapping->host;
+       struct ubifs_info *c = inode->i_sb->s_fs_info;
 
        ret = __set_page_dirty_nobuffers(page);
        /*
         * An attempt to dirty a page without budgeting for it - should not
         * happen.
         */
-       ubifs_assert(ret == 0);
+       ubifs_assert(c, ret == 0);
        return ret;
 }
 
@@ -1497,14 +1500,17 @@ static int ubifs_migrate_page(struct address_space *mapping,
 
 static int ubifs_releasepage(struct page *page, gfp_t unused_gfp_flags)
 {
+       struct inode *inode = page->mapping->host;
+       struct ubifs_info *c = inode->i_sb->s_fs_info;
+
        /*
         * An attempt to release a dirty page without budgeting for it - should
         * not happen.
         */
        if (PageWriteback(page))
                return 0;
-       ubifs_assert(PagePrivate(page));
-       ubifs_assert(0);
+       ubifs_assert(c, PagePrivate(page));
+       ubifs_assert(c, 0);
        ClearPagePrivate(page);
        ClearPageChecked(page);
        return 1;
@@ -1519,13 +1525,13 @@ static vm_fault_t ubifs_vm_page_mkwrite(struct vm_fault *vmf)
        struct page *page = vmf->page;
        struct inode *inode = file_inode(vmf->vma->vm_file);
        struct ubifs_info *c = inode->i_sb->s_fs_info;
-       struct timespec now = timespec64_to_timespec(current_time(inode));
+       struct timespec64 now = current_time(inode);
        struct ubifs_budget_req req = { .new_page = 1 };
        int err, update_time;
 
        dbg_gen("ino %lu, pg %lu, i_size %lld", inode->i_ino, page->index,
                i_size_read(inode));
-       ubifs_assert(!c->ro_media && !c->ro_mount);
+       ubifs_assert(c, !c->ro_media && !c->ro_mount);
 
        if (unlikely(c->ro_error))
                return VM_FAULT_SIGBUS; /* -EROFS */
@@ -1654,7 +1660,9 @@ const struct address_space_operations ubifs_file_address_operations = {
 const struct inode_operations ubifs_file_inode_operations = {
        .setattr     = ubifs_setattr,
        .getattr     = ubifs_getattr,
+#ifdef CONFIG_UBIFS_FS_XATTR
        .listxattr   = ubifs_listxattr,
+#endif
 #ifdef CONFIG_UBIFS_ATIME_SUPPORT
        .update_time = ubifs_update_time,
 #endif
@@ -1664,7 +1672,9 @@ const struct inode_operations ubifs_symlink_inode_operations = {
        .get_link    = ubifs_get_link,
        .setattr     = ubifs_setattr,
        .getattr     = ubifs_getattr,
+#ifdef CONFIG_UBIFS_FS_XATTR
        .listxattr   = ubifs_listxattr,
+#endif
 #ifdef CONFIG_UBIFS_ATIME_SUPPORT
        .update_time = ubifs_update_time,
 #endif
index 9571616b5ddaf1dbee1286dcbc0870b1df11d9b8..f9646835b0269c2347e73ceabd146253b8f42abd 100644 (file)
@@ -183,18 +183,18 @@ static const struct ubifs_lprops *scan_for_dirty(struct ubifs_info *c,
                                    &data);
        if (err)
                return ERR_PTR(err);
-       ubifs_assert(data.lnum >= c->main_first && data.lnum < c->leb_cnt);
+       ubifs_assert(c, data.lnum >= c->main_first && data.lnum < c->leb_cnt);
        c->lscan_lnum = data.lnum;
        lprops = ubifs_lpt_lookup_dirty(c, data.lnum);
        if (IS_ERR(lprops))
                return lprops;
-       ubifs_assert(lprops->lnum == data.lnum);
-       ubifs_assert(lprops->free + lprops->dirty >= min_space);
-       ubifs_assert(lprops->dirty >= c->dead_wm ||
+       ubifs_assert(c, lprops->lnum == data.lnum);
+       ubifs_assert(c, lprops->free + lprops->dirty >= min_space);
+       ubifs_assert(c, lprops->dirty >= c->dead_wm ||
                     (pick_free &&
                      lprops->free + lprops->dirty == c->leb_size));
-       ubifs_assert(!(lprops->flags & LPROPS_TAKEN));
-       ubifs_assert(!exclude_index || !(lprops->flags & LPROPS_INDEX));
+       ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
+       ubifs_assert(c, !exclude_index || !(lprops->flags & LPROPS_INDEX));
        return lprops;
 }
 
@@ -315,7 +315,7 @@ int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp,
                lp = idx_lp;
 
        if (lp) {
-               ubifs_assert(lp->free + lp->dirty >= c->dead_wm);
+               ubifs_assert(c, lp->free + lp->dirty >= c->dead_wm);
                goto found;
        }
 
@@ -326,7 +326,7 @@ int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp,
                err = PTR_ERR(lp);
                goto out;
        }
-       ubifs_assert(lp->dirty >= c->dead_wm ||
+       ubifs_assert(c, lp->dirty >= c->dead_wm ||
                     (pick_free && lp->free + lp->dirty == c->leb_size));
 
 found:
@@ -462,15 +462,15 @@ const struct ubifs_lprops *do_find_free_space(struct ubifs_info *c,
                                    &data);
        if (err)
                return ERR_PTR(err);
-       ubifs_assert(data.lnum >= c->main_first && data.lnum < c->leb_cnt);
+       ubifs_assert(c, data.lnum >= c->main_first && data.lnum < c->leb_cnt);
        c->lscan_lnum = data.lnum;
        lprops = ubifs_lpt_lookup_dirty(c, data.lnum);
        if (IS_ERR(lprops))
                return lprops;
-       ubifs_assert(lprops->lnum == data.lnum);
-       ubifs_assert(lprops->free >= min_space);
-       ubifs_assert(!(lprops->flags & LPROPS_TAKEN));
-       ubifs_assert(!(lprops->flags & LPROPS_INDEX));
+       ubifs_assert(c, lprops->lnum == data.lnum);
+       ubifs_assert(c, lprops->free >= min_space);
+       ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
+       ubifs_assert(c, !(lprops->flags & LPROPS_INDEX));
        return lprops;
 }
 
@@ -574,7 +574,7 @@ int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *offs,
        }
 
        dbg_find("found LEB %d, free %d", lnum, c->leb_size - *offs);
-       ubifs_assert(*offs <= c->leb_size - min_space);
+       ubifs_assert(c, *offs <= c->leb_size - min_space);
        return lnum;
 
 out:
@@ -642,15 +642,15 @@ static const struct ubifs_lprops *scan_for_leb_for_idx(struct ubifs_info *c)
                                    &data);
        if (err)
                return ERR_PTR(err);
-       ubifs_assert(data.lnum >= c->main_first && data.lnum < c->leb_cnt);
+       ubifs_assert(c, data.lnum >= c->main_first && data.lnum < c->leb_cnt);
        c->lscan_lnum = data.lnum;
        lprops = ubifs_lpt_lookup_dirty(c, data.lnum);
        if (IS_ERR(lprops))
                return lprops;
-       ubifs_assert(lprops->lnum == data.lnum);
-       ubifs_assert(lprops->free + lprops->dirty == c->leb_size);
-       ubifs_assert(!(lprops->flags & LPROPS_TAKEN));
-       ubifs_assert(!(lprops->flags & LPROPS_INDEX));
+       ubifs_assert(c, lprops->lnum == data.lnum);
+       ubifs_assert(c, lprops->free + lprops->dirty == c->leb_size);
+       ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
+       ubifs_assert(c, !(lprops->flags & LPROPS_INDEX));
        return lprops;
 }
 
@@ -690,7 +690,7 @@ int ubifs_find_free_leb_for_idx(struct ubifs_info *c)
                         */
                        if (c->in_a_category_cnt != c->main_lebs ||
                            c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
-                               ubifs_assert(c->freeable_cnt == 0);
+                               ubifs_assert(c, c->freeable_cnt == 0);
                                lprops = scan_for_leb_for_idx(c);
                                if (IS_ERR(lprops)) {
                                        err = PTR_ERR(lprops);
@@ -750,10 +750,7 @@ static int cmp_dirty_idx(const struct ubifs_lprops **a,
 static void swap_dirty_idx(struct ubifs_lprops **a, struct ubifs_lprops **b,
                           int size)
 {
-       struct ubifs_lprops *t = *a;
-
-       *a = *b;
-       *b = t;
+       swap(*a, *b);
 }
 
 /**
@@ -870,15 +867,15 @@ static int find_dirty_idx_leb(struct ubifs_info *c)
        if (err)
                return err;
 found:
-       ubifs_assert(data.lnum >= c->main_first && data.lnum < c->leb_cnt);
+       ubifs_assert(c, data.lnum >= c->main_first && data.lnum < c->leb_cnt);
        c->lscan_lnum = data.lnum;
        lprops = ubifs_lpt_lookup_dirty(c, data.lnum);
        if (IS_ERR(lprops))
                return PTR_ERR(lprops);
-       ubifs_assert(lprops->lnum == data.lnum);
-       ubifs_assert(lprops->free + lprops->dirty >= c->min_idx_node_sz);
-       ubifs_assert(!(lprops->flags & LPROPS_TAKEN));
-       ubifs_assert((lprops->flags & LPROPS_INDEX));
+       ubifs_assert(c, lprops->lnum == data.lnum);
+       ubifs_assert(c, lprops->free + lprops->dirty >= c->min_idx_node_sz);
+       ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
+       ubifs_assert(c, (lprops->flags & LPROPS_INDEX));
 
        dbg_find("found dirty LEB %d, free %d, dirty %d, flags %#x",
                 lprops->lnum, lprops->free, lprops->dirty, lprops->flags);
@@ -947,8 +944,8 @@ static int find_dirtiest_idx_leb(struct ubifs_info *c)
        }
        dbg_find("LEB %d, dirty %d and free %d flags %#x", lp->lnum, lp->dirty,
                 lp->free, lp->flags);
-       ubifs_assert(lp->flags & LPROPS_TAKEN);
-       ubifs_assert(lp->flags & LPROPS_INDEX);
+       ubifs_assert(c, lp->flags & LPROPS_TAKEN);
+       ubifs_assert(c, lp->flags & LPROPS_INDEX);
        return lnum;
 }
 
index a03a47cf880dd2e7210d3ef07f6811a9bbc2075c..d2680e0b4a36f38826f253d33c1b7d258b21bb2d 100644 (file)
@@ -83,7 +83,7 @@ static int switch_gc_head(struct ubifs_info *c)
        int err, gc_lnum = c->gc_lnum;
        struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
 
-       ubifs_assert(gc_lnum != -1);
+       ubifs_assert(c, gc_lnum != -1);
        dbg_gc("switch GC head from LEB %d:%d to LEB %d (waste %d bytes)",
               wbuf->lnum, wbuf->offs + wbuf->used, gc_lnum,
               c->leb_size - wbuf->offs - wbuf->used);
@@ -131,10 +131,10 @@ static int data_nodes_cmp(void *priv, struct list_head *a, struct list_head *b)
        sa = list_entry(a, struct ubifs_scan_node, list);
        sb = list_entry(b, struct ubifs_scan_node, list);
 
-       ubifs_assert(key_type(c, &sa->key) == UBIFS_DATA_KEY);
-       ubifs_assert(key_type(c, &sb->key) == UBIFS_DATA_KEY);
-       ubifs_assert(sa->type == UBIFS_DATA_NODE);
-       ubifs_assert(sb->type == UBIFS_DATA_NODE);
+       ubifs_assert(c, key_type(c, &sa->key) == UBIFS_DATA_KEY);
+       ubifs_assert(c, key_type(c, &sb->key) == UBIFS_DATA_KEY);
+       ubifs_assert(c, sa->type == UBIFS_DATA_NODE);
+       ubifs_assert(c, sb->type == UBIFS_DATA_NODE);
 
        inuma = key_inum(c, &sa->key);
        inumb = key_inum(c, &sb->key);
@@ -175,9 +175,9 @@ static int nondata_nodes_cmp(void *priv, struct list_head *a,
        sa = list_entry(a, struct ubifs_scan_node, list);
        sb = list_entry(b, struct ubifs_scan_node, list);
 
-       ubifs_assert(key_type(c, &sa->key) != UBIFS_DATA_KEY &&
+       ubifs_assert(c, key_type(c, &sa->key) != UBIFS_DATA_KEY &&
                     key_type(c, &sb->key) != UBIFS_DATA_KEY);
-       ubifs_assert(sa->type != UBIFS_DATA_NODE &&
+       ubifs_assert(c, sa->type != UBIFS_DATA_NODE &&
                     sb->type != UBIFS_DATA_NODE);
 
        /* Inodes go before directory entries */
@@ -189,13 +189,13 @@ static int nondata_nodes_cmp(void *priv, struct list_head *a,
        if (sb->type == UBIFS_INO_NODE)
                return 1;
 
-       ubifs_assert(key_type(c, &sa->key) == UBIFS_DENT_KEY ||
+       ubifs_assert(c, key_type(c, &sa->key) == UBIFS_DENT_KEY ||
                     key_type(c, &sa->key) == UBIFS_XENT_KEY);
-       ubifs_assert(key_type(c, &sb->key) == UBIFS_DENT_KEY ||
+       ubifs_assert(c, key_type(c, &sb->key) == UBIFS_DENT_KEY ||
                     key_type(c, &sb->key) == UBIFS_XENT_KEY);
-       ubifs_assert(sa->type == UBIFS_DENT_NODE ||
+       ubifs_assert(c, sa->type == UBIFS_DENT_NODE ||
                     sa->type == UBIFS_XENT_NODE);
-       ubifs_assert(sb->type == UBIFS_DENT_NODE ||
+       ubifs_assert(c, sb->type == UBIFS_DENT_NODE ||
                     sb->type == UBIFS_XENT_NODE);
 
        inuma = key_inum(c, &sa->key);
@@ -250,7 +250,7 @@ static int sort_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
 
        /* Separate data nodes and non-data nodes */
        list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) {
-               ubifs_assert(snod->type == UBIFS_INO_NODE  ||
+               ubifs_assert(c, snod->type == UBIFS_INO_NODE  ||
                             snod->type == UBIFS_DATA_NODE ||
                             snod->type == UBIFS_DENT_NODE ||
                             snod->type == UBIFS_XENT_NODE ||
@@ -266,7 +266,7 @@ static int sort_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
                        continue;
                }
 
-               ubifs_assert(key_type(c, &snod->key) == UBIFS_DATA_KEY ||
+               ubifs_assert(c, key_type(c, &snod->key) == UBIFS_DATA_KEY ||
                             key_type(c, &snod->key) == UBIFS_INO_KEY  ||
                             key_type(c, &snod->key) == UBIFS_DENT_KEY ||
                             key_type(c, &snod->key) == UBIFS_XENT_KEY);
@@ -469,21 +469,21 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)
        struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
        int err = 0, lnum = lp->lnum;
 
-       ubifs_assert(c->gc_lnum != -1 || wbuf->offs + wbuf->used == 0 ||
+       ubifs_assert(c, c->gc_lnum != -1 || wbuf->offs + wbuf->used == 0 ||
                     c->need_recovery);
-       ubifs_assert(c->gc_lnum != lnum);
-       ubifs_assert(wbuf->lnum != lnum);
+       ubifs_assert(c, c->gc_lnum != lnum);
+       ubifs_assert(c, wbuf->lnum != lnum);
 
        if (lp->free + lp->dirty == c->leb_size) {
                /* Special case - a free LEB  */
                dbg_gc("LEB %d is free, return it", lp->lnum);
-               ubifs_assert(!(lp->flags & LPROPS_INDEX));
+               ubifs_assert(c, !(lp->flags & LPROPS_INDEX));
 
                if (lp->free != c->leb_size) {
                        /*
                         * Write buffers must be sync'd before unmapping
                         * freeable LEBs, because one of them may contain data
-                        * which obsoletes something in 'lp->pnum'.
+                        * which obsoletes something in 'lp->lnum'.
                         */
                        err = gc_sync_wbufs(c);
                        if (err)
@@ -513,7 +513,7 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)
        if (IS_ERR(sleb))
                return PTR_ERR(sleb);
 
-       ubifs_assert(!list_empty(&sleb->nodes));
+       ubifs_assert(c, !list_empty(&sleb->nodes));
        snod = list_entry(sleb->nodes.next, struct ubifs_scan_node, list);
 
        if (snod->type == UBIFS_IDX_NODE) {
@@ -525,7 +525,7 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)
                        struct ubifs_idx_node *idx = snod->node;
                        int level = le16_to_cpu(idx->level);
 
-                       ubifs_assert(snod->type == UBIFS_IDX_NODE);
+                       ubifs_assert(c, snod->type == UBIFS_IDX_NODE);
                        key_read(c, ubifs_idx_key(c, idx), &snod->key);
                        err = ubifs_dirty_idx_node(c, &snod->key, level, lnum,
                                                   snod->offs);
@@ -648,7 +648,7 @@ int ubifs_garbage_collect(struct ubifs_info *c, int anyway)
        struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
 
        ubifs_assert_cmt_locked(c);
-       ubifs_assert(!c->ro_media && !c->ro_mount);
+       ubifs_assert(c, !c->ro_media && !c->ro_mount);
 
        if (ubifs_gc_should_commit(c))
                return -EAGAIN;
@@ -661,7 +661,7 @@ int ubifs_garbage_collect(struct ubifs_info *c, int anyway)
        }
 
        /* We expect the write-buffer to be empty on entry */
-       ubifs_assert(!wbuf->used);
+       ubifs_assert(c, !wbuf->used);
 
        for (i = 0; ; i++) {
                int space_before, space_after;
@@ -752,7 +752,7 @@ int ubifs_garbage_collect(struct ubifs_info *c, int anyway)
                        continue;
                }
 
-               ubifs_assert(ret == LEB_RETAINED);
+               ubifs_assert(c, ret == LEB_RETAINED);
                space_after = c->leb_size - wbuf->offs - wbuf->used;
                dbg_gc("LEB %d retained, freed %d bytes", lp.lnum,
                       space_after - space_before);
@@ -812,8 +812,8 @@ out_unlock:
        return ret;
 
 out:
-       ubifs_assert(ret < 0);
-       ubifs_assert(ret != -ENOSPC && ret != -EAGAIN);
+       ubifs_assert(c, ret < 0);
+       ubifs_assert(c, ret != -ENOSPC && ret != -EAGAIN);
        ubifs_wbuf_sync_nolock(wbuf);
        ubifs_ro_mode(c, ret);
        mutex_unlock(&wbuf->io_mutex);
@@ -848,8 +848,8 @@ int ubifs_gc_start_commit(struct ubifs_info *c)
                lp = ubifs_fast_find_freeable(c);
                if (!lp)
                        break;
-               ubifs_assert(!(lp->flags & LPROPS_TAKEN));
-               ubifs_assert(!(lp->flags & LPROPS_INDEX));
+               ubifs_assert(c, !(lp->flags & LPROPS_TAKEN));
+               ubifs_assert(c, !(lp->flags & LPROPS_INDEX));
                err = ubifs_leb_unmap(c, lp->lnum);
                if (err)
                        goto out;
@@ -858,8 +858,8 @@ int ubifs_gc_start_commit(struct ubifs_info *c)
                        err = PTR_ERR(lp);
                        goto out;
                }
-               ubifs_assert(!(lp->flags & LPROPS_TAKEN));
-               ubifs_assert(!(lp->flags & LPROPS_INDEX));
+               ubifs_assert(c, !(lp->flags & LPROPS_TAKEN));
+               ubifs_assert(c, !(lp->flags & LPROPS_INDEX));
        }
 
        /* Mark GC'd index LEBs OK to unmap after this commit finishes */
@@ -880,8 +880,8 @@ int ubifs_gc_start_commit(struct ubifs_info *c)
                        err = -ENOMEM;
                        goto out;
                }
-               ubifs_assert(!(lp->flags & LPROPS_TAKEN));
-               ubifs_assert(lp->flags & LPROPS_INDEX);
+               ubifs_assert(c, !(lp->flags & LPROPS_TAKEN));
+               ubifs_assert(c, lp->flags & LPROPS_INDEX);
                /* Don't release the LEB until after the next commit */
                flags = (lp->flags | LPROPS_TAKEN) ^ LPROPS_INDEX;
                lp = ubifs_change_lp(c, lp, c->leb_size, 0, flags, 1);
@@ -890,8 +890,8 @@ int ubifs_gc_start_commit(struct ubifs_info *c)
                        kfree(idx_gc);
                        goto out;
                }
-               ubifs_assert(lp->flags & LPROPS_TAKEN);
-               ubifs_assert(!(lp->flags & LPROPS_INDEX));
+               ubifs_assert(c, lp->flags & LPROPS_TAKEN);
+               ubifs_assert(c, !(lp->flags & LPROPS_INDEX));
                idx_gc->lnum = lp->lnum;
                idx_gc->unmap = 1;
                list_add(&idx_gc->list, &c->idx_gc);
index fe77e9625e84791d007821ef231e633a58539f64..099bec94b82079f8fbd03f0fb74aee2180d1dab3 100644 (file)
@@ -119,7 +119,7 @@ int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
 {
        int err;
 
-       ubifs_assert(!c->ro_media && !c->ro_mount);
+       ubifs_assert(c, !c->ro_media && !c->ro_mount);
        if (c->ro_error)
                return -EROFS;
        if (!dbg_is_tst_rcvry(c))
@@ -139,7 +139,7 @@ int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len)
 {
        int err;
 
-       ubifs_assert(!c->ro_media && !c->ro_mount);
+       ubifs_assert(c, !c->ro_media && !c->ro_mount);
        if (c->ro_error)
                return -EROFS;
        if (!dbg_is_tst_rcvry(c))
@@ -159,7 +159,7 @@ int ubifs_leb_unmap(struct ubifs_info *c, int lnum)
 {
        int err;
 
-       ubifs_assert(!c->ro_media && !c->ro_mount);
+       ubifs_assert(c, !c->ro_media && !c->ro_mount);
        if (c->ro_error)
                return -EROFS;
        if (!dbg_is_tst_rcvry(c))
@@ -178,7 +178,7 @@ int ubifs_leb_map(struct ubifs_info *c, int lnum)
 {
        int err;
 
-       ubifs_assert(!c->ro_media && !c->ro_mount);
+       ubifs_assert(c, !c->ro_media && !c->ro_mount);
        if (c->ro_error)
                return -EROFS;
        if (!dbg_is_tst_rcvry(c))
@@ -241,8 +241,8 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
        uint32_t crc, node_crc, magic;
        const struct ubifs_ch *ch = buf;
 
-       ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
-       ubifs_assert(!(offs & 7) && offs < c->leb_size);
+       ubifs_assert(c, lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
+       ubifs_assert(c, !(offs & 7) && offs < c->leb_size);
 
        magic = le32_to_cpu(ch->magic);
        if (magic != UBIFS_NODE_MAGIC) {
@@ -319,7 +319,7 @@ void ubifs_pad(const struct ubifs_info *c, void *buf, int pad)
 {
        uint32_t crc;
 
-       ubifs_assert(pad >= 0 && !(pad & 7));
+       ubifs_assert(c, pad >= 0 && !(pad & 7));
 
        if (pad >= UBIFS_PAD_NODE_SZ) {
                struct ubifs_ch *ch = buf;
@@ -382,7 +382,7 @@ void ubifs_prepare_node(struct ubifs_info *c, void *node, int len, int pad)
        struct ubifs_ch *ch = node;
        unsigned long long sqnum = next_sqnum(c);
 
-       ubifs_assert(len >= UBIFS_CH_SZ);
+       ubifs_assert(c, len >= UBIFS_CH_SZ);
 
        ch->magic = cpu_to_le32(UBIFS_NODE_MAGIC);
        ch->len = cpu_to_le32(len);
@@ -415,7 +415,7 @@ void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last)
        struct ubifs_ch *ch = node;
        unsigned long long sqnum = next_sqnum(c);
 
-       ubifs_assert(len >= UBIFS_CH_SZ);
+       ubifs_assert(c, len >= UBIFS_CH_SZ);
 
        ch->magic = cpu_to_le32(UBIFS_NODE_MAGIC);
        ch->len = cpu_to_le32(len);
@@ -448,9 +448,10 @@ static enum hrtimer_restart wbuf_timer_callback_nolock(struct hrtimer *timer)
 
 /**
  * new_wbuf_timer - start new write-buffer timer.
+ * @c: UBIFS file-system description object
  * @wbuf: write-buffer descriptor
  */
-static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf)
+static void new_wbuf_timer_nolock(struct ubifs_info *c, struct ubifs_wbuf *wbuf)
 {
        ktime_t softlimit = ms_to_ktime(dirty_writeback_interval * 10);
        unsigned long long delta = dirty_writeback_interval;
@@ -458,8 +459,8 @@ static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf)
        /* centi to milli, milli to nano, then 10% */
        delta *= 10ULL * NSEC_PER_MSEC / 10ULL;
 
-       ubifs_assert(!hrtimer_active(&wbuf->timer));
-       ubifs_assert(delta <= ULONG_MAX);
+       ubifs_assert(c, !hrtimer_active(&wbuf->timer));
+       ubifs_assert(c, delta <= ULONG_MAX);
 
        if (wbuf->no_timer)
                return;
@@ -508,14 +509,14 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf)
 
        dbg_io("LEB %d:%d, %d bytes, jhead %s",
               wbuf->lnum, wbuf->offs, wbuf->used, dbg_jhead(wbuf->jhead));
-       ubifs_assert(!(wbuf->avail & 7));
-       ubifs_assert(wbuf->offs + wbuf->size <= c->leb_size);
-       ubifs_assert(wbuf->size >= c->min_io_size);
-       ubifs_assert(wbuf->size <= c->max_write_size);
-       ubifs_assert(wbuf->size % c->min_io_size == 0);
-       ubifs_assert(!c->ro_media && !c->ro_mount);
+       ubifs_assert(c, !(wbuf->avail & 7));
+       ubifs_assert(c, wbuf->offs + wbuf->size <= c->leb_size);
+       ubifs_assert(c, wbuf->size >= c->min_io_size);
+       ubifs_assert(c, wbuf->size <= c->max_write_size);
+       ubifs_assert(c, wbuf->size % c->min_io_size == 0);
+       ubifs_assert(c, !c->ro_media && !c->ro_mount);
        if (c->leb_size - wbuf->offs >= c->max_write_size)
-               ubifs_assert(!((wbuf->offs + wbuf->size) % c->max_write_size));
+               ubifs_assert(c, !((wbuf->offs + wbuf->size) % c->max_write_size));
 
        if (c->ro_error)
                return -EROFS;
@@ -576,11 +577,11 @@ int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs)
        const struct ubifs_info *c = wbuf->c;
 
        dbg_io("LEB %d:%d, jhead %s", lnum, offs, dbg_jhead(wbuf->jhead));
-       ubifs_assert(lnum >= 0 && lnum < c->leb_cnt);
-       ubifs_assert(offs >= 0 && offs <= c->leb_size);
-       ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7));
-       ubifs_assert(lnum != wbuf->lnum);
-       ubifs_assert(wbuf->used == 0);
+       ubifs_assert(c, lnum >= 0 && lnum < c->leb_cnt);
+       ubifs_assert(c, offs >= 0 && offs <= c->leb_size);
+       ubifs_assert(c, offs % c->min_io_size == 0 && !(offs & 7));
+       ubifs_assert(c, lnum != wbuf->lnum);
+       ubifs_assert(c, wbuf->used == 0);
 
        spin_lock(&wbuf->lock);
        wbuf->lnum = lnum;
@@ -610,7 +611,7 @@ int ubifs_bg_wbufs_sync(struct ubifs_info *c)
 {
        int err, i;
 
-       ubifs_assert(!c->ro_media && !c->ro_mount);
+       ubifs_assert(c, !c->ro_media && !c->ro_mount);
        if (!c->need_wbuf_sync)
                return 0;
        c->need_wbuf_sync = 0;
@@ -686,18 +687,18 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
        dbg_io("%d bytes (%s) to jhead %s wbuf at LEB %d:%d", len,
               dbg_ntype(((struct ubifs_ch *)buf)->node_type),
               dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs + wbuf->used);
-       ubifs_assert(len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt);
-       ubifs_assert(wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0);
-       ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size);
-       ubifs_assert(wbuf->avail > 0 && wbuf->avail <= wbuf->size);
-       ubifs_assert(wbuf->size >= c->min_io_size);
-       ubifs_assert(wbuf->size <= c->max_write_size);
-       ubifs_assert(wbuf->size % c->min_io_size == 0);
-       ubifs_assert(mutex_is_locked(&wbuf->io_mutex));
-       ubifs_assert(!c->ro_media && !c->ro_mount);
-       ubifs_assert(!c->space_fixup);
+       ubifs_assert(c, len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt);
+       ubifs_assert(c, wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0);
+       ubifs_assert(c, !(wbuf->offs & 7) && wbuf->offs <= c->leb_size);
+       ubifs_assert(c, wbuf->avail > 0 && wbuf->avail <= wbuf->size);
+       ubifs_assert(c, wbuf->size >= c->min_io_size);
+       ubifs_assert(c, wbuf->size <= c->max_write_size);
+       ubifs_assert(c, wbuf->size % c->min_io_size == 0);
+       ubifs_assert(c, mutex_is_locked(&wbuf->io_mutex));
+       ubifs_assert(c, !c->ro_media && !c->ro_mount);
+       ubifs_assert(c, !c->space_fixup);
        if (c->leb_size - wbuf->offs >= c->max_write_size)
-               ubifs_assert(!((wbuf->offs + wbuf->size) % c->max_write_size));
+               ubifs_assert(c, !((wbuf->offs + wbuf->size) % c->max_write_size));
 
        if (c->leb_size - wbuf->offs - wbuf->used < aligned_len) {
                err = -ENOSPC;
@@ -834,7 +835,7 @@ exit:
        }
 
        if (wbuf->used)
-               new_wbuf_timer_nolock(wbuf);
+               new_wbuf_timer_nolock(c, wbuf);
 
        return 0;
 
@@ -869,10 +870,10 @@ int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum,
        dbg_io("LEB %d:%d, %s, length %d (aligned %d)",
               lnum, offs, dbg_ntype(((struct ubifs_ch *)buf)->node_type), len,
               buf_len);
-       ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
-       ubifs_assert(offs % c->min_io_size == 0 && offs < c->leb_size);
-       ubifs_assert(!c->ro_media && !c->ro_mount);
-       ubifs_assert(!c->space_fixup);
+       ubifs_assert(c, lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
+       ubifs_assert(c, offs % c->min_io_size == 0 && offs < c->leb_size);
+       ubifs_assert(c, !c->ro_media && !c->ro_mount);
+       ubifs_assert(c, !c->space_fixup);
 
        if (c->ro_error)
                return -EROFS;
@@ -909,9 +910,9 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,
 
        dbg_io("LEB %d:%d, %s, length %d, jhead %s", lnum, offs,
               dbg_ntype(type), len, dbg_jhead(wbuf->jhead));
-       ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
-       ubifs_assert(!(offs & 7) && offs < c->leb_size);
-       ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT);
+       ubifs_assert(c, wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
+       ubifs_assert(c, !(offs & 7) && offs < c->leb_size);
+       ubifs_assert(c, type >= 0 && type < UBIFS_NODE_TYPES_CNT);
 
        spin_lock(&wbuf->lock);
        overlap = (lnum == wbuf->lnum && offs + len > wbuf->offs);
@@ -984,10 +985,10 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,
        struct ubifs_ch *ch = buf;
 
        dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len);
-       ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
-       ubifs_assert(len >= UBIFS_CH_SZ && offs + len <= c->leb_size);
-       ubifs_assert(!(offs & 7) && offs < c->leb_size);
-       ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT);
+       ubifs_assert(c, lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
+       ubifs_assert(c, len >= UBIFS_CH_SZ && offs + len <= c->leb_size);
+       ubifs_assert(c, !(offs & 7) && offs < c->leb_size);
+       ubifs_assert(c, type >= 0 && type < UBIFS_NODE_TYPES_CNT);
 
        err = ubifs_leb_read(c, lnum, buf, offs, len, 0);
        if (err && err != -EBADMSG)
index 07b4956e042522e684e3dec9b36909fd46c83f83..802565a17733ce4b0e304df7daffda9517252bca 100644 (file)
@@ -111,7 +111,7 @@ static int reserve_space(struct ubifs_info *c, int jhead, int len)
         * better to try to allocate space at the ends of eraseblocks. This is
         * what the squeeze parameter does.
         */
-       ubifs_assert(!c->ro_media && !c->ro_mount);
+       ubifs_assert(c, !c->ro_media && !c->ro_mount);
        squeeze = (jhead == BASEHD);
 again:
        mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead);
@@ -215,7 +215,7 @@ out_unlock:
 
 out_return:
        /* An error occurred and the LEB has to be returned to lprops */
-       ubifs_assert(err < 0);
+       ubifs_assert(c, err < 0);
        err1 = ubifs_return_leb(c, lnum);
        if (err1 && err == -EAGAIN)
                /*
@@ -246,7 +246,7 @@ static int write_node(struct ubifs_info *c, int jhead, void *node, int len,
 {
        struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf;
 
-       ubifs_assert(jhead != GCHD);
+       ubifs_assert(c, jhead != GCHD);
 
        *lnum = c->jheads[jhead].wbuf.lnum;
        *offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used;
@@ -278,7 +278,7 @@ static int write_head(struct ubifs_info *c, int jhead, void *buf, int len,
        int err;
        struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf;
 
-       ubifs_assert(jhead != GCHD);
+       ubifs_assert(c, jhead != GCHD);
 
        *lnum = c->jheads[jhead].wbuf.lnum;
        *offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used;
@@ -317,6 +317,7 @@ again:
        down_read(&c->commit_sem);
        err = reserve_space(c, jhead, len);
        if (!err)
+               /* c->commit_sem will get released via finish_reservation(). */
                return 0;
        up_read(&c->commit_sem);
 
@@ -548,7 +549,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
        struct ubifs_ino_node *ino;
        union ubifs_key dent_key, ino_key;
 
-       ubifs_assert(mutex_is_locked(&host_ui->ui_mutex));
+       ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex));
 
        dlen = UBIFS_DENT_NODE_SZ + fname_len(nm) + 1;
        ilen = UBIFS_INO_NODE_SZ;
@@ -664,6 +665,11 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
        spin_lock(&ui->ui_lock);
        ui->synced_i_size = ui->ui_size;
        spin_unlock(&ui->ui_lock);
+       if (xent) {
+               spin_lock(&host_ui->ui_lock);
+               host_ui->synced_i_size = host_ui->ui_size;
+               spin_unlock(&host_ui->ui_lock);
+       }
        mark_inode_clean(c, ui);
        mark_inode_clean(c, host_ui);
        return 0;
@@ -707,7 +713,7 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,
 
        dbg_jnlk(key, "ino %lu, blk %u, len %d, key ",
                (unsigned long)key_inum(c, key), key_block(c, key), len);
-       ubifs_assert(len <= UBIFS_BLOCK_SIZE);
+       ubifs_assert(c, len <= UBIFS_BLOCK_SIZE);
 
        if (encrypted)
                dlen += UBIFS_CIPHER_BLOCK_SIZE;
@@ -738,7 +744,7 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,
 
        out_len = compr_len = dlen - UBIFS_DATA_NODE_SZ;
        ubifs_compress(c, buf, len, &data->data, &compr_len, &compr_type);
-       ubifs_assert(compr_len <= UBIFS_BLOCK_SIZE);
+       ubifs_assert(c, compr_len <= UBIFS_BLOCK_SIZE);
 
        if (encrypted) {
                err = ubifs_encrypt(inode, data, compr_len, &out_len, key_block(c, key));
@@ -898,7 +904,7 @@ int ubifs_jnl_delete_inode(struct ubifs_info *c, const struct inode *inode)
        int err;
        struct ubifs_inode *ui = ubifs_inode(inode);
 
-       ubifs_assert(inode->i_nlink == 0);
+       ubifs_assert(c, inode->i_nlink == 0);
 
        if (ui->del_cmtno != c->cmt_no)
                /* A commit happened for sure */
@@ -953,10 +959,10 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir,
        int twoparents = (fst_dir != snd_dir);
        void *p;
 
-       ubifs_assert(ubifs_inode(fst_dir)->data_len == 0);
-       ubifs_assert(ubifs_inode(snd_dir)->data_len == 0);
-       ubifs_assert(mutex_is_locked(&ubifs_inode(fst_dir)->ui_mutex));
-       ubifs_assert(mutex_is_locked(&ubifs_inode(snd_dir)->ui_mutex));
+       ubifs_assert(c, ubifs_inode(fst_dir)->data_len == 0);
+       ubifs_assert(c, ubifs_inode(snd_dir)->data_len == 0);
+       ubifs_assert(c, mutex_is_locked(&ubifs_inode(fst_dir)->ui_mutex));
+       ubifs_assert(c, mutex_is_locked(&ubifs_inode(snd_dir)->ui_mutex));
 
        dlen1 = UBIFS_DENT_NODE_SZ + fname_len(snd_nm) + 1;
        dlen2 = UBIFS_DENT_NODE_SZ + fname_len(fst_nm) + 1;
@@ -1096,16 +1102,16 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
        int move = (old_dir != new_dir);
        struct ubifs_inode *uninitialized_var(new_ui);
 
-       ubifs_assert(ubifs_inode(old_dir)->data_len == 0);
-       ubifs_assert(ubifs_inode(new_dir)->data_len == 0);
-       ubifs_assert(mutex_is_locked(&ubifs_inode(old_dir)->ui_mutex));
-       ubifs_assert(mutex_is_locked(&ubifs_inode(new_dir)->ui_mutex));
+       ubifs_assert(c, ubifs_inode(old_dir)->data_len == 0);
+       ubifs_assert(c, ubifs_inode(new_dir)->data_len == 0);
+       ubifs_assert(c, mutex_is_locked(&ubifs_inode(old_dir)->ui_mutex));
+       ubifs_assert(c, mutex_is_locked(&ubifs_inode(new_dir)->ui_mutex));
 
        dlen1 = UBIFS_DENT_NODE_SZ + fname_len(new_nm) + 1;
        dlen2 = UBIFS_DENT_NODE_SZ + fname_len(old_nm) + 1;
        if (new_inode) {
                new_ui = ubifs_inode(new_inode);
-               ubifs_assert(mutex_is_locked(&new_ui->ui_mutex));
+               ubifs_assert(c, mutex_is_locked(&new_ui->ui_mutex));
                ilen = UBIFS_INO_NODE_SZ;
                if (!last_reference)
                        ilen += new_ui->data_len;
@@ -1282,8 +1288,7 @@ static int truncate_data_node(const struct ubifs_info *c, const struct inode *in
                              int *new_len)
 {
        void *buf;
-       int err, compr_type;
-       u32 dlen, out_len, old_dlen;
+       int err, dlen, compr_type, out_len, old_dlen;
 
        out_len = le32_to_cpu(dn->size);
        buf = kmalloc_array(out_len, WORST_COMPR_FACTOR, GFP_NOFS);
@@ -1319,7 +1324,7 @@ static int truncate_data_node(const struct ubifs_info *c, const struct inode *in
                dn->compr_size = 0;
        }
 
-       ubifs_assert(out_len <= UBIFS_BLOCK_SIZE);
+       ubifs_assert(c, out_len <= UBIFS_BLOCK_SIZE);
        dn->compr_type = cpu_to_le16(compr_type);
        dn->size = cpu_to_le32(*new_len);
        *new_len = UBIFS_DATA_NODE_SZ + out_len;
@@ -1358,9 +1363,9 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode,
 
        dbg_jnl("ino %lu, size %lld -> %lld",
                (unsigned long)inum, old_size, new_size);
-       ubifs_assert(!ui->data_len);
-       ubifs_assert(S_ISREG(inode->i_mode));
-       ubifs_assert(mutex_is_locked(&ui->ui_mutex));
+       ubifs_assert(c, !ui->data_len);
+       ubifs_assert(c, S_ISREG(inode->i_mode));
+       ubifs_assert(c, mutex_is_locked(&ui->ui_mutex));
 
        sz = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ +
             UBIFS_MAX_DATA_NODE_SZ * WORST_COMPR_FACTOR;
@@ -1388,7 +1393,16 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode,
                else if (err)
                        goto out_free;
                else {
-                       if (le32_to_cpu(dn->size) <= dlen)
+                       int dn_len = le32_to_cpu(dn->size);
+
+                       if (dn_len <= 0 || dn_len > UBIFS_BLOCK_SIZE) {
+                               ubifs_err(c, "bad data node (block %u, inode %lu)",
+                                         blk, inode->i_ino);
+                               ubifs_dump_node(c, dn);
+                               goto out_free;
+                       }
+
+                       if (dn_len <= dlen)
                                dlen = 0; /* Nothing to do */
                        else {
                                err = truncate_data_node(c, inode, blk, dn, &dlen);
@@ -1488,8 +1502,8 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host,
        int sync = IS_DIRSYNC(host);
        struct ubifs_inode *host_ui = ubifs_inode(host);
 
-       ubifs_assert(inode->i_nlink == 0);
-       ubifs_assert(mutex_is_locked(&host_ui->ui_mutex));
+       ubifs_assert(c, inode->i_nlink == 0);
+       ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex));
 
        /*
         * Since we are deleting the inode, we do not bother to attach any data
@@ -1598,9 +1612,9 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode,
        int sync = IS_DIRSYNC(host);
 
        dbg_jnl("ino %lu, ino %lu", host->i_ino, inode->i_ino);
-       ubifs_assert(host->i_nlink > 0);
-       ubifs_assert(inode->i_nlink > 0);
-       ubifs_assert(mutex_is_locked(&host_ui->ui_mutex));
+       ubifs_assert(c, host->i_nlink > 0);
+       ubifs_assert(c, inode->i_nlink > 0);
+       ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex));
 
        len1 = UBIFS_INO_NODE_SZ + host_ui->data_len;
        len2 = UBIFS_INO_NODE_SZ + ubifs_inode(inode)->data_len;
index b1f7c0caa3acb60f53409d306da192b21b253e49..2feff6cbbb773a4581a1994be725da15485cc6d0 100644 (file)
@@ -161,8 +161,8 @@ static inline void dent_key_init(const struct ubifs_info *c,
 {
        uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
 
-       ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
-       ubifs_assert(!nm->hash && !nm->minor_hash);
+       ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK));
+       ubifs_assert(c, !nm->hash && !nm->minor_hash);
        key->u32[0] = inum;
        key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS);
 }
@@ -179,7 +179,7 @@ static inline void dent_key_init_hash(const struct ubifs_info *c,
                                      union ubifs_key *key, ino_t inum,
                                      uint32_t hash)
 {
-       ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
+       ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK));
        key->u32[0] = inum;
        key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS);
 }
@@ -198,7 +198,7 @@ static inline void dent_key_init_flash(const struct ubifs_info *c, void *k,
        union ubifs_key *key = k;
        uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
 
-       ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
+       ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK));
        key->j32[0] = cpu_to_le32(inum);
        key->j32[1] = cpu_to_le32(hash |
                                  (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS));
@@ -231,7 +231,7 @@ static inline void xent_key_init(const struct ubifs_info *c,
 {
        uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
 
-       ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
+       ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK));
        key->u32[0] = inum;
        key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS);
 }
@@ -249,7 +249,7 @@ static inline void xent_key_init_flash(const struct ubifs_info *c, void *k,
        union ubifs_key *key = k;
        uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
 
-       ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
+       ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK));
        key->j32[0] = cpu_to_le32(inum);
        key->j32[1] = cpu_to_le32(hash |
                                  (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS));
@@ -280,7 +280,7 @@ static inline void data_key_init(const struct ubifs_info *c,
                                 union ubifs_key *key, ino_t inum,
                                 unsigned int block)
 {
-       ubifs_assert(!(block & ~UBIFS_S_KEY_BLOCK_MASK));
+       ubifs_assert(c, !(block & ~UBIFS_S_KEY_BLOCK_MASK));
        key->u32[0] = inum;
        key->u32[1] = block | (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS);
 }
index 7cffa120a750995a30f0c4ced105a02761d5a234..86b0828f54991d680bb9e2db72632165673ad3e0 100644 (file)
@@ -132,7 +132,7 @@ void ubifs_add_bud(struct ubifs_info *c, struct ubifs_bud *bud)
        while (*p) {
                parent = *p;
                b = rb_entry(parent, struct ubifs_bud, rb);
-               ubifs_assert(bud->lnum != b->lnum);
+               ubifs_assert(c, bud->lnum != b->lnum);
                if (bud->lnum < b->lnum)
                        p = &(*p)->rb_left;
                else
@@ -145,7 +145,7 @@ void ubifs_add_bud(struct ubifs_info *c, struct ubifs_bud *bud)
                jhead = &c->jheads[bud->jhead];
                list_add_tail(&bud->list, &jhead->buds_list);
        } else
-               ubifs_assert(c->replaying && c->ro_mount);
+               ubifs_assert(c, c->replaying && c->ro_mount);
 
        /*
         * Note, although this is a new bud, we anyway account this space now,
@@ -189,7 +189,7 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)
        }
 
        mutex_lock(&c->log_mutex);
-       ubifs_assert(!c->ro_media && !c->ro_mount);
+       ubifs_assert(c, !c->ro_media && !c->ro_mount);
        if (c->ro_error) {
                err = -EROFS;
                goto out_unlock;
@@ -244,7 +244,7 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)
 
        if (c->lhead_offs > c->leb_size - c->ref_node_alsz) {
                c->lhead_lnum = ubifs_next_log_lnum(c, c->lhead_lnum);
-               ubifs_assert(c->lhead_lnum != c->ltail_lnum);
+               ubifs_assert(c, c->lhead_lnum != c->ltail_lnum);
                c->lhead_offs = 0;
        }
 
@@ -301,7 +301,7 @@ static void remove_buds(struct ubifs_info *c)
 {
        struct rb_node *p;
 
-       ubifs_assert(list_empty(&c->old_buds));
+       ubifs_assert(c, list_empty(&c->old_buds));
        c->cmt_bud_bytes = 0;
        spin_lock(&c->buds_lock);
        p = rb_first(&c->buds);
@@ -409,7 +409,7 @@ int ubifs_log_start_commit(struct ubifs_info *c, int *ltail_lnum)
        /* Switch to the next log LEB */
        if (c->lhead_offs) {
                c->lhead_lnum = ubifs_next_log_lnum(c, c->lhead_lnum);
-               ubifs_assert(c->lhead_lnum != c->ltail_lnum);
+               ubifs_assert(c, c->lhead_lnum != c->ltail_lnum);
                c->lhead_offs = 0;
        }
 
index f5a46844340c0a6e8bde656f2ea48cc513d6900d..fa8d775c9753868fca2dbac32a3cca3b9c217807 100644 (file)
@@ -187,9 +187,9 @@ static int add_to_lpt_heap(struct ubifs_info *c, struct ubifs_lprops *lprops,
                /* Compare to some other LEB on the bottom of heap */
                /* Pick a position kind of randomly */
                cpos = (((size_t)lprops >> 4) & b) + b;
-               ubifs_assert(cpos >= b);
-               ubifs_assert(cpos < LPT_HEAP_SZ);
-               ubifs_assert(cpos < heap->cnt);
+               ubifs_assert(c, cpos >= b);
+               ubifs_assert(c, cpos < LPT_HEAP_SZ);
+               ubifs_assert(c, cpos < heap->cnt);
 
                val1 = get_heap_comp_val(lprops, cat);
                val2 = get_heap_comp_val(heap->arr[cpos], cat);
@@ -230,8 +230,8 @@ static void remove_from_lpt_heap(struct ubifs_info *c,
        int hpos = lprops->hpos;
 
        heap = &c->lpt_heap[cat - 1];
-       ubifs_assert(hpos >= 0 && hpos < heap->cnt);
-       ubifs_assert(heap->arr[hpos] == lprops);
+       ubifs_assert(c, hpos >= 0 && hpos < heap->cnt);
+       ubifs_assert(c, heap->arr[hpos] == lprops);
        heap->cnt -= 1;
        if (hpos < heap->cnt) {
                heap->arr[hpos] = heap->arr[heap->cnt];
@@ -296,13 +296,13 @@ void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops,
                list_add(&lprops->list, &c->frdi_idx_list);
                break;
        default:
-               ubifs_assert(0);
+               ubifs_assert(c, 0);
        }
 
        lprops->flags &= ~LPROPS_CAT_MASK;
        lprops->flags |= cat;
        c->in_a_category_cnt += 1;
-       ubifs_assert(c->in_a_category_cnt <= c->main_lebs);
+       ubifs_assert(c, c->in_a_category_cnt <= c->main_lebs);
 }
 
 /**
@@ -324,20 +324,20 @@ static void ubifs_remove_from_cat(struct ubifs_info *c,
                break;
        case LPROPS_FREEABLE:
                c->freeable_cnt -= 1;
-               ubifs_assert(c->freeable_cnt >= 0);
+               ubifs_assert(c, c->freeable_cnt >= 0);
                /* Fall through */
        case LPROPS_UNCAT:
        case LPROPS_EMPTY:
        case LPROPS_FRDI_IDX:
-               ubifs_assert(!list_empty(&lprops->list));
+               ubifs_assert(c, !list_empty(&lprops->list));
                list_del(&lprops->list);
                break;
        default:
-               ubifs_assert(0);
+               ubifs_assert(c, 0);
        }
 
        c->in_a_category_cnt -= 1;
-       ubifs_assert(c->in_a_category_cnt >= 0);
+       ubifs_assert(c, c->in_a_category_cnt >= 0);
 }
 
 /**
@@ -369,7 +369,7 @@ void ubifs_replace_cat(struct ubifs_info *c, struct ubifs_lprops *old_lprops,
                list_replace(&old_lprops->list, &new_lprops->list);
                break;
        default:
-               ubifs_assert(0);
+               ubifs_assert(c, 0);
        }
 }
 
@@ -412,7 +412,7 @@ int ubifs_categorize_lprops(const struct ubifs_info *c,
                return LPROPS_UNCAT;
 
        if (lprops->free == c->leb_size) {
-               ubifs_assert(!(lprops->flags & LPROPS_INDEX));
+               ubifs_assert(c, !(lprops->flags & LPROPS_INDEX));
                return LPROPS_EMPTY;
        }
 
@@ -478,7 +478,7 @@ static void change_category(struct ubifs_info *c, struct ubifs_lprops *lprops)
  */
 int ubifs_calc_dark(const struct ubifs_info *c, int spc)
 {
-       ubifs_assert(!(spc & 7));
+       ubifs_assert(c, !(spc & 7));
 
        if (spc < c->dark_wm)
                return spc;
@@ -543,27 +543,27 @@ const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c,
        dbg_lp("LEB %d, free %d, dirty %d, flags %d",
               lprops->lnum, free, dirty, flags);
 
-       ubifs_assert(mutex_is_locked(&c->lp_mutex));
-       ubifs_assert(c->lst.empty_lebs >= 0 &&
+       ubifs_assert(c, mutex_is_locked(&c->lp_mutex));
+       ubifs_assert(c, c->lst.empty_lebs >= 0 &&
                     c->lst.empty_lebs <= c->main_lebs);
-       ubifs_assert(c->freeable_cnt >= 0);
-       ubifs_assert(c->freeable_cnt <= c->main_lebs);
-       ubifs_assert(c->lst.taken_empty_lebs >= 0);
-       ubifs_assert(c->lst.taken_empty_lebs <= c->lst.empty_lebs);
-       ubifs_assert(!(c->lst.total_free & 7) && !(c->lst.total_dirty & 7));
-       ubifs_assert(!(c->lst.total_dead & 7) && !(c->lst.total_dark & 7));
-       ubifs_assert(!(c->lst.total_used & 7));
-       ubifs_assert(free == LPROPS_NC || free >= 0);
-       ubifs_assert(dirty == LPROPS_NC || dirty >= 0);
+       ubifs_assert(c, c->freeable_cnt >= 0);
+       ubifs_assert(c, c->freeable_cnt <= c->main_lebs);
+       ubifs_assert(c, c->lst.taken_empty_lebs >= 0);
+       ubifs_assert(c, c->lst.taken_empty_lebs <= c->lst.empty_lebs);
+       ubifs_assert(c, !(c->lst.total_free & 7) && !(c->lst.total_dirty & 7));
+       ubifs_assert(c, !(c->lst.total_dead & 7) && !(c->lst.total_dark & 7));
+       ubifs_assert(c, !(c->lst.total_used & 7));
+       ubifs_assert(c, free == LPROPS_NC || free >= 0);
+       ubifs_assert(c, dirty == LPROPS_NC || dirty >= 0);
 
        if (!is_lprops_dirty(c, lprops)) {
                lprops = ubifs_lpt_lookup_dirty(c, lprops->lnum);
                if (IS_ERR(lprops))
                        return lprops;
        } else
-               ubifs_assert(lprops == ubifs_lpt_lookup_dirty(c, lprops->lnum));
+               ubifs_assert(c, lprops == ubifs_lpt_lookup_dirty(c, lprops->lnum));
 
-       ubifs_assert(!(lprops->free & 7) && !(lprops->dirty & 7));
+       ubifs_assert(c, !(lprops->free & 7) && !(lprops->dirty & 7));
 
        spin_lock(&c->space_lock);
        if ((lprops->flags & LPROPS_TAKEN) && lprops->free == c->leb_size)
@@ -768,15 +768,15 @@ const struct ubifs_lprops *ubifs_fast_find_free(struct ubifs_info *c)
        struct ubifs_lprops *lprops;
        struct ubifs_lpt_heap *heap;
 
-       ubifs_assert(mutex_is_locked(&c->lp_mutex));
+       ubifs_assert(c, mutex_is_locked(&c->lp_mutex));
 
        heap = &c->lpt_heap[LPROPS_FREE - 1];
        if (heap->cnt == 0)
                return NULL;
 
        lprops = heap->arr[0];
-       ubifs_assert(!(lprops->flags & LPROPS_TAKEN));
-       ubifs_assert(!(lprops->flags & LPROPS_INDEX));
+       ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
+       ubifs_assert(c, !(lprops->flags & LPROPS_INDEX));
        return lprops;
 }
 
@@ -791,15 +791,15 @@ const struct ubifs_lprops *ubifs_fast_find_empty(struct ubifs_info *c)
 {
        struct ubifs_lprops *lprops;
 
-       ubifs_assert(mutex_is_locked(&c->lp_mutex));
+       ubifs_assert(c, mutex_is_locked(&c->lp_mutex));
 
        if (list_empty(&c->empty_list))
                return NULL;
 
        lprops = list_entry(c->empty_list.next, struct ubifs_lprops, list);
-       ubifs_assert(!(lprops->flags & LPROPS_TAKEN));
-       ubifs_assert(!(lprops->flags & LPROPS_INDEX));
-       ubifs_assert(lprops->free == c->leb_size);
+       ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
+       ubifs_assert(c, !(lprops->flags & LPROPS_INDEX));
+       ubifs_assert(c, lprops->free == c->leb_size);
        return lprops;
 }
 
@@ -814,16 +814,16 @@ const struct ubifs_lprops *ubifs_fast_find_freeable(struct ubifs_info *c)
 {
        struct ubifs_lprops *lprops;
 
-       ubifs_assert(mutex_is_locked(&c->lp_mutex));
+       ubifs_assert(c, mutex_is_locked(&c->lp_mutex));
 
        if (list_empty(&c->freeable_list))
                return NULL;
 
        lprops = list_entry(c->freeable_list.next, struct ubifs_lprops, list);
-       ubifs_assert(!(lprops->flags & LPROPS_TAKEN));
-       ubifs_assert(!(lprops->flags & LPROPS_INDEX));
-       ubifs_assert(lprops->free + lprops->dirty == c->leb_size);
-       ubifs_assert(c->freeable_cnt > 0);
+       ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
+       ubifs_assert(c, !(lprops->flags & LPROPS_INDEX));
+       ubifs_assert(c, lprops->free + lprops->dirty == c->leb_size);
+       ubifs_assert(c, c->freeable_cnt > 0);
        return lprops;
 }
 
@@ -838,15 +838,15 @@ const struct ubifs_lprops *ubifs_fast_find_frdi_idx(struct ubifs_info *c)
 {
        struct ubifs_lprops *lprops;
 
-       ubifs_assert(mutex_is_locked(&c->lp_mutex));
+       ubifs_assert(c, mutex_is_locked(&c->lp_mutex));
 
        if (list_empty(&c->frdi_idx_list))
                return NULL;
 
        lprops = list_entry(c->frdi_idx_list.next, struct ubifs_lprops, list);
-       ubifs_assert(!(lprops->flags & LPROPS_TAKEN));
-       ubifs_assert((lprops->flags & LPROPS_INDEX));
-       ubifs_assert(lprops->free + lprops->dirty == c->leb_size);
+       ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
+       ubifs_assert(c, (lprops->flags & LPROPS_INDEX));
+       ubifs_assert(c, lprops->free + lprops->dirty == c->leb_size);
        return lprops;
 }
 
@@ -1089,10 +1089,6 @@ static int scan_check_cb(struct ubifs_info *c,
                }
        }
 
-       buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
-       if (!buf)
-               return -ENOMEM;
-
        /*
         * After an unclean unmount, empty and freeable LEBs
         * may contain garbage - do not scan them.
@@ -1111,6 +1107,10 @@ static int scan_check_cb(struct ubifs_info *c,
                return LPT_SCAN_CONTINUE;
        }
 
+       buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
        sleb = ubifs_scan(c, lnum, 0, buf, 0);
        if (IS_ERR(sleb)) {
                ret = PTR_ERR(sleb);
index 8e99dad1888009f764d49ffc359be3a3b23578a3..31393370e334826c182a2ea159df1caa435af158 100644 (file)
@@ -225,21 +225,22 @@ static int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs,
 
 /**
  * pack_bits - pack bit fields end-to-end.
+ * @c: UBIFS file-system description object
  * @addr: address at which to pack (passed and next address returned)
  * @pos: bit position at which to pack (passed and next position returned)
  * @val: value to pack
  * @nrbits: number of bits of value to pack (1-32)
  */
-static void pack_bits(uint8_t **addr, int *pos, uint32_t val, int nrbits)
+static void pack_bits(const struct ubifs_info *c, uint8_t **addr, int *pos, uint32_t val, int nrbits)
 {
        uint8_t *p = *addr;
        int b = *pos;
 
-       ubifs_assert(nrbits > 0);
-       ubifs_assert(nrbits <= 32);
-       ubifs_assert(*pos >= 0);
-       ubifs_assert(*pos < 8);
-       ubifs_assert((val >> nrbits) == 0 || nrbits == 32);
+       ubifs_assert(c, nrbits > 0);
+       ubifs_assert(c, nrbits <= 32);
+       ubifs_assert(c, *pos >= 0);
+       ubifs_assert(c, *pos < 8);
+       ubifs_assert(c, (val >> nrbits) == 0 || nrbits == 32);
        if (b) {
                *p |= ((uint8_t)val) << b;
                nrbits += b;
@@ -274,13 +275,14 @@ static void pack_bits(uint8_t **addr, int *pos, uint32_t val, int nrbits)
 
 /**
  * ubifs_unpack_bits - unpack bit fields.
+ * @c: UBIFS file-system description object
  * @addr: address at which to unpack (passed and next address returned)
  * @pos: bit position at which to unpack (passed and next position returned)
  * @nrbits: number of bits of value to unpack (1-32)
  *
  * This functions returns the value unpacked.
  */
-uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits)
+uint32_t ubifs_unpack_bits(const struct ubifs_info *c, uint8_t **addr, int *pos, int nrbits)
 {
        const int k = 32 - nrbits;
        uint8_t *p = *addr;
@@ -288,10 +290,10 @@ uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits)
        uint32_t uninitialized_var(val);
        const int bytes = (nrbits + b + 7) >> 3;
 
-       ubifs_assert(nrbits > 0);
-       ubifs_assert(nrbits <= 32);
-       ubifs_assert(*pos >= 0);
-       ubifs_assert(*pos < 8);
+       ubifs_assert(c, nrbits > 0);
+       ubifs_assert(c, nrbits <= 32);
+       ubifs_assert(c, *pos >= 0);
+       ubifs_assert(c, *pos < 8);
        if (b) {
                switch (bytes) {
                case 2:
@@ -337,7 +339,7 @@ uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits)
        p += nrbits >> 3;
        *addr = p;
        *pos = b;
-       ubifs_assert((val >> nrbits) == 0 || nrbits - b == 32);
+       ubifs_assert(c, (val >> nrbits) == 0 || nrbits - b == 32);
        return val;
 }
 
@@ -354,24 +356,24 @@ void ubifs_pack_pnode(struct ubifs_info *c, void *buf,
        int i, pos = 0;
        uint16_t crc;
 
-       pack_bits(&addr, &pos, UBIFS_LPT_PNODE, UBIFS_LPT_TYPE_BITS);
+       pack_bits(c, &addr, &pos, UBIFS_LPT_PNODE, UBIFS_LPT_TYPE_BITS);
        if (c->big_lpt)
-               pack_bits(&addr, &pos, pnode->num, c->pcnt_bits);
+               pack_bits(c, &addr, &pos, pnode->num, c->pcnt_bits);
        for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
-               pack_bits(&addr, &pos, pnode->lprops[i].free >> 3,
+               pack_bits(c, &addr, &pos, pnode->lprops[i].free >> 3,
                          c->space_bits);
-               pack_bits(&addr, &pos, pnode->lprops[i].dirty >> 3,
+               pack_bits(c, &addr, &pos, pnode->lprops[i].dirty >> 3,
                          c->space_bits);
                if (pnode->lprops[i].flags & LPROPS_INDEX)
-                       pack_bits(&addr, &pos, 1, 1);
+                       pack_bits(c, &addr, &pos, 1, 1);
                else
-                       pack_bits(&addr, &pos, 0, 1);
+                       pack_bits(c, &addr, &pos, 0, 1);
        }
        crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
                    c->pnode_sz - UBIFS_LPT_CRC_BYTES);
        addr = buf;
        pos = 0;
-       pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS);
+       pack_bits(c, &addr, &pos, crc, UBIFS_LPT_CRC_BITS);
 }
 
 /**
@@ -387,23 +389,23 @@ void ubifs_pack_nnode(struct ubifs_info *c, void *buf,
        int i, pos = 0;
        uint16_t crc;
 
-       pack_bits(&addr, &pos, UBIFS_LPT_NNODE, UBIFS_LPT_TYPE_BITS);
+       pack_bits(c, &addr, &pos, UBIFS_LPT_NNODE, UBIFS_LPT_TYPE_BITS);
        if (c->big_lpt)
-               pack_bits(&addr, &pos, nnode->num, c->pcnt_bits);
+               pack_bits(c, &addr, &pos, nnode->num, c->pcnt_bits);
        for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
                int lnum = nnode->nbranch[i].lnum;
 
                if (lnum == 0)
                        lnum = c->lpt_last + 1;
-               pack_bits(&addr, &pos, lnum - c->lpt_first, c->lpt_lnum_bits);
-               pack_bits(&addr, &pos, nnode->nbranch[i].offs,
+               pack_bits(c, &addr, &pos, lnum - c->lpt_first, c->lpt_lnum_bits);
+               pack_bits(c, &addr, &pos, nnode->nbranch[i].offs,
                          c->lpt_offs_bits);
        }
        crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
                    c->nnode_sz - UBIFS_LPT_CRC_BYTES);
        addr = buf;
        pos = 0;
-       pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS);
+       pack_bits(c, &addr, &pos, crc, UBIFS_LPT_CRC_BITS);
 }
 
 /**
@@ -419,16 +421,16 @@ void ubifs_pack_ltab(struct ubifs_info *c, void *buf,
        int i, pos = 0;
        uint16_t crc;
 
-       pack_bits(&addr, &pos, UBIFS_LPT_LTAB, UBIFS_LPT_TYPE_BITS);
+       pack_bits(c, &addr, &pos, UBIFS_LPT_LTAB, UBIFS_LPT_TYPE_BITS);
        for (i = 0; i < c->lpt_lebs; i++) {
-               pack_bits(&addr, &pos, ltab[i].free, c->lpt_spc_bits);
-               pack_bits(&addr, &pos, ltab[i].dirty, c->lpt_spc_bits);
+               pack_bits(c, &addr, &pos, ltab[i].free, c->lpt_spc_bits);
+               pack_bits(c, &addr, &pos, ltab[i].dirty, c->lpt_spc_bits);
        }
        crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
                    c->ltab_sz - UBIFS_LPT_CRC_BYTES);
        addr = buf;
        pos = 0;
-       pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS);
+       pack_bits(c, &addr, &pos, crc, UBIFS_LPT_CRC_BITS);
 }
 
 /**
@@ -443,14 +445,14 @@ void ubifs_pack_lsave(struct ubifs_info *c, void *buf, int *lsave)
        int i, pos = 0;
        uint16_t crc;
 
-       pack_bits(&addr, &pos, UBIFS_LPT_LSAVE, UBIFS_LPT_TYPE_BITS);
+       pack_bits(c, &addr, &pos, UBIFS_LPT_LSAVE, UBIFS_LPT_TYPE_BITS);
        for (i = 0; i < c->lsave_cnt; i++)
-               pack_bits(&addr, &pos, lsave[i], c->lnum_bits);
+               pack_bits(c, &addr, &pos, lsave[i], c->lnum_bits);
        crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
                    c->lsave_sz - UBIFS_LPT_CRC_BYTES);
        addr = buf;
        pos = 0;
-       pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS);
+       pack_bits(c, &addr, &pos, crc, UBIFS_LPT_CRC_BITS);
 }
 
 /**
@@ -465,7 +467,7 @@ void ubifs_add_lpt_dirt(struct ubifs_info *c, int lnum, int dirty)
                return;
        dbg_lp("LEB %d add %d to %d",
               lnum, dirty, c->ltab[lnum - c->lpt_first].dirty);
-       ubifs_assert(lnum >= c->lpt_first && lnum <= c->lpt_last);
+       ubifs_assert(c, lnum >= c->lpt_first && lnum <= c->lpt_last);
        c->ltab[lnum - c->lpt_first].dirty += dirty;
 }
 
@@ -481,7 +483,7 @@ static void set_ltab(struct ubifs_info *c, int lnum, int free, int dirty)
        dbg_lp("LEB %d free %d dirty %d to %d %d",
               lnum, c->ltab[lnum - c->lpt_first].free,
               c->ltab[lnum - c->lpt_first].dirty, free, dirty);
-       ubifs_assert(lnum >= c->lpt_first && lnum <= c->lpt_last);
+       ubifs_assert(c, lnum >= c->lpt_first && lnum <= c->lpt_last);
        c->ltab[lnum - c->lpt_first].free = free;
        c->ltab[lnum - c->lpt_first].dirty = dirty;
 }
@@ -639,7 +641,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
                goto out;
        }
 
-       ubifs_assert(!c->ltab);
+       ubifs_assert(c, !c->ltab);
        c->ltab = ltab; /* Needed by set_ltab */
 
        /* Initialize LPT's own lprops */
@@ -918,7 +920,7 @@ static int check_lpt_crc(const struct ubifs_info *c, void *buf, int len)
        uint8_t *addr = buf;
        uint16_t crc, calc_crc;
 
-       crc = ubifs_unpack_bits(&addr, &pos, UBIFS_LPT_CRC_BITS);
+       crc = ubifs_unpack_bits(c, &addr, &pos, UBIFS_LPT_CRC_BITS);
        calc_crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
                         len - UBIFS_LPT_CRC_BYTES);
        if (crc != calc_crc) {
@@ -944,7 +946,7 @@ static int check_lpt_type(const struct ubifs_info *c, uint8_t **addr,
 {
        int node_type;
 
-       node_type = ubifs_unpack_bits(addr, pos, UBIFS_LPT_TYPE_BITS);
+       node_type = ubifs_unpack_bits(c, addr, pos, UBIFS_LPT_TYPE_BITS);
        if (node_type != type) {
                ubifs_err(c, "invalid type (%d) in LPT node type %d",
                          node_type, type);
@@ -972,16 +974,16 @@ static int unpack_pnode(const struct ubifs_info *c, void *buf,
        if (err)
                return err;
        if (c->big_lpt)
-               pnode->num = ubifs_unpack_bits(&addr, &pos, c->pcnt_bits);
+               pnode->num = ubifs_unpack_bits(c, &addr, &pos, c->pcnt_bits);
        for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
                struct ubifs_lprops * const lprops = &pnode->lprops[i];
 
-               lprops->free = ubifs_unpack_bits(&addr, &pos, c->space_bits);
+               lprops->free = ubifs_unpack_bits(c, &addr, &pos, c->space_bits);
                lprops->free <<= 3;
-               lprops->dirty = ubifs_unpack_bits(&addr, &pos, c->space_bits);
+               lprops->dirty = ubifs_unpack_bits(c, &addr, &pos, c->space_bits);
                lprops->dirty <<= 3;
 
-               if (ubifs_unpack_bits(&addr, &pos, 1))
+               if (ubifs_unpack_bits(c, &addr, &pos, 1))
                        lprops->flags = LPROPS_INDEX;
                else
                        lprops->flags = 0;
@@ -1009,16 +1011,16 @@ int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf,
        if (err)
                return err;
        if (c->big_lpt)
-               nnode->num = ubifs_unpack_bits(&addr, &pos, c->pcnt_bits);
+               nnode->num = ubifs_unpack_bits(c, &addr, &pos, c->pcnt_bits);
        for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
                int lnum;
 
-               lnum = ubifs_unpack_bits(&addr, &pos, c->lpt_lnum_bits) +
+               lnum = ubifs_unpack_bits(c, &addr, &pos, c->lpt_lnum_bits) +
                       c->lpt_first;
                if (lnum == c->lpt_last + 1)
                        lnum = 0;
                nnode->nbranch[i].lnum = lnum;
-               nnode->nbranch[i].offs = ubifs_unpack_bits(&addr, &pos,
+               nnode->nbranch[i].offs = ubifs_unpack_bits(c, &addr, &pos,
                                                     c->lpt_offs_bits);
        }
        err = check_lpt_crc(c, buf, c->nnode_sz);
@@ -1041,8 +1043,8 @@ static int unpack_ltab(const struct ubifs_info *c, void *buf)
        if (err)
                return err;
        for (i = 0; i < c->lpt_lebs; i++) {
-               int free = ubifs_unpack_bits(&addr, &pos, c->lpt_spc_bits);
-               int dirty = ubifs_unpack_bits(&addr, &pos, c->lpt_spc_bits);
+               int free = ubifs_unpack_bits(c, &addr, &pos, c->lpt_spc_bits);
+               int dirty = ubifs_unpack_bits(c, &addr, &pos, c->lpt_spc_bits);
 
                if (free < 0 || free > c->leb_size || dirty < 0 ||
                    dirty > c->leb_size || free + dirty > c->leb_size)
@@ -1073,7 +1075,7 @@ static int unpack_lsave(const struct ubifs_info *c, void *buf)
        if (err)
                return err;
        for (i = 0; i < c->lsave_cnt; i++) {
-               int lnum = ubifs_unpack_bits(&addr, &pos, c->lnum_bits);
+               int lnum = ubifs_unpack_bits(c, &addr, &pos, c->lnum_bits);
 
                if (lnum < c->main_first || lnum >= c->leb_cnt)
                        return -EINVAL;
@@ -1515,7 +1517,7 @@ static struct ubifs_nnode *dirty_cow_nnode(struct ubifs_info *c,
                        branch->cnode->parent = n;
        }
 
-       ubifs_assert(!test_bit(OBSOLETE_CNODE, &nnode->flags));
+       ubifs_assert(c, !test_bit(OBSOLETE_CNODE, &nnode->flags));
        __set_bit(OBSOLETE_CNODE, &nnode->flags);
 
        c->dirty_nn_cnt += 1;
@@ -1558,7 +1560,7 @@ static struct ubifs_pnode *dirty_cow_pnode(struct ubifs_info *c,
        __clear_bit(COW_CNODE, &p->flags);
        replace_cats(c, pnode, p);
 
-       ubifs_assert(!test_bit(OBSOLETE_CNODE, &pnode->flags));
+       ubifs_assert(c, !test_bit(OBSOLETE_CNODE, &pnode->flags));
        __set_bit(OBSOLETE_CNODE, &pnode->flags);
 
        c->dirty_pn_cnt += 1;
@@ -1613,7 +1615,7 @@ struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum)
        dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum,
               pnode->lprops[iip].free, pnode->lprops[iip].dirty,
               pnode->lprops[iip].flags);
-       ubifs_assert(test_bit(DIRTY_CNODE, &pnode->flags));
+       ubifs_assert(c, test_bit(DIRTY_CNODE, &pnode->flags));
        return &pnode->lprops[iip];
 }
 
@@ -1889,9 +1891,9 @@ static struct ubifs_pnode *scan_get_pnode(struct ubifs_info *c,
                        lprops->flags = ubifs_categorize_lprops(c, lprops);
                }
        } else {
-               ubifs_assert(branch->lnum >= c->lpt_first &&
+               ubifs_assert(c, branch->lnum >= c->lpt_first &&
                             branch->lnum <= c->lpt_last);
-               ubifs_assert(branch->offs >= 0 && branch->offs < c->leb_size);
+               ubifs_assert(c, branch->offs >= 0 && branch->offs < c->leb_size);
                err = ubifs_leb_read(c, branch->lnum, buf, branch->offs,
                                     c->pnode_sz, 1);
                if (err)
@@ -1935,8 +1937,8 @@ int ubifs_lpt_scan_nolock(struct ubifs_info *c, int start_lnum, int end_lnum,
                        start_lnum = c->main_first;
        }
 
-       ubifs_assert(start_lnum >= c->main_first && start_lnum < c->leb_cnt);
-       ubifs_assert(end_lnum >= c->main_first && end_lnum < c->leb_cnt);
+       ubifs_assert(c, start_lnum >= c->main_first && start_lnum < c->leb_cnt);
+       ubifs_assert(c, end_lnum >= c->main_first && end_lnum < c->leb_cnt);
 
        if (!c->nroot) {
                err = ubifs_read_nnode(c, NULL, 0);
@@ -2055,7 +2057,7 @@ again:
                iip = pnode->iip;
                while (1) {
                        h -= 1;
-                       ubifs_assert(h >= 0);
+                       ubifs_assert(c, h >= 0);
                        nnode = path[h].ptr.nnode;
                        if (iip + 1 < UBIFS_LPT_FANOUT)
                                break;
@@ -2234,7 +2236,7 @@ int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode,
                return 0;
 
        while (cnode) {
-               ubifs_assert(row >= 0);
+               ubifs_assert(c, row >= 0);
                nnode = cnode->parent;
                if (cnode->level) {
                        /* cnode is a nnode */
index 78da65b2fb85066b7c36f8ba400e47d0c8d58309..7ce30994bbbac726c30a16262cbfd4411243026e 100644 (file)
@@ -34,13 +34,14 @@ static int dbg_populate_lsave(struct ubifs_info *c);
 
 /**
  * first_dirty_cnode - find first dirty cnode.
+ * @c: UBIFS file-system description object
  * @nnode: nnode at which to start
  *
  * This function returns the first dirty cnode or %NULL if there is not one.
  */
-static struct ubifs_cnode *first_dirty_cnode(struct ubifs_nnode *nnode)
+static struct ubifs_cnode *first_dirty_cnode(const struct ubifs_info *c, struct ubifs_nnode *nnode)
 {
-       ubifs_assert(nnode);
+       ubifs_assert(c, nnode);
        while (1) {
                int i, cont = 0;
 
@@ -64,16 +65,17 @@ static struct ubifs_cnode *first_dirty_cnode(struct ubifs_nnode *nnode)
 
 /**
  * next_dirty_cnode - find next dirty cnode.
+ * @c: UBIFS file-system description object
  * @cnode: cnode from which to begin searching
  *
  * This function returns the next dirty cnode or %NULL if there is not one.
  */
-static struct ubifs_cnode *next_dirty_cnode(struct ubifs_cnode *cnode)
+static struct ubifs_cnode *next_dirty_cnode(const struct ubifs_info *c, struct ubifs_cnode *cnode)
 {
        struct ubifs_nnode *nnode;
        int i;
 
-       ubifs_assert(cnode);
+       ubifs_assert(c, cnode);
        nnode = cnode->parent;
        if (!nnode)
                return NULL;
@@ -83,7 +85,7 @@ static struct ubifs_cnode *next_dirty_cnode(struct ubifs_cnode *cnode)
                        if (cnode->level == 0)
                                return cnode; /* cnode is a pnode */
                        /* cnode is a nnode */
-                       return first_dirty_cnode((struct ubifs_nnode *)cnode);
+                       return first_dirty_cnode(c, (struct ubifs_nnode *)cnode);
                }
        }
        return (struct ubifs_cnode *)nnode;
@@ -106,15 +108,15 @@ static int get_cnodes_to_commit(struct ubifs_info *c)
        if (!test_bit(DIRTY_CNODE, &c->nroot->flags))
                return 0;
 
-       c->lpt_cnext = first_dirty_cnode(c->nroot);
+       c->lpt_cnext = first_dirty_cnode(c, c->nroot);
        cnode = c->lpt_cnext;
        if (!cnode)
                return 0;
        cnt += 1;
        while (1) {
-               ubifs_assert(!test_bit(COW_CNODE, &cnode->flags));
+               ubifs_assert(c, !test_bit(COW_CNODE, &cnode->flags));
                __set_bit(COW_CNODE, &cnode->flags);
-               cnext = next_dirty_cnode(cnode);
+               cnext = next_dirty_cnode(c, cnode);
                if (!cnext) {
                        cnode->cnext = c->lpt_cnext;
                        break;
@@ -125,7 +127,7 @@ static int get_cnodes_to_commit(struct ubifs_info *c)
        }
        dbg_cmt("committing %d cnodes", cnt);
        dbg_lp("committing %d cnodes", cnt);
-       ubifs_assert(cnt == c->dirty_nn_cnt + c->dirty_pn_cnt);
+       ubifs_assert(c, cnt == c->dirty_nn_cnt + c->dirty_pn_cnt);
        return cnt;
 }
 
@@ -141,7 +143,7 @@ static void upd_ltab(struct ubifs_info *c, int lnum, int free, int dirty)
        dbg_lp("LEB %d free %d dirty %d to %d +%d",
               lnum, c->ltab[lnum - c->lpt_first].free,
               c->ltab[lnum - c->lpt_first].dirty, free, dirty);
-       ubifs_assert(lnum >= c->lpt_first && lnum <= c->lpt_last);
+       ubifs_assert(c, lnum >= c->lpt_first && lnum <= c->lpt_last);
        c->ltab[lnum - c->lpt_first].free = free;
        c->ltab[lnum - c->lpt_first].dirty += dirty;
 }
@@ -237,7 +239,7 @@ static int layout_cnodes(struct ubifs_info *c)
                        if (err)
                                goto no_space;
                        offs = 0;
-                       ubifs_assert(lnum >= c->lpt_first &&
+                       ubifs_assert(c, lnum >= c->lpt_first &&
                                     lnum <= c->lpt_last);
                        /* Try to place lsave and ltab nicely */
                        if (!done_lsave) {
@@ -280,7 +282,7 @@ static int layout_cnodes(struct ubifs_info *c)
                        if (err)
                                goto no_space;
                        offs = 0;
-                       ubifs_assert(lnum >= c->lpt_first &&
+                       ubifs_assert(c, lnum >= c->lpt_first &&
                                     lnum <= c->lpt_last);
                }
                done_lsave = 1;
@@ -300,7 +302,7 @@ static int layout_cnodes(struct ubifs_info *c)
                        if (err)
                                goto no_space;
                        offs = 0;
-                       ubifs_assert(lnum >= c->lpt_first &&
+                       ubifs_assert(c, lnum >= c->lpt_first &&
                                     lnum <= c->lpt_last);
                }
                c->ltab_lnum = lnum;
@@ -423,7 +425,7 @@ static int write_cnodes(struct ubifs_info *c)
                        if (err)
                                goto no_space;
                        offs = from = 0;
-                       ubifs_assert(lnum >= c->lpt_first &&
+                       ubifs_assert(c, lnum >= c->lpt_first &&
                                     lnum <= c->lpt_last);
                        err = ubifs_leb_unmap(c, lnum);
                        if (err)
@@ -480,7 +482,7 @@ static int write_cnodes(struct ubifs_info *c)
                        if (err)
                                goto no_space;
                        offs = from = 0;
-                       ubifs_assert(lnum >= c->lpt_first &&
+                       ubifs_assert(c, lnum >= c->lpt_first &&
                                     lnum <= c->lpt_last);
                        err = ubifs_leb_unmap(c, lnum);
                        if (err)
@@ -506,7 +508,7 @@ static int write_cnodes(struct ubifs_info *c)
                        if (err)
                                goto no_space;
                        offs = from = 0;
-                       ubifs_assert(lnum >= c->lpt_first &&
+                       ubifs_assert(c, lnum >= c->lpt_first &&
                                     lnum <= c->lpt_last);
                        err = ubifs_leb_unmap(c, lnum);
                        if (err)
@@ -806,7 +808,7 @@ static void populate_lsave(struct ubifs_info *c)
        struct ubifs_lpt_heap *heap;
        int i, cnt = 0;
 
-       ubifs_assert(c->big_lpt);
+       ubifs_assert(c, c->big_lpt);
        if (!(c->lpt_drty_flgs & LSAVE_DIRTY)) {
                c->lpt_drty_flgs |= LSAVE_DIRTY;
                ubifs_add_lpt_dirt(c, c->lsave_lnum, c->lsave_sz);
@@ -1095,8 +1097,8 @@ static int get_lpt_node_type(const struct ubifs_info *c, uint8_t *buf,
        uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
        int pos = 0, node_type;
 
-       node_type = ubifs_unpack_bits(&addr, &pos, UBIFS_LPT_TYPE_BITS);
-       *node_num = ubifs_unpack_bits(&addr, &pos, c->pcnt_bits);
+       node_type = ubifs_unpack_bits(c, &addr, &pos, UBIFS_LPT_TYPE_BITS);
+       *node_num = ubifs_unpack_bits(c, &addr, &pos, c->pcnt_bits);
        return node_type;
 }
 
@@ -1116,7 +1118,7 @@ static int is_a_node(const struct ubifs_info *c, uint8_t *buf, int len)
 
        if (len < UBIFS_LPT_CRC_BYTES + (UBIFS_LPT_TYPE_BITS + 7) / 8)
                return 0;
-       node_type = ubifs_unpack_bits(&addr, &pos, UBIFS_LPT_TYPE_BITS);
+       node_type = ubifs_unpack_bits(c, &addr, &pos, UBIFS_LPT_TYPE_BITS);
        if (node_type == UBIFS_LPT_NOT_A_NODE)
                return 0;
        node_len = get_lpt_node_len(c, node_type);
@@ -1124,7 +1126,7 @@ static int is_a_node(const struct ubifs_info *c, uint8_t *buf, int len)
                return 0;
        pos = 0;
        addr = buf;
-       crc = ubifs_unpack_bits(&addr, &pos, UBIFS_LPT_CRC_BITS);
+       crc = ubifs_unpack_bits(c, &addr, &pos, UBIFS_LPT_CRC_BITS);
        calc_crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
                         node_len - UBIFS_LPT_CRC_BYTES);
        if (crc != calc_crc)
@@ -1170,7 +1172,7 @@ static int lpt_gc_lnum(struct ubifs_info *c, int lnum)
                node_type = get_lpt_node_type(c, buf, &node_num);
                node_len = get_lpt_node_len(c, node_type);
                offs = c->leb_size - len;
-               ubifs_assert(node_len != 0);
+               ubifs_assert(c, node_len != 0);
                mutex_lock(&c->lp_mutex);
                err = make_node_dirty(c, node_type, node_num, lnum, offs);
                mutex_unlock(&c->lp_mutex);
@@ -1195,7 +1197,7 @@ static int lpt_gc(struct ubifs_info *c)
 
        mutex_lock(&c->lp_mutex);
        for (i = 0; i < c->lpt_lebs; i++) {
-               ubifs_assert(!c->ltab[i].tgc);
+               ubifs_assert(c, !c->ltab[i].tgc);
                if (i + c->lpt_first == c->nhead_lnum ||
                    c->ltab[i].free + c->ltab[i].dirty == c->leb_size)
                        continue;
@@ -1271,7 +1273,7 @@ int ubifs_lpt_start_commit(struct ubifs_info *c)
                populate_lsave(c);
 
        cnt = get_cnodes_to_commit(c);
-       ubifs_assert(cnt != 0);
+       ubifs_assert(c, cnt != 0);
 
        err = layout_cnodes(c);
        if (err)
index c6a5e39e2ba5347ea3a9f8169bb241a4e8d62b0e..9df4a41bba523d6a58fb3369cd90225a1ad8617a 100644 (file)
@@ -360,7 +360,7 @@ int ubifs_write_master(struct ubifs_info *c)
 {
        int err, lnum, offs, len;
 
-       ubifs_assert(!c->ro_media && !c->ro_mount);
+       ubifs_assert(c, !c->ro_media && !c->ro_mount);
        if (c->ro_error)
                return -EROFS;
 
index 586fd5b578a766f3f56c81e2f06738e1a9dd9489..cd23de0f211dd074a7d949cc0ab771bf94fa80bd 100644 (file)
@@ -56,3 +56,14 @@ void ubifs_warn(const struct ubifs_info *c, const char *fmt, ...)
 
        va_end(args);
 }
+
+static char *assert_names[] = {
+       [ASSACT_REPORT] = "report",
+       [ASSACT_RO] = "read-only",
+       [ASSACT_PANIC] = "panic",
+};
+
+const char *ubifs_assert_action_name(struct ubifs_info *c)
+{
+       return assert_names[c->assert_action];
+}
index caf83d68fb38c2918bf9d421b4a67cd8a96571b7..21d35d7dd975ca32c6d638e448b2e1632db1aa35 100644 (file)
@@ -105,25 +105,27 @@ static inline struct ubifs_inode *ubifs_inode(const struct inode *inode)
 /**
  * ubifs_compr_present - check if compressor was compiled in.
  * @compr_type: compressor type to check
+ * @c: the UBIFS file-system description object
  *
  * This function returns %1 of compressor of type @compr_type is present, and
  * %0 if not.
  */
-static inline int ubifs_compr_present(int compr_type)
+static inline int ubifs_compr_present(struct ubifs_info *c, int compr_type)
 {
-       ubifs_assert(compr_type >= 0 && compr_type < UBIFS_COMPR_TYPES_CNT);
+       ubifs_assert(c, compr_type >= 0 && compr_type < UBIFS_COMPR_TYPES_CNT);
        return !!ubifs_compressors[compr_type]->capi_name;
 }
 
 /**
  * ubifs_compr_name - get compressor name string by its type.
  * @compr_type: compressor type
+ * @c: the UBIFS file-system description object
  *
  * This function returns compressor type string.
  */
-static inline const char *ubifs_compr_name(int compr_type)
+static inline const char *ubifs_compr_name(struct ubifs_info *c, int compr_type)
 {
-       ubifs_assert(compr_type >= 0 && compr_type < UBIFS_COMPR_TYPES_CNT);
+       ubifs_assert(c, compr_type >= 0 && compr_type < UBIFS_COMPR_TYPES_CNT);
        return ubifs_compressors[compr_type]->name;
 }
 
@@ -262,8 +264,8 @@ static inline void ubifs_get_lprops(struct ubifs_info *c)
  */
 static inline void ubifs_release_lprops(struct ubifs_info *c)
 {
-       ubifs_assert(mutex_is_locked(&c->lp_mutex));
-       ubifs_assert(c->lst.empty_lebs >= 0 &&
+       ubifs_assert(c, mutex_is_locked(&c->lp_mutex));
+       ubifs_assert(c, c->lst.empty_lebs >= 0 &&
                     c->lst.empty_lebs <= c->main_lebs);
        mutex_unlock(&c->lp_mutex);
 }
@@ -285,4 +287,6 @@ static inline int ubifs_next_log_lnum(const struct ubifs_info *c, int lnum)
        return lnum;
 }
 
+const char *ubifs_assert_action_name(struct ubifs_info *c);
+
 #endif /* __UBIFS_MISC_H__ */
index caf2d123e9eeaec3f4dfc88c51571e2c0b62b7d3..8f70494efb0c65123f55d4633dd515b205549a2f 100644 (file)
@@ -172,8 +172,8 @@ int ubifs_orphan_start_commit(struct ubifs_info *c)
        spin_lock(&c->orphan_lock);
        last = &c->orph_cnext;
        list_for_each_entry(orphan, &c->orph_new, new_list) {
-               ubifs_assert(orphan->new);
-               ubifs_assert(!orphan->cmt);
+               ubifs_assert(c, orphan->new);
+               ubifs_assert(c, !orphan->cmt);
                orphan->new = 0;
                orphan->cmt = 1;
                *last = orphan;
@@ -244,7 +244,7 @@ static int do_write_orph_node(struct ubifs_info *c, int len, int atomic)
        int err = 0;
 
        if (atomic) {
-               ubifs_assert(c->ohead_offs == 0);
+               ubifs_assert(c, c->ohead_offs == 0);
                ubifs_prepare_node(c, c->orph_buf, len, 1);
                len = ALIGN(len, c->min_io_size);
                err = ubifs_leb_change(c, c->ohead_lnum, c->orph_buf, len);
@@ -276,7 +276,7 @@ static int write_orph_node(struct ubifs_info *c, int atomic)
        struct ubifs_orph_node *orph;
        int gap, err, len, cnt, i;
 
-       ubifs_assert(c->cmt_orphans > 0);
+       ubifs_assert(c, c->cmt_orphans > 0);
        gap = c->leb_size - c->ohead_offs;
        if (gap < UBIFS_ORPH_NODE_SZ + sizeof(__le64)) {
                c->ohead_lnum += 1;
@@ -295,14 +295,14 @@ static int write_orph_node(struct ubifs_info *c, int atomic)
        if (cnt > c->cmt_orphans)
                cnt = c->cmt_orphans;
        len = UBIFS_ORPH_NODE_SZ + cnt * sizeof(__le64);
-       ubifs_assert(c->orph_buf);
+       ubifs_assert(c, c->orph_buf);
        orph = c->orph_buf;
        orph->ch.node_type = UBIFS_ORPH_NODE;
        spin_lock(&c->orphan_lock);
        cnext = c->orph_cnext;
        for (i = 0; i < cnt; i++) {
                orphan = cnext;
-               ubifs_assert(orphan->cmt);
+               ubifs_assert(c, orphan->cmt);
                orph->inos[i] = cpu_to_le64(orphan->inum);
                orphan->cmt = 0;
                cnext = orphan->cnext;
@@ -316,9 +316,9 @@ static int write_orph_node(struct ubifs_info *c, int atomic)
        else
                /* Mark the last node of the commit */
                orph->cmt_no = cpu_to_le64((c->cmt_no) | (1ULL << 63));
-       ubifs_assert(c->ohead_offs + len <= c->leb_size);
-       ubifs_assert(c->ohead_lnum >= c->orph_first);
-       ubifs_assert(c->ohead_lnum <= c->orph_last);
+       ubifs_assert(c, c->ohead_offs + len <= c->leb_size);
+       ubifs_assert(c, c->ohead_lnum >= c->orph_first);
+       ubifs_assert(c, c->ohead_lnum <= c->orph_last);
        err = do_write_orph_node(c, len, atomic);
        c->ohead_offs += ALIGN(len, c->min_io_size);
        c->ohead_offs = ALIGN(c->ohead_offs, 8);
@@ -388,7 +388,7 @@ static int consolidate(struct ubifs_info *c)
                        cnt += 1;
                }
                *last = NULL;
-               ubifs_assert(cnt == c->tot_orphans - c->new_orphans);
+               ubifs_assert(c, cnt == c->tot_orphans - c->new_orphans);
                c->cmt_orphans = cnt;
                c->ohead_lnum = c->orph_first;
                c->ohead_offs = 0;
@@ -415,7 +415,7 @@ static int commit_orphans(struct ubifs_info *c)
 {
        int avail, atomic = 0, err;
 
-       ubifs_assert(c->cmt_orphans > 0);
+       ubifs_assert(c, c->cmt_orphans > 0);
        avail = avail_orphs(c);
        if (avail < c->cmt_orphans) {
                /* Not enough space to write new orphans, so consolidate */
@@ -446,8 +446,8 @@ static void erase_deleted(struct ubifs_info *c)
        while (dnext) {
                orphan = dnext;
                dnext = orphan->dnext;
-               ubifs_assert(!orphan->new);
-               ubifs_assert(orphan->del);
+               ubifs_assert(c, !orphan->new);
+               ubifs_assert(c, orphan->del);
                rb_erase(&orphan->rb, &c->orph_tree);
                list_del(&orphan->list);
                c->tot_orphans -= 1;
index 3af4472061cc0139638efa80245516f27fe175b0..984e30e83c0b3eead78fdc61190026c78cd15d51 100644 (file)
@@ -444,7 +444,7 @@ static void clean_buf(const struct ubifs_info *c, void **buf, int lnum,
 
        dbg_rcvry("cleaning corruption at %d:%d", lnum, *offs);
 
-       ubifs_assert(!(*offs & 7));
+       ubifs_assert(c, !(*offs & 7));
        empty_offs = ALIGN(*offs, c->min_io_size);
        pad_len = empty_offs - *offs;
        ubifs_pad(c, *buf, pad_len);
@@ -644,7 +644,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
        if (IS_ERR(sleb))
                return sleb;
 
-       ubifs_assert(len >= 8);
+       ubifs_assert(c, len >= 8);
        while (len >= 8) {
                dbg_scan("look at LEB %d:%d (%d bytes left)",
                         lnum, offs, len);
@@ -966,7 +966,7 @@ int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf)
 {
        int err;
 
-       ubifs_assert(!c->ro_mount || c->remounting_rw);
+       ubifs_assert(c, !c->ro_mount || c->remounting_rw);
 
        dbg_rcvry("checking index head at %d:%d", c->ihead_lnum, c->ihead_offs);
        err = recover_head(c, c->ihead_lnum, c->ihead_offs, sbuf);
@@ -1187,8 +1187,8 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c)
                return grab_empty_leb(c);
        }
 
-       ubifs_assert(!(lp.flags & LPROPS_INDEX));
-       ubifs_assert(lp.free + lp.dirty >= wbuf->offs);
+       ubifs_assert(c, !(lp.flags & LPROPS_INDEX));
+       ubifs_assert(c, lp.free + lp.dirty >= wbuf->offs);
 
        /*
         * We run the commit before garbage collection otherwise subsequent
@@ -1216,7 +1216,7 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c)
                return err;
        }
 
-       ubifs_assert(err == LEB_RETAINED);
+       ubifs_assert(c, err == LEB_RETAINED);
        if (err != LEB_RETAINED)
                return -EINVAL;
 
@@ -1507,7 +1507,7 @@ int ubifs_recover_size(struct ubifs_info *c)
                                struct inode *inode;
                                struct ubifs_inode *ui;
 
-                               ubifs_assert(!e->inode);
+                               ubifs_assert(c, !e->inode);
 
                                inode = ubifs_iget(c->vfs_sb, e->inum);
                                if (IS_ERR(inode))
index 85c2a43082b7f45264cf76a32d6af55e453cb7ce..4844538eb92626212394839e4734111866fbc085 100644 (file)
@@ -273,6 +273,7 @@ static int apply_replay_entry(struct ubifs_info *c, struct replay_entry *r)
 static int replay_entries_cmp(void *priv, struct list_head *a,
                              struct list_head *b)
 {
+       struct ubifs_info *c = priv;
        struct replay_entry *ra, *rb;
 
        cond_resched();
@@ -281,7 +282,7 @@ static int replay_entries_cmp(void *priv, struct list_head *a,
 
        ra = list_entry(a, struct replay_entry, list);
        rb = list_entry(b, struct replay_entry, list);
-       ubifs_assert(ra->sqnum != rb->sqnum);
+       ubifs_assert(c, ra->sqnum != rb->sqnum);
        if (ra->sqnum > rb->sqnum)
                return 1;
        return -1;
@@ -668,9 +669,9 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b)
                        goto out;
        }
 
-       ubifs_assert(ubifs_search_bud(c, lnum));
-       ubifs_assert(sleb->endpt - offs >= used);
-       ubifs_assert(sleb->endpt % c->min_io_size == 0);
+       ubifs_assert(c, ubifs_search_bud(c, lnum));
+       ubifs_assert(c, sleb->endpt - offs >= used);
+       ubifs_assert(c, sleb->endpt % c->min_io_size == 0);
 
        b->dirty = sleb->endpt - offs - used;
        b->free = c->leb_size - sleb->endpt;
@@ -706,7 +707,7 @@ static int replay_buds(struct ubifs_info *c)
                if (err)
                        return err;
 
-               ubifs_assert(b->sqnum > prev_sqnum);
+               ubifs_assert(c, b->sqnum > prev_sqnum);
                prev_sqnum = b->sqnum;
        }
 
@@ -1067,7 +1068,7 @@ int ubifs_replay_journal(struct ubifs_info *c)
        c->bi.uncommitted_idx = atomic_long_read(&c->dirty_zn_cnt);
        c->bi.uncommitted_idx *= c->max_idx_node_sz;
 
-       ubifs_assert(c->bud_bytes <= c->max_bud_bytes || c->need_recovery);
+       ubifs_assert(c, c->bud_bytes <= c->max_bud_bytes || c->need_recovery);
        dbg_mnt("finished, log head LEB %d:%d, max_sqnum %llu, highest_inum %lu",
                c->lhead_lnum, c->lhead_offs, c->max_sqnum,
                (unsigned long)c->highest_inum);
index 8c25081a510969055405b95ed57e8d94ec556f44..bf17f58908ff95bc63efbe48dd5ede204a28ac78 100644 (file)
@@ -85,7 +85,7 @@ static int create_default_filesystem(struct ubifs_info *c)
        long long tmp64, main_bytes;
        __le64 tmp_le64;
        __le32 tmp_le32;
-       struct timespec ts;
+       struct timespec64 ts;
 
        /* Some functions called from here depend on the @c->key_len filed */
        c->key_len = UBIFS_SK_LEN;
@@ -301,8 +301,8 @@ static int create_default_filesystem(struct ubifs_info *c)
        ino->creat_sqnum = cpu_to_le64(++c->max_sqnum);
        ino->nlink = cpu_to_le32(2);
 
-       ktime_get_real_ts(&ts);
-       ts = timespec_trunc(ts, DEFAULT_TIME_GRAN);
+       ktime_get_real_ts64(&ts);
+       ts = timespec64_trunc(ts, DEFAULT_TIME_GRAN);
        tmp_le64 = cpu_to_le64(ts.tv_sec);
        ino->atime_sec   = tmp_le64;
        ino->ctime_sec   = tmp_le64;
@@ -563,7 +563,7 @@ int ubifs_read_superblock(struct ubifs_info *c)
         * due to the unavailability of time-travelling equipment.
         */
        if (c->fmt_version > UBIFS_FORMAT_VERSION) {
-               ubifs_assert(!c->ro_media || c->ro_mount);
+               ubifs_assert(c, !c->ro_media || c->ro_mount);
                if (!c->ro_mount ||
                    c->ro_compat_version > UBIFS_RO_COMPAT_VERSION) {
                        ubifs_err(c, "on-flash format version is w%d/r%d, but software only supports up to version w%d/r%d",
@@ -705,9 +705,9 @@ static int fixup_leb(struct ubifs_info *c, int lnum, int len)
 {
        int err;
 
-       ubifs_assert(len >= 0);
-       ubifs_assert(len % c->min_io_size == 0);
-       ubifs_assert(len < c->leb_size);
+       ubifs_assert(c, len >= 0);
+       ubifs_assert(c, len % c->min_io_size == 0);
+       ubifs_assert(c, len < c->leb_size);
 
        if (len == 0) {
                dbg_mnt("unmap empty LEB %d", lnum);
@@ -817,8 +817,8 @@ int ubifs_fixup_free_space(struct ubifs_info *c)
        int err;
        struct ubifs_sb_node *sup;
 
-       ubifs_assert(c->space_fixup);
-       ubifs_assert(!c->ro_mount);
+       ubifs_assert(c, c->space_fixup);
+       ubifs_assert(c, !c->ro_mount);
 
        ubifs_msg(c, "start fixing up free space");
 
index 16f03d9929e5ed7d90366992726793db16d1177d..ea88926163f43ff20b7121d72d08a4533506c91c 100644 (file)
@@ -176,7 +176,7 @@ void ubifs_end_scan(const struct ubifs_info *c, struct ubifs_scan_leb *sleb,
                    int lnum, int offs)
 {
        dbg_scan("stop scanning LEB %d at offset %d", lnum, offs);
-       ubifs_assert(offs % c->min_io_size == 0);
+       ubifs_assert(c, offs % c->min_io_size == 0);
 
        sleb->endpt = ALIGN(offs, c->min_io_size);
 }
index 9a9fb94a41c6823fdd5c4a4908af6f3e8bb604d1..5eb5958723d4879c257a5976dd6f16b4fec3461c 100644 (file)
@@ -71,10 +71,10 @@ static int shrink_tnc(struct ubifs_info *c, int nr, int age, int *contention)
 {
        int total_freed = 0;
        struct ubifs_znode *znode, *zprev;
-       int time = get_seconds();
+       time64_t time = ktime_get_seconds();
 
-       ubifs_assert(mutex_is_locked(&c->umount_mutex));
-       ubifs_assert(mutex_is_locked(&c->tnc_mutex));
+       ubifs_assert(c, mutex_is_locked(&c->umount_mutex));
+       ubifs_assert(c, mutex_is_locked(&c->tnc_mutex));
 
        if (!c->zroot.znode || atomic_long_read(&c->clean_zn_cnt) == 0)
                return 0;
@@ -89,7 +89,7 @@ static int shrink_tnc(struct ubifs_info *c, int nr, int age, int *contention)
         * changed only when the 'c->tnc_mutex' is held.
         */
        zprev = NULL;
-       znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL);
+       znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, NULL);
        while (znode && total_freed < nr &&
               atomic_long_read(&c->clean_zn_cnt) > 0) {
                int freed;
@@ -125,7 +125,7 @@ static int shrink_tnc(struct ubifs_info *c, int nr, int age, int *contention)
                        else
                                c->zroot.znode = NULL;
 
-                       freed = ubifs_destroy_tnc_subtree(znode);
+                       freed = ubifs_destroy_tnc_subtree(c, znode);
                        atomic_long_sub(freed, &ubifs_clean_zn_cnt);
                        atomic_long_sub(freed, &c->clean_zn_cnt);
                        total_freed += freed;
@@ -136,7 +136,7 @@ static int shrink_tnc(struct ubifs_info *c, int nr, int age, int *contention)
                        break;
 
                zprev = znode;
-               znode = ubifs_tnc_levelorder_next(c->zroot.znode, znode);
+               znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, znode);
                cond_resched();
        }
 
index c5466c70d620015aaa16ede0790aefb3c6efbc14..23e7042666a755dd361720e3a29b1a56585fee33 100644 (file)
@@ -89,9 +89,9 @@ static int validate_inode(struct ubifs_info *c, const struct inode *inode)
        if (ui->xattr && !S_ISREG(inode->i_mode))
                return 5;
 
-       if (!ubifs_compr_present(ui->compr_type)) {
+       if (!ubifs_compr_present(c, ui->compr_type)) {
                ubifs_warn(c, "inode %lu uses '%s' compression, but it was not compiled in",
-                          inode->i_ino, ubifs_compr_name(ui->compr_type));
+                          inode->i_ino, ubifs_compr_name(c, ui->compr_type));
        }
 
        err = dbg_check_dir(c, inode);
@@ -296,7 +296,7 @@ static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc)
        struct ubifs_info *c = inode->i_sb->s_fs_info;
        struct ubifs_inode *ui = ubifs_inode(inode);
 
-       ubifs_assert(!ui->xattr);
+       ubifs_assert(c, !ui->xattr);
        if (is_bad_inode(inode))
                return 0;
 
@@ -349,7 +349,7 @@ static void ubifs_evict_inode(struct inode *inode)
                goto out;
 
        dbg_gen("inode %lu, mode %#x", inode->i_ino, (int)inode->i_mode);
-       ubifs_assert(!atomic_read(&inode->i_count));
+       ubifs_assert(c, !atomic_read(&inode->i_count));
 
        truncate_inode_pages_final(&inode->i_data);
 
@@ -384,9 +384,10 @@ done:
 
 static void ubifs_dirty_inode(struct inode *inode, int flags)
 {
+       struct ubifs_info *c = inode->i_sb->s_fs_info;
        struct ubifs_inode *ui = ubifs_inode(inode);
 
-       ubifs_assert(mutex_is_locked(&ui->ui_mutex));
+       ubifs_assert(c, mutex_is_locked(&ui->ui_mutex));
        if (!ui->dirty) {
                ui->dirty = 1;
                dbg_gen("inode %lu",  inode->i_ino);
@@ -416,7 +417,7 @@ static int ubifs_statfs(struct dentry *dentry, struct kstatfs *buf)
        buf->f_namelen = UBIFS_MAX_NLEN;
        buf->f_fsid.val[0] = le32_to_cpu(uuid[0]) ^ le32_to_cpu(uuid[2]);
        buf->f_fsid.val[1] = le32_to_cpu(uuid[1]) ^ le32_to_cpu(uuid[3]);
-       ubifs_assert(buf->f_bfree <= c->block_cnt);
+       ubifs_assert(c, buf->f_bfree <= c->block_cnt);
        return 0;
 }
 
@@ -441,9 +442,10 @@ static int ubifs_show_options(struct seq_file *s, struct dentry *root)
 
        if (c->mount_opts.override_compr) {
                seq_printf(s, ",compr=%s",
-                          ubifs_compr_name(c->mount_opts.compr_type));
+                          ubifs_compr_name(c, c->mount_opts.compr_type));
        }
 
+       seq_printf(s, ",assert=%s", ubifs_assert_action_name(c));
        seq_printf(s, ",ubi=%d,vol=%d", c->vi.ubi_num, c->vi.vol_id);
 
        return 0;
@@ -921,6 +923,7 @@ static int check_volume_empty(struct ubifs_info *c)
  * Opt_chk_data_crc: check CRCs when reading data nodes
  * Opt_no_chk_data_crc: do not check CRCs when reading data nodes
  * Opt_override_compr: override default compressor
+ * Opt_assert: set ubifs_assert() action
  * Opt_err: just end of array marker
  */
 enum {
@@ -931,6 +934,7 @@ enum {
        Opt_chk_data_crc,
        Opt_no_chk_data_crc,
        Opt_override_compr,
+       Opt_assert,
        Opt_ignore,
        Opt_err,
 };
@@ -945,6 +949,7 @@ static const match_table_t tokens = {
        {Opt_override_compr, "compr=%s"},
        {Opt_ignore, "ubi=%s"},
        {Opt_ignore, "vol=%s"},
+       {Opt_assert, "assert=%s"},
        {Opt_err, NULL},
 };
 
@@ -1045,6 +1050,26 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
                        c->default_compr = c->mount_opts.compr_type;
                        break;
                }
+               case Opt_assert:
+               {
+                       char *act = match_strdup(&args[0]);
+
+                       if (!act)
+                               return -ENOMEM;
+                       if (!strcmp(act, "report"))
+                               c->assert_action = ASSACT_REPORT;
+                       else if (!strcmp(act, "read-only"))
+                               c->assert_action = ASSACT_RO;
+                       else if (!strcmp(act, "panic"))
+                               c->assert_action = ASSACT_PANIC;
+                       else {
+                               ubifs_err(c, "unknown assert action \"%s\"", act);
+                               kfree(act);
+                               return -EINVAL;
+                       }
+                       kfree(act);
+                       break;
+               }
                case Opt_ignore:
                        break;
                default:
@@ -1103,7 +1128,7 @@ static void destroy_journal(struct ubifs_info *c)
  */
 static void bu_init(struct ubifs_info *c)
 {
-       ubifs_assert(c->bulk_read == 1);
+       ubifs_assert(c, c->bulk_read == 1);
 
        if (c->bu.buf)
                return; /* Already initialized */
@@ -1134,7 +1159,7 @@ again:
  */
 static int check_free_space(struct ubifs_info *c)
 {
-       ubifs_assert(c->dark_wm > 0);
+       ubifs_assert(c, c->dark_wm > 0);
        if (c->lst.total_free + c->lst.total_dirty < c->dark_wm) {
                ubifs_err(c, "insufficient free space to mount in R/W mode");
                ubifs_dump_budg(c, &c->bi);
@@ -1234,9 +1259,9 @@ static int mount_ubifs(struct ubifs_info *c)
         * Make sure the compressor which is set as default in the superblock
         * or overridden by mount options is actually compiled in.
         */
-       if (!ubifs_compr_present(c->default_compr)) {
+       if (!ubifs_compr_present(c, c->default_compr)) {
                ubifs_err(c, "'compressor \"%s\" is not compiled in",
-                         ubifs_compr_name(c->default_compr));
+                         ubifs_compr_name(c, c->default_compr));
                err = -ENOTSUPP;
                goto out_free;
        }
@@ -1396,10 +1421,10 @@ static int mount_ubifs(struct ubifs_info *c)
                         * the journal head LEBs may also be accounted as
                         * "empty taken" if they are empty.
                         */
-                       ubifs_assert(c->lst.taken_empty_lebs > 0);
+                       ubifs_assert(c, c->lst.taken_empty_lebs > 0);
                }
        } else
-               ubifs_assert(c->lst.taken_empty_lebs > 0);
+               ubifs_assert(c, c->lst.taken_empty_lebs > 0);
 
        err = dbg_check_filesystem(c);
        if (err)
@@ -1429,7 +1454,7 @@ static int mount_ubifs(struct ubifs_info *c)
                  UBIFS_FORMAT_VERSION, UBIFS_RO_COMPAT_VERSION, c->uuid,
                  c->big_lpt ? ", big LPT model" : ", small LPT model");
 
-       dbg_gen("default compressor:  %s", ubifs_compr_name(c->default_compr));
+       dbg_gen("default compressor:  %s", ubifs_compr_name(c, c->default_compr));
        dbg_gen("data journal heads:  %d",
                c->jhead_cnt - NONDATA_JHEADS_CNT);
        dbg_gen("log LEBs:            %d (%d - %d)",
@@ -1610,7 +1635,7 @@ static int ubifs_remount_rw(struct ubifs_info *c)
                        goto out;
        } else {
                /* A readonly mount is not allowed to have orphans */
-               ubifs_assert(c->tot_orphans == 0);
+               ubifs_assert(c, c->tot_orphans == 0);
                err = ubifs_clear_orphans(c);
                if (err)
                        goto out;
@@ -1727,8 +1752,8 @@ static void ubifs_remount_ro(struct ubifs_info *c)
 {
        int i, err;
 
-       ubifs_assert(!c->need_recovery);
-       ubifs_assert(!c->ro_mount);
+       ubifs_assert(c, !c->need_recovery);
+       ubifs_assert(c, !c->ro_mount);
 
        mutex_lock(&c->umount_mutex);
        if (c->bgt) {
@@ -1778,9 +1803,9 @@ static void ubifs_put_super(struct super_block *sb)
         * to write them back because of I/O errors.
         */
        if (!c->ro_error) {
-               ubifs_assert(c->bi.idx_growth == 0);
-               ubifs_assert(c->bi.dd_growth == 0);
-               ubifs_assert(c->bi.data_growth == 0);
+               ubifs_assert(c, c->bi.idx_growth == 0);
+               ubifs_assert(c, c->bi.dd_growth == 0);
+               ubifs_assert(c, c->bi.data_growth == 0);
        }
 
        /*
@@ -1887,7 +1912,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
                mutex_unlock(&c->bu_mutex);
        }
 
-       ubifs_assert(c->lst.taken_empty_lebs > 0);
+       ubifs_assert(c, c->lst.taken_empty_lebs > 0);
        return 0;
 }
 
@@ -2002,6 +2027,7 @@ static struct ubifs_info *alloc_ubifs_info(struct ubi_volume_desc *ubi)
                INIT_LIST_HEAD(&c->orph_list);
                INIT_LIST_HEAD(&c->orph_new);
                c->no_chk_data_crc = 1;
+               c->assert_action = ASSACT_RO;
 
                c->highest_inum = UBIFS_FIRST_INO;
                c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM;
@@ -2053,7 +2079,9 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
        if (c->max_inode_sz > MAX_LFS_FILESIZE)
                sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE;
        sb->s_op = &ubifs_super_operations;
+#ifdef CONFIG_UBIFS_FS_XATTR
        sb->s_xattr = ubifs_xattr_handlers;
+#endif
 #ifdef CONFIG_UBIFS_FS_ENCRYPTION
        sb->s_cop = &ubifs_crypt_operations;
 #endif
@@ -2061,7 +2089,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
        mutex_lock(&c->umount_mutex);
        err = mount_ubifs(c);
        if (err) {
-               ubifs_assert(err < 0);
+               ubifs_assert(c, err < 0);
                goto out_unlock;
        }
 
@@ -2304,8 +2332,8 @@ late_initcall(ubifs_init);
 
 static void __exit ubifs_exit(void)
 {
-       ubifs_assert(list_empty(&ubifs_infos));
-       ubifs_assert(atomic_long_read(&ubifs_clean_zn_cnt) == 0);
+       WARN_ON(list_empty(&ubifs_infos));
+       WARN_ON(atomic_long_read(&ubifs_clean_zn_cnt) == 0);
 
        dbg_debugfs_exit();
        ubifs_compressors_exit();
index 4a21e7f75e7a16537353c90bf850e52709252a34..bf416e5127431aae03a6211bbd89ab069bb7ceda 100644 (file)
@@ -211,7 +211,7 @@ static struct ubifs_znode *copy_znode(struct ubifs_info *c,
        __set_bit(DIRTY_ZNODE, &zn->flags);
        __clear_bit(COW_ZNODE, &zn->flags);
 
-       ubifs_assert(!ubifs_zn_obsolete(znode));
+       ubifs_assert(c, !ubifs_zn_obsolete(znode));
        __set_bit(OBSOLETE_ZNODE, &znode->flags);
 
        if (znode->level != 0) {
@@ -321,9 +321,9 @@ static int lnc_add(struct ubifs_info *c, struct ubifs_zbranch *zbr,
        void *lnc_node;
        const struct ubifs_dent_node *dent = node;
 
-       ubifs_assert(!zbr->leaf);
-       ubifs_assert(zbr->len != 0);
-       ubifs_assert(is_hash_key(c, &zbr->key));
+       ubifs_assert(c, !zbr->leaf);
+       ubifs_assert(c, zbr->len != 0);
+       ubifs_assert(c, is_hash_key(c, &zbr->key));
 
        err = ubifs_validate_entry(c, dent);
        if (err) {
@@ -355,8 +355,8 @@ static int lnc_add_directly(struct ubifs_info *c, struct ubifs_zbranch *zbr,
 {
        int err;
 
-       ubifs_assert(!zbr->leaf);
-       ubifs_assert(zbr->len != 0);
+       ubifs_assert(c, !zbr->leaf);
+       ubifs_assert(c, zbr->len != 0);
 
        err = ubifs_validate_entry(c, node);
        if (err) {
@@ -398,11 +398,11 @@ static int tnc_read_hashed_node(struct ubifs_info *c, struct ubifs_zbranch *zbr,
 {
        int err;
 
-       ubifs_assert(is_hash_key(c, &zbr->key));
+       ubifs_assert(c, is_hash_key(c, &zbr->key));
 
        if (zbr->leaf) {
                /* Read from the leaf node cache */
-               ubifs_assert(zbr->len != 0);
+               ubifs_assert(c, zbr->len != 0);
                memcpy(node, zbr->leaf, zbr->len);
                return 0;
        }
@@ -721,7 +721,7 @@ static int resolve_collision(struct ubifs_info *c, const union ubifs_key *key,
                while (1) {
                        err = tnc_prev(c, zn, n);
                        if (err == -ENOENT) {
-                               ubifs_assert(*n == 0);
+                               ubifs_assert(c, *n == 0);
                                *n = -1;
                                return 0;
                        }
@@ -761,12 +761,12 @@ static int resolve_collision(struct ubifs_info *c, const union ubifs_key *key,
                                        err = tnc_next(c, zn, n);
                                        if (err) {
                                                /* Should be impossible */
-                                               ubifs_assert(0);
+                                               ubifs_assert(c, 0);
                                                if (err == -ENOENT)
                                                        err = -EINVAL;
                                                return err;
                                        }
-                                       ubifs_assert(*n == 0);
+                                       ubifs_assert(c, *n == 0);
                                        *n = -1;
                                }
                                return 0;
@@ -778,7 +778,7 @@ static int resolve_collision(struct ubifs_info *c, const union ubifs_key *key,
                                return 0;
                        if (err == NAME_MATCHES)
                                return 1;
-                       ubifs_assert(err == NAME_GREATER);
+                       ubifs_assert(c, err == NAME_GREATER);
                }
        } else {
                int nn = *n;
@@ -802,7 +802,7 @@ static int resolve_collision(struct ubifs_info *c, const union ubifs_key *key,
                        *n = nn;
                        if (err == NAME_MATCHES)
                                return 1;
-                       ubifs_assert(err == NAME_LESS);
+                       ubifs_assert(c, err == NAME_LESS);
                }
        }
 }
@@ -843,7 +843,7 @@ static int fallible_matches_name(struct ubifs_info *c,
                        err = NOT_ON_MEDIA;
                        goto out_free;
                }
-               ubifs_assert(err == 1);
+               ubifs_assert(c, err == 1);
 
                err = lnc_add_directly(c, zbr, dent);
                if (err)
@@ -923,7 +923,7 @@ static int fallible_resolve_collision(struct ubifs_info *c,
                while (1) {
                        err = tnc_prev(c, zn, n);
                        if (err == -ENOENT) {
-                               ubifs_assert(*n == 0);
+                               ubifs_assert(c, *n == 0);
                                *n = -1;
                                break;
                        }
@@ -935,12 +935,12 @@ static int fallible_resolve_collision(struct ubifs_info *c,
                                        err = tnc_next(c, zn, n);
                                        if (err) {
                                                /* Should be impossible */
-                                               ubifs_assert(0);
+                                               ubifs_assert(c, 0);
                                                if (err == -ENOENT)
                                                        err = -EINVAL;
                                                return err;
                                        }
-                                       ubifs_assert(*n == 0);
+                                       ubifs_assert(c, *n == 0);
                                        *n = -1;
                                }
                                break;
@@ -1100,8 +1100,8 @@ static struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c,
        struct ubifs_znode *zp;
        int *path = c->bottom_up_buf, p = 0;
 
-       ubifs_assert(c->zroot.znode);
-       ubifs_assert(znode);
+       ubifs_assert(c, c->zroot.znode);
+       ubifs_assert(c, znode);
        if (c->zroot.znode->level > BOTTOM_UP_HEIGHT) {
                kfree(c->bottom_up_buf);
                c->bottom_up_buf = kmalloc_array(c->zroot.znode->level,
@@ -1120,7 +1120,7 @@ static struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c,
                        if (!zp)
                                break;
                        n = znode->iip;
-                       ubifs_assert(p < c->zroot.znode->level);
+                       ubifs_assert(c, p < c->zroot.znode->level);
                        path[p++] = n;
                        if (!zp->cnext && ubifs_zn_dirty(znode))
                                break;
@@ -1134,18 +1134,18 @@ static struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c,
 
                zp = znode->parent;
                if (zp) {
-                       ubifs_assert(path[p - 1] >= 0);
-                       ubifs_assert(path[p - 1] < zp->child_cnt);
+                       ubifs_assert(c, path[p - 1] >= 0);
+                       ubifs_assert(c, path[p - 1] < zp->child_cnt);
                        zbr = &zp->zbranch[path[--p]];
                        znode = dirty_cow_znode(c, zbr);
                } else {
-                       ubifs_assert(znode == c->zroot.znode);
+                       ubifs_assert(c, znode == c->zroot.znode);
                        znode = dirty_cow_znode(c, &c->zroot);
                }
                if (IS_ERR(znode) || !p)
                        break;
-               ubifs_assert(path[p - 1] >= 0);
-               ubifs_assert(path[p - 1] < znode->child_cnt);
+               ubifs_assert(c, path[p - 1] >= 0);
+               ubifs_assert(c, path[p - 1] < znode->child_cnt);
                znode = znode->zbranch[path[p - 1]].znode;
        }
 
@@ -1179,10 +1179,10 @@ int ubifs_lookup_level0(struct ubifs_info *c, const union ubifs_key *key,
 {
        int err, exact;
        struct ubifs_znode *znode;
-       unsigned long time = get_seconds();
+       time64_t time = ktime_get_seconds();
 
        dbg_tnck(key, "search key ");
-       ubifs_assert(key_type(c, key) < UBIFS_INVALID_KEY);
+       ubifs_assert(c, key_type(c, key) < UBIFS_INVALID_KEY);
 
        znode = c->zroot.znode;
        if (unlikely(!znode)) {
@@ -1315,7 +1315,7 @@ static int lookup_level0_dirty(struct ubifs_info *c, const union ubifs_key *key,
 {
        int err, exact;
        struct ubifs_znode *znode;
-       unsigned long time = get_seconds();
+       time64_t time = ktime_get_seconds();
 
        dbg_tnck(key, "search and dirty key ");
 
@@ -1658,9 +1658,9 @@ static int read_wbuf(struct ubifs_wbuf *wbuf, void *buf, int len, int lnum,
        int rlen, overlap;
 
        dbg_io("LEB %d:%d, length %d", lnum, offs, len);
-       ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
-       ubifs_assert(!(offs & 7) && offs < c->leb_size);
-       ubifs_assert(offs + len <= c->leb_size);
+       ubifs_assert(c, wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
+       ubifs_assert(c, !(offs & 7) && offs < c->leb_size);
+       ubifs_assert(c, offs + len <= c->leb_size);
 
        spin_lock(&wbuf->lock);
        overlap = (lnum == wbuf->lnum && offs + len > wbuf->offs);
@@ -1824,7 +1824,7 @@ static int do_lookup_nm(struct ubifs_info *c, const union ubifs_key *key,
                goto out_unlock;
        }
 
-       ubifs_assert(n >= 0);
+       ubifs_assert(c, n >= 0);
 
        err = resolve_collision(c, key, &znode, &n, nm);
        dbg_tnc("rc returned %d, znode %p, n %d", err, znode, n);
@@ -1922,7 +1922,7 @@ static int do_lookup_dh(struct ubifs_info *c, const union ubifs_key *key,
        struct ubifs_znode *znode;
        union ubifs_key start_key;
 
-       ubifs_assert(is_hash_key(c, key));
+       ubifs_assert(c, is_hash_key(c, key));
 
        lowest_dent_key(c, &start_key, key_inum(c, key));
 
@@ -1993,8 +1993,8 @@ static void correct_parent_keys(const struct ubifs_info *c,
 {
        union ubifs_key *key, *key1;
 
-       ubifs_assert(znode->parent);
-       ubifs_assert(znode->iip == 0);
+       ubifs_assert(c, znode->parent);
+       ubifs_assert(c, znode->iip == 0);
 
        key = &znode->zbranch[0].key;
        key1 = &znode->parent->zbranch[0].key;
@@ -2011,6 +2011,7 @@ static void correct_parent_keys(const struct ubifs_info *c,
 
 /**
  * insert_zbranch - insert a zbranch into a znode.
+ * @c: UBIFS file-system description object
  * @znode: znode into which to insert
  * @zbr: zbranch to insert
  * @n: slot number to insert to
@@ -2020,12 +2021,12 @@ static void correct_parent_keys(const struct ubifs_info *c,
  * zbranch has to be inserted to the @znode->zbranches[]' array at the @n-th
  * slot, zbranches starting from @n have to be moved right.
  */
-static void insert_zbranch(struct ubifs_znode *znode,
+static void insert_zbranch(struct ubifs_info *c, struct ubifs_znode *znode,
                           const struct ubifs_zbranch *zbr, int n)
 {
        int i;
 
-       ubifs_assert(ubifs_zn_dirty(znode));
+       ubifs_assert(c, ubifs_zn_dirty(znode));
 
        if (znode->level) {
                for (i = znode->child_cnt; i > n; i--) {
@@ -2079,16 +2080,16 @@ static int tnc_insert(struct ubifs_info *c, struct ubifs_znode *znode,
        int i, keep, move, appending = 0;
        union ubifs_key *key = &zbr->key, *key1;
 
-       ubifs_assert(n >= 0 && n <= c->fanout);
+       ubifs_assert(c, n >= 0 && n <= c->fanout);
 
        /* Implement naive insert for now */
 again:
        zp = znode->parent;
        if (znode->child_cnt < c->fanout) {
-               ubifs_assert(n != c->fanout);
+               ubifs_assert(c, n != c->fanout);
                dbg_tnck(key, "inserted at %d level %d, key ", n, znode->level);
 
-               insert_zbranch(znode, zbr, n);
+               insert_zbranch(c, znode, zbr, n);
 
                /* Ensure parent's key is correct */
                if (n == 0 && zp && znode->iip == 0)
@@ -2197,7 +2198,7 @@ do_split:
        /* Insert new key and branch */
        dbg_tnck(key, "inserting at %d level %d, key ", n, zn->level);
 
-       insert_zbranch(zi, zbr, n);
+       insert_zbranch(c, zi, zbr, n);
 
        /* Insert new znode (produced by spitting) into the parent */
        if (zp) {
@@ -2495,8 +2496,8 @@ static int tnc_delete(struct ubifs_info *c, struct ubifs_znode *znode, int n)
        int i, err;
 
        /* Delete without merge for now */
-       ubifs_assert(znode->level == 0);
-       ubifs_assert(n >= 0 && n < c->fanout);
+       ubifs_assert(c, znode->level == 0);
+       ubifs_assert(c, n >= 0 && n < c->fanout);
        dbg_tnck(&znode->zbranch[n].key, "deleting key ");
 
        zbr = &znode->zbranch[n];
@@ -2522,8 +2523,8 @@ static int tnc_delete(struct ubifs_info *c, struct ubifs_znode *znode, int n)
         */
 
        do {
-               ubifs_assert(!ubifs_zn_obsolete(znode));
-               ubifs_assert(ubifs_zn_dirty(znode));
+               ubifs_assert(c, !ubifs_zn_obsolete(znode));
+               ubifs_assert(c, ubifs_zn_dirty(znode));
 
                zp = znode->parent;
                n = znode->iip;
@@ -2545,7 +2546,7 @@ static int tnc_delete(struct ubifs_info *c, struct ubifs_znode *znode, int n)
 
        /* Remove from znode, entry n - 1 */
        znode->child_cnt -= 1;
-       ubifs_assert(znode->level != 0);
+       ubifs_assert(c, znode->level != 0);
        for (i = n; i < znode->child_cnt; i++) {
                znode->zbranch[i] = znode->zbranch[i + 1];
                if (znode->zbranch[i].znode)
@@ -2578,8 +2579,8 @@ static int tnc_delete(struct ubifs_info *c, struct ubifs_znode *znode, int n)
                        c->zroot.offs = zbr->offs;
                        c->zroot.len = zbr->len;
                        c->zroot.znode = znode;
-                       ubifs_assert(!ubifs_zn_obsolete(zp));
-                       ubifs_assert(ubifs_zn_dirty(zp));
+                       ubifs_assert(c, !ubifs_zn_obsolete(zp));
+                       ubifs_assert(c, ubifs_zn_dirty(zp));
                        atomic_long_dec(&c->dirty_zn_cnt);
 
                        if (zp->cnext) {
@@ -2944,7 +2945,7 @@ struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c,
        union ubifs_key *dkey;
 
        dbg_tnck(key, "key ");
-       ubifs_assert(is_hash_key(c, key));
+       ubifs_assert(c, is_hash_key(c, key));
 
        mutex_lock(&c->tnc_mutex);
        err = ubifs_lookup_level0(c, key, &znode, &n);
@@ -3031,7 +3032,7 @@ static void tnc_destroy_cnext(struct ubifs_info *c)
 
        if (!c->cnext)
                return;
-       ubifs_assert(c->cmt_state == COMMIT_BROKEN);
+       ubifs_assert(c, c->cmt_state == COMMIT_BROKEN);
        cnext = c->cnext;
        do {
                struct ubifs_znode *znode = cnext;
@@ -3053,8 +3054,8 @@ void ubifs_tnc_close(struct ubifs_info *c)
                long n, freed;
 
                n = atomic_long_read(&c->clean_zn_cnt);
-               freed = ubifs_destroy_tnc_subtree(c->zroot.znode);
-               ubifs_assert(freed == n);
+               freed = ubifs_destroy_tnc_subtree(c, c->zroot.znode);
+               ubifs_assert(c, freed == n);
                atomic_long_sub(n, &ubifs_clean_zn_cnt);
        }
        kfree(c->gap_lebs);
@@ -3167,7 +3168,7 @@ static struct ubifs_znode *lookup_znode(struct ubifs_info *c,
        struct ubifs_znode *znode, *zn;
        int n, nn;
 
-       ubifs_assert(key_type(c, key) < UBIFS_INVALID_KEY);
+       ubifs_assert(c, key_type(c, key) < UBIFS_INVALID_KEY);
 
        /*
         * The arguments have probably been read off flash, so don't assume
@@ -3206,7 +3207,7 @@ static struct ubifs_znode *lookup_znode(struct ubifs_info *c,
                        if (IS_ERR(znode))
                                return znode;
                        ubifs_search_zbranch(c, znode, key, &n);
-                       ubifs_assert(n >= 0);
+                       ubifs_assert(c, n >= 0);
                }
                if (znode->level == level + 1)
                        break;
@@ -3497,7 +3498,7 @@ int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode,
        if (err < 0)
                goto out_unlock;
 
-       ubifs_assert(err == 0);
+       ubifs_assert(c, err == 0);
        key = &znode->zbranch[n].key;
        if (!key_in_range(c, key, &from_key, &to_key))
                goto out_unlock;
index a9df94ad46a34a91f95f4d25562760031937bb0a..dba87d09b989375cea13b168bd43977cd43e60ef 100644 (file)
@@ -87,8 +87,8 @@ static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx,
 
        atomic_long_dec(&c->dirty_zn_cnt);
 
-       ubifs_assert(ubifs_zn_dirty(znode));
-       ubifs_assert(ubifs_zn_cow(znode));
+       ubifs_assert(c, ubifs_zn_dirty(znode));
+       ubifs_assert(c, ubifs_zn_cow(znode));
 
        /*
         * Note, unlike 'write_index()' we do not add memory barriers here
@@ -115,9 +115,9 @@ static int fill_gap(struct ubifs_info *c, int lnum, int gap_start, int gap_end,
 {
        int len, gap_remains, gap_pos, written, pad_len;
 
-       ubifs_assert((gap_start & 7) == 0);
-       ubifs_assert((gap_end & 7) == 0);
-       ubifs_assert(gap_end >= gap_start);
+       ubifs_assert(c, (gap_start & 7) == 0);
+       ubifs_assert(c, (gap_end & 7) == 0);
+       ubifs_assert(c, gap_end >= gap_start);
 
        gap_remains = gap_end - gap_start;
        if (!gap_remains)
@@ -131,7 +131,7 @@ static int fill_gap(struct ubifs_info *c, int lnum, int gap_start, int gap_end,
                        const int alen = ALIGN(len, 8);
                        int err;
 
-                       ubifs_assert(alen <= gap_remains);
+                       ubifs_assert(c, alen <= gap_remains);
                        err = make_idx_node(c, c->ileb_buf + gap_pos, znode,
                                            lnum, gap_pos, len);
                        if (err)
@@ -259,7 +259,7 @@ static int layout_leb_in_gaps(struct ubifs_info *c, int *p)
                struct ubifs_idx_node *idx;
                int in_use, level;
 
-               ubifs_assert(snod->type == UBIFS_IDX_NODE);
+               ubifs_assert(c, snod->type == UBIFS_IDX_NODE);
                idx = snod->node;
                key_read(c, ubifs_idx_key(c, idx), &snod->key);
                level = le16_to_cpu(idx->level);
@@ -373,7 +373,7 @@ static int layout_in_gaps(struct ubifs_info *c, int cnt)
 
        p = c->gap_lebs;
        do {
-               ubifs_assert(p < c->gap_lebs + c->lst.idx_lebs);
+               ubifs_assert(c, p < c->gap_lebs + c->lst.idx_lebs);
                written = layout_leb_in_gaps(c, p);
                if (written < 0) {
                        err = written;
@@ -639,7 +639,7 @@ static int get_znodes_to_commit(struct ubifs_info *c)
        }
        cnt += 1;
        while (1) {
-               ubifs_assert(!ubifs_zn_cow(znode));
+               ubifs_assert(c, !ubifs_zn_cow(znode));
                __set_bit(COW_ZNODE, &znode->flags);
                znode->alt = 0;
                cnext = find_next_dirty(znode);
@@ -652,7 +652,7 @@ static int get_znodes_to_commit(struct ubifs_info *c)
                cnt += 1;
        }
        dbg_cmt("committing %d znodes", cnt);
-       ubifs_assert(cnt == atomic_long_read(&c->dirty_zn_cnt));
+       ubifs_assert(c, cnt == atomic_long_read(&c->dirty_zn_cnt));
        return cnt;
 }
 
@@ -760,7 +760,7 @@ int ubifs_tnc_start_commit(struct ubifs_info *c, struct ubifs_zbranch *zroot)
                err = layout_commit(c, no_space, cnt);
                if (err)
                        goto out_free;
-               ubifs_assert(atomic_long_read(&c->dirty_zn_cnt) == 0);
+               ubifs_assert(c, atomic_long_read(&c->dirty_zn_cnt) == 0);
                err = free_unused_idx_lebs(c);
                if (err)
                        goto out;
@@ -781,7 +781,7 @@ int ubifs_tnc_start_commit(struct ubifs_info *c, struct ubifs_zbranch *zroot)
         * budgeting subsystem to assume the index is already committed,
         * even though it is not.
         */
-       ubifs_assert(c->bi.min_idx_lebs == ubifs_calc_min_idx_lebs(c));
+       ubifs_assert(c, c->bi.min_idx_lebs == ubifs_calc_min_idx_lebs(c));
        c->bi.old_idx_sz = c->calc_idx_sz;
        c->bi.uncommitted_idx = 0;
        c->bi.min_idx_lebs = ubifs_calc_min_idx_lebs(c);
@@ -887,8 +887,8 @@ static int write_index(struct ubifs_info *c)
                /* Grab some stuff from znode while we still can */
                cnext = znode->cnext;
 
-               ubifs_assert(ubifs_zn_dirty(znode));
-               ubifs_assert(ubifs_zn_cow(znode));
+               ubifs_assert(c, ubifs_zn_dirty(znode));
+               ubifs_assert(c, ubifs_zn_cow(znode));
 
                /*
                 * It is important that other threads should see %DIRTY_ZNODE
index 93f5b7859e6f0ddc31acab9e75b3af3434b1ea2b..d90ee01076a9ea5559dd8afb26cffc4e61a5cb81 100644 (file)
 
 /**
  * ubifs_tnc_levelorder_next - next TNC tree element in levelorder traversal.
+ * @c: UBIFS file-system description object
  * @zr: root of the subtree to traverse
  * @znode: previous znode
  *
  * This function implements levelorder TNC traversal. The LNC is ignored.
  * Returns the next element or %NULL if @znode is already the last one.
  */
-struct ubifs_znode *ubifs_tnc_levelorder_next(struct ubifs_znode *zr,
+struct ubifs_znode *ubifs_tnc_levelorder_next(const struct ubifs_info *c,
+                                             struct ubifs_znode *zr,
                                              struct ubifs_znode *znode)
 {
        int level, iip, level_search = 0;
        struct ubifs_znode *zn;
 
-       ubifs_assert(zr);
+       ubifs_assert(c, zr);
 
        if (unlikely(!znode))
                return zr;
@@ -58,7 +60,7 @@ struct ubifs_znode *ubifs_tnc_levelorder_next(struct ubifs_znode *zr,
 
        iip = znode->iip;
        while (1) {
-               ubifs_assert(znode->level <= zr->level);
+               ubifs_assert(c, znode->level <= zr->level);
 
                /*
                 * First walk up until there is a znode with next branch to
@@ -85,7 +87,7 @@ struct ubifs_znode *ubifs_tnc_levelorder_next(struct ubifs_znode *zr,
                        level_search = 1;
                        iip = -1;
                        znode = ubifs_tnc_find_child(zr, 0);
-                       ubifs_assert(znode);
+                       ubifs_assert(c, znode);
                }
 
                /* Switch to the next index */
@@ -111,7 +113,7 @@ struct ubifs_znode *ubifs_tnc_levelorder_next(struct ubifs_znode *zr,
                }
 
                if (zn) {
-                       ubifs_assert(zn->level >= 0);
+                       ubifs_assert(c, zn->level >= 0);
                        return zn;
                }
        }
@@ -140,7 +142,7 @@ int ubifs_search_zbranch(const struct ubifs_info *c,
        int uninitialized_var(cmp);
        const struct ubifs_zbranch *zbr = &znode->zbranch[0];
 
-       ubifs_assert(end > beg);
+       ubifs_assert(c, end > beg);
 
        while (end > beg) {
                mid = (beg + end) >> 1;
@@ -158,13 +160,13 @@ int ubifs_search_zbranch(const struct ubifs_info *c,
        *n = end - 1;
 
        /* The insert point is after *n */
-       ubifs_assert(*n >= -1 && *n < znode->child_cnt);
+       ubifs_assert(c, *n >= -1 && *n < znode->child_cnt);
        if (*n == -1)
-               ubifs_assert(keys_cmp(c, key, &zbr[0].key) < 0);
+               ubifs_assert(c, keys_cmp(c, key, &zbr[0].key) < 0);
        else
-               ubifs_assert(keys_cmp(c, key, &zbr[*n].key) > 0);
+               ubifs_assert(c, keys_cmp(c, key, &zbr[*n].key) > 0);
        if (*n + 1 < znode->child_cnt)
-               ubifs_assert(keys_cmp(c, key, &zbr[*n + 1].key) < 0);
+               ubifs_assert(c, keys_cmp(c, key, &zbr[*n + 1].key) < 0);
 
        return 0;
 }
@@ -195,16 +197,18 @@ struct ubifs_znode *ubifs_tnc_postorder_first(struct ubifs_znode *znode)
 
 /**
  * ubifs_tnc_postorder_next - next TNC tree element in postorder traversal.
+ * @c: UBIFS file-system description object
  * @znode: previous znode
  *
  * This function implements postorder TNC traversal. The LNC is ignored.
  * Returns the next element or %NULL if @znode is already the last one.
  */
-struct ubifs_znode *ubifs_tnc_postorder_next(struct ubifs_znode *znode)
+struct ubifs_znode *ubifs_tnc_postorder_next(const struct ubifs_info *c,
+                                            struct ubifs_znode *znode)
 {
        struct ubifs_znode *zn;
 
-       ubifs_assert(znode);
+       ubifs_assert(c, znode);
        if (unlikely(!znode->parent))
                return NULL;
 
@@ -220,18 +224,20 @@ struct ubifs_znode *ubifs_tnc_postorder_next(struct ubifs_znode *znode)
 
 /**
  * ubifs_destroy_tnc_subtree - destroy all znodes connected to a subtree.
+ * @c: UBIFS file-system description object
  * @znode: znode defining subtree to destroy
  *
  * This function destroys subtree of the TNC tree. Returns number of clean
  * znodes in the subtree.
  */
-long ubifs_destroy_tnc_subtree(struct ubifs_znode *znode)
+long ubifs_destroy_tnc_subtree(const struct ubifs_info *c,
+                              struct ubifs_znode *znode)
 {
        struct ubifs_znode *zn = ubifs_tnc_postorder_first(znode);
        long clean_freed = 0;
        int n;
 
-       ubifs_assert(zn);
+       ubifs_assert(c, zn);
        while (1) {
                for (n = 0; n < zn->child_cnt; n++) {
                        if (!zn->zbranch[n].znode)
@@ -252,7 +258,7 @@ long ubifs_destroy_tnc_subtree(struct ubifs_znode *znode)
                        return clean_freed;
                }
 
-               zn = ubifs_tnc_postorder_next(zn);
+               zn = ubifs_tnc_postorder_next(c, zn);
        }
 }
 
@@ -410,7 +416,7 @@ struct ubifs_znode *ubifs_load_znode(struct ubifs_info *c,
        int err;
        struct ubifs_znode *znode;
 
-       ubifs_assert(!zbr->znode);
+       ubifs_assert(c, !zbr->znode);
        /*
         * A slab cache is not presently used for znodes because the znode size
         * depends on the fanout which is stored in the superblock.
@@ -435,7 +441,7 @@ struct ubifs_znode *ubifs_load_znode(struct ubifs_info *c,
 
        zbr->znode = znode;
        znode->parent = parent;
-       znode->time = get_seconds();
+       znode->time = ktime_get_seconds();
        znode->iip = iip;
 
        return znode;
index 04bf84d71e7bbae5339d4f7ceea70406be7d1cc8..4368cde476b0fa4360ab942790fb70ff62937530 100644 (file)
@@ -258,6 +258,18 @@ enum {
        LEB_RETAINED,
 };
 
+/*
+ * Action taken upon a failed ubifs_assert().
+ * @ASSACT_REPORT: just report the failed assertion
+ * @ASSACT_RO: switch to read-only mode
+ * @ASSACT_PANIC: call BUG() and possible panic the kernel
+ */
+enum {
+       ASSACT_REPORT = 0,
+       ASSACT_RO,
+       ASSACT_PANIC,
+};
+
 /**
  * struct ubifs_old_idx - index node obsoleted since last commit start.
  * @rb: rb-tree node
@@ -758,7 +770,7 @@ struct ubifs_znode {
        struct ubifs_znode *parent;
        struct ubifs_znode *cnext;
        unsigned long flags;
-       unsigned long time;
+       time64_t time;
        int level;
        int child_cnt;
        int iip;
@@ -1015,6 +1027,7 @@ struct ubifs_debug_info;
  * @bulk_read: enable bulk-reads
  * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc)
  * @rw_incompat: the media is not R/W compatible
+ * @assert_action: action to take when a ubifs_assert() fails
  *
  * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and
  *             @calc_idx_sz
@@ -1256,6 +1269,7 @@ struct ubifs_info {
        unsigned int bulk_read:1;
        unsigned int default_compr:2;
        unsigned int rw_incompat:1;
+       unsigned int assert_action:2;
 
        struct mutex tnc_mutex;
        struct ubifs_zbranch zroot;
@@ -1608,14 +1622,17 @@ int ubifs_tnc_get_bu_keys(struct ubifs_info *c, struct bu_info *bu);
 int ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu);
 
 /* tnc_misc.c */
-struct ubifs_znode *ubifs_tnc_levelorder_next(struct ubifs_znode *zr,
+struct ubifs_znode *ubifs_tnc_levelorder_next(const struct ubifs_info *c,
+                                             struct ubifs_znode *zr,
                                              struct ubifs_znode *znode);
 int ubifs_search_zbranch(const struct ubifs_info *c,
                         const struct ubifs_znode *znode,
                         const union ubifs_key *key, int *n);
 struct ubifs_znode *ubifs_tnc_postorder_first(struct ubifs_znode *znode);
-struct ubifs_znode *ubifs_tnc_postorder_next(struct ubifs_znode *znode);
-long ubifs_destroy_tnc_subtree(struct ubifs_znode *zr);
+struct ubifs_znode *ubifs_tnc_postorder_next(const struct ubifs_info *c,
+                                            struct ubifs_znode *znode);
+long ubifs_destroy_tnc_subtree(const struct ubifs_info *c,
+                              struct ubifs_znode *zr);
 struct ubifs_znode *ubifs_load_znode(struct ubifs_info *c,
                                     struct ubifs_zbranch *zbr,
                                     struct ubifs_znode *parent, int iip);
@@ -1698,7 +1715,7 @@ struct ubifs_nnode *ubifs_get_nnode(struct ubifs_info *c,
 int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip);
 void ubifs_add_lpt_dirt(struct ubifs_info *c, int lnum, int dirty);
 void ubifs_add_nnode_dirt(struct ubifs_info *c, struct ubifs_nnode *nnode);
-uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits);
+uint32_t ubifs_unpack_bits(const struct ubifs_info *c, uint8_t **addr, int *pos, int nrbits);
 struct ubifs_nnode *ubifs_first_nnode(struct ubifs_info *c, int *hght);
 /* Needed only in debugging code in lpt_commit.c */
 int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf,
@@ -1755,7 +1772,13 @@ int ubifs_xattr_set(struct inode *host, const char *name, const void *value,
                    size_t size, int flags, bool check_lock);
 ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf,
                        size_t size);
+
+#ifdef CONFIG_UBIFS_FS_XATTR
 void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum);
+#else
+static inline void ubifs_evict_xattr_inode(struct ubifs_info *c,
+                                          ino_t xattr_inum) { }
+#endif
 
 #ifdef CONFIG_UBIFS_FS_SECURITY
 extern int ubifs_init_security(struct inode *dentry, struct inode *inode,
@@ -1812,14 +1835,16 @@ static inline int ubifs_encrypt(const struct inode *inode,
                                unsigned int in_len, unsigned int *out_len,
                                int block)
 {
-       ubifs_assert(0);
+       struct ubifs_info *c = inode->i_sb->s_fs_info;
+       ubifs_assert(c, 0);
        return -EOPNOTSUPP;
 }
 static inline int ubifs_decrypt(const struct inode *inode,
                                struct ubifs_data_node *dn,
                                unsigned int *out_len, int block)
 {
-       ubifs_assert(0);
+       struct ubifs_info *c = inode->i_sb->s_fs_info;
+       ubifs_assert(c, 0);
        return -EOPNOTSUPP;
 }
 #else
index 6f720fdf5020abca26ca9d8bcae7d56792e79c4e..61afdfee4b28bcacf49c65096e1d66d3603b9a2c 100644 (file)
@@ -152,6 +152,12 @@ static int create_xattr(struct ubifs_info *c, struct inode *host,
        ui->data_len = size;
 
        mutex_lock(&host_ui->ui_mutex);
+
+       if (!host->i_nlink) {
+               err = -ENOENT;
+               goto out_noent;
+       }
+
        host->i_ctime = current_time(host);
        host_ui->xattr_cnt += 1;
        host_ui->xattr_size += CALC_DENT_SIZE(fname_len(nm));
@@ -184,6 +190,7 @@ out_cancel:
        host_ui->xattr_size -= CALC_XATTR_BYTES(size);
        host_ui->xattr_names -= fname_len(nm);
        host_ui->flags &= ~UBIFS_CRYPT_FL;
+out_noent:
        mutex_unlock(&host_ui->ui_mutex);
 out_free:
        make_bad_inode(inode);
@@ -216,7 +223,7 @@ static int change_xattr(struct ubifs_info *c, struct inode *host,
        struct ubifs_budget_req req = { .dirtied_ino = 2,
                .dirtied_ino_d = ALIGN(size, 8) + ALIGN(host_ui->data_len, 8) };
 
-       ubifs_assert(ui->data_len == inode->i_size);
+       ubifs_assert(c, ui->data_len == inode->i_size);
        err = ubifs_budget_space(c, &req);
        if (err)
                return err;
@@ -235,6 +242,12 @@ static int change_xattr(struct ubifs_info *c, struct inode *host,
        mutex_unlock(&ui->ui_mutex);
 
        mutex_lock(&host_ui->ui_mutex);
+
+       if (!host->i_nlink) {
+               err = -ENOENT;
+               goto out_noent;
+       }
+
        host->i_ctime = current_time(host);
        host_ui->xattr_size -= CALC_XATTR_BYTES(old_size);
        host_ui->xattr_size += CALC_XATTR_BYTES(size);
@@ -256,6 +269,7 @@ static int change_xattr(struct ubifs_info *c, struct inode *host,
 out_cancel:
        host_ui->xattr_size -= CALC_XATTR_BYTES(size);
        host_ui->xattr_size += CALC_XATTR_BYTES(old_size);
+out_noent:
        mutex_unlock(&host_ui->ui_mutex);
        make_bad_inode(inode);
 out_free:
@@ -291,7 +305,7 @@ int ubifs_xattr_set(struct inode *host, const char *name, const void *value,
        int err;
 
        if (check_lock)
-               ubifs_assert(inode_is_locked(host));
+               ubifs_assert(c, inode_is_locked(host));
 
        if (size > UBIFS_MAX_INO_DATA)
                return -ERANGE;
@@ -374,8 +388,8 @@ ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf,
        }
 
        ui = ubifs_inode(inode);
-       ubifs_assert(inode->i_size == ui->data_len);
-       ubifs_assert(ubifs_inode(host)->xattr_size > ui->data_len);
+       ubifs_assert(c, inode->i_size == ui->data_len);
+       ubifs_assert(c, ubifs_inode(host)->xattr_size > ui->data_len);
 
        mutex_lock(&ui->ui_mutex);
        if (buf) {
@@ -462,7 +476,7 @@ ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size)
                return err;
        }
 
-       ubifs_assert(written <= size);
+       ubifs_assert(c, written <= size);
        return written;
 }
 
@@ -475,13 +489,19 @@ static int remove_xattr(struct ubifs_info *c, struct inode *host,
        struct ubifs_budget_req req = { .dirtied_ino = 2, .mod_dent = 1,
                                .dirtied_ino_d = ALIGN(host_ui->data_len, 8) };
 
-       ubifs_assert(ui->data_len == inode->i_size);
+       ubifs_assert(c, ui->data_len == inode->i_size);
 
        err = ubifs_budget_space(c, &req);
        if (err)
                return err;
 
        mutex_lock(&host_ui->ui_mutex);
+
+       if (!host->i_nlink) {
+               err = -ENOENT;
+               goto out_noent;
+       }
+
        host->i_ctime = current_time(host);
        host_ui->xattr_cnt -= 1;
        host_ui->xattr_size -= CALC_DENT_SIZE(fname_len(nm));
@@ -501,6 +521,7 @@ out_cancel:
        host_ui->xattr_size += CALC_DENT_SIZE(fname_len(nm));
        host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len);
        host_ui->xattr_names += fname_len(nm);
+out_noent:
        mutex_unlock(&host_ui->ui_mutex);
        ubifs_release_budget(c, &req);
        make_bad_inode(inode);
@@ -538,7 +559,10 @@ static int ubifs_xattr_remove(struct inode *host, const char *name)
        union ubifs_key key;
        int err;
 
-       ubifs_assert(inode_is_locked(host));
+       ubifs_assert(c, inode_is_locked(host));
+
+       if (!host->i_nlink)
+               return -ENOENT;
 
        if (fname_len(&nm) > UBIFS_MAX_NLEN)
                return -ENAMETOOLONG;
@@ -561,7 +585,7 @@ static int ubifs_xattr_remove(struct inode *host, const char *name)
                goto out_free;
        }
 
-       ubifs_assert(inode->i_nlink == 1);
+       ubifs_assert(c, inode->i_nlink == 1);
        clear_nlink(inode);
        err = remove_xattr(c, host, inode, &nm);
        if (err)
index 3040dc2a32f6a17a4822343497577e871b03161c..6f515651a2c2fe3817c763e3d77d351509a862d9 100644 (file)
@@ -764,9 +764,7 @@ static int udf_find_fileset(struct super_block *sb,
                            struct kernel_lb_addr *root)
 {
        struct buffer_head *bh = NULL;
-       long lastblock;
        uint16_t ident;
-       struct udf_sb_info *sbi;
 
        if (fileset->logicalBlockNum != 0xFFFFFFFF ||
            fileset->partitionReferenceNum != 0xFFFF) {
@@ -779,69 +777,11 @@ static int udf_find_fileset(struct super_block *sb,
                        return 1;
                }
 
-       }
-
-       sbi = UDF_SB(sb);
-       if (!bh) {
-               /* Search backwards through the partitions */
-               struct kernel_lb_addr newfileset;
-
-/* --> cvg: FIXME - is it reasonable? */
-               return 1;
-
-               for (newfileset.partitionReferenceNum = sbi->s_partitions - 1;
-                    (newfileset.partitionReferenceNum != 0xFFFF &&
-                     fileset->logicalBlockNum == 0xFFFFFFFF &&
-                     fileset->partitionReferenceNum == 0xFFFF);
-                    newfileset.partitionReferenceNum--) {
-                       lastblock = sbi->s_partmaps
-                                       [newfileset.partitionReferenceNum]
-                                               .s_partition_len;
-                       newfileset.logicalBlockNum = 0;
-
-                       do {
-                               bh = udf_read_ptagged(sb, &newfileset, 0,
-                                                     &ident);
-                               if (!bh) {
-                                       newfileset.logicalBlockNum++;
-                                       continue;
-                               }
-
-                               switch (ident) {
-                               case TAG_IDENT_SBD:
-                               {
-                                       struct spaceBitmapDesc *sp;
-                                       sp = (struct spaceBitmapDesc *)
-                                                               bh->b_data;
-                                       newfileset.logicalBlockNum += 1 +
-                                               ((le32_to_cpu(sp->numOfBytes) +
-                                                 sizeof(struct spaceBitmapDesc)
-                                                 - 1) >> sb->s_blocksize_bits);
-                                       brelse(bh);
-                                       break;
-                               }
-                               case TAG_IDENT_FSD:
-                                       *fileset = newfileset;
-                                       break;
-                               default:
-                                       newfileset.logicalBlockNum++;
-                                       brelse(bh);
-                                       bh = NULL;
-                                       break;
-                               }
-                       } while (newfileset.logicalBlockNum < lastblock &&
-                                fileset->logicalBlockNum == 0xFFFFFFFF &&
-                                fileset->partitionReferenceNum == 0xFFFF);
-               }
-       }
-
-       if ((fileset->logicalBlockNum != 0xFFFFFFFF ||
-            fileset->partitionReferenceNum != 0xFFFF) && bh) {
                udf_debug("Fileset at block=%u, partition=%u\n",
                          fileset->logicalBlockNum,
                          fileset->partitionReferenceNum);
 
-               sbi->s_partition = fileset->partitionReferenceNum;
+               UDF_SB(sb)->s_partition = fileset->partitionReferenceNum;
                udf_load_fileset(sb, bh, root);
                brelse(bh);
                return 0;
@@ -1570,10 +1510,16 @@ static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_
  */
 #define PART_DESC_ALLOC_STEP 32
 
+struct part_desc_seq_scan_data {
+       struct udf_vds_record rec;
+       u32 partnum;
+};
+
 struct desc_seq_scan_data {
        struct udf_vds_record vds[VDS_POS_LENGTH];
        unsigned int size_part_descs;
-       struct udf_vds_record *part_descs_loc;
+       unsigned int num_part_descs;
+       struct part_desc_seq_scan_data *part_descs_loc;
 };
 
 static struct udf_vds_record *handle_partition_descriptor(
@@ -1582,10 +1528,14 @@ static struct udf_vds_record *handle_partition_descriptor(
 {
        struct partitionDesc *desc = (struct partitionDesc *)bh->b_data;
        int partnum;
+       int i;
 
        partnum = le16_to_cpu(desc->partitionNumber);
-       if (partnum >= data->size_part_descs) {
-               struct udf_vds_record *new_loc;
+       for (i = 0; i < data->num_part_descs; i++)
+               if (partnum == data->part_descs_loc[i].partnum)
+                       return &(data->part_descs_loc[i].rec);
+       if (data->num_part_descs >= data->size_part_descs) {
+               struct part_desc_seq_scan_data *new_loc;
                unsigned int new_size = ALIGN(partnum, PART_DESC_ALLOC_STEP);
 
                new_loc = kcalloc(new_size, sizeof(*new_loc), GFP_KERNEL);
@@ -1597,7 +1547,7 @@ static struct udf_vds_record *handle_partition_descriptor(
                data->part_descs_loc = new_loc;
                data->size_part_descs = new_size;
        }
-       return &(data->part_descs_loc[partnum]);
+       return &(data->part_descs_loc[data->num_part_descs++].rec);
 }
 
 
@@ -1647,6 +1597,7 @@ static noinline int udf_process_sequence(
 
        memset(data.vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
        data.size_part_descs = PART_DESC_ALLOC_STEP;
+       data.num_part_descs = 0;
        data.part_descs_loc = kcalloc(data.size_part_descs,
                                      sizeof(*data.part_descs_loc),
                                      GFP_KERNEL);
@@ -1658,7 +1609,6 @@ static noinline int udf_process_sequence(
         * are in it.
         */
        for (; (!done && block <= lastblock); block++) {
-
                bh = udf_read_tagged(sb, block, block, &ident);
                if (!bh)
                        break;
@@ -1730,13 +1680,10 @@ static noinline int udf_process_sequence(
        }
 
        /* Now handle prevailing Partition Descriptors */
-       for (i = 0; i < data.size_part_descs; i++) {
-               if (data.part_descs_loc[i].block) {
-                       ret = udf_load_partdesc(sb,
-                                               data.part_descs_loc[i].block);
-                       if (ret < 0)
-                               return ret;
-               }
+       for (i = 0; i < data.num_part_descs; i++) {
+               ret = udf_load_partdesc(sb, data.part_descs_loc[i].rec.block);
+               if (ret < 0)
+                       return ret;
        }
 
        return 0;
index 15c265d450bf897568aed207c8fccdb6a00f40f9..bfa0ec69f924bcbdebca1456d007b89d4e172a1c 100644 (file)
@@ -340,17 +340,15 @@ out:
  * fatal_signal_pending()s, and the mmap_sem must be released before
  * returning it.
  */
-int handle_userfault(struct vm_fault *vmf, unsigned long reason)
+vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason)
 {
        struct mm_struct *mm = vmf->vma->vm_mm;
        struct userfaultfd_ctx *ctx;
        struct userfaultfd_wait_queue uwq;
-       int ret;
+       vm_fault_t ret = VM_FAULT_SIGBUS;
        bool must_wait, return_to_userland;
        long blocking_state;
 
-       ret = VM_FAULT_SIGBUS;
-
        /*
         * We don't do userfault handling for the final child pid update.
         *
@@ -910,7 +908,7 @@ wakeup:
         */
        spin_lock(&ctx->fault_pending_wqh.lock);
        __wake_up_locked_key(&ctx->fault_pending_wqh, TASK_NORMAL, &range);
-       __wake_up_locked_key(&ctx->fault_wqh, TASK_NORMAL, &range);
+       __wake_up(&ctx->fault_wqh, TASK_NORMAL, 1, &range);
        spin_unlock(&ctx->fault_pending_wqh.lock);
 
        /* Flush pending events that may still wait on event_wqh */
@@ -1066,7 +1064,7 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,
                         * anyway.
                         */
                        list_del(&uwq->wq.entry);
-                       __add_wait_queue(&ctx->fault_wqh, &uwq->wq);
+                       add_wait_queue(&ctx->fault_wqh, &uwq->wq);
 
                        write_seqcount_end(&ctx->refile_seq);
 
@@ -1215,7 +1213,7 @@ static void __wake_userfault(struct userfaultfd_ctx *ctx,
                __wake_up_locked_key(&ctx->fault_pending_wqh, TASK_NORMAL,
                                     range);
        if (waitqueue_active(&ctx->fault_wqh))
-               __wake_up_locked_key(&ctx->fault_wqh, TASK_NORMAL, range);
+               __wake_up(&ctx->fault_wqh, TASK_NORMAL, 1, range);
        spin_unlock(&ctx->fault_pending_wqh.lock);
 }
 
index f9cb1db187b740b9b7ef8cd19be9cdb6155d9300..daa732550088957538842fc34f8d84228ccbde33 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/posix_acl_xattr.h>
 
 #include <linux/uaccess.h>
-#include "internal.h"
 
 static const char *
 strcmp_prefix(const char *a, const char *a_prefix)
@@ -501,10 +500,10 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
        if (!f.file)
                return error;
        audit_file(f.file);
-       error = mnt_want_write_file_path(f.file);
+       error = mnt_want_write_file(f.file);
        if (!error) {
                error = setxattr(f.file->f_path.dentry, name, value, size, flags);
-               mnt_drop_write_file_path(f.file);
+               mnt_drop_write_file(f.file);
        }
        fdput(f);
        return error;
@@ -539,7 +538,7 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
        if (error > 0) {
                if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
                    (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
-                       posix_acl_fix_xattr_to_user(kvalue, size);
+                       posix_acl_fix_xattr_to_user(kvalue, error);
                if (size && copy_to_user(value, kvalue, error))
                        error = -EFAULT;
        } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) {
@@ -733,10 +732,10 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
        if (!f.file)
                return error;
        audit_file(f.file);
-       error = mnt_want_write_file_path(f.file);
+       error = mnt_want_write_file(f.file);
        if (!error) {
                error = removexattr(f.file->f_path.dentry, name);
-               mnt_drop_write_file_path(f.file);
+               mnt_drop_write_file(f.file);
        }
        fdput(f);
        return error;
index 17cf4856439034450e5a83c1ca1e8cb6d421f1e3..9f08dd9bf1d553934bf2aa2f8a108ab8435bc19c 100644 (file)
@@ -195,8 +195,8 @@ xrep_calc_ag_resblks(
        struct xfs_scrub_metadata       *sm = sc->sm;
        struct xfs_perag                *pag;
        struct xfs_buf                  *bp;
-       xfs_agino_t                     icount = 0;
-       xfs_extlen_t                    aglen = 0;
+       xfs_agino_t                     icount = NULLAGINO;
+       xfs_extlen_t                    aglen = NULLAGBLOCK;
        xfs_extlen_t                    usedlen;
        xfs_extlen_t                    freelen;
        xfs_extlen_t                    bnobt_sz;
@@ -208,20 +208,14 @@ xrep_calc_ag_resblks(
        if (!(sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR))
                return 0;
 
-       /* Use in-core counters if possible. */
        pag = xfs_perag_get(mp, sm->sm_agno);
-       if (pag->pagi_init)
+       if (pag->pagi_init) {
+               /* Use in-core icount if possible. */
                icount = pag->pagi_count;
-
-       /*
-        * Otherwise try to get the actual counters from disk; if not, make
-        * some worst case assumptions.
-        */
-       if (icount == 0) {
+       } else {
+               /* Try to get the actual counters from disk. */
                error = xfs_ialloc_read_agi(mp, NULL, sm->sm_agno, &bp);
-               if (error) {
-                       icount = mp->m_sb.sb_agblocks / mp->m_sb.sb_inopblock;
-               } else {
+               if (!error) {
                        icount = pag->pagi_count;
                        xfs_buf_relse(bp);
                }
@@ -229,18 +223,32 @@ xrep_calc_ag_resblks(
 
        /* Now grab the block counters from the AGF. */
        error = xfs_alloc_read_agf(mp, NULL, sm->sm_agno, 0, &bp);
-       if (error) {
-               aglen = mp->m_sb.sb_agblocks;
-               freelen = aglen;
-               usedlen = aglen;
-       } else {
+       if (!error) {
                aglen = be32_to_cpu(XFS_BUF_TO_AGF(bp)->agf_length);
-               freelen = pag->pagf_freeblks;
+               freelen = be32_to_cpu(XFS_BUF_TO_AGF(bp)->agf_freeblks);
                usedlen = aglen - freelen;
                xfs_buf_relse(bp);
        }
        xfs_perag_put(pag);
 
+       /* If the icount is impossible, make some worst-case assumptions. */
+       if (icount == NULLAGINO ||
+           !xfs_verify_agino(mp, sm->sm_agno, icount)) {
+               xfs_agino_t     first, last;
+
+               xfs_agino_range(mp, sm->sm_agno, &first, &last);
+               icount = last - first + 1;
+       }
+
+       /* If the block counts are impossible, make worst-case assumptions. */
+       if (aglen == NULLAGBLOCK ||
+           aglen != xfs_ag_block_count(mp, sm->sm_agno) ||
+           freelen >= aglen) {
+               aglen = xfs_ag_block_count(mp, sm->sm_agno);
+               freelen = aglen;
+               usedlen = aglen;
+       }
+
        trace_xrep_calc_ag_resblks(mp, sm->sm_agno, icount, aglen,
                        freelen, usedlen);
 
index 5eaef2c17293095d9505914140f88950e791dfcd..61a5ad2600e865a6b11a8345f956eba10203abd2 100644 (file)
@@ -931,31 +931,16 @@ xfs_file_clone_range(
                                     len, false);
 }
 
-STATIC ssize_t
+STATIC int
 xfs_file_dedupe_range(
-       struct file     *src_file,
-       u64             loff,
-       u64             len,
-       struct file     *dst_file,
-       u64             dst_loff)
+       struct file     *file_in,
+       loff_t          pos_in,
+       struct file     *file_out,
+       loff_t          pos_out,
+       u64             len)
 {
-       struct inode    *srci = file_inode(src_file);
-       u64             max_dedupe;
-       int             error;
-
-       /*
-        * Since we have to read all these pages in to compare them, cut
-        * it off at MAX_RW_COUNT/2 rounded down to the nearest block.
-        * That means we won't do more than MAX_RW_COUNT IO per request.
-        */
-       max_dedupe = (MAX_RW_COUNT >> 1) & ~(i_blocksize(srci) - 1);
-       if (len > max_dedupe)
-               len = max_dedupe;
-       error = xfs_reflink_remap_range(src_file, loff, dst_file, dst_loff,
+       return xfs_reflink_remap_range(file_in, pos_in, file_out, pos_out,
                                     len, true);
-       if (error)
-               return error;
-       return len;
 }
 
 STATIC int
index 99db27d6ac8a4f25de6405d69a8952144b277847..02d15098dbee3f830101dbca3aef7cad04bb4ba8 100644 (file)
@@ -637,6 +637,7 @@ xfs_check_summary_counts(
         */
        if (XFS_LAST_UNMOUNT_WAS_CLEAN(mp) &&
            (mp->m_sb.sb_fdblocks > mp->m_sb.sb_dblocks ||
+            !xfs_verify_icount(mp, mp->m_sb.sb_icount) ||
             mp->m_sb.sb_ifree > mp->m_sb.sb_icount))
                mp->m_flags |= XFS_MOUNT_BAD_SUMMARY;
 
index 012c55cb22bae5edade614aa975877a1537e30c2..e6964e97acdd832d41425562aa7a51d9b24b9145 100644 (file)
@@ -89,7 +89,7 @@
 
 /* Maximum object reference count (detects object deletion issues) */
 
-#define ACPI_MAX_REFERENCE_COUNT        0x1000
+#define ACPI_MAX_REFERENCE_COUNT        0x4000
 
 /* Default page size for use in mapping memory for operation regions */
 
index 226e5aeba6c21b03465afd2e9177b50994ce425d..856c56ef01431e0467ac63fadeeee0907202c2f0 100644 (file)
@@ -59,6 +59,12 @@ struct acpi_exception_info {
 
 #define AE_OK                           (acpi_status) 0x0000
 
+#define ACPI_ENV_EXCEPTION(status)      (status & AE_CODE_ENVIRONMENTAL)
+#define ACPI_AML_EXCEPTION(status)      (status & AE_CODE_AML)
+#define ACPI_PROG_EXCEPTION(status)     (status & AE_CODE_PROGRAMMER)
+#define ACPI_TABLE_EXCEPTION(status)    (status & AE_CODE_ACPI_TABLES)
+#define ACPI_CNTL_EXCEPTION(status)     (status & AE_CODE_CONTROL)
+
 /*
  * Environmental exceptions
  */
index 88072c92ace25af8a89b0966adf07018b914ca24..9566f99cc3c054e0775ebfedcf42a3bf209670d6 100644 (file)
@@ -12,7 +12,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20180629
+#define ACPI_CA_VERSION                 0x20180810
 
 #include <acpi/acconfig.h>
 #include <acpi/actypes.h>
index a7613e1b0c87a4a38635b6fe99333afde18238b6..20561a60db9c4f077c68ee1a182eac38ff96d4dd 100644 (file)
@@ -75,9 +75,19 @@ struct bug_entry {
 
 /*
  * WARN(), WARN_ON(), WARN_ON_ONCE, and so on can be used to report
- * significant issues that need prompt attention if they should ever
- * appear at runtime.  Use the versions with printk format strings
- * to provide better diagnostics.
+ * significant kernel issues that need prompt attention if they should ever
+ * appear at runtime.
+ *
+ * Do not use these macros when checking for invalid external inputs
+ * (e.g. invalid system call arguments, or invalid data coming from
+ * network/devices), and on transient conditions like ENOMEM or EAGAIN.
+ * These macros should be used for recoverable kernel issues only.
+ * For invalid external inputs, transient conditions, etc use
+ * pr_err[_once/_ratelimited]() followed by dump_stack(), if necessary.
+ * Do not include "BUG"/"WARNING" in format strings manually to make these
+ * conditions distinguishable from kernel issues.
+ *
+ * Use the versions with printk format strings to provide better diagnostics.
  */
 #ifndef __WARN_TAINT
 extern __printf(3, 4)
index 68efb950a9184cae22225a38a0fc7d9053cffa8a..4d73e6e3c66c6977acd08e97fa93e2e229a9b283 100644 (file)
@@ -5,12 +5,10 @@
 #define KSYM_FUNC(x) x
 #endif
 #ifdef CONFIG_64BIT
-#define __put .quad
 #ifndef KSYM_ALIGN
 #define KSYM_ALIGN 8
 #endif
 #else
-#define __put .long
 #ifndef KSYM_ALIGN
 #define KSYM_ALIGN 4
 #endif
 #define KCRC_ALIGN 4
 #endif
 
+.macro __put, val, name
+#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
+       .long   \val - ., \name - .
+#elif defined(CONFIG_64BIT)
+       .quad   \val, \name
+#else
+       .long   \val, \name
+#endif
+.endm
+
 /*
  * note on .section use: @progbits vs %progbits nastiness doesn't matter,
  * since we immediately emit into those sections anyway.
index e811ef7b835006e232bad707f02fd5dfdc7e0691..b3353e21f3b3ec95220e1706bae89d3969d9e918 100644 (file)
@@ -15,6 +15,7 @@
 #ifndef _ASM_GENERIC__TLB_H
 #define _ASM_GENERIC__TLB_H
 
+#include <linux/mmu_notifier.h>
 #include <linux/swap.h>
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
@@ -138,6 +139,16 @@ static inline void __tlb_reset_range(struct mmu_gather *tlb)
        }
 }
 
+static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb)
+{
+       if (!tlb->end)
+               return;
+
+       tlb_flush(tlb);
+       mmu_notifier_invalidate_range(tlb->mm, tlb->start, tlb->end);
+       __tlb_reset_range(tlb);
+}
+
 static inline void tlb_remove_page_size(struct mmu_gather *tlb,
                                        struct page *page, int page_size)
 {
@@ -186,10 +197,8 @@ static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
 
 #define __tlb_end_vma(tlb, vma)                                        \
        do {                                                    \
-               if (!tlb->fullmm && tlb->end) {                 \
-                       tlb_flush(tlb);                         \
-                       __tlb_reset_range(tlb);                 \
-               }                                               \
+               if (!tlb->fullmm)                               \
+                       tlb_flush_mmu_tlbonly(tlb);             \
        } while (0)
 
 #ifndef tlb_end_vma
@@ -303,14 +312,4 @@ static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
 
 #define tlb_migrate_finish(mm) do {} while (0)
 
-/*
- * Used to flush the TLB when page tables are removed, when lazy
- * TLB mode may cause a CPU to retain intermediate translations
- * pointing to about-to-be-freed page table memory.
- */
-#ifndef HAVE_TLB_FLUSH_REMOVE_TABLES
-#define tlb_flush_remove_tables(mm) do {} while (0)
-#define tlb_flush_remove_tables_local(mm) do {} while (0)
-#endif
-
 #endif /* _ASM_GENERIC__TLB_H */
index f173b5f30dbe9a68192cd5892cdcab37d8cb81ed..7b75ff6e2fceeb407e828c4e171176afc5ae7281 100644 (file)
@@ -54,8 +54,6 @@
 #define LOAD_OFFSET 0
 #endif
 
-#include <linux/export.h>
-
 /* Align . to a 8 byte boundary equals to maximum function alignment. */
 #define ALIGN_FUNCTION()  . = ALIGN(8)
 
index 2c005376ac0e3f68f4631180acbe7c83a06d415e..7138384e2ef9f4ef9865d4b417ea986ff9e36ef3 100644 (file)
@@ -15,6 +15,8 @@
 /* SmartReflex sysc found on 36xx and later */
 #define SYSC_OMAP3_SR_ENAWAKEUP                (1 << 26)
 
+#define SYSC_DRA7_MCAN_ENAWAKEUP       (1 << 4)
+
 /* SYSCONFIG STANDBYMODE/MIDLEMODE/SIDLEMODE supported by hardware */
 #define SYSC_IDLE_FORCE                        0
 #define SYSC_IDLE_NO                   1
index 5e1061b15aed95bb1392dc58bf723e689dc6861e..d7549c57cac36c66bae2373eef4e517acb022f7b 100644 (file)
 #define DRA7_COUNTER_32K_CLKCTRL       DRA7_CLKCTRL_INDEX(0x50)
 #define DRA7_UART10_CLKCTRL    DRA7_CLKCTRL_INDEX(0x80)
 #define DRA7_DCAN1_CLKCTRL     DRA7_CLKCTRL_INDEX(0x88)
+#define DRA7_ADC_CLKCTRL       DRA7_CLKCTRL_INDEX(0xa0)
 
 #endif
diff --git a/include/dt-bindings/clock/exynos5440.h b/include/dt-bindings/clock/exynos5440.h
deleted file mode 100644 (file)
index 842cdc0..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2013 Samsung Electronics Co., Ltd.
- * Author: Andrzej Hajda <a.hajda@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.
- *
- * Device Tree binding constants for Exynos5440 clock controller.
-*/
-
-#ifndef _DT_BINDINGS_CLOCK_EXYNOS_5440_H
-#define _DT_BINDINGS_CLOCK_EXYNOS_5440_H
-
-#define CLK_XTAL               1
-#define CLK_ARM_CLK            2
-#define CLK_CPLLA              3
-#define CLK_CPLLB              4
-#define CLK_SPI_BAUD           16
-#define CLK_PB0_250            17
-#define CLK_PR0_250            18
-#define CLK_PR1_250            19
-#define CLK_B_250              20
-#define CLK_B_125              21
-#define CLK_B_200              22
-#define CLK_SATA               23
-#define CLK_USB                        24
-#define CLK_GMAC0              25
-#define CLK_CS250              26
-#define CLK_PB0_250_O          27
-#define CLK_PR0_250_O          28
-#define CLK_PR1_250_O          29
-#define CLK_B_250_O            30
-#define CLK_B_125_O            31
-#define CLK_B_200_O            32
-#define CLK_SATA_O             33
-#define CLK_USB_O              34
-#define CLK_GMAC0_O            35
-#define CLK_CS250_O            36
-
-/* must be greater than maximal clock id */
-#define CLK_NR_CLKS            37
-
-#endif /* _DT_BINDINGS_CLOCK_EXYNOS_5440_H */
diff --git a/include/dt-bindings/memory/mt2712-larb-port.h b/include/dt-bindings/memory/mt2712-larb-port.h
new file mode 100644 (file)
index 0000000..6f9aa73
--- /dev/null
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ * Author: Yong Wu <yong.wu@mediatek.com>
+ */
+#ifndef __DTS_IOMMU_PORT_MT2712_H
+#define __DTS_IOMMU_PORT_MT2712_H
+
+#define MTK_M4U_ID(larb, port)         (((larb) << 5) | (port))
+
+#define M4U_LARB0_ID                   0
+#define M4U_LARB1_ID                   1
+#define M4U_LARB2_ID                   2
+#define M4U_LARB3_ID                   3
+#define M4U_LARB4_ID                   4
+#define M4U_LARB5_ID                   5
+#define M4U_LARB6_ID                   6
+#define M4U_LARB7_ID                   7
+#define M4U_LARB8_ID                   8
+#define M4U_LARB9_ID                   9
+
+/* larb0 */
+#define M4U_PORT_DISP_OVL0             MTK_M4U_ID(M4U_LARB0_ID, 0)
+#define M4U_PORT_DISP_RDMA0            MTK_M4U_ID(M4U_LARB0_ID, 1)
+#define M4U_PORT_DISP_WDMA0            MTK_M4U_ID(M4U_LARB0_ID, 2)
+#define M4U_PORT_DISP_OD_R             MTK_M4U_ID(M4U_LARB0_ID, 3)
+#define M4U_PORT_DISP_OD_W             MTK_M4U_ID(M4U_LARB0_ID, 4)
+#define M4U_PORT_MDP_RDMA0             MTK_M4U_ID(M4U_LARB0_ID, 5)
+#define M4U_PORT_MDP_WDMA              MTK_M4U_ID(M4U_LARB0_ID, 6)
+#define M4U_PORT_DISP_RDMA2            MTK_M4U_ID(M4U_LARB0_ID, 7)
+
+/* larb1 */
+#define M4U_PORT_HW_VDEC_MC_EXT                MTK_M4U_ID(M4U_LARB1_ID, 0)
+#define M4U_PORT_HW_VDEC_PP_EXT                MTK_M4U_ID(M4U_LARB1_ID, 1)
+#define M4U_PORT_HW_VDEC_UFO_EXT       MTK_M4U_ID(M4U_LARB1_ID, 2)
+#define M4U_PORT_HW_VDEC_VLD_EXT       MTK_M4U_ID(M4U_LARB1_ID, 3)
+#define M4U_PORT_HW_VDEC_VLD2_EXT      MTK_M4U_ID(M4U_LARB1_ID, 4)
+#define M4U_PORT_HW_VDEC_AVC_MV_EXT    MTK_M4U_ID(M4U_LARB1_ID, 5)
+#define M4U_PORT_HW_VDEC_PRED_RD_EXT   MTK_M4U_ID(M4U_LARB1_ID, 6)
+#define M4U_PORT_HW_VDEC_PRED_WR_EXT   MTK_M4U_ID(M4U_LARB1_ID, 7)
+#define M4U_PORT_HW_VDEC_PPWRAP_EXT    MTK_M4U_ID(M4U_LARB1_ID, 8)
+#define M4U_PORT_HW_VDEC_TILE          MTK_M4U_ID(M4U_LARB1_ID, 9)
+#define M4U_PORT_HW_IMG_RESZ_EXT       MTK_M4U_ID(M4U_LARB1_ID, 10)
+
+/* larb2 */
+#define M4U_PORT_CAM_DMA0              MTK_M4U_ID(M4U_LARB2_ID, 0)
+#define M4U_PORT_CAM_DMA1              MTK_M4U_ID(M4U_LARB2_ID, 1)
+#define M4U_PORT_CAM_DMA2              MTK_M4U_ID(M4U_LARB2_ID, 2)
+
+/* larb3 */
+#define M4U_PORT_VENC_RCPU             MTK_M4U_ID(M4U_LARB3_ID, 0)
+#define M4U_PORT_VENC_REC              MTK_M4U_ID(M4U_LARB3_ID, 1)
+#define M4U_PORT_VENC_BSDMA            MTK_M4U_ID(M4U_LARB3_ID, 2)
+#define M4U_PORT_VENC_SV_COMV          MTK_M4U_ID(M4U_LARB3_ID, 3)
+#define M4U_PORT_VENC_RD_COMV          MTK_M4U_ID(M4U_LARB3_ID, 4)
+#define M4U_PORT_VENC_CUR_CHROMA       MTK_M4U_ID(M4U_LARB3_ID, 5)
+#define M4U_PORT_VENC_REF_CHROMA       MTK_M4U_ID(M4U_LARB3_ID, 6)
+#define M4U_PORT_VENC_CUR_LUMA         MTK_M4U_ID(M4U_LARB3_ID, 7)
+#define M4U_PORT_VENC_REF_LUMA         MTK_M4U_ID(M4U_LARB3_ID, 8)
+
+/* larb4 */
+#define M4U_PORT_DISP_OVL1             MTK_M4U_ID(M4U_LARB4_ID, 0)
+#define M4U_PORT_DISP_RDMA1            MTK_M4U_ID(M4U_LARB4_ID, 1)
+#define M4U_PORT_DISP_WDMA1            MTK_M4U_ID(M4U_LARB4_ID, 2)
+#define M4U_PORT_DISP_OD1_R            MTK_M4U_ID(M4U_LARB4_ID, 3)
+#define M4U_PORT_DISP_OD1_W            MTK_M4U_ID(M4U_LARB4_ID, 4)
+#define M4U_PORT_MDP_RDMA1             MTK_M4U_ID(M4U_LARB4_ID, 5)
+#define M4U_PORT_MDP_WROT1             MTK_M4U_ID(M4U_LARB4_ID, 6)
+
+/* larb5 */
+#define M4U_PORT_DISP_OVL2             MTK_M4U_ID(M4U_LARB5_ID, 0)
+#define M4U_PORT_DISP_WDMA2            MTK_M4U_ID(M4U_LARB5_ID, 1)
+#define M4U_PORT_MDP_RDMA2             MTK_M4U_ID(M4U_LARB5_ID, 2)
+#define M4U_PORT_MDP_WROT0             MTK_M4U_ID(M4U_LARB5_ID, 3)
+
+/* larb6 */
+#define M4U_PORT_JPGDEC_WDMA_0         MTK_M4U_ID(M4U_LARB6_ID, 0)
+#define M4U_PORT_JPGDEC_WDMA_1         MTK_M4U_ID(M4U_LARB6_ID, 1)
+#define M4U_PORT_JPGDEC_BSDMA_0                MTK_M4U_ID(M4U_LARB6_ID, 2)
+#define M4U_PORT_JPGDEC_BSDMA_1                MTK_M4U_ID(M4U_LARB6_ID, 3)
+
+/* larb7 */
+#define M4U_PORT_MDP_RDMA3             MTK_M4U_ID(M4U_LARB7_ID, 0)
+#define M4U_PORT_MDP_WROT2             MTK_M4U_ID(M4U_LARB7_ID, 1)
+
+/* larb8 */
+#define M4U_PORT_VDO                   MTK_M4U_ID(M4U_LARB8_ID, 0)
+#define M4U_PORT_NR                    MTK_M4U_ID(M4U_LARB8_ID, 1)
+#define M4U_PORT_WR_CHANNEL0           MTK_M4U_ID(M4U_LARB8_ID, 2)
+
+/* larb9 */
+#define M4U_PORT_TVD                   MTK_M4U_ID(M4U_LARB9_ID, 0)
+#define M4U_PORT_WR_CHANNEL1           MTK_M4U_ID(M4U_LARB9_ID, 1)
+
+#endif
diff --git a/include/dt-bindings/reset/amlogic,meson-axg-audio-arb.h b/include/dt-bindings/reset/amlogic,meson-axg-audio-arb.h
new file mode 100644 (file)
index 0000000..05c3636
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT)
+ *
+ * Copyright (c) 2018 Baylibre SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+#ifndef _DT_BINDINGS_AMLOGIC_MESON_AXG_AUDIO_ARB_H
+#define _DT_BINDINGS_AMLOGIC_MESON_AXG_AUDIO_ARB_H
+
+#define AXG_ARB_TODDR_A        0
+#define AXG_ARB_TODDR_B        1
+#define AXG_ARB_TODDR_C        2
+#define AXG_ARB_FRDDR_A        3
+#define AXG_ARB_FRDDR_B        4
+#define AXG_ARB_FRDDR_C        5
+
+#endif /* _DT_BINDINGS_AMLOGIC_MESON_AXG_AUDIO_ARB_H */
diff --git a/include/dt-bindings/reset/qcom,sdm845-aoss.h b/include/dt-bindings/reset/qcom,sdm845-aoss.h
new file mode 100644 (file)
index 0000000..476c5fc
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_RESET_AOSS_SDM_845_H
+#define _DT_BINDINGS_RESET_AOSS_SDM_845_H
+
+#define AOSS_CC_MSS_RESTART    0
+#define AOSS_CC_CAMSS_RESTART  1
+#define AOSS_CC_VENUS_RESTART  2
+#define AOSS_CC_GPU_RESTART    3
+#define AOSS_CC_DISPSS_RESTART 4
+#define AOSS_CC_WCSS_RESTART   5
+#define AOSS_CC_LPASS_RESTART  6
+
+#endif
index cfdd2484cc4263375fbb3ba527a75db2789bbb36..4f31f96bbfabd06aad4691366861946fed570bbf 100644 (file)
@@ -133,6 +133,7 @@ struct vgic_irq {
        u8 source;                      /* GICv2 SGIs only */
        u8 active_source;               /* GICv2 SGIs only */
        u8 priority;
+       u8 group;                       /* 0 == group 0, 1 == group 1 */
        enum vgic_irq_config config;    /* Level or edge */
 
        /*
@@ -217,6 +218,12 @@ struct vgic_dist {
        /* vGIC model the kernel emulates for the guest (GICv2 or GICv3) */
        u32                     vgic_model;
 
+       /* Implementation revision as reported in the GICD_IIDR */
+       u32                     implementation_rev;
+
+       /* Userspace can write to GICv2 IGROUPR */
+       bool                    v2_groups_user_writable;
+
        /* Do injected MSIs require an additional device ID? */
        bool                    msis_require_devid;
 
@@ -366,7 +373,7 @@ void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
 void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
 void kvm_vgic_reset_mapped_irq(struct kvm_vcpu *vcpu, u32 vintid);
 
-void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
+void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg, bool allow_group1);
 
 /**
  * kvm_vgic_get_max_vcpus - Get the maximum number of VCPUs allowed by HW
index 1b0a17b22cd3c8e224a7d3dd1fdaa155830ac49a..eaedca5fe6fca8c84f02b90ccecad44ac72c84b9 100644 (file)
@@ -30,7 +30,7 @@ void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv);
 int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
 void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
 struct ahci_host_priv *ahci_platform_get_resources(
-       struct platform_device *pdev);
+       struct platform_device *pdev, unsigned int flags);
 int ahci_platform_init_host(struct platform_device *pdev,
                            struct ahci_host_priv *hpriv,
                            const struct ata_port_info *pi_template,
@@ -43,4 +43,6 @@ int ahci_platform_resume_host(struct device *dev);
 int ahci_platform_suspend(struct device *dev);
 int ahci_platform_resume(struct device *dev);
 
+#define AHCI_PLATFORM_GET_RESETS       0x01
+
 #endif /* _AHCI_PLATFORM_H */
index ca1d2cc2cdfa09a8a760693b6b3c10e9c3f6a704..18863d56273cc7ea144bfaf366a2c74755ee72c9 100644 (file)
@@ -199,47 +199,57 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
 
 #define __declare_arg_0(a0, res)                                       \
        struct arm_smccc_res   *___res = res;                           \
-       register u32           r0 asm("r0") = a0;                       \
+       register unsigned long r0 asm("r0") = (u32)a0;                  \
        register unsigned long r1 asm("r1");                            \
        register unsigned long r2 asm("r2");                            \
        register unsigned long r3 asm("r3")
 
 #define __declare_arg_1(a0, a1, res)                                   \
+       typeof(a1) __a1 = a1;                                           \
        struct arm_smccc_res   *___res = res;                           \
-       register u32           r0 asm("r0") = a0;                       \
-       register typeof(a1)    r1 asm("r1") = a1;                       \
+       register unsigned long r0 asm("r0") = (u32)a0;                  \
+       register unsigned long r1 asm("r1") = __a1;                     \
        register unsigned long r2 asm("r2");                            \
        register unsigned long r3 asm("r3")
 
 #define __declare_arg_2(a0, a1, a2, res)                               \
+       typeof(a1) __a1 = a1;                                           \
+       typeof(a2) __a2 = a2;                                           \
        struct arm_smccc_res   *___res = res;                           \
-       register u32           r0 asm("r0") = a0;                       \
-       register typeof(a1)    r1 asm("r1") = a1;                       \
-       register typeof(a2)    r2 asm("r2") = a2;                       \
+       register unsigned long r0 asm("r0") = (u32)a0;                  \
+       register unsigned long r1 asm("r1") = __a1;                     \
+       register unsigned long r2 asm("r2") = __a2;                     \
        register unsigned long r3 asm("r3")
 
 #define __declare_arg_3(a0, a1, a2, a3, res)                           \
+       typeof(a1) __a1 = a1;                                           \
+       typeof(a2) __a2 = a2;                                           \
+       typeof(a3) __a3 = a3;                                           \
        struct arm_smccc_res   *___res = res;                           \
-       register u32           r0 asm("r0") = a0;                       \
-       register typeof(a1)    r1 asm("r1") = a1;                       \
-       register typeof(a2)    r2 asm("r2") = a2;                       \
-       register typeof(a3)    r3 asm("r3") = a3
+       register unsigned long r0 asm("r0") = (u32)a0;                  \
+       register unsigned long r1 asm("r1") = __a1;                     \
+       register unsigned long r2 asm("r2") = __a2;                     \
+       register unsigned long r3 asm("r3") = __a3
 
 #define __declare_arg_4(a0, a1, a2, a3, a4, res)                       \
+       typeof(a4) __a4 = a4;                                           \
        __declare_arg_3(a0, a1, a2, a3, res);                           \
-       register typeof(a4) r4 asm("r4") = a4
+       register unsigned long r4 asm("r4") = __a4
 
 #define __declare_arg_5(a0, a1, a2, a3, a4, a5, res)                   \
+       typeof(a5) __a5 = a5;                                           \
        __declare_arg_4(a0, a1, a2, a3, a4, res);                       \
-       register typeof(a5) r5 asm("r5") = a5
+       register unsigned long r5 asm("r5") = __a5
 
 #define __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res)               \
+       typeof(a6) __a6 = a6;                                           \
        __declare_arg_5(a0, a1, a2, a3, a4, a5, res);                   \
-       register typeof(a6) r6 asm("r6") = a6
+       register unsigned long r6 asm("r6") = __a6
 
 #define __declare_arg_7(a0, a1, a2, a3, a4, a5, a6, a7, res)           \
+       typeof(a7) __a7 = a7;                                           \
        __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res);               \
-       register typeof(a7) r7 asm("r7") = a7
+       register unsigned long r7 asm("r7") = __a7
 
 #define ___declare_args(count, ...) __declare_arg_ ## count(__VA_ARGS__)
 #define __declare_args(count, ...)  ___declare_args(count, __VA_ARGS__)
index 24251762c20c94edd238cfca1c1f55f0269d4e80..9a6bc0951cfaf1559607ea2a6a6df6f1abb106f0 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/timer.h>
 #include <linux/workqueue.h>
 #include <linux/kref.h>
+#include <linux/refcount.h>
 
 struct page;
 struct device;
@@ -75,7 +76,7 @@ enum wb_reason {
  */
 struct bdi_writeback_congested {
        unsigned long state;            /* WB_[a]sync_congested flags */
-       atomic_t refcnt;                /* nr of attached wb's and blkg */
+       refcount_t refcnt;              /* nr of attached wb's and blkg */
 
 #ifdef CONFIG_CGROUP_WRITEBACK
        struct backing_dev_info *__bdi; /* the associated bdi, set to NULL
index 72ca0f3d39f3039b0cda57c2a350c941075bdd62..c28a47cbe355ea8e74e94e72035cdae8d16cb168 100644 (file)
@@ -404,13 +404,13 @@ static inline bool inode_cgwb_enabled(struct inode *inode)
 static inline struct bdi_writeback_congested *
 wb_congested_get_create(struct backing_dev_info *bdi, int blkcg_id, gfp_t gfp)
 {
-       atomic_inc(&bdi->wb_congested->refcnt);
+       refcount_inc(&bdi->wb_congested->refcnt);
        return bdi->wb_congested;
 }
 
 static inline void wb_congested_put(struct bdi_writeback_congested *congested)
 {
-       if (atomic_dec_and_test(&congested->refcnt))
+       if (refcount_dec_and_test(&congested->refcnt))
                kfree(congested);
 }
 
index af419012d77de428dd7df26c958001f615ab8c3f..7ddb1349394dbc4472779592ce590366d7571094 100644 (file)
@@ -4,7 +4,8 @@
 #include <asm/types.h>
 #include <linux/bits.h>
 
-#define BITS_TO_LONGS(nr)      DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
+#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
+#define BITS_TO_LONGS(nr)      DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
 
 extern unsigned int __sw_hweight8(unsigned int w);
 extern unsigned int __sw_hweight16(unsigned int w);
index 34aec30e06c734a47bc9806990eb816994ad2a98..6d766a19f2bbb2b62facc79ff3871aa81be68534 100644 (file)
@@ -56,6 +56,7 @@ struct blkcg {
        struct list_head                all_blkcgs_node;
 #ifdef CONFIG_CGROUP_WRITEBACK
        struct list_head                cgwb_list;
+       refcount_t                      cgwb_refcnt;
 #endif
 };
 
@@ -89,7 +90,6 @@ struct blkg_policy_data {
        /* the blkg and policy id this per-policy data belongs to */
        struct blkcg_gq                 *blkg;
        int                             plid;
-       bool                            offline;
 };
 
 /*
@@ -387,6 +387,49 @@ static inline struct blkcg *cpd_to_blkcg(struct blkcg_policy_data *cpd)
        return cpd ? cpd->blkcg : NULL;
 }
 
+extern void blkcg_destroy_blkgs(struct blkcg *blkcg);
+
+#ifdef CONFIG_CGROUP_WRITEBACK
+
+/**
+ * blkcg_cgwb_get - get a reference for blkcg->cgwb_list
+ * @blkcg: blkcg of interest
+ *
+ * This is used to track the number of active wb's related to a blkcg.
+ */
+static inline void blkcg_cgwb_get(struct blkcg *blkcg)
+{
+       refcount_inc(&blkcg->cgwb_refcnt);
+}
+
+/**
+ * blkcg_cgwb_put - put a reference for @blkcg->cgwb_list
+ * @blkcg: blkcg of interest
+ *
+ * This is used to track the number of active wb's related to a blkcg.
+ * When this count goes to zero, all active wb has finished so the
+ * blkcg can continue destruction by calling blkcg_destroy_blkgs().
+ * This work may occur in cgwb_release_workfn() on the cgwb_release
+ * workqueue.
+ */
+static inline void blkcg_cgwb_put(struct blkcg *blkcg)
+{
+       if (refcount_dec_and_test(&blkcg->cgwb_refcnt))
+               blkcg_destroy_blkgs(blkcg);
+}
+
+#else
+
+static inline void blkcg_cgwb_get(struct blkcg *blkcg) { }
+
+static inline void blkcg_cgwb_put(struct blkcg *blkcg)
+{
+       /* wb isn't being accounted, so trigger destruction right away */
+       blkcg_destroy_blkgs(blkcg);
+}
+
+#endif
+
 /**
  * blkg_path - format cgroup path of blkg
  * @blkg: blkg of interest
index e931da8424a44f82666cf0233a2e1c527c1442e3..6728c2ee0205d3770286400839f22c7bfeccdfc1 100644 (file)
@@ -64,6 +64,10 @@ struct ceph_auth_client_ops {
        /* ensure that an existing authorizer is up to date */
        int (*update_authorizer)(struct ceph_auth_client *ac, int peer_type,
                                 struct ceph_auth_handshake *auth);
+       int (*add_authorizer_challenge)(struct ceph_auth_client *ac,
+                                       struct ceph_authorizer *a,
+                                       void *challenge_buf,
+                                       int challenge_buf_len);
        int (*verify_authorizer_reply)(struct ceph_auth_client *ac,
                                       struct ceph_authorizer *a);
        void (*invalidate_authorizer)(struct ceph_auth_client *ac,
@@ -118,6 +122,10 @@ void ceph_auth_destroy_authorizer(struct ceph_authorizer *a);
 extern int ceph_auth_update_authorizer(struct ceph_auth_client *ac,
                                       int peer_type,
                                       struct ceph_auth_handshake *a);
+int ceph_auth_add_authorizer_challenge(struct ceph_auth_client *ac,
+                                      struct ceph_authorizer *a,
+                                      void *challenge_buf,
+                                      int challenge_buf_len);
 extern int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
                                             struct ceph_authorizer *a);
 extern void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac,
index 3901927cf6a0618122798e8b16491099d35e2cda..6b92b3395fa9954ec140df3ed5b2b6d7b4f527f1 100644 (file)
@@ -165,9 +165,9 @@ DEFINE_CEPH_FEATURE(58, 1, FS_FILE_LAYOUT_V2) // overlap
 DEFINE_CEPH_FEATURE(59, 1, FS_BTIME)
 DEFINE_CEPH_FEATURE(59, 1, FS_CHANGE_ATTR) // overlap
 DEFINE_CEPH_FEATURE(59, 1, MSG_ADDR2) // overlap
-DEFINE_CEPH_FEATURE(60, 1, BLKIN_TRACING)  // *do not share this bit*
+DEFINE_CEPH_FEATURE(60, 1, OSD_RECOVERY_DELETES) // *do not share this bit*
+DEFINE_CEPH_FEATURE(61, 1, CEPHX_V2)             // *do not share this bit*
 
-DEFINE_CEPH_FEATURE(61, 1, RESERVED2)          // unused, but slow down!
 DEFINE_CEPH_FEATURE(62, 1, RESERVED)           // do not use; used as a sentinal
 DEFINE_CEPH_FEATURE_DEPRECATED(63, 1, RESERVED_BROKEN, LUMINOUS) // client-facing
 
@@ -210,7 +210,8 @@ DEFINE_CEPH_FEATURE_DEPRECATED(63, 1, RESERVED_BROKEN, LUMINOUS) // client-facin
         CEPH_FEATURE_SERVER_JEWEL |            \
         CEPH_FEATURE_MON_STATEFUL_SUB |        \
         CEPH_FEATURE_CRUSH_TUNABLES5 |         \
-        CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING)
+        CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING | \
+        CEPH_FEATURE_CEPHX_V2)
 
 #define CEPH_FEATURES_REQUIRED_DEFAULT   \
        (CEPH_FEATURE_NOSRCADDR |        \
index d143ac8879c6bdcbbed432e4cedf8e897194e1fb..a6c2a48d42e02a7e20abc4434e381968855dc6e6 100644 (file)
@@ -194,16 +194,22 @@ ceph_decode_skip_n(p, end, sizeof(u8), bad)
        } while (0)
 
 /*
- * struct ceph_timespec <-> struct timespec
+ * struct ceph_timespec <-> struct timespec64
  */
-static inline void ceph_decode_timespec(struct timespec *ts,
-                                       const struct ceph_timespec *tv)
+static inline void ceph_decode_timespec64(struct timespec64 *ts,
+                                         const struct ceph_timespec *tv)
 {
-       ts->tv_sec = (__kernel_time_t)le32_to_cpu(tv->tv_sec);
+       /*
+        * This will still overflow in year 2106.  We could extend
+        * the protocol to steal two more bits from tv_nsec to
+        * add three more 136 year epochs after that the way ext4
+        * does if necessary.
+        */
+       ts->tv_sec = (time64_t)le32_to_cpu(tv->tv_sec);
        ts->tv_nsec = (long)le32_to_cpu(tv->tv_nsec);
 }
-static inline void ceph_encode_timespec(struct ceph_timespec *tv,
-                                       const struct timespec *ts)
+static inline void ceph_encode_timespec64(struct ceph_timespec *tv,
+                                         const struct timespec64 *ts)
 {
        tv->tv_sec = cpu_to_le32((u32)ts->tv_sec);
        tv->tv_nsec = cpu_to_le32((u32)ts->tv_nsec);
index c7dfcb8a1fb2fcb5e253ab0202955a0752d5b844..fc2b4491ee0aac1101ef553b6bf4e88d9807b7bb 100644 (file)
@@ -31,6 +31,9 @@ struct ceph_connection_operations {
        struct ceph_auth_handshake *(*get_authorizer) (
                                struct ceph_connection *con,
                               int *proto, int force_new);
+       int (*add_authorizer_challenge)(struct ceph_connection *con,
+                                       void *challenge_buf,
+                                       int challenge_buf_len);
        int (*verify_authorizer_reply) (struct ceph_connection *con);
        int (*invalidate_authorizer)(struct ceph_connection *con);
 
@@ -286,9 +289,8 @@ struct ceph_connection {
                                 attempt for this connection, client */
        u32 peer_global_seq;  /* peer's global seq for this connection */
 
+       struct ceph_auth_handshake *auth;
        int auth_retry;       /* true if we need a newer authorizer */
-       void *auth_reply_buf;   /* where to put the authorizer reply */
-       int auth_reply_buf_len;
 
        struct mutex mutex;
 
@@ -330,7 +332,7 @@ struct ceph_connection {
        int in_base_pos;     /* bytes read */
        __le64 in_temp_ack;  /* for reading an ack */
 
-       struct timespec last_keepalive_ack; /* keepalive2 ack stamp */
+       struct timespec64 last_keepalive_ack; /* keepalive2 ack stamp */
 
        struct delayed_work work;           /* send|recv work */
        unsigned long       delay;          /* current delay interval */
index 73ae2a92654851fd7fd68eaf71481e635dc6ca08..9e50aede46c8327bec9309b2ad21eb1ecff2c711 100644 (file)
@@ -91,7 +91,7 @@ struct ceph_entity_inst {
 #define CEPH_MSGR_TAG_SEQ           13 /* 64-bit int follows with seen seq number */
 #define CEPH_MSGR_TAG_KEEPALIVE2    14 /* keepalive2 byte + ceph_timespec */
 #define CEPH_MSGR_TAG_KEEPALIVE2_ACK 15 /* keepalive2 reply */
-
+#define CEPH_MSGR_TAG_CHALLENGE_AUTHORIZER 16  /* cephx v2 doing server challenge */
 
 /*
  * connection negotiation
index 0d6ee04b4c417c3fcd82c320ce3c7f2a75254d13..02096da01845c992d5b8217a9291337fed3ff6cd 100644 (file)
@@ -199,7 +199,7 @@ struct ceph_osd_request {
        /* set by submitter */
        u64 r_snapid;                         /* for reads, CEPH_NOSNAP o/w */
        struct ceph_snap_context *r_snapc;    /* for writes */
-       struct timespec r_mtime;              /* ditto */
+       struct timespec64 r_mtime;            /* ditto */
        u64 r_data_offset;                    /* ditto */
        bool r_linger;                        /* don't resend on failure */
 
@@ -253,7 +253,7 @@ struct ceph_osd_linger_request {
        struct ceph_osd_request_target t;
        u32 map_dne_bound;
 
-       struct timespec mtime;
+       struct timespec64 mtime;
 
        struct kref kref;
        struct mutex lock;
@@ -508,7 +508,7 @@ extern int ceph_osdc_writepages(struct ceph_osd_client *osdc,
                                struct ceph_snap_context *sc,
                                u64 off, u64 len,
                                u32 truncate_seq, u64 truncate_size,
-                               struct timespec *mtime,
+                               struct timespec64 *mtime,
                                struct page **pages, int nr_pages);
 
 /* watch/notify */
@@ -528,12 +528,12 @@ int ceph_osdc_notify_ack(struct ceph_osd_client *osdc,
                         u64 notify_id,
                         u64 cookie,
                         void *payload,
-                        size_t payload_len);
+                        u32 payload_len);
 int ceph_osdc_notify(struct ceph_osd_client *osdc,
                     struct ceph_object_id *oid,
                     struct ceph_object_locator *oloc,
                     void *payload,
-                    size_t payload_len,
+                    u32 payload_len,
                     u32 timeout,
                     struct page ***preply_pages,
                     size_t *preply_len);
index 7edcded0764185732adfb824c94770878201cbf0..d0223364349f772ae4086ddc1304e02cf53a9d89 100644 (file)
@@ -68,7 +68,7 @@ static inline int ceph_pagelist_encode_8(struct ceph_pagelist *pl, u8 v)
        return ceph_pagelist_append(pl, &v, 1);
 }
 static inline int ceph_pagelist_encode_string(struct ceph_pagelist *pl,
-                                             char *s, size_t len)
+                                             char *s, u32 len)
 {
        int ret = ceph_pagelist_encode_32(pl, len);
        if (ret)
index 6aca5ce8a99a5fb52dc5b8a89cc51d8573f771db..931ab05f771d66046fcd566f713bbeaf25139b50 100644 (file)
 #define        AT91_CKGR_MOR           0x20                    /* Main Oscillator Register [not on SAM9RL] */
 #define                AT91_PMC_MOSCEN         (1    <<  0)            /* Main Oscillator Enable */
 #define                AT91_PMC_OSCBYPASS      (1    <<  1)            /* Oscillator Bypass */
+#define                AT91_PMC_WAITMODE       (1    <<  2)            /* Wait Mode Command */
 #define                AT91_PMC_MOSCRCEN       (1    <<  3)            /* Main On-Chip RC Oscillator Enable [some SAM9] */
 #define                AT91_PMC_OSCOUNT        (0xff <<  8)            /* Main Oscillator Start-up Time */
+#define                AT91_PMC_KEY_MASK       (0xff << 16)
 #define                AT91_PMC_KEY            (0x37 << 16)            /* MOR Writing Key */
 #define                AT91_PMC_MOSCSEL        (1    << 24)            /* Main Oscillator Selection [some SAM9] */
 #define                AT91_PMC_CFDEN          (1    << 25)            /* Clock Failure Detector Enable [some SAM9] */
 #define                AT91_PMC_GCKRDY         (1 << 24)               /* Generated Clocks */
 #define        AT91_PMC_IMR            0x6c                    /* Interrupt Mask Register */
 
+#define AT91_PMC_FSMR          0x70            /* Fast Startup Mode Register */
+#define AT91_PMC_FSTT(n)       BIT(n)
+#define AT91_PMC_RTCAL         BIT(17)         /* RTC Alarm Enable */
+#define AT91_PMC_USBAL         BIT(18)         /* USB Resume Enable */
+#define AT91_PMC_SDMMC_CD      BIT(19)         /* SDMMC Card Detect Enable */
+#define AT91_PMC_LPM           BIT(20)         /* Low-power Mode */
+#define AT91_PMC_RXLP_MCE      BIT(24)         /* Backup UART Receive Enable */
+#define AT91_PMC_ACC_CE                BIT(25)         /* ACC Enable */
+
+#define AT91_PMC_FSPR          0x74            /* Fast Startup Polarity Reg */
+
+#define AT91_PMC_FS_INPUT_MASK  0x7ff
+
 #define AT91_PMC_PLLICPR       0x80                    /* PLL Charge Pump Current Register */
 
 #define AT91_PMC_PROT          0xe4                    /* Write Protect Mode Register [some SAM9] */
index 7087446c24c8c5d1f471925c17a9512dc213e1fc..b1ce500fe8b3df06a8fca84d6f022b02813000f8 100644 (file)
@@ -6,11 +6,7 @@
 /* Some compiler specific definitions are overwritten here
  * for Clang compiler
  */
-
-#ifdef uninitialized_var
-#undef uninitialized_var
 #define uninitialized_var(x) x = *(&(x))
-#endif
 
 /* same as gcc, this was present in clang-2.6 so we can assume it works
  * with any version that can compile the kernel
 #define __SANITIZE_ADDRESS__
 #endif
 
-#undef __no_sanitize_address
 #define __no_sanitize_address __attribute__((no_sanitize("address")))
 
-/* Clang doesn't have a way to turn it off per-function, yet. */
-#ifdef __noretpoline
-#undef __noretpoline
-#endif
-
 /*
  * Not all versions of clang implement the the type-generic versions
  * of the builtin overflow checkers. Fortunately, clang implements
  * checks. Unfortunately, we don't know which version of gcc clang
  * pretends to be, so the macro may or may not be defined.
  */
-#undef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW
 #if __has_builtin(__builtin_mul_overflow) && \
     __has_builtin(__builtin_add_overflow) && \
     __has_builtin(__builtin_sub_overflow)
 #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1
 #endif
+
+/* The following are for compatibility with GCC, from compiler-gcc.h,
+ * and may be redefined here because they should not be shared with other
+ * compilers, like ICC.
+ */
+#define barrier() __asm__ __volatile__("" : : : "memory")
+#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
+#define __assume_aligned(a, ...)       \
+       __attribute__((__assume_aligned__(a, ## __VA_ARGS__)))
index 250b9b7cfd60b5020a910becb5867bd768dc461f..763bbad1e258048d9ea3e32764f4a79b8c5b59fb 100644 (file)
 #define __must_be_array(a)     BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
 #endif
 
-/*
- * Feature detection for gnu_inline (gnu89 extern inline semantics). Either
- * __GNUC_STDC_INLINE__ is defined (not using gnu89 extern inline semantics,
- * and we opt in to the gnu89 semantics), or __GNUC_STDC_INLINE__ is not
- * defined so the gnu89 semantics are the default.
- */
-#ifdef __GNUC_STDC_INLINE__
-# define __gnu_inline  __attribute__((gnu_inline))
-#else
-# define __gnu_inline
-#endif
-
-/*
- * Force always-inline if the user requests it so via the .config,
- * or if gcc is too old.
- * GCC does not warn about unused static inline functions for
- * -Wunused-function.  This turns out to avoid the need for complex #ifdef
- * directives.  Suppress the warning in clang as well by using "unused"
- * function attribute, which is redundant but not harmful for gcc.
- * Prefer gnu_inline, so that extern inline functions do not emit an
- * externally visible function. This makes extern inline behave as per gnu89
- * semantics rather than c99. This prevents multiple symbol definition errors
- * of extern inline functions at link time.
- * A lot of inline functions can cause havoc with function tracing.
- */
-#if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) ||               \
-    !defined(CONFIG_OPTIMIZE_INLINING)
-#define inline \
-       inline __attribute__((always_inline, unused)) notrace __gnu_inline
-#else
-#define inline inline          __attribute__((unused)) notrace __gnu_inline
-#endif
-
-#define __inline__ inline
-#define __inline inline
-#define __always_inline        inline __attribute__((always_inline))
-#define  noinline      __attribute__((noinline))
-
-#define __packed       __attribute__((packed))
-#define __weak         __attribute__((weak))
-#define __alias(symbol)        __attribute__((alias(#symbol)))
-
 #ifdef RETPOLINE
 #define __noretpoline __attribute__((indirect_branch("keep")))
 #endif
  */
 #define __naked                __attribute__((naked)) noinline __noclone notrace
 
-#define __noreturn     __attribute__((noreturn))
-
-/*
- * From the GCC manual:
- *
- * Many functions have no effects except the return value and their
- * return value depends only on the parameters and/or global
- * variables.  Such a function can be subject to common subexpression
- * elimination and loop optimization just as an arithmetic operator
- * would be.
- * [...]
- */
-#define __pure                 __attribute__((pure))
-#define __aligned(x)           __attribute__((aligned(x)))
-#define __aligned_largest      __attribute__((aligned))
-#define __printf(a, b)         __attribute__((format(printf, a, b)))
-#define __scanf(a, b)          __attribute__((format(scanf, a, b)))
-#define __attribute_const__    __attribute__((__const__))
-#define __maybe_unused         __attribute__((unused))
-#define __always_unused                __attribute__((unused))
-#define __mode(x)               __attribute__((mode(x)))
-
-#define __must_check           __attribute__((warn_unused_result))
-#define __malloc               __attribute__((__malloc__))
-
-#define __used                 __attribute__((__used__))
-#define __compiler_offsetof(a, b)                                      \
-       __builtin_offsetof(a, b)
-
-/* Mark functions as cold. gcc will assume any path leading to a call
- * to them will be unlikely.  This means a lot of manual unlikely()s
- * are unnecessary now for any paths leading to the usual suspects
- * like BUG(), printk(), panic() etc. [but let's keep them for now for
- * older compilers]
- *
- * Early snapshots of gcc 4.3 don't support this and we can't detect this
- * in the preprocessor, but we can live with this because they're unreleased.
- * Maketime probing would be overkill here.
- *
- * gcc also has a __attribute__((__hot__)) to move hot functions into
- * a special section, but I don't see any sense in this right now in
- * the kernel context
- */
-#define __cold                 __attribute__((__cold__))
-
 #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
 
 #define __optimize(level)      __attribute__((__optimize__(level)))
-#define __nostackprotector     __optimize("no-stack-protector")
 
 #define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
 
index 547cdc920a3c8128e704e207b125d2c644cc3b15..4c7f9befa9f6c66694c8146aafe4139614733d18 100644 (file)
 /* Intel ECC compiler doesn't support gcc specific asm stmts.
  * It uses intrinsics to do the equivalent things.
  */
-#undef barrier
-#undef barrier_data
-#undef RELOC_HIDE
-#undef OPTIMIZER_HIDE_VAR
 
 #define barrier() __memory_barrier()
 #define barrier_data(ptr) barrier()
 
 #endif
 
-#ifndef __HAVE_BUILTIN_BSWAP16__
 /* icc has this, but it's called _bswap16 */
 #define __HAVE_BUILTIN_BSWAP16__
 #define __builtin_bswap16 _bswap16
-#endif
 
-/*
- * icc defines __GNUC__, but does not implement the builtin overflow checkers.
+/* The following are for compatibility with GCC, from compiler-gcc.h,
+ * and may be redefined here because they should not be shared with other
+ * compilers, like clang.
  */
-#undef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW
+#define __visible      __attribute__((externally_visible))
index 42506e4d1f53699a10d100e4d49a098c95d27b10..681d866efb1eb858c377cae5a35806e2931a97d8 100644 (file)
@@ -280,6 +280,25 @@ unsigned long read_word_at_a_time(const void *addr)
 
 #endif /* __KERNEL__ */
 
+/*
+ * Force the compiler to emit 'sym' as a symbol, so that we can reference
+ * it from inline assembler. Necessary in case 'sym' could be inlined
+ * otherwise, or eliminated entirely due to lack of references that are
+ * visible to the compiler.
+ */
+#define __ADDRESSABLE(sym) \
+       static void * __attribute__((section(".discard.addressable"), used)) \
+               __PASTE(__addressable_##sym, __LINE__) = (void *)&sym;
+
+/**
+ * offset_to_ptr - convert a relative memory offset to an absolute pointer
+ * @off:       the address of the 32-bit offset value
+ */
+static inline void *offset_to_ptr(const int *off)
+{
+       return (void *)((unsigned long)off + *off);
+}
+
 #endif /* __ASSEMBLY__ */
 
 #ifndef __optimize
@@ -313,7 +332,7 @@ unsigned long read_word_at_a_time(const void *addr)
 #ifdef __OPTIMIZE__
 # define __compiletime_assert(condition, msg, prefix, suffix)          \
        do {                                                            \
-               bool __cond = !(condition);                             \
+               int __cond = !(condition);                              \
                extern void prefix ## suffix(void) __compiletime_error(msg); \
                if (__cond)                                             \
                        prefix ## suffix();                             \
index fbf337933fd816bb247937010583239a358878f7..3525c179698c238c70145574c03e71620054777c 100644 (file)
@@ -54,32 +54,32 @@ extern void __chk_io_ptr(const volatile void __iomem *);
 
 #ifdef __KERNEL__
 
-#ifdef __GNUC__
+/* Compiler specific macros. */
+#ifdef __clang__
+#include <linux/compiler-clang.h>
+#elif defined(__INTEL_COMPILER)
+#include <linux/compiler-intel.h>
+#elif defined(__GNUC__)
+/* The above compilers also define __GNUC__, so order is important here. */
 #include <linux/compiler-gcc.h>
-#endif
-
-#if defined(CC_USING_HOTPATCH) && !defined(__CHECKER__)
-#define notrace __attribute__((hotpatch(0,0)))
 #else
-#define notrace __attribute__((no_instrument_function))
+#error "Unknown compiler"
 #endif
 
-/* Intel compiler defines __GNUC__. So we will overwrite implementations
- * coming from above header files here
- */
-#ifdef __INTEL_COMPILER
-# include <linux/compiler-intel.h>
-#endif
-
-/* Clang compiler defines __GNUC__. So we will overwrite implementations
- * coming from above header files here
+/*
+ * Some architectures need to provide custom definitions of macros provided
+ * by linux/compiler-*.h, and can do so using asm/compiler.h. We include that
+ * conditionally rather than using an asm-generic wrapper in order to avoid
+ * build failures if any C compilation, which will include this file via an
+ * -include argument in c_flags, occurs prior to the asm-generic wrappers being
+ * generated.
  */
-#ifdef __clang__
-#include <linux/compiler-clang.h>
+#ifdef CONFIG_HAVE_ARCH_COMPILER_H
+#include <asm/compiler.h>
 #endif
 
 /*
- * Generic compiler-dependent macros required for kernel
+ * Generic compiler-independent macros required for kernel
  * build go below this comment. Actual compiler/compiler version
  * specific implementations come from the above header files
  */
@@ -106,93 +106,19 @@ struct ftrace_likely_data {
        unsigned long                   constant;
 };
 
-#endif /* __KERNEL__ */
-
-#endif /* __ASSEMBLY__ */
-
-#ifdef __KERNEL__
-
 /* Don't. Just don't. */
 #define __deprecated
 #define __deprecated_for_modules
 
-#ifndef __must_check
-#define __must_check
-#endif
-
-#ifndef CONFIG_ENABLE_MUST_CHECK
-#undef __must_check
-#define __must_check
-#endif
-
-#ifndef __malloc
-#define __malloc
-#endif
-
-/*
- * Allow us to avoid 'defined but not used' warnings on functions and data,
- * as well as force them to be emitted to the assembly file.
- *
- * As of gcc 3.4, static functions that are not marked with attribute((used))
- * may be elided from the assembly file.  As of gcc 3.4, static data not so
- * marked will not be elided, but this may change in a future gcc version.
- *
- * NOTE: Because distributions shipped with a backported unit-at-a-time
- * compiler in gcc 3.3, we must define __used to be __attribute__((used))
- * for gcc >=3.3 instead of 3.4.
- *
- * In prior versions of gcc, such functions and data would be emitted, but
- * would be warned about except with attribute((unused)).
- *
- * Mark functions that are referenced only in inline assembly as __used so
- * the code is emitted even though it appears to be unreferenced.
- */
-#ifndef __used
-# define __used                        /* unimplemented */
-#endif
-
-#ifndef __maybe_unused
-# define __maybe_unused                /* unimplemented */
-#endif
-
-#ifndef __always_unused
-# define __always_unused       /* unimplemented */
-#endif
-
-#ifndef noinline
-#define noinline
-#endif
-
-/*
- * Rather then using noinline to prevent stack consumption, use
- * noinline_for_stack instead.  For documentation reasons.
- */
-#define noinline_for_stack noinline
-
-#ifndef __always_inline
-#define __always_inline inline
-#endif
-
 #endif /* __KERNEL__ */
 
+#endif /* __ASSEMBLY__ */
+
 /*
- * From the GCC manual:
- *
- * Many functions do not examine any values except their arguments,
- * and have no effects except the return value.  Basically this is
- * just slightly more strict class than the `pure' attribute above,
- * since function is not allowed to read global memory.
- *
- * Note that a function that has pointer arguments and examines the
- * data pointed to must _not_ be declared `const'.  Likewise, a
- * function that calls a non-`const' function usually must not be
- * `const'.  It does not make sense for a `const' function to return
- * `void'.
+ * The below symbols may be defined for one or more, but not ALL, of the above
+ * compilers. We don't consider that to be an error, so set them to nothing.
+ * For example, some of them are for compiler specific plugins.
  */
-#ifndef __attribute_const__
-# define __attribute_const__   /* unimplemented */
-#endif
-
 #ifndef __designated_init
 # define __designated_init
 #endif
@@ -214,28 +140,10 @@ struct ftrace_likely_data {
 # define randomized_struct_fields_end
 #endif
 
-/*
- * Tell gcc if a function is cold. The compiler will assume any path
- * directly leading to the call is unlikely.
- */
-
-#ifndef __cold
-#define __cold
-#endif
-
-/* Simple shorthand for a section definition */
-#ifndef __section
-# define __section(S) __attribute__ ((__section__(#S)))
-#endif
-
 #ifndef __visible
 #define __visible
 #endif
 
-#ifndef __nostackprotector
-# define __nostackprotector
-#endif
-
 /*
  * Assume alignment of return value.
  */
@@ -243,17 +151,23 @@ struct ftrace_likely_data {
 #define __assume_aligned(a, ...)
 #endif
 
-
 /* Are two types/vars the same type (ignoring qualifiers)? */
-#ifndef __same_type
-# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
-#endif
+#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
 
 /* Is this type a native word size -- useful for atomic operations */
-#ifndef __native_word
-# define __native_word(t) (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
+#define __native_word(t) \
+       (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
+        sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
+
+#ifndef __attribute_const__
+#define __attribute_const__    __attribute__((__const__))
 #endif
 
+#ifndef __noclone
+#define __noclone
+#endif
+
+/* Helpers for emitting diagnostics in pragmas. */
 #ifndef __diag
 #define __diag(string)
 #endif
@@ -272,4 +186,92 @@ struct ftrace_likely_data {
 #define __diag_error(compiler, version, option, comment) \
        __diag_ ## compiler(version, error, option)
 
+/*
+ * From the GCC manual:
+ *
+ * Many functions have no effects except the return value and their
+ * return value depends only on the parameters and/or global
+ * variables.  Such a function can be subject to common subexpression
+ * elimination and loop optimization just as an arithmetic operator
+ * would be.
+ * [...]
+ */
+#define __pure                 __attribute__((pure))
+#define __aligned(x)           __attribute__((aligned(x)))
+#define __aligned_largest      __attribute__((aligned))
+#define __printf(a, b)         __attribute__((format(printf, a, b)))
+#define __scanf(a, b)          __attribute__((format(scanf, a, b)))
+#define __maybe_unused         __attribute__((unused))
+#define __always_unused                __attribute__((unused))
+#define __mode(x)              __attribute__((mode(x)))
+#define __malloc               __attribute__((__malloc__))
+#define __used                 __attribute__((__used__))
+#define __noreturn             __attribute__((noreturn))
+#define __packed               __attribute__((packed))
+#define __weak                 __attribute__((weak))
+#define __alias(symbol)                __attribute__((alias(#symbol)))
+#define __cold                 __attribute__((cold))
+#define __section(S)           __attribute__((__section__(#S)))
+
+
+#ifdef CONFIG_ENABLE_MUST_CHECK
+#define __must_check           __attribute__((warn_unused_result))
+#else
+#define __must_check
+#endif
+
+#if defined(CC_USING_HOTPATCH) && !defined(__CHECKER__)
+#define notrace                        __attribute__((hotpatch(0, 0)))
+#else
+#define notrace                        __attribute__((no_instrument_function))
+#endif
+
+#define __compiler_offsetof(a, b)      __builtin_offsetof(a, b)
+
+/*
+ * Feature detection for gnu_inline (gnu89 extern inline semantics). Either
+ * __GNUC_STDC_INLINE__ is defined (not using gnu89 extern inline semantics,
+ * and we opt in to the gnu89 semantics), or __GNUC_STDC_INLINE__ is not
+ * defined so the gnu89 semantics are the default.
+ */
+#ifdef __GNUC_STDC_INLINE__
+# define __gnu_inline  __attribute__((gnu_inline))
+#else
+# define __gnu_inline
+#endif
+
+/*
+ * Force always-inline if the user requests it so via the .config.
+ * GCC does not warn about unused static inline functions for
+ * -Wunused-function.  This turns out to avoid the need for complex #ifdef
+ * directives.  Suppress the warning in clang as well by using "unused"
+ * function attribute, which is redundant but not harmful for gcc.
+ * Prefer gnu_inline, so that extern inline functions do not emit an
+ * externally visible function. This makes extern inline behave as per gnu89
+ * semantics rather than c99. This prevents multiple symbol definition errors
+ * of extern inline functions at link time.
+ * A lot of inline functions can cause havoc with function tracing.
+ */
+#if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \
+       !defined(CONFIG_OPTIMIZE_INLINING)
+#define inline \
+       inline __attribute__((always_inline, unused)) notrace __gnu_inline
+#else
+#define inline inline  __attribute__((unused)) notrace __gnu_inline
+#endif
+
+#define __inline__ inline
+#define __inline inline
+#define noinline       __attribute__((noinline))
+
+#ifndef __always_inline
+#define __always_inline inline __attribute__((always_inline))
+#endif
+
+/*
+ * Rather then using noinline to prevent stack consumption, use
+ * noinline_for_stack instead.  For documentation reasons.
+ */
+#define noinline_for_stack noinline
+
 #endif /* __LINUX_COMPILER_TYPES_H */
index f59f3dbca65cb02d257ca0f1cf69f508200d508e..ec9bdb3d7bab6368a1ef7fb6598d70e0a5720a6d 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef _LINUX_CONSOLE_H_
 #define _LINUX_CONSOLE_H_ 1
 
+#include <linux/atomic.h>
 #include <linux/types.h>
 
 struct vc_data;
@@ -201,11 +202,14 @@ void vcs_make_sysfs(int index);
 void vcs_remove_sysfs(int index);
 
 /* Some debug stub to catch some of the obvious races in the VT code */
-#if 1
-#define WARN_CONSOLE_UNLOCKED()        WARN_ON(!is_console_locked() && !oops_in_progress)
-#else
-#define WARN_CONSOLE_UNLOCKED()
-#endif
+#define WARN_CONSOLE_UNLOCKED()                                                \
+       WARN_ON(!atomic_read(&ignore_console_lock_warning) &&           \
+               !is_console_locked() && !oops_in_progress)
+/*
+ * Increment ignore_console_lock_warning if you need to quiet
+ * WARN_CONSOLE_UNLOCKED() for debugging purposes.
+ */
+extern atomic_t ignore_console_lock_warning;
 
 /* VESA Blanking Levels */
 #define VESA_NO_BLANKING        0
index c49843c4d031bfd289ed26b4617e5bc5592578b2..caf40ad0bbc6e0f42027aa1c68f3fa5d07477c9a 100644 (file)
@@ -144,6 +144,7 @@ enum cpuhp_state {
        CPUHP_AP_SMPBOOT_THREADS,
        CPUHP_AP_X86_VDSO_VMA_ONLINE,
        CPUHP_AP_IRQ_AFFINITY_ONLINE,
+       CPUHP_AP_ARM_MVEBU_SYNC_CLOCKS,
        CPUHP_AP_PERF_ONLINE,
        CPUHP_AP_PERF_X86_ONLINE,
        CPUHP_AP_PERF_X86_UNCORE_ONLINE,
index b511f6d24b42b0c4a2796bc33f494d86b7c7854b..525510a9f965f5877ce161f4e623cad9144bfd97 100644 (file)
@@ -60,6 +60,8 @@ phys_addr_t paddr_vmcoreinfo_note(void);
 #define VMCOREINFO_CONFIG(name) \
        vmcoreinfo_append_str("CONFIG_%s=y\n", #name)
 
+extern unsigned char *vmcoreinfo_data;
+extern size_t vmcoreinfo_size;
 extern u32 *vmcoreinfo_note;
 
 Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
diff --git a/include/linux/crc64.h b/include/linux/crc64.h
new file mode 100644 (file)
index 0000000..c756e65
--- /dev/null
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * See lib/crc64.c for the related specification and polynomial arithmetic.
+ */
+#ifndef _LINUX_CRC64_H
+#define _LINUX_CRC64_H
+
+#include <linux/types.h>
+
+u64 __pure crc64_be(u64 crc, const void *p, size_t len);
+#endif /* _LINUX_CRC64_H */
index deb0f663252fc55e39546c7d3107e96dfb3f03ae..450b28db95331ffbe19963c804391d7249cfb2c3 100644 (file)
@@ -88,6 +88,8 @@ int dax_writeback_mapping_range(struct address_space *mapping,
                struct block_device *bdev, struct writeback_control *wbc);
 
 struct page *dax_layout_busy_page(struct address_space *mapping);
+bool dax_lock_mapping_entry(struct page *page);
+void dax_unlock_mapping_entry(struct page *page);
 #else
 static inline bool bdev_dax_supported(struct block_device *bdev,
                int blocksize)
@@ -119,6 +121,17 @@ static inline int dax_writeback_mapping_range(struct address_space *mapping,
 {
        return -EOPNOTSUPP;
 }
+
+static inline bool dax_lock_mapping_entry(struct page *page)
+{
+       if (IS_DAX(page->mapping->host))
+               return true;
+       return false;
+}
+
+static inline void dax_unlock_mapping_entry(struct page *page)
+{
+}
 #endif
 
 int dax_read_lock(void);
index d32957b423d58d171fab10afc97c9c0c5d01486c..ef4b70f64f333ac6c29bd93031a3a80b71c7b439 100644 (file)
@@ -145,8 +145,7 @@ struct dentry_operations {
        char *(*d_dname)(struct dentry *, char *, int);
        struct vfsmount *(*d_automount)(struct path *);
        int (*d_manage)(const struct path *, bool);
-       struct dentry *(*d_real)(struct dentry *, const struct inode *,
-                                unsigned int, unsigned int);
+       struct dentry *(*d_real)(struct dentry *, const struct inode *);
 } ____cacheline_aligned;
 
 /*
@@ -561,15 +560,10 @@ static inline struct dentry *d_backing_dentry(struct dentry *upper)
        return upper;
 }
 
-/* d_real() flags */
-#define D_REAL_UPPER   0x2     /* return upper dentry or NULL if non-upper */
-
 /**
  * d_real - Return the real dentry
  * @dentry: the dentry to query
  * @inode: inode to select the dentry from multiple layers (can be NULL)
- * @open_flags: open flags to control copy-up behavior
- * @flags: flags to control what is returned by this function
  *
  * If dentry is on a union/overlay, then return the underlying, real dentry.
  * Otherwise return the dentry itself.
@@ -577,11 +571,10 @@ static inline struct dentry *d_backing_dentry(struct dentry *upper)
  * See also: Documentation/filesystems/vfs.txt
  */
 static inline struct dentry *d_real(struct dentry *dentry,
-                                   const struct inode *inode,
-                                   unsigned int open_flags, unsigned int flags)
+                                   const struct inode *inode)
 {
        if (unlikely(dentry->d_flags & DCACHE_OP_REAL))
-               return dentry->d_op->d_real(dentry, inode, open_flags, flags);
+               return dentry->d_op->d_real(dentry, inode);
        else
                return dentry;
 }
@@ -596,7 +589,7 @@ static inline struct dentry *d_real(struct dentry *dentry,
 static inline struct inode *d_real_inode(const struct dentry *dentry)
 {
        /* This usage of d_real() results in const dentry */
-       return d_backing_inode(d_real((struct dentry *) dentry, NULL, 0, 0));
+       return d_backing_inode(d_real((struct dentry *) dentry, NULL));
 }
 
 struct name_snapshot {
index e2433bc50210bb3a2b36aaa293d632b201649d72..843a41ba7e280bda1bc70f646254949f3c7e579c 100644 (file)
@@ -265,11 +265,6 @@ static inline void dmar_copy_shared_irte(struct irte *dst, struct irte *src)
 #define PDA_LOW_BIT    26
 #define PDA_HIGH_BIT   32
 
-enum {
-       IRQ_REMAP_XAPIC_MODE,
-       IRQ_REMAP_X2APIC_MODE,
-};
-
 /* Can't use the common MSI interrupt functions
  * since DMAR is not a pci device
  */
index b768d6dd3c9035de05452969642295ab50916460..ce764a5d2ee45023c99da81485f77bd958480de7 100644 (file)
  * hackers place grumpy comments in header files.
  */
 
-#define __VMLINUX_SYMBOL(x) x
-#define __VMLINUX_SYMBOL_STR(x) #x
-
-/* Indirect, so macros are expanded before pasting. */
-#define VMLINUX_SYMBOL(x) __VMLINUX_SYMBOL(x)
-#define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x)
-
 #ifndef __ASSEMBLY__
-struct kernel_symbol
-{
-       unsigned long value;
-       const char *name;
-};
-
 #ifdef MODULE
 extern struct module __this_module;
 #define THIS_MODULE (&__this_module)
@@ -54,19 +41,58 @@ extern struct module __this_module;
 #define __CRC_SYMBOL(sym, sec)
 #endif
 
+#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
+#include <linux/compiler.h>
+/*
+ * Emit the ksymtab entry as a pair of relative references: this reduces
+ * the size by half on 64-bit architectures, and eliminates the need for
+ * absolute relocations that require runtime processing on relocatable
+ * kernels.
+ */
+#define __KSYMTAB_ENTRY(sym, sec)                                      \
+       __ADDRESSABLE(sym)                                              \
+       asm("   .section \"___ksymtab" sec "+" #sym "\", \"a\"  \n"     \
+           "   .balign 8                                       \n"     \
+           "__ksymtab_" #sym ":                                \n"     \
+           "   .long   " #sym "- .                             \n"     \
+           "   .long   __kstrtab_" #sym "- .                   \n"     \
+           "   .previous                                       \n")
+
+struct kernel_symbol {
+       int value_offset;
+       int name_offset;
+};
+#else
+#define __KSYMTAB_ENTRY(sym, sec)                                      \
+       static const struct kernel_symbol __ksymtab_##sym               \
+       __attribute__((section("___ksymtab" sec "+" #sym), used))       \
+       = { (unsigned long)&sym, __kstrtab_##sym }
+
+struct kernel_symbol {
+       unsigned long value;
+       const char *name;
+};
+#endif
+
 /* For every exported symbol, place a struct in the __ksymtab section */
 #define ___EXPORT_SYMBOL(sym, sec)                                     \
        extern typeof(sym) sym;                                         \
        __CRC_SYMBOL(sym, sec)                                          \
        static const char __kstrtab_##sym[]                             \
-       __attribute__((section("__ksymtab_strings"), aligned(1)))       \
+       __attribute__((section("__ksymtab_strings"), used, aligned(1))) \
        = #sym;                                                         \
-       static const struct kernel_symbol __ksymtab_##sym               \
-       __used                                                          \
-       __attribute__((section("___ksymtab" sec "+" #sym), used))       \
-       = { (unsigned long)&sym, __kstrtab_##sym }
+       __KSYMTAB_ENTRY(sym, sec)
+
+#if defined(__DISABLE_EXPORTS)
+
+/*
+ * Allow symbol exports to be disabled completely so that C code may
+ * be reused in other execution contexts such as the UEFI stub or the
+ * decompressor.
+ */
+#define __EXPORT_SYMBOL(sym, sec)
 
-#if defined(__KSYM_DEPS__)
+#elif defined(__KSYM_DEPS__)
 
 /*
  * For fine grained build dependencies, we want to tell the build system
index aa5db8b5521a589ae48cebd7c6119e315f45a460..f70f8ac9c4f442a239f32ca948c92cfa32d2e09e 100644 (file)
@@ -304,11 +304,6 @@ struct f2fs_node {
  * For NAT entries
  */
 #define NAT_ENTRY_PER_BLOCK (PAGE_SIZE / sizeof(struct f2fs_nat_entry))
-#define NAT_ENTRY_BITMAP_SIZE  ((NAT_ENTRY_PER_BLOCK + 7) / 8)
-#define NAT_ENTRY_BITMAP_SIZE_ALIGNED                          \
-       ((NAT_ENTRY_BITMAP_SIZE + BITS_PER_LONG - 1) /          \
-       BITS_PER_LONG * BITS_PER_LONG)
-
 
 struct f2fs_nat_entry {
        __u8 version;           /* latest version of cached nat entry */
index aa74a228bb92ec90885ce57f0957b1d8f58903e4..3e7e75383d327d2dbd2e81410033cd26c193e003 100644 (file)
@@ -126,7 +126,7 @@ struct fb_cursor_user {
 
 /*     The resolution of the passed in fb_info about to change */ 
 #define FB_EVENT_MODE_CHANGE           0x01
-/*     The display on this fb_info is beeing suspended, no access to the
+/*     The display on this fb_info is being suspended, no access to the
  *     framebuffer is allowed any more after that call returns
  */
 #define FB_EVENT_SUSPEND               0x02
@@ -159,9 +159,9 @@ struct fb_cursor_user {
 #define FB_EVENT_FB_UNBIND              0x0E
 /*      CONSOLE-SPECIFIC: remap all consoles to new fb - for vga_switcheroo */
 #define FB_EVENT_REMAP_ALL_CONSOLE      0x0F
-/*      A hardware display blank early change occured */
+/*      A hardware display blank early change occurred */
 #define FB_EARLY_EVENT_BLANK           0x10
-/*      A hardware display blank revert early change occured */
+/*      A hardware display blank revert early change occurred */
 #define FB_R_EARLY_EVENT_BLANK         0x11
 
 struct fb_event {
@@ -650,6 +650,10 @@ extern struct fb_info *registered_fb[FB_MAX];
 extern int num_registered_fb;
 extern struct class *fb_class;
 
+#define for_each_registered_fb(i)              \
+       for (i = 0; i < FB_MAX; i++)            \
+               if (!registered_fb[i]) {} else
+
 extern int lock_fb_info(struct fb_info *info);
 
 static inline void unlock_fb_info(struct fb_info *info)
index a9242f336f02d72b82b4a3a229c126bff88fcdd0..33322702c910b9cb879d05a03c070c51487c0d26 100644 (file)
@@ -74,6 +74,8 @@ extern struct inodes_stat_t inodes_stat;
 extern int leases_enable, lease_break_time;
 extern int sysctl_protected_symlinks;
 extern int sysctl_protected_hardlinks;
+extern int sysctl_protected_fifos;
+extern int sysctl_protected_regular;
 
 typedef __kernel_rwf_t rwf_t;
 
@@ -157,6 +159,9 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
 /* File is capable of returning -EAGAIN if I/O will block */
 #define FMODE_NOWAIT   ((__force fmode_t)0x8000000)
 
+/* File does not contribute to nr_files count */
+#define FMODE_NOACCOUNT        ((__force fmode_t)0x20000000)
+
 /*
  * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector
  * that indicates that they should check the contents of the iovec are
@@ -1067,17 +1072,7 @@ struct file_lock_context {
 
 extern void send_sigio(struct fown_struct *fown, int fd, int band);
 
-/*
- * Return the inode to use for locking
- *
- * For overlayfs this should be the overlay inode, not the real inode returned
- * by file_inode().  For any other fs file_inode(filp) and locks_inode(filp) are
- * equal.
- */
-static inline struct inode *locks_inode(const struct file *f)
-{
-       return f->f_path.dentry->d_inode;
-}
+#define locks_inode(f) file_inode(f)
 
 #ifdef CONFIG_FILE_LOCKING
 extern int fcntl_getlk(struct file *, unsigned int, struct flock *);
@@ -1262,7 +1257,7 @@ static inline struct inode *file_inode(const struct file *f)
 
 static inline struct dentry *file_dentry(const struct file *file)
 {
-       return d_real(file->f_path.dentry, file_inode(file), 0, 0);
+       return d_real(file->f_path.dentry, file_inode(file));
 }
 
 static inline int locks_lock_file_wait(struct file *filp, struct file_lock *fl)
@@ -1318,7 +1313,6 @@ extern int send_sigurg(struct fown_struct *fown);
 
 /* These sb flags are internal to the kernel */
 #define SB_SUBMOUNT     (1<<26)
-#define SB_NOREMOTELOCK        (1<<27)
 #define SB_NOSEC       (1<<28)
 #define SB_BORN                (1<<29)
 #define SB_ACTIVE      (1<<30)
@@ -1647,6 +1641,8 @@ int vfs_mkobj(struct dentry *, umode_t,
                int (*f)(struct dentry *, umode_t, void *),
                void *);
 
+extern long vfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+
 /*
  * VFS file helper functions.
  */
@@ -1765,7 +1761,7 @@ struct file_operations {
                        loff_t, size_t, unsigned int);
        int (*clone_file_range)(struct file *, loff_t, struct file *, loff_t,
                        u64);
-       ssize_t (*dedupe_file_range)(struct file *, u64, u64, struct file *,
+       int (*dedupe_file_range)(struct file *, loff_t, struct file *, loff_t,
                        u64);
 } __randomize_layout;
 
@@ -1838,6 +1834,10 @@ extern int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff,
                                         loff_t len, bool *is_same);
 extern int vfs_dedupe_file_range(struct file *file,
                                 struct file_dedupe_range *same);
+extern int vfs_dedupe_file_range_one(struct file *src_file, loff_t src_pos,
+                                    struct file *dst_file, loff_t dst_pos,
+                                    u64 len);
+
 
 struct super_operations {
        struct inode *(*alloc_inode)(struct super_block *sb);
@@ -2096,6 +2096,7 @@ enum file_time_flags {
        S_VERSION = 8,
 };
 
+extern bool atime_needs_update(const struct path *, struct inode *);
 extern void touch_atime(const struct path *);
 static inline void file_accessed(struct file *file)
 {
@@ -2441,6 +2442,8 @@ extern struct file *filp_open(const char *, int, umode_t);
 extern struct file *file_open_root(struct dentry *, struct vfsmount *,
                                   const char *, int, umode_t);
 extern struct file * dentry_open(const struct path *, int, const struct cred *);
+extern struct file * open_with_fake_path(const struct path *, int,
+                                        struct inode*, const struct cred *);
 static inline struct file *file_clone_open(struct file *file)
 {
        return dentry_open(&file->f_path, file->f_flags, file->f_cred);
index bdaf22582f6ea5c59a1eb9e4e7c319854087df42..fd1ce10553bfad43fbbfdc1faa367f9fd0fd93c8 100644 (file)
@@ -30,11 +30,7 @@ static inline int fsnotify_parent(const struct path *path, struct dentry *dentry
 static inline int fsnotify_perm(struct file *file, int mask)
 {
        const struct path *path = &file->f_path;
-       /*
-        * Do not use file_inode() here or anywhere in this file to get the
-        * inode.  That would break *notity on overlayfs.
-        */
-       struct inode *inode = path->dentry->d_inode;
+       struct inode *inode = file_inode(file);
        __u32 fsnotify_mask = 0;
        int ret;
 
@@ -178,7 +174,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
 static inline void fsnotify_access(struct file *file)
 {
        const struct path *path = &file->f_path;
-       struct inode *inode = path->dentry->d_inode;
+       struct inode *inode = file_inode(file);
        __u32 mask = FS_ACCESS;
 
        if (S_ISDIR(inode->i_mode))
@@ -196,7 +192,7 @@ static inline void fsnotify_access(struct file *file)
 static inline void fsnotify_modify(struct file *file)
 {
        const struct path *path = &file->f_path;
-       struct inode *inode = path->dentry->d_inode;
+       struct inode *inode = file_inode(file);
        __u32 mask = FS_MODIFY;
 
        if (S_ISDIR(inode->i_mode))
@@ -214,7 +210,7 @@ static inline void fsnotify_modify(struct file *file)
 static inline void fsnotify_open(struct file *file)
 {
        const struct path *path = &file->f_path;
-       struct inode *inode = path->dentry->d_inode;
+       struct inode *inode = file_inode(file);
        __u32 mask = FS_OPEN;
 
        if (S_ISDIR(inode->i_mode))
@@ -230,7 +226,7 @@ static inline void fsnotify_open(struct file *file)
 static inline void fsnotify_close(struct file *file)
 {
        const struct path *path = &file->f_path;
-       struct inode *inode = path->dentry->d_inode;
+       struct inode *inode = file_inode(file);
        fmode_t mode = file->f_mode;
        __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE;
 
index ebb77674be90cfff4466667c7bb62c121db5a235..a397907e8d727481cfb933e7a7c5e80ca194b0d7 100644 (file)
@@ -234,10 +234,6 @@ extern void ftrace_stub(unsigned long a0, unsigned long a1,
  */
 #define register_ftrace_function(ops) ({ 0; })
 #define unregister_ftrace_function(ops) ({ 0; })
-static inline int ftrace_nr_registered_ops(void)
-{
-       return 0;
-}
 static inline void ftrace_kill(void) { }
 static inline void ftrace_free_init_mem(void) { }
 static inline void ftrace_free_mem(struct module *mod, void *start, void *end) { }
@@ -328,8 +324,6 @@ struct seq_file;
 
 extern int ftrace_text_reserved(const void *start, const void *end);
 
-extern int ftrace_nr_registered_ops(void);
-
 struct ftrace_ops *ftrace_ops_trampoline(unsigned long addr);
 
 bool is_ftrace_trampoline(unsigned long addr);
@@ -707,16 +701,7 @@ static inline unsigned long get_lock_parent_ip(void)
        return CALLER_ADDR2;
 }
 
-#ifdef CONFIG_IRQSOFF_TRACER
-  extern void time_hardirqs_on(unsigned long a0, unsigned long a1);
-  extern void time_hardirqs_off(unsigned long a0, unsigned long a1);
-#else
-  static inline void time_hardirqs_on(unsigned long a0, unsigned long a1) { }
-  static inline void time_hardirqs_off(unsigned long a0, unsigned long a1) { }
-#endif
-
-#if defined(CONFIG_PREEMPT_TRACER) || \
-       (defined(CONFIG_DEBUG_PREEMPT) && defined(CONFIG_PREEMPTIRQ_EVENTS))
+#ifdef CONFIG_TRACE_PREEMPT_TOGGLE
   extern void trace_preempt_on(unsigned long a0, unsigned long a1);
   extern void trace_preempt_off(unsigned long a0, unsigned long a1);
 #else
index a6afcec537955c88b2dd1e34e337312169f3a713..24bcc5eec6b409ec379602156a94d74373ec2633 100644 (file)
@@ -59,29 +59,32 @@ struct vm_area_struct;
 #define __GFP_MOVABLE  ((__force gfp_t)___GFP_MOVABLE)  /* ZONE_MOVABLE allowed */
 #define GFP_ZONEMASK   (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE)
 
-/*
+/**
+ * DOC: Page mobility and placement hints
+ *
  * Page mobility and placement hints
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
  * These flags provide hints about how mobile the page is. Pages with similar
  * mobility are placed within the same pageblocks to minimise problems due
  * to external fragmentation.
  *
- * __GFP_MOVABLE (also a zone modifier) indicates that the page can be
- *   moved by page migration during memory compaction or can be reclaimed.
+ * %__GFP_MOVABLE (also a zone modifier) indicates that the page can be
+ * moved by page migration during memory compaction or can be reclaimed.
  *
- * __GFP_RECLAIMABLE is used for slab allocations that specify
- *   SLAB_RECLAIM_ACCOUNT and whose pages can be freed via shrinkers.
+ * %__GFP_RECLAIMABLE is used for slab allocations that specify
+ * SLAB_RECLAIM_ACCOUNT and whose pages can be freed via shrinkers.
  *
- * __GFP_WRITE indicates the caller intends to dirty the page. Where possible,
- *   these pages will be spread between local zones to avoid all the dirty
- *   pages being in one zone (fair zone allocation policy).
+ * %__GFP_WRITE indicates the caller intends to dirty the page. Where possible,
+ * these pages will be spread between local zones to avoid all the dirty
+ * pages being in one zone (fair zone allocation policy).
  *
- * __GFP_HARDWALL enforces the cpuset memory allocation policy.
+ * %__GFP_HARDWALL enforces the cpuset memory allocation policy.
  *
- * __GFP_THISNODE forces the allocation to be satisified from the requested
- *   node with no fallbacks or placement policy enforcements.
+ * %__GFP_THISNODE forces the allocation to be satisified from the requested
+ * node with no fallbacks or placement policy enforcements.
  *
- * __GFP_ACCOUNT causes the allocation to be accounted to kmemcg.
+ * %__GFP_ACCOUNT causes the allocation to be accounted to kmemcg.
  */
 #define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE)
 #define __GFP_WRITE    ((__force gfp_t)___GFP_WRITE)
@@ -89,54 +92,60 @@ struct vm_area_struct;
 #define __GFP_THISNODE ((__force gfp_t)___GFP_THISNODE)
 #define __GFP_ACCOUNT  ((__force gfp_t)___GFP_ACCOUNT)
 
-/*
+/**
+ * DOC: Watermark modifiers
+ *
  * Watermark modifiers -- controls access to emergency reserves
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
- * __GFP_HIGH indicates that the caller is high-priority and that granting
- *   the request is necessary before the system can make forward progress.
- *   For example, creating an IO context to clean pages.
+ * %__GFP_HIGH indicates that the caller is high-priority and that granting
+ * the request is necessary before the system can make forward progress.
+ * For example, creating an IO context to clean pages.
  *
- * __GFP_ATOMIC indicates that the caller cannot reclaim or sleep and is
- *   high priority. Users are typically interrupt handlers. This may be
- *   used in conjunction with __GFP_HIGH
+ * %__GFP_ATOMIC indicates that the caller cannot reclaim or sleep and is
+ * high priority. Users are typically interrupt handlers. This may be
+ * used in conjunction with %__GFP_HIGH
  *
- * __GFP_MEMALLOC allows access to all memory. This should only be used when
- *   the caller guarantees the allocation will allow more memory to be freed
- *   very shortly e.g. process exiting or swapping. Users either should
- *   be the MM or co-ordinating closely with the VM (e.g. swap over NFS).
+ * %__GFP_MEMALLOC allows access to all memory. This should only be used when
+ * the caller guarantees the allocation will allow more memory to be freed
+ * very shortly e.g. process exiting or swapping. Users either should
+ * be the MM or co-ordinating closely with the VM (e.g. swap over NFS).
  *
- * __GFP_NOMEMALLOC is used to explicitly forbid access to emergency reserves.
- *   This takes precedence over the __GFP_MEMALLOC flag if both are set.
+ * %__GFP_NOMEMALLOC is used to explicitly forbid access to emergency reserves.
+ * This takes precedence over the %__GFP_MEMALLOC flag if both are set.
  */
 #define __GFP_ATOMIC   ((__force gfp_t)___GFP_ATOMIC)
 #define __GFP_HIGH     ((__force gfp_t)___GFP_HIGH)
 #define __GFP_MEMALLOC ((__force gfp_t)___GFP_MEMALLOC)
 #define __GFP_NOMEMALLOC ((__force gfp_t)___GFP_NOMEMALLOC)
 
-/*
+/**
+ * DOC: Reclaim modifiers
+ *
  * Reclaim modifiers
+ * ~~~~~~~~~~~~~~~~~
  *
- * __GFP_IO can start physical IO.
+ * %__GFP_IO can start physical IO.
  *
- * __GFP_FS can call down to the low-level FS. Clearing the flag avoids the
- *   allocator recursing into the filesystem which might already be holding
- *   locks.
+ * %__GFP_FS can call down to the low-level FS. Clearing the flag avoids the
+ * allocator recursing into the filesystem which might already be holding
+ * locks.
  *
- * __GFP_DIRECT_RECLAIM indicates that the caller may enter direct reclaim.
- *   This flag can be cleared to avoid unnecessary delays when a fallback
- *   option is available.
+ * %__GFP_DIRECT_RECLAIM indicates that the caller may enter direct reclaim.
+ * This flag can be cleared to avoid unnecessary delays when a fallback
+ * option is available.
  *
- * __GFP_KSWAPD_RECLAIM indicates that the caller wants to wake kswapd when
- *   the low watermark is reached and have it reclaim pages until the high
- *   watermark is reached. A caller may wish to clear this flag when fallback
- *   options are available and the reclaim is likely to disrupt the system. The
- *   canonical example is THP allocation where a fallback is cheap but
- *   reclaim/compaction may cause indirect stalls.
+ * %__GFP_KSWAPD_RECLAIM indicates that the caller wants to wake kswapd when
+ * the low watermark is reached and have it reclaim pages until the high
+ * watermark is reached. A caller may wish to clear this flag when fallback
+ * options are available and the reclaim is likely to disrupt the system. The
+ * canonical example is THP allocation where a fallback is cheap but
+ * reclaim/compaction may cause indirect stalls.
  *
- * __GFP_RECLAIM is shorthand to allow/forbid both direct and kswapd reclaim.
+ * %__GFP_RECLAIM is shorthand to allow/forbid both direct and kswapd reclaim.
  *
  * The default allocator behavior depends on the request size. We have a concept
- * of so called costly allocations (with order > PAGE_ALLOC_COSTLY_ORDER).
+ * of so called costly allocations (with order > %PAGE_ALLOC_COSTLY_ORDER).
  * !costly allocations are too essential to fail so they are implicitly
  * non-failing by default (with some exceptions like OOM victims might fail so
  * the caller still has to check for failures) while costly requests try to be
@@ -144,40 +153,40 @@ struct vm_area_struct;
  * The following three modifiers might be used to override some of these
  * implicit rules
  *
- * __GFP_NORETRY: The VM implementation will try only very lightweight
- *   memory direct reclaim to get some memory under memory pressure (thus
- *   it can sleep). It will avoid disruptive actions like OOM killer. The
- *   caller must handle the failure which is quite likely to happen under
- *   heavy memory pressure. The flag is suitable when failure can easily be
- *   handled at small cost, such as reduced throughput
- *
- * __GFP_RETRY_MAYFAIL: The VM implementation will retry memory reclaim
- *   procedures that have previously failed if there is some indication
- *   that progress has been made else where.  It can wait for other
- *   tasks to attempt high level approaches to freeing memory such as
- *   compaction (which removes fragmentation) and page-out.
- *   There is still a definite limit to the number of retries, but it is
- *   a larger limit than with __GFP_NORETRY.
- *   Allocations with this flag may fail, but only when there is
- *   genuinely little unused memory. While these allocations do not
- *   directly trigger the OOM killer, their failure indicates that
- *   the system is likely to need to use the OOM killer soon.  The
- *   caller must handle failure, but can reasonably do so by failing
- *   a higher-level request, or completing it only in a much less
- *   efficient manner.
- *   If the allocation does fail, and the caller is in a position to
- *   free some non-essential memory, doing so could benefit the system
- *   as a whole.
- *
- * __GFP_NOFAIL: The VM implementation _must_ retry infinitely: the caller
- *   cannot handle allocation failures. The allocation could block
- *   indefinitely but will never return with failure. Testing for
- *   failure is pointless.
- *   New users should be evaluated carefully (and the flag should be
- *   used only when there is no reasonable failure policy) but it is
- *   definitely preferable to use the flag rather than opencode endless
- *   loop around allocator.
- *   Using this flag for costly allocations is _highly_ discouraged.
+ * %__GFP_NORETRY: The VM implementation will try only very lightweight
+ * memory direct reclaim to get some memory under memory pressure (thus
+ * it can sleep). It will avoid disruptive actions like OOM killer. The
+ * caller must handle the failure which is quite likely to happen under
+ * heavy memory pressure. The flag is suitable when failure can easily be
+ * handled at small cost, such as reduced throughput
+ *
+ * %__GFP_RETRY_MAYFAIL: The VM implementation will retry memory reclaim
+ * procedures that have previously failed if there is some indication
+ * that progress has been made else where.  It can wait for other
+ * tasks to attempt high level approaches to freeing memory such as
+ * compaction (which removes fragmentation) and page-out.
+ * There is still a definite limit to the number of retries, but it is
+ * a larger limit than with %__GFP_NORETRY.
+ * Allocations with this flag may fail, but only when there is
+ * genuinely little unused memory. While these allocations do not
+ * directly trigger the OOM killer, their failure indicates that
+ * the system is likely to need to use the OOM killer soon.  The
+ * caller must handle failure, but can reasonably do so by failing
+ * a higher-level request, or completing it only in a much less
+ * efficient manner.
+ * If the allocation does fail, and the caller is in a position to
+ * free some non-essential memory, doing so could benefit the system
+ * as a whole.
+ *
+ * %__GFP_NOFAIL: The VM implementation _must_ retry infinitely: the caller
+ * cannot handle allocation failures. The allocation could block
+ * indefinitely but will never return with failure. Testing for
+ * failure is pointless.
+ * New users should be evaluated carefully (and the flag should be
+ * used only when there is no reasonable failure policy) but it is
+ * definitely preferable to use the flag rather than opencode endless
+ * loop around allocator.
+ * Using this flag for costly allocations is _highly_ discouraged.
  */
 #define __GFP_IO       ((__force gfp_t)___GFP_IO)
 #define __GFP_FS       ((__force gfp_t)___GFP_FS)
@@ -188,14 +197,17 @@ struct vm_area_struct;
 #define __GFP_NOFAIL   ((__force gfp_t)___GFP_NOFAIL)
 #define __GFP_NORETRY  ((__force gfp_t)___GFP_NORETRY)
 
-/*
+/**
+ * DOC: Action modifiers
+ *
  * Action modifiers
+ * ~~~~~~~~~~~~~~~~
  *
- * __GFP_NOWARN suppresses allocation failure reports.
+ * %__GFP_NOWARN suppresses allocation failure reports.
  *
- * __GFP_COMP address compound page metadata.
+ * %__GFP_COMP address compound page metadata.
  *
- * __GFP_ZERO returns a zeroed page on success.
+ * %__GFP_ZERO returns a zeroed page on success.
  */
 #define __GFP_NOWARN   ((__force gfp_t)___GFP_NOWARN)
 #define __GFP_COMP     ((__force gfp_t)___GFP_COMP)
@@ -208,66 +220,71 @@ struct vm_area_struct;
 #define __GFP_BITS_SHIFT (23 + IS_ENABLED(CONFIG_LOCKDEP))
 #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
 
-/*
+/**
+ * DOC: Useful GFP flag combinations
+ *
+ * Useful GFP flag combinations
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
  * Useful GFP flag combinations that are commonly used. It is recommended
  * that subsystems start with one of these combinations and then set/clear
- * __GFP_FOO flags as necessary.
- *
- * GFP_ATOMIC users can not sleep and need the allocation to succeed. A lower
- *   watermark is applied to allow access to "atomic reserves"
- *
- * GFP_KERNEL is typical for kernel-internal allocations. The caller requires
- *   ZONE_NORMAL or a lower zone for direct access but can direct reclaim.
- *
- * GFP_KERNEL_ACCOUNT is the same as GFP_KERNEL, except the allocation is
- *   accounted to kmemcg.
- *
- * GFP_NOWAIT is for kernel allocations that should not stall for direct
- *   reclaim, start physical IO or use any filesystem callback.
- *
- * GFP_NOIO will use direct reclaim to discard clean pages or slab pages
- *   that do not require the starting of any physical IO.
- *   Please try to avoid using this flag directly and instead use
- *   memalloc_noio_{save,restore} to mark the whole scope which cannot
- *   perform any IO with a short explanation why. All allocation requests
- *   will inherit GFP_NOIO implicitly.
- *
- * GFP_NOFS will use direct reclaim but will not use any filesystem interfaces.
- *   Please try to avoid using this flag directly and instead use
- *   memalloc_nofs_{save,restore} to mark the whole scope which cannot/shouldn't
- *   recurse into the FS layer with a short explanation why. All allocation
- *   requests will inherit GFP_NOFS implicitly.
- *
- * GFP_USER is for userspace allocations that also need to be directly
- *   accessibly by the kernel or hardware. It is typically used by hardware
- *   for buffers that are mapped to userspace (e.g. graphics) that hardware
- *   still must DMA to. cpuset limits are enforced for these allocations.
- *
- * GFP_DMA exists for historical reasons and should be avoided where possible.
- *   The flags indicates that the caller requires that the lowest zone be
- *   used (ZONE_DMA or 16M on x86-64). Ideally, this would be removed but
- *   it would require careful auditing as some users really require it and
- *   others use the flag to avoid lowmem reserves in ZONE_DMA and treat the
- *   lowest zone as a type of emergency reserve.
- *
- * GFP_DMA32 is similar to GFP_DMA except that the caller requires a 32-bit
- *   address.
- *
- * GFP_HIGHUSER is for userspace allocations that may be mapped to userspace,
- *   do not need to be directly accessible by the kernel but that cannot
- *   move once in use. An example may be a hardware allocation that maps
- *   data directly into userspace but has no addressing limitations.
- *
- * GFP_HIGHUSER_MOVABLE is for userspace allocations that the kernel does not
- *   need direct access to but can use kmap() when access is required. They
- *   are expected to be movable via page reclaim or page migration. Typically,
- *   pages on the LRU would also be allocated with GFP_HIGHUSER_MOVABLE.
- *
- * GFP_TRANSHUGE and GFP_TRANSHUGE_LIGHT are used for THP allocations. They are
- *   compound allocations that will generally fail quickly if memory is not
- *   available and will not wake kswapd/kcompactd on failure. The _LIGHT
- *   version does not attempt reclaim/compaction at all and is by default used
- *   in page fault path, while the non-light is used by khugepaged.
+ * %__GFP_FOO flags as necessary.
+ *
+ * %GFP_ATOMIC users can not sleep and need the allocation to succeed. A lower
+ * watermark is applied to allow access to "atomic reserves"
+ *
+ * %GFP_KERNEL is typical for kernel-internal allocations. The caller requires
+ * %ZONE_NORMAL or a lower zone for direct access but can direct reclaim.
+ *
+ * %GFP_KERNEL_ACCOUNT is the same as GFP_KERNEL, except the allocation is
+ * accounted to kmemcg.
+ *
+ * %GFP_NOWAIT is for kernel allocations that should not stall for direct
+ * reclaim, start physical IO or use any filesystem callback.
+ *
+ * %GFP_NOIO will use direct reclaim to discard clean pages or slab pages
+ * that do not require the starting of any physical IO.
+ * Please try to avoid using this flag directly and instead use
+ * memalloc_noio_{save,restore} to mark the whole scope which cannot
+ * perform any IO with a short explanation why. All allocation requests
+ * will inherit GFP_NOIO implicitly.
+ *
+ * %GFP_NOFS will use direct reclaim but will not use any filesystem interfaces.
+ * Please try to avoid using this flag directly and instead use
+ * memalloc_nofs_{save,restore} to mark the whole scope which cannot/shouldn't
+ * recurse into the FS layer with a short explanation why. All allocation
+ * requests will inherit GFP_NOFS implicitly.
+ *
+ * %GFP_USER is for userspace allocations that also need to be directly
+ * accessibly by the kernel or hardware. It is typically used by hardware
+ * for buffers that are mapped to userspace (e.g. graphics) that hardware
+ * still must DMA to. cpuset limits are enforced for these allocations.
+ *
+ * %GFP_DMA exists for historical reasons and should be avoided where possible.
+ * The flags indicates that the caller requires that the lowest zone be
+ * used (%ZONE_DMA or 16M on x86-64). Ideally, this would be removed but
+ * it would require careful auditing as some users really require it and
+ * others use the flag to avoid lowmem reserves in %ZONE_DMA and treat the
+ * lowest zone as a type of emergency reserve.
+ *
+ * %GFP_DMA32 is similar to %GFP_DMA except that the caller requires a 32-bit
+ * address.
+ *
+ * %GFP_HIGHUSER is for userspace allocations that may be mapped to userspace,
+ * do not need to be directly accessible by the kernel but that cannot
+ * move once in use. An example may be a hardware allocation that maps
+ * data directly into userspace but has no addressing limitations.
+ *
+ * %GFP_HIGHUSER_MOVABLE is for userspace allocations that the kernel does not
+ * need direct access to but can use kmap() when access is required. They
+ * are expected to be movable via page reclaim or page migration. Typically,
+ * pages on the LRU would also be allocated with %GFP_HIGHUSER_MOVABLE.
+ *
+ * %GFP_TRANSHUGE and %GFP_TRANSHUGE_LIGHT are used for THP allocations. They
+ * are compound allocations that will generally fail quickly if memory is not
+ * available and will not wake kswapd/kcompactd on failure. The _LIGHT
+ * version does not attempt reclaim/compaction at all and is by default used
+ * in page fault path, while the non-light is used by khugepaged.
  */
 #define GFP_ATOMIC     (__GFP_HIGH|__GFP_ATOMIC|__GFP_KSWAPD_RECLAIM)
 #define GFP_KERNEL     (__GFP_RECLAIM | __GFP_IO | __GFP_FS)
index a8a126259bc4c8e8590e5ef29793787de92f8d8c..99c19b06d9a46d2cebf20ad5f21a1612a94b5855 100644 (file)
@@ -3,10 +3,11 @@
 #define _LINUX_HUGE_MM_H
 
 #include <linux/sched/coredump.h>
+#include <linux/mm_types.h>
 
 #include <linux/fs.h> /* only for vma_is_dax() */
 
-extern int do_huge_pmd_anonymous_page(struct vm_fault *vmf);
+extern vm_fault_t do_huge_pmd_anonymous_page(struct vm_fault *vmf);
 extern int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm,
                         pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long addr,
                         struct vm_area_struct *vma);
@@ -23,7 +24,7 @@ static inline void huge_pud_set_accessed(struct vm_fault *vmf, pud_t orig_pud)
 }
 #endif
 
-extern int do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd);
+extern vm_fault_t do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd);
 extern struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
                                          unsigned long addr,
                                          pmd_t *pmd,
@@ -46,9 +47,9 @@ extern bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr,
 extern int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
                        unsigned long addr, pgprot_t newprot,
                        int prot_numa);
-int vmf_insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr,
+vm_fault_t vmf_insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr,
                        pmd_t *pmd, pfn_t pfn, bool write);
-int vmf_insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr,
+vm_fault_t vmf_insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr,
                        pud_t *pud, pfn_t pfn, bool write);
 enum transparent_hugepage_flag {
        TRANSPARENT_HUGEPAGE_FLAG,
@@ -216,7 +217,7 @@ struct page *follow_devmap_pmd(struct vm_area_struct *vma, unsigned long addr,
 struct page *follow_devmap_pud(struct vm_area_struct *vma, unsigned long addr,
                pud_t *pud, int flags);
 
-extern int do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t orig_pmd);
+extern vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t orig_pmd);
 
 extern struct page *huge_zero_page;
 
@@ -321,7 +322,8 @@ static inline spinlock_t *pud_trans_huge_lock(pud_t *pud,
        return NULL;
 }
 
-static inline int do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t orig_pmd)
+static inline vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf,
+               pmd_t orig_pmd)
 {
        return 0;
 }
index c39d9170a8a0293c03d0b2abf9e0222d3f2213b1..6b68e345f0ca64da6590817f719796471d0c5c2d 100644 (file)
@@ -105,7 +105,7 @@ void hugetlb_report_meminfo(struct seq_file *);
 int hugetlb_report_node_meminfo(int, char *);
 void hugetlb_show_meminfo(void);
 unsigned long hugetlb_total_pages(void);
-int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+vm_fault_t hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
                        unsigned long address, unsigned int flags);
 int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm, pte_t *dst_pte,
                                struct vm_area_struct *dst_vma,
index 465afb092fa7892b5d670ddefc5abe54c3947d6a..65b4eaed1d965ca193407f9209a62310a51aafb1 100644 (file)
@@ -231,7 +231,6 @@ enum i2c_alert_protocol {
 /**
  * struct i2c_driver - represent an I2C device driver
  * @class: What kind of i2c device we instantiate (for detect)
- * @attach_adapter: Callback for bus addition (deprecated)
  * @probe: Callback for device binding - soon to be deprecated
  * @probe_new: New callback for device binding
  * @remove: Callback for device unbinding
@@ -268,11 +267,6 @@ enum i2c_alert_protocol {
 struct i2c_driver {
        unsigned int class;
 
-       /* Notifies the driver that a new bus has appeared. You should avoid
-        * using this, it will be removed in a near future.
-        */
-       int (*attach_adapter)(struct i2c_adapter *) __deprecated;
-
        /* Standard driver model interfaces */
        int (*probe)(struct i2c_client *, const struct i2c_device_id *);
        int (*remove)(struct i2c_client *);
@@ -564,6 +558,7 @@ struct i2c_lock_operations {
  * @scl_fall_ns: time SCL signal takes to fall in ns; t(f) in the I2C specification
  * @scl_int_delay_ns: time IP core additionally needs to setup SCL in ns
  * @sda_fall_ns: time SDA signal takes to fall in ns; t(f) in the I2C specification
+ * @sda_hold_ns: time IP core additionally needs to hold SDA in ns
  */
 struct i2c_timings {
        u32 bus_freq_hz;
@@ -571,6 +566,7 @@ struct i2c_timings {
        u32 scl_fall_ns;
        u32 scl_int_delay_ns;
        u32 sda_fall_ns;
+       u32 sda_hold_ns;
 };
 
 /**
@@ -581,12 +577,14 @@ struct i2c_timings {
  *      recovery. Populated internally for generic GPIO recovery.
  * @set_scl: This sets/clears the SCL line. Mandatory for generic SCL recovery.
  *      Populated internally for generic GPIO recovery.
- * @get_sda: This gets current value of SDA line. Optional for generic SCL
- *      recovery. Populated internally, if sda_gpio is a valid GPIO, for generic
- *      GPIO recovery.
- * @set_sda: This sets/clears the SDA line. Optional for generic SCL recovery.
- *     Populated internally, if sda_gpio is a valid GPIO, for generic GPIO
- *     recovery.
+ * @get_sda: This gets current value of SDA line. This or set_sda() is mandatory
+ *     for generic SCL recovery. Populated internally, if sda_gpio is a valid
+ *     GPIO, for generic GPIO recovery.
+ * @set_sda: This sets/clears the SDA line. This or get_sda() is mandatory for
+ *     generic SCL recovery. Populated internally, if sda_gpio is a valid GPIO,
+ *     for generic GPIO recovery.
+ * @get_bus_free: Returns the bus free state as seen from the IP core in case it
+ *     has a more complex internal logic than just reading SDA. Optional.
  * @prepare_recovery: This will be called before starting recovery. Platform may
  *     configure padmux here for SDA/SCL line or something else they want.
  * @unprepare_recovery: This will be called after completing recovery. Platform
@@ -601,6 +599,7 @@ struct i2c_bus_recovery_info {
        void (*set_scl)(struct i2c_adapter *adap, int val);
        int (*get_sda)(struct i2c_adapter *adap);
        void (*set_sda)(struct i2c_adapter *adap, int val);
+       int (*get_bus_free)(struct i2c_adapter *adap);
 
        void (*prepare_recovery)(struct i2c_adapter *adap);
        void (*unprepare_recovery)(struct i2c_adapter *adap);
@@ -658,6 +657,10 @@ struct i2c_adapter_quirks {
                                         I2C_AQ_COMB_READ_SECOND | I2C_AQ_COMB_SAME_ADDR)
 /* clock stretching is not supported */
 #define I2C_AQ_NO_CLK_STRETCH          BIT(4)
+/* message cannot have length of 0 */
+#define I2C_AQ_NO_ZERO_LEN_READ                BIT(5)
+#define I2C_AQ_NO_ZERO_LEN_WRITE       BIT(6)
+#define I2C_AQ_NO_ZERO_LEN             (I2C_AQ_NO_ZERO_LEN_READ | I2C_AQ_NO_ZERO_LEN_WRITE)
 
 /*
  * i2c_adapter is the structure used to identify a physical i2c bus along
@@ -759,18 +762,6 @@ i2c_unlock_bus(struct i2c_adapter *adapter, unsigned int flags)
        adapter->lock_ops->unlock_bus(adapter, flags);
 }
 
-static inline void
-i2c_lock_adapter(struct i2c_adapter *adapter)
-{
-       i2c_lock_bus(adapter, I2C_LOCK_ROOT_ADAPTER);
-}
-
-static inline void
-i2c_unlock_adapter(struct i2c_adapter *adapter)
-{
-       i2c_unlock_bus(adapter, I2C_LOCK_ROOT_ADAPTER);
-}
-
 /*flags for the client struct: */
 #define I2C_CLIENT_PEC         0x04    /* Use Packet Error Checking */
 #define I2C_CLIENT_TEN         0x10    /* we have a ten bit chip address */
@@ -864,7 +855,7 @@ static inline u8 i2c_8bit_addr_from_msg(const struct i2c_msg *msg)
 }
 
 u8 *i2c_get_dma_safe_msg_buf(struct i2c_msg *msg, unsigned int threshold);
-void i2c_release_dma_safe_msg_buf(struct i2c_msg *msg, u8 *buf);
+void i2c_put_dma_safe_msg_buf(u8 *buf, struct i2c_msg *msg, bool xferred);
 
 int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr);
 /**
index 3e8215b2c371c27406280fa5c4eccc098cebde7f..3ec8628ce17f044ad1d3ce626e95f368a55844d9 100644 (file)
@@ -236,34 +236,74 @@ struct ida {
 }
 #define DEFINE_IDA(name)       struct ida name = IDA_INIT(name)
 
-int ida_pre_get(struct ida *ida, gfp_t gfp_mask);
-int ida_get_new_above(struct ida *ida, int starting_id, int *p_id);
-void ida_remove(struct ida *ida, int id);
+int ida_alloc_range(struct ida *, unsigned int min, unsigned int max, gfp_t);
+void ida_free(struct ida *, unsigned int id);
 void ida_destroy(struct ida *ida);
 
-int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end,
-                  gfp_t gfp_mask);
-void ida_simple_remove(struct ida *ida, unsigned int id);
+/**
+ * ida_alloc() - Allocate an unused ID.
+ * @ida: IDA handle.
+ * @gfp: Memory allocation flags.
+ *
+ * Allocate an ID between 0 and %INT_MAX, inclusive.
+ *
+ * Context: Any context.
+ * Return: The allocated ID, or %-ENOMEM if memory could not be allocated,
+ * or %-ENOSPC if there are no free IDs.
+ */
+static inline int ida_alloc(struct ida *ida, gfp_t gfp)
+{
+       return ida_alloc_range(ida, 0, ~0, gfp);
+}
 
-static inline void ida_init(struct ida *ida)
+/**
+ * ida_alloc_min() - Allocate an unused ID.
+ * @ida: IDA handle.
+ * @min: Lowest ID to allocate.
+ * @gfp: Memory allocation flags.
+ *
+ * Allocate an ID between @min and %INT_MAX, inclusive.
+ *
+ * Context: Any context.
+ * Return: The allocated ID, or %-ENOMEM if memory could not be allocated,
+ * or %-ENOSPC if there are no free IDs.
+ */
+static inline int ida_alloc_min(struct ida *ida, unsigned int min, gfp_t gfp)
 {
-       INIT_RADIX_TREE(&ida->ida_rt, IDR_RT_MARKER | GFP_NOWAIT);
+       return ida_alloc_range(ida, min, ~0, gfp);
 }
 
 /**
- * ida_get_new - allocate new ID
- * @ida:       idr handle
- * @p_id:      pointer to the allocated handle
+ * ida_alloc_max() - Allocate an unused ID.
+ * @ida: IDA handle.
+ * @max: Highest ID to allocate.
+ * @gfp: Memory allocation flags.
+ *
+ * Allocate an ID between 0 and @max, inclusive.
  *
- * Simple wrapper around ida_get_new_above() w/ @starting_id of zero.
+ * Context: Any context.
+ * Return: The allocated ID, or %-ENOMEM if memory could not be allocated,
+ * or %-ENOSPC if there are no free IDs.
  */
-static inline int ida_get_new(struct ida *ida, int *p_id)
+static inline int ida_alloc_max(struct ida *ida, unsigned int max, gfp_t gfp)
 {
-       return ida_get_new_above(ida, 0, p_id);
+       return ida_alloc_range(ida, 0, max, gfp);
 }
 
+static inline void ida_init(struct ida *ida)
+{
+       INIT_RADIX_TREE(&ida->ida_rt, IDR_RT_MARKER | GFP_NOWAIT);
+}
+
+#define ida_simple_get(ida, start, end, gfp)   \
+                       ida_alloc_range(ida, start, (end) - 1, gfp)
+#define ida_simple_remove(ida, id)     ida_free(ida, id)
+
 static inline bool ida_is_empty(const struct ida *ida)
 {
        return radix_tree_empty(&ida->ida_rt);
 }
+
+/* in lib/radix-tree.c */
+int ida_pre_get(struct ida *ida, gfp_t gfp_mask);
 #endif /* __IDR_H__ */
index bc27cf03c41ea5a4b19d87bb82da0f3d36e9390e..2538d176dd1fac053c6ccac3ff907ab4e66b8118 100644 (file)
 typedef int (*initcall_t)(void);
 typedef void (*exitcall_t)(void);
 
-extern initcall_t __con_initcall_start[], __con_initcall_end[];
-extern initcall_t __security_initcall_start[], __security_initcall_end[];
+#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
+typedef int initcall_entry_t;
+
+static inline initcall_t initcall_from_entry(initcall_entry_t *entry)
+{
+       return offset_to_ptr(entry);
+}
+#else
+typedef initcall_t initcall_entry_t;
+
+static inline initcall_t initcall_from_entry(initcall_entry_t *entry)
+{
+       return *entry;
+}
+#endif
+
+extern initcall_entry_t __con_initcall_start[], __con_initcall_end[];
+extern initcall_entry_t __security_initcall_start[], __security_initcall_end[];
 
 /* Used for contructor calls. */
 typedef void (*ctor_fn_t)(void);
@@ -167,9 +183,20 @@ extern bool initcall_debug;
  * as KEEP() in the linker script.
  */
 
-#define __define_initcall(fn, id) \
+#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
+#define ___define_initcall(fn, id, __sec)                      \
+       __ADDRESSABLE(fn)                                       \
+       asm(".section   \"" #__sec ".init\", \"a\"      \n"     \
+       "__initcall_" #fn #id ":                        \n"     \
+           ".long      " #fn " - .                     \n"     \
+           ".previous                                  \n");
+#else
+#define ___define_initcall(fn, id, __sec) \
        static initcall_t __initcall_##fn##id __used \
-       __attribute__((__section__(".initcall" #id ".init"))) = fn;
+               __attribute__((__section__(#__sec ".init"))) = fn;
+#endif
+
+#define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id)
 
 /*
  * Early initcalls run before initializing SMP.
@@ -208,13 +235,8 @@ extern bool initcall_debug;
 #define __exitcall(fn)                                         \
        static exitcall_t __exitcall_##fn __exit_call = fn
 
-#define console_initcall(fn)                                   \
-       static initcall_t __initcall_##fn                       \
-       __used __section(.con_initcall.init) = fn
-
-#define security_initcall(fn)                                  \
-       static initcall_t __initcall_##fn                       \
-       __used __section(.security_initcall.init) = fn
+#define console_initcall(fn)   ___define_initcall(fn,, .con_initcall)
+#define security_initcall(fn)  ___define_initcall(fn,, .security_initcall)
 
 struct obs_kernel_param {
        const char *str;
index a454b8aeb9387052509b60ba9f7b1db6a36f174b..a7083a45a26c03f99cd13e887434b70d5487c154 100644 (file)
@@ -46,15 +46,6 @@ extern struct cred init_cred;
 #define INIT_CPU_TIMERS(s)
 #endif
 
-#define INIT_PID_LINK(type)                                    \
-{                                                              \
-       .node = {                                               \
-               .next = NULL,                                   \
-               .pprev = NULL,                                  \
-       },                                                      \
-       .pid = &init_struct_pid,                                \
-}
-
 #define INIT_TASK_COMM "swapper"
 
 /* Attach to the init_task data structure for proper alignment */
index ef169d67df9217a8bf9d1dad19be7920ae0352f2..28004d74ae046596f00205139071b585c349b734 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/list.h>
 #include <linux/iommu.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
+#include <linux/dmar.h>
 
 #include <asm/cacheflush.h>
 #include <asm/iommu.h>
  * Extended Capability Register
  */
 
+#define ecap_dit(e)            ((e >> 41) & 0x1)
 #define ecap_pasid(e)          ((e >> 40) & 0x1)
 #define ecap_pss(e)            ((e >> 35) & 0x1f)
 #define ecap_eafs(e)           ((e >> 34) & 0x1)
@@ -284,6 +286,7 @@ enum {
 #define QI_DEV_IOTLB_SID(sid)  ((u64)((sid) & 0xffff) << 32)
 #define QI_DEV_IOTLB_QDEP(qdep)        (((qdep) & 0x1f) << 16)
 #define QI_DEV_IOTLB_ADDR(addr)        ((u64)(addr) & VTD_PAGE_MASK)
+#define QI_DEV_IOTLB_PFSID(pfsid) (((u64)(pfsid & 0xf) << 12) | ((u64)(pfsid & 0xfff) << 52))
 #define QI_DEV_IOTLB_SIZE      1
 #define QI_DEV_IOTLB_MAX_INVS  32
 
@@ -308,6 +311,7 @@ enum {
 #define QI_DEV_EIOTLB_PASID(p) (((u64)p) << 32)
 #define QI_DEV_EIOTLB_SID(sid) ((u64)((sid) & 0xffff) << 16)
 #define QI_DEV_EIOTLB_QDEP(qd) ((u64)((qd) & 0x1f) << 4)
+#define QI_DEV_EIOTLB_PFSID(pfsid) (((u64)(pfsid & 0xf) << 12) | ((u64)(pfsid & 0xfff) << 52))
 #define QI_DEV_EIOTLB_MAX_INVS 32
 
 #define QI_PGRP_IDX(idx)       (((u64)(idx)) << 55)
@@ -385,6 +389,42 @@ struct pasid_entry;
 struct pasid_state_entry;
 struct page_req_dsc;
 
+struct dmar_domain {
+       int     nid;                    /* node id */
+
+       unsigned        iommu_refcnt[DMAR_UNITS_SUPPORTED];
+                                       /* Refcount of devices per iommu */
+
+
+       u16             iommu_did[DMAR_UNITS_SUPPORTED];
+                                       /* Domain ids per IOMMU. Use u16 since
+                                        * domain ids are 16 bit wide according
+                                        * to VT-d spec, section 9.3 */
+
+       bool has_iotlb_device;
+       struct list_head devices;       /* all devices' list */
+       struct iova_domain iovad;       /* iova's that belong to this domain */
+
+       struct dma_pte  *pgd;           /* virtual address */
+       int             gaw;            /* max guest address width */
+
+       /* adjusted guest address width, 0 is level 2 30-bit */
+       int             agaw;
+
+       int             flags;          /* flags to find out type of domain */
+
+       int             iommu_coherency;/* indicate coherency of iommu access */
+       int             iommu_snooping; /* indicate snooping control feature*/
+       int             iommu_count;    /* reference count of iommu */
+       int             iommu_superpage;/* Level of superpages supported:
+                                          0 == 4KiB (no superpages), 1 == 2MiB,
+                                          2 == 1GiB, 3 == 512GiB, 4 == 1TiB */
+       u64             max_addr;       /* maximum mapped address */
+
+       struct iommu_domain domain;     /* generic domain data structure for
+                                          iommu core */
+};
+
 struct intel_iommu {
        void __iomem    *reg; /* Pointer to hardware regs, virtual addr */
        u64             reg_phys; /* physical address of hw register set */
@@ -414,11 +454,9 @@ struct intel_iommu {
         * devices away to userspace processes (e.g. for DPDK) and don't
         * want to trust that userspace will use *only* the PASID it was
         * told to. But while it's all driver-arbitrated, we're fine. */
-       struct pasid_entry *pasid_table;
        struct pasid_state_entry *pasid_state_table;
        struct page_req_dsc *prq;
        unsigned char prq_name[16];    /* Name for PRQ interrupt */
-       struct idr pasid_idr;
        u32 pasid_max;
 #endif
        struct q_inval  *qi;            /* Queued invalidation info */
@@ -434,6 +472,27 @@ struct intel_iommu {
        u32             flags;      /* Software defined flags */
 };
 
+/* PCI domain-device relationship */
+struct device_domain_info {
+       struct list_head link;  /* link to domain siblings */
+       struct list_head global; /* link to global list */
+       struct list_head table; /* link to pasid table */
+       u8 bus;                 /* PCI bus number */
+       u8 devfn;               /* PCI devfn number */
+       u16 pfsid;              /* SRIOV physical function source ID */
+       u8 pasid_supported:3;
+       u8 pasid_enabled:1;
+       u8 pri_supported:1;
+       u8 pri_enabled:1;
+       u8 ats_supported:1;
+       u8 ats_enabled:1;
+       u8 ats_qdep;
+       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 pasid_table *pasid_table; /* pasid table */
+};
+
 static inline void __iommu_flush_cache(
        struct intel_iommu *iommu, void *addr, int size)
 {
@@ -453,16 +512,22 @@ extern void qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid,
                             u8 fm, u64 type);
 extern void qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
                          unsigned int size_order, u64 type);
-extern void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 qdep,
-                              u64 addr, unsigned mask);
-
+extern void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid,
+                       u16 qdep, u64 addr, unsigned mask);
 extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu);
 
 extern int dmar_ir_support(void);
 
+struct dmar_domain *get_valid_domain_for_dev(struct device *dev);
+void *alloc_pgtable_page(int node);
+void free_pgtable_page(void *vaddr);
+struct intel_iommu *domain_get_iommu(struct dmar_domain *domain);
+int for_each_device_domain(int (*fn)(struct device_domain_info *info,
+                                    void *data), void *data);
+
 #ifdef CONFIG_INTEL_IOMMU_SVM
-extern int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu);
-extern int intel_svm_free_pasid_tables(struct intel_iommu *iommu);
+int intel_svm_init(struct intel_iommu *iommu);
+int intel_svm_exit(struct intel_iommu *iommu);
 extern int intel_svm_enable_prq(struct intel_iommu *iommu);
 extern int intel_svm_finish_prq(struct intel_iommu *iommu);
 
@@ -486,6 +551,7 @@ struct intel_svm {
        int flags;
        int pasid;
        struct list_head devs;
+       struct list_head list;
 };
 
 extern int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev);
index 19938ee6eb31638d487a71c6823c4a7e6ceefef2..87994c265bf5068cc31381623629521f59cf4aa2 100644 (file)
@@ -166,8 +166,6 @@ struct iommu_resv_region {
  * @detach_dev: detach device from an iommu domain
  * @map: map a physically contiguous memory region to an iommu domain
  * @unmap: unmap a physically contiguous memory region from an iommu domain
- * @map_sg: map a scatter-gather list of physically contiguous memory chunks
- *          to an iommu domain
  * @flush_tlb_all: Synchronously flush all hardware TLBs for this domain
  * @tlb_range_add: Add a given iova range to the flush queue for this domain
  * @tlb_sync: Flush all queued ranges from the hardware TLBs and empty flush
@@ -201,8 +199,6 @@ struct iommu_ops {
                   phys_addr_t paddr, size_t size, int prot);
        size_t (*unmap)(struct iommu_domain *domain, unsigned long iova,
                     size_t size);
-       size_t (*map_sg)(struct iommu_domain *domain, unsigned long iova,
-                        struct scatterlist *sg, unsigned int nents, int prot);
        void (*flush_iotlb_all)(struct iommu_domain *domain);
        void (*iotlb_range_add)(struct iommu_domain *domain,
                                unsigned long iova, size_t size);
@@ -303,9 +299,8 @@ extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova,
                          size_t size);
 extern size_t iommu_unmap_fast(struct iommu_domain *domain,
                               unsigned long iova, size_t size);
-extern size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
-                               struct scatterlist *sg,unsigned int nents,
-                               int prot);
+extern size_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
+                          struct scatterlist *sg,unsigned int nents, int prot);
 extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova);
 extern void iommu_set_fault_handler(struct iommu_domain *domain,
                        iommu_fault_handler_t handler, void *token);
@@ -378,13 +373,6 @@ static inline void iommu_tlb_sync(struct iommu_domain *domain)
                domain->ops->iotlb_sync(domain);
 }
 
-static inline size_t iommu_map_sg(struct iommu_domain *domain,
-                                 unsigned long iova, struct scatterlist *sg,
-                                 unsigned int nents, int prot)
-{
-       return domain->ops->map_sg(domain, iova, sg, nents, prot);
-}
-
 /* PCI device grouping function */
 extern struct iommu_group *pci_device_group(struct device *dev);
 /* Generic device grouping function */
@@ -698,4 +686,11 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 
 #endif /* CONFIG_IOMMU_API */
 
+#ifdef CONFIG_IOMMU_DEBUGFS
+extern struct dentry *iommu_debugfs_dir;
+void iommu_debugfs_setup(void);
+#else
+static inline void iommu_debugfs_setup(void) {}
+#endif
+
 #endif /* __LINUX_IOMMU_H */
index 6cea726612b770168eab5041259d8c52fc264bf2..6ab8c1bada3fccb11119f93130b1989ddb090ad3 100644 (file)
@@ -16,10 +16,9 @@ struct user_namespace;
 struct ipc_ids {
        int in_use;
        unsigned short seq;
-       bool tables_initialized;
        struct rw_semaphore rwsem;
        struct idr ipcs_idr;
-       int max_id;
+       int max_idx;
 #ifdef CONFIG_CHECKPOINT_RESTORE
        int next_id;
 #endif
index 9d2ea3e907d0fc018d8f7e13d2912537c83c5e70..8bdbb5f29494b494b47dadc8d57943eeb4011612 100644 (file)
 #define GICD_CTLR_ENABLE_G1A           (1U << 1)
 #define GICD_CTLR_ENABLE_G1            (1U << 0)
 
+#define GICD_IIDR_IMPLEMENTER_SHIFT    0
+#define GICD_IIDR_IMPLEMENTER_MASK     (0xfff << GICD_IIDR_IMPLEMENTER_SHIFT)
+#define GICD_IIDR_REVISION_SHIFT       12
+#define GICD_IIDR_REVISION_MASK                (0xf << GICD_IIDR_REVISION_SHIFT)
+#define GICD_IIDR_VARIANT_SHIFT                16
+#define GICD_IIDR_VARIANT_MASK         (0xf << GICD_IIDR_VARIANT_SHIFT)
+#define GICD_IIDR_PRODUCT_ID_SHIFT     24
+#define GICD_IIDR_PRODUCT_ID_MASK      (0xff << GICD_IIDR_PRODUCT_ID_SHIFT)
+
+
 /*
  * In systems with a single security state (what we emulate in KVM)
  * the meaning of the interrupt group enable bits is slightly different
index 68d8b1f73682be899af097adf1d95f6452c8a0c8..6c4aaf04046c0f81eb149e8aacfcb813663c5467 100644 (file)
                                        (GICD_INT_DEF_PRI << 8) |\
                                        GICD_INT_DEF_PRI)
 
+#define GICD_IIDR_IMPLEMENTER_SHIFT    0
+#define GICD_IIDR_IMPLEMENTER_MASK     (0xfff << GICD_IIDR_IMPLEMENTER_SHIFT)
+#define GICD_IIDR_REVISION_SHIFT       12
+#define GICD_IIDR_REVISION_MASK                (0xf << GICD_IIDR_REVISION_SHIFT)
+#define GICD_IIDR_VARIANT_SHIFT                16
+#define GICD_IIDR_VARIANT_MASK         (0xf << GICD_IIDR_VARIANT_SHIFT)
+#define GICD_IIDR_PRODUCT_ID_SHIFT     24
+#define GICD_IIDR_PRODUCT_ID_MASK      (0xff << GICD_IIDR_PRODUCT_ID_SHIFT)
+
+
 #define GICH_HCR                       0x0
 #define GICH_VTR                       0x4
 #define GICH_VMCR                      0x8
 #define GICH_LR_PENDING_BIT            (1 << 28)
 #define GICH_LR_ACTIVE_BIT             (1 << 29)
 #define GICH_LR_EOI                    (1 << 19)
+#define GICH_LR_GROUP1                 (1 << 30)
 #define GICH_LR_HW                     (1 << 31)
 
 #define GICH_VMCR_ENABLE_GRP0_SHIFT    0
index 9700f00bbc043ff5bdfb73986eb0ee0cc5903aca..21619c92c3770ca0cfc1f3381bee2fe8f065da88 100644 (file)
 #include <linux/typecheck.h>
 #include <asm/irqflags.h>
 
-#ifdef CONFIG_TRACE_IRQFLAGS
+/* Currently trace_softirqs_on/off is used only by lockdep */
+#ifdef CONFIG_PROVE_LOCKING
   extern void trace_softirqs_on(unsigned long ip);
   extern void trace_softirqs_off(unsigned long ip);
+  extern void lockdep_hardirqs_on(unsigned long ip);
+  extern void lockdep_hardirqs_off(unsigned long ip);
+#else
+  static inline void trace_softirqs_on(unsigned long ip) { }
+  static inline void trace_softirqs_off(unsigned long ip) { }
+  static inline void lockdep_hardirqs_on(unsigned long ip) { }
+  static inline void lockdep_hardirqs_off(unsigned long ip) { }
+#endif
+
+#ifdef CONFIG_TRACE_IRQFLAGS
   extern void trace_hardirqs_on(void);
   extern void trace_hardirqs_off(void);
 # define trace_hardirq_context(p)      ((p)->hardirq_context)
@@ -43,8 +54,6 @@ do {                                          \
 #else
 # define trace_hardirqs_on()           do { } while (0)
 # define trace_hardirqs_off()          do { } while (0)
-# define trace_softirqs_on(ip)         do { } while (0)
-# define trace_softirqs_off(ip)                do { } while (0)
 # define trace_hardirq_context(p)      0
 # define trace_softirq_context(p)      0
 # define trace_hardirqs_enabled(p)     0
index 8de55e4b5ee93bf824ba2a33a6cd4664c590acd8..8c3f8c14eeaafd5b1035f4ef2fec81384f94f77c 100644 (file)
@@ -12,11 +12,13 @@ enum kcore_type {
        KCORE_VMEMMAP,
        KCORE_USER,
        KCORE_OTHER,
+       KCORE_REMAP,
 };
 
 struct kcore_list {
        struct list_head list;
        unsigned long addr;
+       unsigned long vaddr;
        size_t size;
        int type;
 };
@@ -35,12 +37,23 @@ struct vmcoredd_node {
 };
 
 #ifdef CONFIG_PROC_KCORE
-extern void kclist_add(struct kcore_list *, void *, size_t, int type);
+void __init kclist_add(struct kcore_list *, void *, size_t, int type);
+static inline
+void kclist_add_remap(struct kcore_list *m, void *addr, void *vaddr, size_t sz)
+{
+       m->vaddr = (unsigned long)vaddr;
+       kclist_add(m, addr, sz, KCORE_REMAP);
+}
 #else
 static inline
 void kclist_add(struct kcore_list *new, void *addr, size_t size, int type)
 {
 }
+
+static inline
+void kclist_add_remap(struct kcore_list *m, void *addr, void *vaddr, size_t sz)
+{
+}
 #endif
 
 #endif /* _LINUX_KCORE_H */
index 941dc0a5a877998e46d11541bdb491655a5f34af..d6aac75b51baab469d05ad6ca816b46bcd590906 100644 (file)
  * arguments just once each.
  */
 #define __round_mask(x, y) ((__typeof__(x))((y)-1))
+/**
+ * round_up - round up to next specified power of 2
+ * @x: the value to round
+ * @y: multiple to round up to (must be a power of 2)
+ *
+ * Rounds @x up to next multiple of @y (which must be a power of 2).
+ * To perform arbitrary rounding up, use roundup() below.
+ */
 #define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
+/**
+ * round_down - round down to next specified power of 2
+ * @x: the value to round
+ * @y: multiple to round down to (must be a power of 2)
+ *
+ * Rounds @x down to next multiple of @y (which must be a power of 2).
+ * To perform arbitrary rounding down, use rounddown() below.
+ */
 #define round_down(x, y) ((x) & ~__round_mask(x, y))
 
 /**
 # define DIV_ROUND_UP_SECTOR_T(ll,d) DIV_ROUND_UP(ll,d)
 #endif
 
-/* The `const' in roundup() prevents gcc-3.3 from calling __divdi3 */
+/**
+ * roundup - round up to the next specified multiple
+ * @x: the value to up
+ * @y: multiple to round up to
+ *
+ * Rounds @x up to next multiple of @y. If @y will always be a power
+ * of 2, consider using the faster round_up().
+ *
+ * The `const' here prevents gcc-3.3 from calling __divdi3
+ */
 #define roundup(x, y) (                                        \
 {                                                      \
        const typeof(y) __y = y;                        \
        (((x) + (__y - 1)) / __y) * __y;                \
 }                                                      \
 )
+/**
+ * rounddown - round down to next specified multiple
+ * @x: the value to round
+ * @y: multiple to round down to
+ *
+ * Rounds @x down to next multiple of @y. If @y will always be a power
+ * of 2, consider using the faster round_down().
+ */
 #define rounddown(x, y) (                              \
 {                                                      \
        typeof(x) __x = (x);                            \
index 7c7362dd2faa9c549500756713ea5512c973cfcf..0205aee44dedd8522be52ffe7d3237dd3819656a 100644 (file)
@@ -1289,8 +1289,8 @@ static inline long kvm_arch_vcpu_async_ioctl(struct file *filp,
 }
 #endif /* CONFIG_HAVE_KVM_VCPU_ASYNC_IOCTL */
 
-void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
-               unsigned long start, unsigned long end);
+int kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
+               unsigned long start, unsigned long end, bool blockable);
 
 #ifdef CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE
 int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu);
index bc4f87cbe7f40d70d61a942b819769560816fb73..38c95d66ab12f1465fe02c9b62752a8887976dae 100644 (file)
@@ -523,7 +523,8 @@ enum ata_lpm_policy {
        ATA_LPM_MAX_POWER,
        ATA_LPM_MED_POWER,
        ATA_LPM_MED_POWER_WITH_DIPM, /* Med power + DIPM as win IRST does */
-       ATA_LPM_MIN_POWER,
+       ATA_LPM_MIN_POWER_WITH_PARTIAL, /* Min Power + partial and slumber */
+       ATA_LPM_MIN_POWER, /* Min power + no partial (slumber only) */
 };
 
 enum ata_lpm_hints {
@@ -1858,8 +1859,6 @@ extern unsigned int ata_sff_data_xfer(struct ata_queued_cmd *qc,
                        unsigned char *buf, unsigned int buflen, int rw);
 extern unsigned int ata_sff_data_xfer32(struct ata_queued_cmd *qc,
                        unsigned char *buf, unsigned int buflen, int rw);
-extern unsigned int ata_sff_data_xfer_noirq(struct ata_queued_cmd *qc,
-                       unsigned char *buf, unsigned int buflen, int rw);
 extern void ata_sff_irq_on(struct ata_port *ap);
 extern void ata_sff_irq_clear(struct ata_port *ap);
 extern int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
index 4fd95dbeb52f2254f8d3fc9b597528c9affd1d3a..b065ef4067701b6892c9f09b03094677d941b506 100644 (file)
@@ -299,7 +299,7 @@ int           nlmsvc_unlock_all_by_ip(struct sockaddr *server_addr);
 
 static inline struct inode *nlmsvc_file_inode(struct nlm_file *file)
 {
-       return file_inode(file->f_file);
+       return locks_inode(file->f_file);
 }
 
 static inline int __nlm_privileged_request4(const struct sockaddr *sap)
@@ -359,7 +359,7 @@ static inline int nlm_privileged_requester(const struct svc_rqst *rqstp)
 static inline int nlm_compare_locks(const struct file_lock *fl1,
                                    const struct file_lock *fl2)
 {
-       return file_inode(fl1->fl_file) == file_inode(fl2->fl_file)
+       return locks_inode(fl1->fl_file) == locks_inode(fl2->fl_file)
             && fl1->fl_pid   == fl2->fl_pid
             && fl1->fl_owner == fl2->fl_owner
             && fl1->fl_start == fl2->fl_start
index 6fc77d4dbdcd242b40432a579c63312bb88b80b7..b0d0b51c4d850892f01de631006d0b585697926e 100644 (file)
@@ -266,7 +266,7 @@ struct held_lock {
 /*
  * Initialization, self-test and debugging-output methods:
  */
-extern void lockdep_info(void);
+extern void lockdep_init(void);
 extern void lockdep_reset(void);
 extern void lockdep_reset_lock(struct lockdep_map *lock);
 extern void lockdep_free_key_range(void *start, unsigned long size);
@@ -406,7 +406,7 @@ static inline void lockdep_on(void)
 # define lock_downgrade(l, i)                  do { } while (0)
 # define lock_set_class(l, n, k, s, i)         do { } while (0)
 # define lock_set_subclass(l, s, i)            do { } while (0)
-# define lockdep_info()                                do { } while (0)
+# define lockdep_init()                                do { } while (0)
 # define lockdep_init_map(lock, name, key, sub) \
                do { (void)(name); (void)(key); } while (0)
 # define lockdep_set_class(lock, key)          do { (void)(key); } while (0)
@@ -532,7 +532,7 @@ do {                                                                \
 
 #endif /* CONFIG_LOCKDEP */
 
-#ifdef CONFIG_TRACE_IRQFLAGS
+#ifdef CONFIG_PROVE_LOCKING
 extern void print_irqtrace_events(struct task_struct *curr);
 #else
 static inline void print_irqtrace_events(struct task_struct *curr)
index 0e6c515fb698f7a6e8c139b2fc87b9286342ca06..652f602167df49b58830acca591e3fbe5fb67185 100644 (file)
@@ -225,6 +225,11 @@ struct mem_cgroup {
         */
        bool use_hierarchy;
 
+       /*
+        * Should the OOM killer kill all belonging tasks, had it kill one?
+        */
+       bool oom_group;
+
        /* protected by memcg_oom_lock */
        bool            oom_lock;
        int             under_oom;
@@ -542,6 +547,9 @@ static inline bool task_in_memcg_oom(struct task_struct *p)
 }
 
 bool mem_cgroup_oom_synchronize(bool wait);
+struct mem_cgroup *mem_cgroup_get_oom_group(struct task_struct *victim,
+                                           struct mem_cgroup *oom_domain);
+void mem_cgroup_print_oom_group(struct mem_cgroup *memcg);
 
 #ifdef CONFIG_MEMCG_SWAP
 extern int do_swap_account;
@@ -1001,6 +1009,16 @@ static inline bool mem_cgroup_oom_synchronize(bool wait)
        return false;
 }
 
+static inline struct mem_cgroup *mem_cgroup_get_oom_group(
+       struct task_struct *victim, struct mem_cgroup *oom_domain)
+{
+       return NULL;
+}
+
+static inline void mem_cgroup_print_oom_group(struct mem_cgroup *memcg)
+{
+}
+
 static inline unsigned long memcg_page_state(struct mem_cgroup *memcg,
                                             int idx)
 {
index 4e9828cda7a26ee6796b127c06a35513bd5a29d1..34a28227068dcba6cba30feb13e15aeff9f69b08 100644 (file)
@@ -319,6 +319,7 @@ static inline int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
 static inline void remove_memory(int nid, u64 start, u64 size) {}
 #endif /* CONFIG_MEMORY_HOTREMOVE */
 
+extern void __ref free_area_init_core_hotplug(int nid);
 extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn,
                void *arg, int (*func)(struct memory_block *, void *));
 extern int add_memory(int nid, u64 start, u64 size);
index e06f5f79eaef8e0dd8ce446b811406edf6704662..6c1ad160ed879090c9fdb3ec6cd8772bb3431d03 100644 (file)
 #define MCLK_DIR(x) (x == 1 ? IMX6UL_GPR1_SAI1_MCLK_DIR : x == 2 ? \
                     IMX6UL_GPR1_SAI2_MCLK_DIR : IMX6UL_GPR1_SAI3_MCLK_DIR)
 
+/* For imx6sll iomux gpr register field define */
+#define IMX6SLL_GPR5_AFCG_X_BYPASS_MASK                (0x1f << 11)
+
 #endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */
index a3cae495f9ce951716d4e13ca1a23e6c6e36bd83..a61ebe8ad4ca92e72e23855c17f8e7c9ad059a54 100644 (file)
@@ -456,6 +456,7 @@ static inline void vma_init(struct vm_area_struct *vma, struct mm_struct *mm)
 {
        static const struct vm_operations_struct dummy_vm_ops = {};
 
+       memset(vma, 0, sizeof(*vma));
        vma->vm_mm = mm;
        vma->vm_ops = &dummy_vm_ops;
        INIT_LIST_HEAD(&vma->anon_vma_chain);
@@ -727,10 +728,10 @@ static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma)
        return pte;
 }
 
-int alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg,
+vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg,
                struct page *page);
-int finish_fault(struct vm_fault *vmf);
-int finish_mkwrite_fault(struct vm_fault *vmf);
+vm_fault_t finish_fault(struct vm_fault *vmf);
+vm_fault_t finish_mkwrite_fault(struct vm_fault *vmf);
 #endif
 
 /*
@@ -959,15 +960,6 @@ static inline int page_zone_id(struct page *page)
        return (page->flags >> ZONEID_PGSHIFT) & ZONEID_MASK;
 }
 
-static inline int zone_to_nid(struct zone *zone)
-{
-#ifdef CONFIG_NUMA
-       return zone->node;
-#else
-       return 0;
-#endif
-}
-
 #ifdef NODE_NOT_IN_PAGE_FLAGS
 extern int page_to_nid(const struct page *page);
 #else
@@ -1411,8 +1403,8 @@ int generic_error_remove_page(struct address_space *mapping, struct page *page);
 int invalidate_inode_page(struct page *page);
 
 #ifdef CONFIG_MMU
-extern int handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
-               unsigned int flags);
+extern vm_fault_t handle_mm_fault(struct vm_area_struct *vma,
+                       unsigned long address, unsigned int flags);
 extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm,
                            unsigned long address, unsigned int fault_flags,
                            bool *unlocked);
@@ -1421,7 +1413,7 @@ void unmap_mapping_pages(struct address_space *mapping,
 void unmap_mapping_range(struct address_space *mapping,
                loff_t const holebegin, loff_t const holelen, int even_cows);
 #else
-static inline int handle_mm_fault(struct vm_area_struct *vma,
+static inline vm_fault_t handle_mm_fault(struct vm_area_struct *vma,
                unsigned long address, unsigned int flags)
 {
        /* should never happen if there's no MMU */
@@ -2023,7 +2015,7 @@ static inline spinlock_t *pud_lock(struct mm_struct *mm, pud_t *pud)
 
 extern void __init pagecache_init(void);
 extern void free_area_init(unsigned long * zones_size);
-extern void free_area_init_node(int nid, unsigned long * zones_size,
+extern void __init free_area_init_node(int nid, unsigned long * zones_size,
                unsigned long zone_start_pfn, unsigned long *zholes_size);
 extern void free_initmem(void);
 
@@ -2571,7 +2563,7 @@ static inline struct page *follow_page(struct vm_area_struct *vma,
 #define FOLL_COW       0x4000  /* internal GUP flag */
 #define FOLL_ANON      0x8000  /* don't do file mappings */
 
-static inline int vm_fault_to_errno(int vm_fault, int foll_flags)
+static inline int vm_fault_to_errno(vm_fault_t vm_fault, int foll_flags)
 {
        if (vm_fault & VM_FAULT_OOM)
                return -ENOMEM;
@@ -2739,6 +2731,7 @@ enum mf_action_page_type {
        MF_MSG_TRUNCATED_LRU,
        MF_MSG_BUDDY,
        MF_MSG_BUDDY_2ND,
+       MF_MSG_DAX,
        MF_MSG_UNKNOWN,
 };
 
index 392e6af827016cb48d8bfffde0b096463378aaad..133ba78820ee5f2da69b865df43689c0a736ba3e 100644 (file)
@@ -151,13 +151,15 @@ struct mmu_notifier_ops {
         * address space but may still be referenced by sptes until
         * the last refcount is dropped.
         *
-        * If both of these callbacks cannot block, and invalidate_range
-        * cannot block, mmu_notifier_ops.flags should have
-        * MMU_INVALIDATE_DOES_NOT_BLOCK set.
+        * If blockable argument is set to false then the callback cannot
+        * sleep and has to return with -EAGAIN. 0 should be returned
+        * otherwise.
+        *
         */
-       void (*invalidate_range_start)(struct mmu_notifier *mn,
+       int (*invalidate_range_start)(struct mmu_notifier *mn,
                                       struct mm_struct *mm,
-                                      unsigned long start, unsigned long end);
+                                      unsigned long start, unsigned long end,
+                                      bool blockable);
        void (*invalidate_range_end)(struct mmu_notifier *mn,
                                     struct mm_struct *mm,
                                     unsigned long start, unsigned long end);
@@ -229,8 +231,9 @@ extern int __mmu_notifier_test_young(struct mm_struct *mm,
                                     unsigned long address);
 extern void __mmu_notifier_change_pte(struct mm_struct *mm,
                                      unsigned long address, pte_t pte);
-extern void __mmu_notifier_invalidate_range_start(struct mm_struct *mm,
-                                 unsigned long start, unsigned long end);
+extern int __mmu_notifier_invalidate_range_start(struct mm_struct *mm,
+                                 unsigned long start, unsigned long end,
+                                 bool blockable);
 extern void __mmu_notifier_invalidate_range_end(struct mm_struct *mm,
                                  unsigned long start, unsigned long end,
                                  bool only_end);
@@ -281,7 +284,15 @@ static inline void mmu_notifier_invalidate_range_start(struct mm_struct *mm,
                                  unsigned long start, unsigned long end)
 {
        if (mm_has_notifiers(mm))
-               __mmu_notifier_invalidate_range_start(mm, start, end);
+               __mmu_notifier_invalidate_range_start(mm, start, end, true);
+}
+
+static inline int mmu_notifier_invalidate_range_start_nonblock(struct mm_struct *mm,
+                                 unsigned long start, unsigned long end)
+{
+       if (mm_has_notifiers(mm))
+               return __mmu_notifier_invalidate_range_start(mm, start, end, false);
+       return 0;
 }
 
 static inline void mmu_notifier_invalidate_range_end(struct mm_struct *mm,
@@ -461,6 +472,12 @@ static inline void mmu_notifier_invalidate_range_start(struct mm_struct *mm,
 {
 }
 
+static inline int mmu_notifier_invalidate_range_start_nonblock(struct mm_struct *mm,
+                                 unsigned long start, unsigned long end)
+{
+       return 0;
+}
+
 static inline void mmu_notifier_invalidate_range_end(struct mm_struct *mm,
                                  unsigned long start, unsigned long end)
 {
index 32699b2dc52a1f8bece62d3ae7d35d67cbe1e88f..1e22d96734e0099476b18d14ca7c11a991d3a470 100644 (file)
@@ -755,25 +755,6 @@ static inline bool pgdat_is_empty(pg_data_t *pgdat)
        return !pgdat->node_start_pfn && !pgdat->node_spanned_pages;
 }
 
-static inline int zone_id(const struct zone *zone)
-{
-       struct pglist_data *pgdat = zone->zone_pgdat;
-
-       return zone - pgdat->node_zones;
-}
-
-#ifdef CONFIG_ZONE_DEVICE
-static inline bool is_dev_zone(const struct zone *zone)
-{
-       return zone_id(zone) == ZONE_DEVICE;
-}
-#else
-static inline bool is_dev_zone(const struct zone *zone)
-{
-       return false;
-}
-#endif
-
 #include <linux/memory_hotplug.h>
 
 void build_all_zonelists(pg_data_t *pgdat);
@@ -824,6 +805,18 @@ static inline int local_memory_node(int node_id) { return node_id; };
  */
 #define zone_idx(zone)         ((zone) - (zone)->zone_pgdat->node_zones)
 
+#ifdef CONFIG_ZONE_DEVICE
+static inline bool is_dev_zone(const struct zone *zone)
+{
+       return zone_idx(zone) == ZONE_DEVICE;
+}
+#else
+static inline bool is_dev_zone(const struct zone *zone)
+{
+       return false;
+}
+#endif
+
 /*
  * Returns true if a zone has pages managed by the buddy allocator.
  * All the reclaim decisions have to use this function rather than
@@ -841,6 +834,25 @@ static inline bool populated_zone(struct zone *zone)
        return zone->present_pages;
 }
 
+#ifdef CONFIG_NUMA
+static inline int zone_to_nid(struct zone *zone)
+{
+       return zone->node;
+}
+
+static inline void zone_set_nid(struct zone *zone, int nid)
+{
+       zone->node = nid;
+}
+#else
+static inline int zone_to_nid(struct zone *zone)
+{
+       return 0;
+}
+
+static inline void zone_set_nid(struct zone *zone, int nid) {}
+#endif
+
 extern int movable_zone;
 
 #ifdef CONFIG_HIGHMEM
@@ -956,12 +968,7 @@ static inline int zonelist_zone_idx(struct zoneref *zoneref)
 
 static inline int zonelist_node_idx(struct zoneref *zoneref)
 {
-#ifdef CONFIG_NUMA
-       /* zone_to_nid not available in this context */
-       return zoneref->zone->node;
-#else
-       return 0;
-#endif /* CONFIG_NUMA */
+       return zone_to_nid(zoneref->zone);
 }
 
 struct zoneref *__next_zones_zonelist(struct zoneref *z,
index db99240d00bdfea565ea6ed838bbfe5eeba4aa33..c79e859408e62d7cd7306407bbaf4c6489103905 100644 (file)
@@ -363,7 +363,6 @@ static inline void net_dim_sample(u16 event_ctr,
 }
 
 #define NET_DIM_NEVENTS 64
-#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
 #define BIT_GAP(bits, end, start) ((((end) - (start)) + BIT_ULL(bits)) & (BIT_ULL(bits) - 1))
 
 static inline void net_dim_calc_stats(struct net_dim_sample *start,
index 57ffaa20d5649f5cdc77e4a1fd088201e66286ed..1b06f0b284533b025031bd198d244ececfe9b675 100644 (file)
@@ -374,6 +374,13 @@ enum lock_type4 {
        NFS4_WRITEW_LT = 4
 };
 
+enum change_attr_type4 {
+       NFS4_CHANGE_TYPE_IS_MONOTONIC_INCR = 0,
+       NFS4_CHANGE_TYPE_IS_VERSION_COUNTER = 1,
+       NFS4_CHANGE_TYPE_IS_VERSION_COUNTER_NOPNFS = 2,
+       NFS4_CHANGE_TYPE_IS_TIME_METADATA = 3,
+       NFS4_CHANGE_TYPE_IS_UNDEFINED = 4
+};
 
 /* Mandatory Attributes */
 #define FATTR4_WORD0_SUPPORTED_ATTRS    (1UL << 0)
@@ -441,6 +448,7 @@ enum lock_type4 {
 #define FATTR4_WORD2_LAYOUT_BLKSIZE     (1UL << 1)
 #define FATTR4_WORD2_MDSTHRESHOLD       (1UL << 4)
 #define FATTR4_WORD2_CLONE_BLKSIZE     (1UL << 13)
+#define FATTR4_WORD2_CHANGE_ATTR_TYPE  (1UL << 15)
 #define FATTR4_WORD2_SECURITY_LABEL     (1UL << 16)
 #define FATTR4_WORD2_MODE_UMASK                (1UL << 17)
 
@@ -527,6 +535,7 @@ enum {
        NFSPROC4_CLNT_LAYOUTSTATS,
        NFSPROC4_CLNT_CLONE,
        NFSPROC4_CLNT_COPY,
+       NFSPROC4_CLNT_OFFLOAD_CANCEL,
 
        NFSPROC4_CLNT_LOOKUPP,
 };
index 2f129bbfaae829cd9d04c8b7f91d13f9305221ec..a0831e9d19c9df9f26c6d0777e198c32241550b4 100644 (file)
@@ -185,6 +185,17 @@ struct nfs_inode {
        struct inode            vfs_inode;
 };
 
+struct nfs4_copy_state {
+       struct list_head        copies;
+       nfs4_stateid            stateid;
+       struct completion       completion;
+       uint64_t                count;
+       struct nfs_writeverf    verf;
+       int                     error;
+       int                     flags;
+       struct nfs4_state       *parent_state;
+};
+
 /*
  * Access bit flags
  */
index 74ae3e1d19a04a8e3e1fbaa24dc64aa152c75f2d..bf39d9c92201f811c76df9db76ab44a60b29eb41 100644 (file)
@@ -28,7 +28,6 @@ struct nfs41_impl_id;
 struct nfs_client {
        refcount_t              cl_count;
        atomic_t                cl_mds_count;
-       seqcount_t              cl_callback_count;
        int                     cl_cons_state;  /* current construction state (-ve: init error) */
 #define NFS_CS_READY           0               /* ready to be used */
 #define NFS_CS_INITING         1               /* busy initialising */
@@ -122,6 +121,7 @@ struct nfs_client {
 #endif
 
        struct net              *cl_net;
+       struct list_head        pending_cb_stateids;
 };
 
 /*
@@ -209,6 +209,7 @@ struct nfs_server {
        struct list_head        state_owners_lru;
        struct list_head        layouts;
        struct list_head        delegations;
+       struct list_head        ss_copies;
 
        unsigned long           mig_gen;
        unsigned long           mig_status;
@@ -256,5 +257,6 @@ struct nfs_server {
 #define NFS_CAP_LAYOUTSTATS    (1U << 22)
 #define NFS_CAP_CLONE          (1U << 23)
 #define NFS_CAP_COPY           (1U << 24)
+#define NFS_CAP_OFFLOAD_CANCEL (1U << 25)
 
 #endif
index 712eed156d0912f1aecc97de222597f1d7cc5dc9..bd1c889a9ed956c14543117a8835eb4ae4474a9a 100644 (file)
@@ -271,7 +271,6 @@ struct nfs4_layoutget {
        struct nfs4_layoutget_args args;
        struct nfs4_layoutget_res res;
        struct rpc_cred *cred;
-       unsigned callback_count;
        gfp_t gfp_flags;
 };
 
@@ -1389,9 +1388,11 @@ struct nfs42_copy_args {
        u64                             dst_pos;
 
        u64                             count;
+       bool                            sync;
 };
 
 struct nfs42_write_res {
+       nfs4_stateid            stateid;
        u64                     count;
        struct nfs_writeverf    verifier;
 };
@@ -1404,6 +1405,18 @@ struct nfs42_copy_res {
        struct nfs_commitres            commit_res;
 };
 
+struct nfs42_offload_status_args {
+       struct nfs4_sequence_args       osa_seq_args;
+       struct nfs_fh                   *osa_src_fh;
+       nfs4_stateid                    osa_stateid;
+};
+
+struct nfs42_offload_status_res {
+       struct nfs4_sequence_res        osr_seq_res;
+       uint64_t                        osr_count;
+       int                             osr_status;
+};
+
 struct nfs42_seek_args {
        struct nfs4_sequence_args       seq_args;
 
index 1fbde8a880d9a08b43cf57373f134b306c136dd3..5a30ad594ccc11d40879ec8438b587f519b5c791 100644 (file)
@@ -518,7 +518,7 @@ static inline int node_random(const nodemask_t *mask)
  * NODEMASK_ALLOC(type, name) allocates an object with a specified type and
  * name.
  */
-#if NODES_SHIFT > 8 /* nodemask_t > 256 bytes */
+#if NODES_SHIFT > 8 /* nodemask_t > 32 bytes */
 #define NODEMASK_ALLOC(type, name, gfp_flags)  \
                        type *name = kmalloc(sizeof(*name), gfp_flags)
 #define NODEMASK_FREE(m)                       kfree(m)
index 4d25e4f952d9bd4c02b1f3c33fea0c4254907e14..99b0ebf496329f347cf723ad5da07ad5c23bcf9d 100644 (file)
@@ -256,6 +256,9 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
 #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
 #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
 
+extern bool of_node_name_eq(const struct device_node *np, const char *name);
+extern bool of_node_name_prefix(const struct device_node *np, const char *prefix);
+
 static inline const char *of_node_full_name(const struct device_node *np)
 {
        return np ? np->full_name : "<no-node>";
@@ -290,6 +293,8 @@ extern struct device_node *of_get_next_child(const struct device_node *node,
 extern struct device_node *of_get_next_available_child(
        const struct device_node *node, struct device_node *prev);
 
+extern struct device_node *of_get_compatible_child(const struct device_node *parent,
+                                       const char *compatible);
 extern struct device_node *of_get_child_by_name(const struct device_node *node,
                                        const char *name);
 
@@ -561,6 +566,16 @@ static inline struct device_node *to_of_node(const struct fwnode_handle *fwnode)
        return NULL;
 }
 
+static inline bool of_node_name_eq(const struct device_node *np, const char *name)
+{
+       return false;
+}
+
+static inline bool of_node_name_prefix(const struct device_node *np, const char *prefix)
+{
+       return false;
+}
+
 static inline const char* of_node_full_name(const struct device_node *np)
 {
        return "<no-node>";
@@ -632,6 +647,12 @@ static inline bool of_have_populated_dt(void)
        return false;
 }
 
+static inline struct device_node *of_get_compatible_child(const struct device_node *parent,
+                                       const char *compatible)
+{
+       return NULL;
+}
+
 static inline struct device_node *of_get_child_by_name(
                                        const struct device_node *node,
                                        const char *name)
@@ -967,6 +988,18 @@ static inline struct device_node *of_find_matching_node(
        return of_find_matching_node_and_match(from, matches, NULL);
 }
 
+static inline const char *of_node_get_device_type(const struct device_node *np)
+{
+       return of_get_property(np, "type", NULL);
+}
+
+static inline bool of_node_is_type(const struct device_node *np, const char *type)
+{
+       const char *match = of_node_get_device_type(np);
+
+       return np && match && type && !strcmp(match, type);
+}
+
 /**
  * of_property_count_u8_elems - Count the number of u8 elements in a property
  *
index 6adac113e96d29b5059ed65ac0522237c9b94388..69864a547663ecda818ac17c171ed085dbe33c26 100644 (file)
@@ -88,14 +88,14 @@ static inline bool mm_is_oom_victim(struct mm_struct *mm)
  *
  * Return 0 when the PF is safe VM_FAULT_SIGBUS otherwise.
  */
-static inline int check_stable_address_space(struct mm_struct *mm)
+static inline vm_fault_t check_stable_address_space(struct mm_struct *mm)
 {
        if (unlikely(test_bit(MMF_UNSTABLE, &mm->flags)))
                return VM_FAULT_SIGBUS;
        return 0;
 }
 
-void __oom_reap_task_mm(struct mm_struct *mm);
+bool __oom_reap_task_mm(struct mm_struct *mm);
 
 extern unsigned long oom_badness(struct task_struct *p,
                struct mem_cgroup *memcg, const nodemask_t *nodemask,
index 901943e4754b3388b59620c401aff7659d673f45..74bee8cecf4ce864322157d3e93defe200ec0173 100644 (file)
@@ -369,8 +369,13 @@ PAGEFLAG_FALSE(Uncached)
 PAGEFLAG(HWPoison, hwpoison, PF_ANY)
 TESTSCFLAG(HWPoison, hwpoison, PF_ANY)
 #define __PG_HWPOISON (1UL << PG_hwpoison)
+extern bool set_hwpoison_free_buddy_page(struct page *page);
 #else
 PAGEFLAG_FALSE(HWPoison)
+static inline bool set_hwpoison_free_buddy_page(struct page *page)
+{
+       return 0;
+}
 #define __PG_HWPOISON 0
 #endif
 
index 9b87f19369067db116e4fab9086a571b2406a89c..e72ca8dd6241b88cae56cc27de7e05e10182f267 100644 (file)
@@ -1809,7 +1809,11 @@ struct pci_fixup {
        u16 device;                     /* Or PCI_ANY_ID */
        u32 class;                      /* Or PCI_ANY_ID */
        unsigned int class_shift;       /* should be 0, 8, 16 */
+#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
+       int hook_offset;
+#else
        void (*hook)(struct pci_dev *dev);
+#endif
 };
 
 enum pci_fixup_pass {
@@ -1823,12 +1827,28 @@ enum pci_fixup_pass {
        pci_fixup_suspend_late, /* pci_device_suspend_late() */
 };
 
+#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
+#define __DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class,  \
+                                   class_shift, hook)                  \
+       __ADDRESSABLE(hook)                                             \
+       asm(".section " #sec ", \"a\"                           \n"     \
+           ".balign    16                                      \n"     \
+           ".short "   #vendor ", " #device "                  \n"     \
+           ".long "    #class ", " #class_shift "              \n"     \
+           ".long "    #hook " - .                             \n"     \
+           ".previous                                          \n");
+#define DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class,    \
+                                 class_shift, hook)                    \
+       __DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class,   \
+                                 class_shift, hook)
+#else
 /* Anonymous variables would be nice... */
 #define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, class,        \
                                  class_shift, hook)                    \
        static const struct pci_fixup __PASTE(__pci_fixup_##name,__LINE__) __used       \
        __attribute__((__section__(#section), aligned((sizeof(void *)))))    \
                = { vendor, device, class, class_shift, hook };
+#endif
 
 #define DECLARE_PCI_FIXUP_CLASS_EARLY(vendor, device, class,           \
                                         class_shift, hook)             \
index 99d366cb0e9f5327081cea07b34c798df6aec35f..d157983b84cf9258fa43b639accc8ee3904a080c 100644 (file)
 
 #define PCI_VENDOR_ID_OCZ              0x1b85
 
+#define PCI_VENDOR_ID_NCUBE            0x10ff
+
 #endif /* _LINUX_PCI_IDS_H */
index 296bbe49d5d18368737e89203cf96d6937f8f016..70b7123f38c7c9044bb262a2cecc96ab415b1f4d 100644 (file)
@@ -149,4 +149,6 @@ extern phys_addr_t per_cpu_ptr_to_phys(void *addr);
        (typeof(type) __percpu *)__alloc_percpu(sizeof(type),           \
                                                __alignof__(type))
 
+extern unsigned long pcpu_nr_pages(void);
+
 #endif /* __LINUX_PERCPU_H */
index 7633d55d9a24730c0dacdc43ec50bb72b1bbbbe0..14a9a39da9c77eab3fa21cb05e2b30206ed526d9 100644 (file)
@@ -7,11 +7,10 @@
 enum pid_type
 {
        PIDTYPE_PID,
+       PIDTYPE_TGID,
        PIDTYPE_PGID,
        PIDTYPE_SID,
        PIDTYPE_MAX,
-       /* only valid to __task_pid_nr_ns() */
-       __PIDTYPE_TGID
 };
 
 /*
@@ -67,12 +66,6 @@ struct pid
 
 extern struct pid init_struct_pid;
 
-struct pid_link
-{
-       struct hlist_node node;
-       struct pid *pid;
-};
-
 static inline struct pid *get_pid(struct pid *pid)
 {
        if (pid)
@@ -177,7 +170,7 @@ pid_t pid_vnr(struct pid *pid);
        do {                                                            \
                if ((pid) != NULL)                                      \
                        hlist_for_each_entry_rcu((task),                \
-                               &(pid)->tasks[type], pids[type].node) {
+                               &(pid)->tasks[type], pid_links[type]) {
 
                        /*
                         * Both old and new leaders may be attached to
diff --git a/include/linux/platform_data/ams-delta-fiq.h b/include/linux/platform_data/ams-delta-fiq.h
new file mode 100644 (file)
index 0000000..cf4589c
--- /dev/null
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * include/linux/platform_data/ams-delta-fiq.h
+ *
+ * Taken from the original Amstrad modifications to fiq.h
+ *
+ * Copyright (c) 2004 Amstrad Plc
+ * Copyright (c) 2006 Matt Callow
+ * Copyright (c) 2010 Janusz Krzysztofik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __LINUX_PLATFORM_DATA_AMS_DELTA_FIQ_H
+#define __LINUX_PLATFORM_DATA_AMS_DELTA_FIQ_H
+
+/*
+ * These are the offsets from the beginning of the fiq_buffer. They are put here
+ * since the buffer and header need to be accessed by drivers servicing devices
+ * which generate GPIO interrupts - e.g. keyboard, modem, hook switch.
+ */
+#define FIQ_MASK                0
+#define FIQ_STATE               1
+#define FIQ_KEYS_CNT            2
+#define FIQ_TAIL_OFFSET                 3
+#define FIQ_HEAD_OFFSET                 4
+#define FIQ_BUF_LEN             5
+#define FIQ_KEY                         6
+#define FIQ_MISSED_KEYS                 7
+#define FIQ_BUFFER_START        8
+#define FIQ_GPIO_INT_MASK       9
+#define FIQ_KEYS_HICNT         10
+#define FIQ_IRQ_PEND           11
+#define FIQ_SIR_CODE_L1                12
+#define IRQ_SIR_CODE_L2                13
+
+#define FIQ_CNT_INT_00         14
+#define FIQ_CNT_INT_KEY                15
+#define FIQ_CNT_INT_MDM                16
+#define FIQ_CNT_INT_03         17
+#define FIQ_CNT_INT_HSW                18
+#define FIQ_CNT_INT_05         19
+#define FIQ_CNT_INT_06         20
+#define FIQ_CNT_INT_07         21
+#define FIQ_CNT_INT_08         22
+#define FIQ_CNT_INT_09         23
+#define FIQ_CNT_INT_10         24
+#define FIQ_CNT_INT_11         25
+#define FIQ_CNT_INT_12         26
+#define FIQ_CNT_INT_13         27
+#define FIQ_CNT_INT_14         28
+#define FIQ_CNT_INT_15         29
+
+#define FIQ_CIRC_BUFF          30      /*Start of circular buffer */
+
+#endif
index 01edd96fe1f76a3a1ccc06c49f49e2f0a6f3ce4a..113d6b12f6507e765cd7eb2cc805d1c09f8b50ff 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * i2c-ocores.h - definitions for the i2c-ocores interface
  *
- * Peter Korsgaard <jacmet@sunsite.dk>
+ * Peter Korsgaard <peter@korsgaard.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
index 9abc0ca7259b78d5400166dbafd81825ca05b915..9f0aa1b48c7849ae4fd7545bfbf5d8b5a3db102e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Driver for Texas Instruments INA219, INA226 power monitor chips
  *
- * Copyright (C) 2012 Lothar Felten <l-felten@ti.com>
+ * Copyright (C) 2012 Lothar Felten <lothar.felten@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
index 97948ac2bb9be9de784ad7f14e73602f8793e670..a403dd51dacceb6bd94f39240e996f8b63282d40 100644 (file)
@@ -33,5 +33,4 @@ struct davinci_aemif_timing {
        u8      ta;
 };
 
-int davinci_aemif_setup(struct platform_device *pdev);
 #endif
index f9bed2a0af9d56af6d0f56a5ceb67f8d22f6de15..fbf5ed73c7cca47c9afa3ff66134af8b6ec6429d 100644 (file)
 #include <linux/kbuild.h>
 #include <linux/types.h>
 
+/*
+ * WFI Flags for sleep code control
+ *
+ * These flags allow PM code to exclude certain operations from happening
+ * in the low level ASM code found in sleep33xx.S and sleep43xx.S
+ *
+ * WFI_FLAG_FLUSH_CACHE: Flush the ARM caches and disable caching. Only
+ *                      needed when MPU will lose context.
+ * WFI_FLAG_SELF_REFRESH: Let EMIF place DDR memory into self-refresh and
+ *                       disable EMIF.
+ * WFI_FLAG_SAVE_EMIF: Save context of all EMIF registers and restore in
+ *                    resume path. Only needed if PER domain loses context
+ *                    and must also have WFI_FLAG_SELF_REFRESH set.
+ * WFI_FLAG_WAKE_M3: Disable MPU clock or clockdomain to cause wkup_m3 to
+ *                  execute when WFI instruction executes.
+ * WFI_FLAG_RTC_ONLY: Configure the RTC to enter RTC+DDR mode.
+ */
+#define WFI_FLAG_FLUSH_CACHE           BIT(0)
+#define WFI_FLAG_SELF_REFRESH          BIT(1)
+#define WFI_FLAG_SAVE_EMIF             BIT(2)
+#define WFI_FLAG_WAKE_M3               BIT(3)
+#define WFI_FLAG_RTC_ONLY              BIT(4)
+
 #ifndef __ASSEMBLER__
 struct am33xx_pm_sram_addr {
        void (*do_wfi)(void);
@@ -19,12 +42,15 @@ struct am33xx_pm_sram_addr {
        unsigned long *resume_offset;
        unsigned long *emif_sram_table;
        unsigned long *ro_sram_data;
+       unsigned long resume_address;
 };
 
 struct am33xx_pm_platform_data {
        int     (*init)(void);
-       int     (*soc_suspend)(unsigned int state, int (*fn)(unsigned long));
+       int     (*soc_suspend)(unsigned int state, int (*fn)(unsigned long),
+                              unsigned long args);
        struct  am33xx_pm_sram_addr *(*get_sram_addrs)(void);
+       void __iomem *(*get_rtc_base_addr)(void);
 };
 
 struct am33xx_pm_sram_data {
@@ -36,6 +62,7 @@ struct am33xx_pm_sram_data {
 struct am33xx_pm_ro_sram_data {
        u32 amx3_pm_sram_data_virt;
        u32 amx3_pm_sram_data_phys;
+       void __iomem *rtc_base_virt;
 } __packed __aligned(8);
 
 #endif /* __ASSEMBLER__ */
diff --git a/include/linux/platform_data/sh_ipmmu.h b/include/linux/platform_data/sh_ipmmu.h
deleted file mode 100644 (file)
index 39f7405..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* sh_ipmmu.h
- *
- * Copyright (C) 2012  Hideki EIRAKU
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- */
-
-#ifndef __SH_IPMMU_H__
-#define __SH_IPMMU_H__
-
-struct shmobile_ipmmu_platform_data {
-       const char * const *dev_names;
-       unsigned int num_dev_names;
-};
-
-#endif /* __SH_IPMMU_H__ */
index 990aad477458113abf887af2f12e68bf56eec66d..2efa3470a451b9d1d3fc3f082d0c59bcfd247c17 100644 (file)
@@ -14,6 +14,7 @@ enum ti_sysc_module_type {
        TI_SYSC_OMAP4_SR,
        TI_SYSC_OMAP4_MCASP,
        TI_SYSC_OMAP4_USB_HOST_FS,
+       TI_SYSC_DRA7_MCAN,
 };
 
 struct ti_sysc_cookie {
index b21c4bd96b84f2b78397114efb3062e68dbe59c6..f80769175c56dc9f07a234e950394b30cc891230 100644 (file)
@@ -269,6 +269,7 @@ struct power_supply {
        spinlock_t changed_lock;
        bool changed;
        bool initialized;
+       bool removing;
        atomic_t use_cnt;
 #ifdef CONFIG_THERMAL
        struct thermal_zone_device *tzd;
index 5bd3f151da7857ca488bdd1740833ab6f48bc5b9..c01813c3fbe9336ed69a54a0296ed7bb69186a5f 100644 (file)
  */
 #define in_atomic_preempt_off() (preempt_count() != PREEMPT_DISABLE_OFFSET)
 
-#if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_PREEMPT_TRACER)
+#if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_TRACE_PREEMPT_TOGGLE)
 extern void preempt_count_add(int val);
 extern void preempt_count_sub(int val);
 #define preempt_count_dec_and_test() \
index 626fc65c433640c5d6c6302949c9a3028c84a6de..d0e1f1522a78e4213381614f77eea1a0d37d3f9e 100644 (file)
@@ -129,7 +129,7 @@ int open_related_ns(struct ns_common *ns,
                   struct ns_common *(*get_ns)(struct ns_common *ns));
 
 /* get the associated pid namespace for a file in procfs */
-static inline struct pid_namespace *proc_pid_ns(struct inode *inode)
+static inline struct pid_namespace *proc_pid_ns(const struct inode *inode)
 {
        return inode->i_sb->s_fs_info;
 }
index 037bf0ef1ae94ffddd23906901c82fa362582cbf..4f36431c380bcdb9b70b2cf6f2599488e404ca2e 100644 (file)
@@ -214,8 +214,6 @@ static inline void ptrace_init_task(struct task_struct *child, bool ptrace)
                        task_set_jobctl_pending(child, JOBCTL_TRAP_STOP);
                else
                        sigaddset(&child->pending.signal, SIGSTOP);
-
-               set_tsk_thread_flag(child, TIF_SIGPENDING);
        }
        else
                child->ptracer_cred = NULL;
index ca9772c8e48b0652cf1cfa0929d037cff1e846f3..f32dd270b8e3f26a91cb6b10cdd7ac3dbb2cf6e8 100644 (file)
@@ -408,13 +408,7 @@ struct qc_type_state {
 
 struct qc_state {
        unsigned int s_incoredqs;       /* Number of dquots in core */
-       /*
-        * Per quota type information. The array should really have
-        * max(MAXQUOTAS, XQM_MAXQUOTAS) entries. BUILD_BUG_ON in
-        * quota_getinfo() makes sure XQM_MAXQUOTAS is large enough.  Once VFS
-        * supports project quotas, this can be changed to MAXQUOTAS
-        */
-       struct qc_type_state s_state[XQM_MAXQUOTAS];
+       struct qc_type_state s_state[MAXQUOTAS];  /* Per quota type information */
 };
 
 /* Structure for communicating via ->set_info */
index 003d09ab308d99681a56e01b0f3bd7f3c8cce4a0..0940fda59872c039d8a555bc533113648a0b1d08 100644 (file)
@@ -164,8 +164,8 @@ void ring_buffer_record_disable(struct ring_buffer *buffer);
 void ring_buffer_record_enable(struct ring_buffer *buffer);
 void ring_buffer_record_off(struct ring_buffer *buffer);
 void ring_buffer_record_on(struct ring_buffer *buffer);
-int ring_buffer_record_is_on(struct ring_buffer *buffer);
-int ring_buffer_record_is_set_on(struct ring_buffer *buffer);
+bool ring_buffer_record_is_on(struct ring_buffer *buffer);
+bool ring_buffer_record_is_set_on(struct ring_buffer *buffer);
 void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu);
 void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu);
 
index 6268208760e9587acac1114a4ce071e4bbacb160..6aedc30003e731576ae87857666b2abe5b510187 100644 (file)
@@ -87,16 +87,11 @@ struct rtc_class_ops {
        int (*set_offset)(struct device *, long offset);
 };
 
-typedef struct rtc_task {
-       void (*func)(void *private_data);
-       void *private_data;
-} rtc_task_t;
-
-
 struct rtc_timer {
-       struct rtc_task task;
        struct timerqueue_node node;
        ktime_t period;
+       void (*func)(void *private_data);
+       void *private_data;
        int enabled;
 };
 
@@ -121,8 +116,6 @@ struct rtc_device {
        wait_queue_head_t irq_queue;
        struct fasync_struct *async_queue;
 
-       struct rtc_task *irq_task;
-       spinlock_t irq_task_lock;
        int irq_freq;
        int max_user_freq;
 
@@ -204,14 +197,8 @@ extern void rtc_update_irq(struct rtc_device *rtc,
 extern struct rtc_device *rtc_class_open(const char *name);
 extern void rtc_class_close(struct rtc_device *rtc);
 
-extern int rtc_irq_register(struct rtc_device *rtc,
-                               struct rtc_task *task);
-extern void rtc_irq_unregister(struct rtc_device *rtc,
-                               struct rtc_task *task);
-extern int rtc_irq_set_state(struct rtc_device *rtc,
-                               struct rtc_task *task, int enabled);
-extern int rtc_irq_set_freq(struct rtc_device *rtc,
-                               struct rtc_task *task, int freq);
+extern int rtc_irq_set_state(struct rtc_device *rtc, int enabled);
+extern int rtc_irq_set_freq(struct rtc_device *rtc, int freq);
 extern int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled);
 extern int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled);
 extern int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc,
index 789923fbee3a8a8dc849c92a08ce37893e175b31..977cb57d7bc9e7183e6ca628e4f75d236ddf3951 100644 (file)
@@ -779,7 +779,8 @@ struct task_struct {
        struct list_head                ptrace_entry;
 
        /* PID/PID hash table linkage. */
-       struct pid_link                 pids[PIDTYPE_MAX];
+       struct pid                      *thread_pid;
+       struct hlist_node               pid_links[PIDTYPE_MAX];
        struct list_head                thread_group;
        struct list_head                thread_node;
 
@@ -853,6 +854,7 @@ struct task_struct {
 #endif
 #ifdef CONFIG_DETECT_HUNG_TASK
        unsigned long                   last_switch_count;
+       unsigned long                   last_switch_time;
 #endif
        /* Filesystem information: */
        struct fs_struct                *fs;
@@ -1209,27 +1211,7 @@ struct task_struct {
 
 static inline struct pid *task_pid(struct task_struct *task)
 {
-       return task->pids[PIDTYPE_PID].pid;
-}
-
-static inline struct pid *task_tgid(struct task_struct *task)
-{
-       return task->group_leader->pids[PIDTYPE_PID].pid;
-}
-
-/*
- * Without tasklist or RCU lock it is not safe to dereference
- * the result of task_pgrp/task_session even if task == current,
- * we can race with another thread doing sys_setsid/sys_setpgid.
- */
-static inline struct pid *task_pgrp(struct task_struct *task)
-{
-       return task->group_leader->pids[PIDTYPE_PGID].pid;
-}
-
-static inline struct pid *task_session(struct task_struct *task)
-{
-       return task->group_leader->pids[PIDTYPE_SID].pid;
+       return task->thread_pid;
 }
 
 /*
@@ -1278,7 +1260,7 @@ static inline pid_t task_tgid_nr(struct task_struct *tsk)
  */
 static inline int pid_alive(const struct task_struct *p)
 {
-       return p->pids[PIDTYPE_PID].pid != NULL;
+       return p->thread_pid != NULL;
 }
 
 static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
@@ -1304,12 +1286,12 @@ static inline pid_t task_session_vnr(struct task_struct *tsk)
 
 static inline pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
 {
-       return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, ns);
+       return __task_pid_nr_ns(tsk, PIDTYPE_TGID, ns);
 }
 
 static inline pid_t task_tgid_vnr(struct task_struct *tsk)
 {
-       return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, NULL);
+       return __task_pid_nr_ns(tsk, PIDTYPE_TGID, NULL);
 }
 
 static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns)
index 113d1ad1ced76e0c138c9dd05d1420ff28c71616..1be35729c2c5b9c0bb915653d7778e0acbdfd29b 100644 (file)
@@ -69,6 +69,11 @@ struct thread_group_cputimer {
        bool checking_timer;
 };
 
+struct multiprocess_signals {
+       sigset_t signal;
+       struct hlist_node node;
+};
+
 /*
  * NOTE! "signal_struct" does not have its own
  * locking, because a shared signal_struct always
@@ -90,6 +95,9 @@ struct signal_struct {
        /* shared signal handling: */
        struct sigpending       shared_pending;
 
+       /* For collecting multiprocess signals during fork */
+       struct hlist_head       multiprocess;
+
        /* thread group exit support */
        int                     group_exit_code;
        /* overloaded:
@@ -146,7 +154,8 @@ struct signal_struct {
 
 #endif
 
-       struct pid *leader_pid;
+       /* PID/PID hash table linkage. */
+       struct pid *pids[PIDTYPE_MAX];
 
 #ifdef CONFIG_NO_HZ_FULL
        atomic_t tick_dep_mask;
@@ -314,7 +323,7 @@ int force_sig_pkuerr(void __user *addr, u32 pkey);
 int force_sig_ptrace_errno_trap(int errno, void __user *addr);
 
 extern int send_sig_info(int, struct siginfo *, struct task_struct *);
-extern int force_sigsegv(int, struct task_struct *);
+extern void force_sigsegv(int sig, struct task_struct *p);
 extern int force_sig_info(int, struct siginfo *, struct task_struct *);
 extern int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp);
 extern int kill_pid_info(int sig, struct siginfo *info, struct pid *pid);
@@ -329,7 +338,7 @@ extern int send_sig(int, struct task_struct *, int);
 extern int zap_other_threads(struct task_struct *p);
 extern struct sigqueue *sigqueue_alloc(void);
 extern void sigqueue_free(struct sigqueue *);
-extern int send_sigqueue(struct sigqueue *,  struct task_struct *, int group);
+extern int send_sigqueue(struct sigqueue *, struct pid *, enum pid_type);
 extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *);
 
 static inline int restart_syscall(void)
@@ -371,6 +380,7 @@ static inline int signal_pending_state(long state, struct task_struct *p)
  */
 extern void recalc_sigpending_and_wake(struct task_struct *t);
 extern void recalc_sigpending(void);
+extern void calculate_sigpending(void);
 
 extern void signal_wake_up_state(struct task_struct *t, unsigned int state);
 
@@ -383,6 +393,8 @@ static inline void ptrace_signal_wake_up(struct task_struct *t, bool resume)
        signal_wake_up_state(t, resume ? __TASK_TRACED : 0);
 }
 
+void task_join_group_stop(struct task_struct *task);
+
 #ifdef TIF_RESTORE_SIGMASK
 /*
  * Legacy restore_sigmask accessors.  These are inefficient on
@@ -556,6 +568,37 @@ extern bool current_is_single_threaded(void);
 typedef int (*proc_visitor)(struct task_struct *p, void *data);
 void walk_process_tree(struct task_struct *top, proc_visitor, void *);
 
+static inline
+struct pid *task_pid_type(struct task_struct *task, enum pid_type type)
+{
+       struct pid *pid;
+       if (type == PIDTYPE_PID)
+               pid = task_pid(task);
+       else
+               pid = task->signal->pids[type];
+       return pid;
+}
+
+static inline struct pid *task_tgid(struct task_struct *task)
+{
+       return task->signal->pids[PIDTYPE_TGID];
+}
+
+/*
+ * Without tasklist or RCU lock it is not safe to dereference
+ * the result of task_pgrp/task_session even if task == current,
+ * we can race with another thread doing sys_setsid/sys_setpgid.
+ */
+static inline struct pid *task_pgrp(struct task_struct *task)
+{
+       return task->signal->pids[PIDTYPE_PGID];
+}
+
+static inline struct pid *task_session(struct task_struct *task)
+{
+       return task->signal->pids[PIDTYPE_SID];
+}
+
 static inline int get_nr_threads(struct task_struct *tsk)
 {
        return tsk->signal->nr_threads;
@@ -574,7 +617,7 @@ static inline bool thread_group_leader(struct task_struct *p)
  */
 static inline bool has_group_leader_pid(struct task_struct *p)
 {
-       return task_pid(p) == p->signal->leader_pid;
+       return task_pid(p) == task_tgid(p);
 }
 
 static inline
index 913488d828cb609e15d3bb4f379b49f60f62a659..a9c32daeb9d88376a4e7ce79e7de13534c95b2ea 100644 (file)
@@ -10,6 +10,7 @@ struct ctl_table;
 extern int          sysctl_hung_task_check_count;
 extern unsigned int  sysctl_hung_task_panic;
 extern unsigned long sysctl_hung_task_timeout_secs;
+extern unsigned long sysctl_hung_task_check_interval_secs;
 extern int sysctl_hung_task_warnings;
 extern int proc_dohung_task_timeout_secs(struct ctl_table *table, int write,
                                         void __user *buffer,
index 96fe289c4c6e496fefd005d3100c84bf58f81698..39ad98c09c5808e42a04c5155f0d52aef92cbae8 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/uidgid.h>
 #include <linux/atomic.h>
+#include <linux/refcount.h>
 #include <linux/ratelimit.h>
 
 struct key;
@@ -12,7 +13,7 @@ struct key;
  * Some day this will be a full-fledged user tracking system..
  */
 struct user_struct {
-       atomic_t __count;       /* reference count */
+       refcount_t __count;     /* reference count */
        atomic_t processes;     /* How many processes does this user have? */
        atomic_t sigpending;    /* How many pending signals does this user have? */
 #ifdef CONFIG_FANOTIFY
@@ -59,7 +60,7 @@ extern struct user_struct root_user;
 extern struct user_struct * alloc_uid(kuid_t);
 static inline struct user_struct *get_uid(struct user_struct *u)
 {
-       atomic_inc(&u->__count);
+       refcount_inc(&u->__count);
        return u;
 }
 extern void free_uid(struct user_struct *);
index da5178216da54705e905f2c81388b8006b4a37d4..2a986d282a975b5bb5b244efad5419334f74cfaa 100644 (file)
@@ -17,6 +17,20 @@ static inline int set_memory_x(unsigned long addr,  int numpages) { return 0; }
 static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; }
 #endif
 
+#ifndef set_mce_nospec
+static inline int set_mce_nospec(unsigned long pfn)
+{
+       return 0;
+}
+#endif
+
+#ifndef clear_mce_nospec
+static inline int clear_mce_nospec(unsigned long pfn)
+{
+       return 0;
+}
+#endif
+
 #ifndef CONFIG_ARCH_HAS_MEM_ENCRYPT
 static inline int set_memory_encrypted(unsigned long addr, int numpages)
 {
index b154fd2b084c11ab3718ba8a6afcbc69481acf49..9443cafd19696a65919514abb140a522ea6312b6 100644 (file)
@@ -12,6 +12,9 @@
 struct shrink_control {
        gfp_t gfp_mask;
 
+       /* current node being shrunk (for NUMA aware shrinkers) */
+       int nid;
+
        /*
         * How many objects scan_objects should scan and try to reclaim.
         * This is reset before every call, so it is safe for callees
@@ -26,9 +29,6 @@ struct shrink_control {
         */
        unsigned long nr_scanned;
 
-       /* current node being shrunk (for NUMA aware shrinkers) */
-       int nid;
-
        /* current memcg being shrunk (for memcg aware shrinkers) */
        struct mem_cgroup *memcg;
 };
@@ -63,9 +63,9 @@ struct shrinker {
        unsigned long (*scan_objects)(struct shrinker *,
                                      struct shrink_control *sc);
 
-       int seeks;      /* seeks to recreate an obj */
        long batch;     /* reclaim batch size, 0 = default */
-       unsigned long flags;
+       int seeks;      /* seeks to recreate an obj */
+       unsigned flags;
 
        /* These are for internal use */
        struct list_head list;
index 3c5200137b24f67725997532af950ffb5daf8fdf..3d4cd5db30a966b015a89cccc78b9fc2301bb895 100644 (file)
@@ -254,18 +254,20 @@ static inline int valid_signal(unsigned long sig)
 
 struct timespec;
 struct pt_regs;
+enum pid_type;
 
 extern int next_signal(struct sigpending *pending, sigset_t *mask);
 extern int do_send_sig_info(int sig, struct siginfo *info,
-                               struct task_struct *p, bool group);
-extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p);
+                               struct task_struct *p, enum pid_type type);
+extern int group_send_sig_info(int sig, struct siginfo *info,
+                              struct task_struct *p, enum pid_type type);
 extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
 extern int sigprocmask(int, sigset_t *, sigset_t *);
 extern void set_current_blocked(sigset_t *);
 extern void __set_current_blocked(const sigset_t *);
 extern int show_unhandled_signals;
 
-extern int get_signal(struct ksignal *ksig);
+extern bool get_signal(struct ksignal *ksig);
 extern void signal_setup_done(int failed, struct ksignal *ksig, int stepping);
 extern void exit_signals(struct task_struct *tsk);
 extern void kernel_sigaction(int, __sighandler_t);
@@ -287,7 +289,7 @@ static inline void disallow_signal(int sig)
 
 extern struct kmem_cache *sighand_cachep;
 
-int unhandled_signal(struct task_struct *tsk, int sig);
+extern bool unhandled_signal(struct task_struct *tsk, int sig);
 
 /*
  * In POSIX a signal is sent either to a specific thread (Linux task)
index 8a6086d2e9c37585991ab2a9de249a5d71151ec9..00fae6fd234d7895ca6ff9ee4ba817cb65916dd0 100644 (file)
@@ -2,16 +2,7 @@
 #ifndef __LINUX_SOC_RENESAS_RCAR_SYSC_H__
 #define __LINUX_SOC_RENESAS_RCAR_SYSC_H__
 
-#include <linux/types.h>
-
-struct rcar_sysc_ch {
-       u16 chan_offs;
-       u8 chan_bit;
-       u8 isr_bit;
-};
-
-int rcar_sysc_power_down(const struct rcar_sysc_ch *sysc_ch);
-int rcar_sysc_power_up(const struct rcar_sysc_ch *sysc_ch);
-void rcar_sysc_init(phys_addr_t base, u32 syscier);
+int rcar_sysc_power_down_cpu(unsigned int cpu);
+int rcar_sysc_power_up_cpu(unsigned int cpu);
 
 #endif /* __LINUX_SOC_RENESAS_RCAR_SYSC_H__ */
index 3e72a291c40142d45ae4ee9722239ac8ad2896b0..67135d4a8a30e31fe2c72e69eaaf09b6d2521453 100644 (file)
@@ -169,6 +169,11 @@ static inline int srcu_read_lock_held(const struct srcu_struct *sp)
  */
 #define srcu_dereference(p, sp) srcu_dereference_check((p), (sp), 0)
 
+/**
+ * srcu_dereference_notrace - no tracing and no lockdep calls from here
+ */
+#define srcu_dereference_notrace(p, sp) srcu_dereference_check((p), (sp), 1)
+
 /**
  * srcu_read_lock - register a new reader for an SRCU-protected structure.
  * @sp: srcu_struct in which to register the new reader.
index d9af474a857d9f2c9ff96f2a98a4f6e2519c46af..58a6765c1c5e880f5efa2ef1948868e9d3ef2732 100644 (file)
@@ -125,7 +125,8 @@ struct rpc_authops {
        struct module           *owner;
        rpc_authflavor_t        au_flavor;      /* flavor (RPC_AUTH_*) */
        char *                  au_name;
-       struct rpc_auth *       (*create)(struct rpc_auth_create_args *, struct rpc_clnt *);
+       struct rpc_auth *       (*create)(const struct rpc_auth_create_args *,
+                                         struct rpc_clnt *);
        void                    (*destroy)(struct rpc_auth *);
 
        int                     (*hash_cred)(struct auth_cred *, unsigned int);
@@ -174,7 +175,7 @@ struct rpc_cred *   rpc_lookup_generic_cred(struct auth_cred *, int, gfp_t);
 struct rpc_cred *      rpc_lookup_machine_cred(const char *service_name);
 int                    rpcauth_register(const struct rpc_authops *);
 int                    rpcauth_unregister(const struct rpc_authops *);
-struct rpc_auth *      rpcauth_create(struct rpc_auth_create_args *,
+struct rpc_auth *      rpcauth_create(const struct rpc_auth_create_args *,
                                struct rpc_clnt *);
 void                   rpcauth_release(struct rpc_auth *);
 rpc_authflavor_t       rpcauth_get_pseudoflavor(rpc_authflavor_t,
index 9b11b6a0978c95467761d142716c873ac5c201d4..73d5c4a870faee9188f0d3f8e218d585b1e17148 100644 (file)
@@ -156,6 +156,7 @@ int         rpc_switch_client_transport(struct rpc_clnt *,
 
 void           rpc_shutdown_client(struct rpc_clnt *);
 void           rpc_release_client(struct rpc_clnt *);
+void           rpc_task_release_transport(struct rpc_task *);
 void           rpc_task_release_client(struct rpc_task *);
 
 int            rpcb_create_local(struct net *);
index 9baed7b355b20894058560ea78e9246cd4e6676a..1b37513275754f90337203d7b400e0f8e65da81a 100644 (file)
@@ -82,7 +82,7 @@ void                  rpc_count_iostats(const struct rpc_task *,
                                          struct rpc_iostats *);
 void                   rpc_count_iostats_metrics(const struct rpc_task *,
                                          struct rpc_iostats *);
-void                   rpc_print_iostats(struct seq_file *, struct rpc_clnt *);
+void                   rpc_clnt_show_stats(struct seq_file *, struct rpc_clnt *);
 void                   rpc_free_iostats(struct rpc_iostats *);
 
 #else  /*  CONFIG_PROC_FS  */
@@ -95,7 +95,7 @@ static inline void rpc_count_iostats_metrics(const struct rpc_task *task,
 {
 }
 
-static inline void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) {}
+static inline void rpc_clnt_show_stats(struct seq_file *seq, struct rpc_clnt *clnt) {}
 static inline void rpc_free_iostats(struct rpc_iostats *stats) {}
 
 #endif  /*  CONFIG_PROC_FS  */
index 574368e8a16f389eeb249d46f8cc7d9ecad9d449..73e130a840ce4774df4e977759d46c42ddbd820d 100644 (file)
@@ -496,9 +496,11 @@ void                  svc_reserve(struct svc_rqst *rqstp, int space);
 struct svc_pool *  svc_pool_for_cpu(struct svc_serv *serv, int cpu);
 char *            svc_print_addr(struct svc_rqst *, char *, size_t);
 unsigned int      svc_fill_write_vector(struct svc_rqst *rqstp,
+                                        struct page **pages,
                                         struct kvec *first, size_t total);
 char             *svc_fill_symlink_pathname(struct svc_rqst *rqstp,
-                                            struct kvec *first, size_t total);
+                                            struct kvec *first, void *p,
+                                            size_t total);
 
 #define        RPC_MAX_ADDRBUFLEN      (63U)
 
index 7c365650584785277dbedb43e619b44e901103ed..04e404a0788222be04f12f84724a5595f52acfe4 100644 (file)
@@ -31,6 +31,7 @@ struct svc_cred {
        /* name of form servicetype@hostname, passed down by
         * rpc.svcgssd, or computed from the above: */
        char                    *cr_principal;
+       char                    *cr_targ_princ;
        struct gss_api_mech     *cr_gss_mech;
 };
 
@@ -39,6 +40,7 @@ static inline void init_svc_cred(struct svc_cred *cred)
        cred->cr_group_info = NULL;
        cred->cr_raw_principal = NULL;
        cred->cr_principal = NULL;
+       cred->cr_targ_princ = NULL;
        cred->cr_gss_mech = NULL;
 }
 
@@ -48,6 +50,7 @@ static inline void free_svc_cred(struct svc_cred *cred)
                put_group_info(cred->cr_group_info);
        kfree(cred->cr_raw_principal);
        kfree(cred->cr_principal);
+       kfree(cred->cr_targ_princ);
        gss_mech_put(cred->cr_gss_mech);
        init_svc_cred(cred);
 }
index 1a8bd05a335ed787b29142913035eacef7c36273..8e2c11e692baf9bba6380d63888cfbf5a206cf0b 100644 (file)
@@ -447,7 +447,7 @@ extern void si_swapinfo(struct sysinfo *);
 extern swp_entry_t get_swap_page(struct page *page);
 extern void put_swap_page(struct page *page, swp_entry_t entry);
 extern swp_entry_t get_swap_page_of_type(int);
-extern int get_swap_pages(int n, bool cluster, swp_entry_t swp_entries[]);
+extern int get_swap_pages(int n, swp_entry_t swp_entries[], int entry_size);
 extern int add_swap_count_continuation(swp_entry_t, gfp_t);
 extern void swap_shmem_alloc(swp_entry_t);
 extern int swap_duplicate(swp_entry_t);
index 1d3877c39a000a6e5a4fb7647a38de51c5c47c50..22af9d8a84ae2fe6f11402250b6e6a9367d867d0 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/radix-tree.h>
 #include <linux/bug.h>
+#include <linux/mm_types.h>
 
 /*
  * swapcache pages are stored in the swapper_space radix tree.  We want to
@@ -134,7 +135,7 @@ static inline struct page *device_private_entry_to_page(swp_entry_t entry)
        return pfn_to_page(swp_offset(entry));
 }
 
-int device_private_entry_fault(struct vm_area_struct *vma,
+vm_fault_t device_private_entry_fault(struct vm_area_struct *vma,
                       unsigned long addr,
                       swp_entry_t entry,
                       unsigned int flags,
@@ -169,7 +170,7 @@ static inline struct page *device_private_entry_to_page(swp_entry_t entry)
        return NULL;
 }
 
-static inline int device_private_entry_fault(struct vm_area_struct *vma,
+static inline vm_fault_t device_private_entry_fault(struct vm_area_struct *vma,
                                     unsigned long addr,
                                     swp_entry_t entry,
                                     unsigned int flags,
@@ -340,11 +341,6 @@ static inline int is_hwpoison_entry(swp_entry_t entry)
        return swp_type(entry) == SWP_HWPOISON;
 }
 
-static inline bool test_set_page_hwpoison(struct page *page)
-{
-       return TestSetPageHWPoison(page);
-}
-
 static inline void num_poisoned_pages_inc(void)
 {
        atomic_long_inc(&num_poisoned_pages);
@@ -367,11 +363,6 @@ static inline int is_hwpoison_entry(swp_entry_t swp)
        return 0;
 }
 
-static inline bool test_set_page_hwpoison(struct page *page)
-{
-       return false;
-}
-
 static inline void num_poisoned_pages_inc(void)
 {
 }
index 0b14f936100a24ead41455de43dda08c8448cca2..d1ae43c13e25940e2febed51919c171e3018ed3f 100644 (file)
@@ -207,4 +207,19 @@ static inline s64 timeval_to_ns(const struct timeval *tv)
 extern struct timeval ns_to_timeval(const s64 nsec);
 extern struct __kernel_old_timeval ns_to_kernel_old_timeval(s64 nsec);
 
+/*
+ * New aliases for compat time functions. These will be used to replace
+ * the compat code so it can be shared between 32-bit and 64-bit builds
+ * both of which provide compatibility with old 32-bit tasks.
+ */
+#define old_time32_t           compat_time_t
+#define old_timeval32          compat_timeval
+#define old_timespec32         compat_timespec
+#define old_itimerspec32       compat_itimerspec
+#define ns_to_old_timeval32    ns_to_compat_timeval
+#define get_old_itimerspec32   get_compat_itimerspec64
+#define put_old_itimerspec32   put_compat_itimerspec64
+#define get_old_timespec32     compat_get_timespec64
+#define put_old_timespec32     compat_put_timespec64
+
 #endif
index 5d738804e3d6241dae4961c93324efbdd4f5aaea..a5a3cfc3c2fa754fd8f21fc721094268a4aa256b 100644 (file)
@@ -258,8 +258,8 @@ extern void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot);
 extern int persistent_clock_is_local;
 
 extern void read_persistent_clock64(struct timespec64 *ts);
-void read_persistent_clock_and_boot_offset(struct timespec64 *wall_clock,
-                                          struct timespec64 *boot_offset);
+void read_persistent_wall_and_boot_offset(struct timespec64 *wall_clock,
+                                         struct timespec64 *boot_offset);
 extern int update_persistent_clock64(struct timespec64 now);
 
 /*
index 19a690b559ca1b1850336ffe5133e80db77121f2..041f7e56a2894f3f800fc470d8a5bccaffc58b88 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include <linux/smp.h>
+#include <linux/srcu.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/cpumask.h>
@@ -33,6 +34,8 @@ struct trace_eval_map {
 
 #define TRACEPOINT_DEFAULT_PRIO        10
 
+extern struct srcu_struct tracepoint_srcu;
+
 extern int
 tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data);
 extern int
@@ -75,10 +78,16 @@ int unregister_tracepoint_module_notifier(struct notifier_block *nb)
  * probe unregistration and the end of module exit to make sure there is no
  * caller executing a probe when it is freed.
  */
+#ifdef CONFIG_TRACEPOINTS
 static inline void tracepoint_synchronize_unregister(void)
 {
+       synchronize_srcu(&tracepoint_srcu);
        synchronize_sched();
 }
+#else
+static inline void tracepoint_synchronize_unregister(void)
+{ }
+#endif
 
 #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
 extern int syscall_regfunc(void);
@@ -129,18 +138,33 @@ extern void syscall_unregfunc(void);
  * as "(void *, void)". The DECLARE_TRACE_NOARGS() will pass in just
  * "void *data", where as the DECLARE_TRACE() will pass in "void *data, proto".
  */
-#define __DO_TRACE(tp, proto, args, cond, rcucheck)                    \
+#define __DO_TRACE(tp, proto, args, cond, rcuidle)                     \
        do {                                                            \
                struct tracepoint_func *it_func_ptr;                    \
                void *it_func;                                          \
                void *__data;                                           \
+               int __maybe_unused idx = 0;                             \
                                                                        \
                if (!(cond))                                            \
                        return;                                         \
-               if (rcucheck)                                           \
+                                                                       \
+               /* srcu can't be used from NMI */                       \
+               WARN_ON_ONCE(rcuidle && in_nmi());                      \
+                                                                       \
+               /* keep srcu and sched-rcu usage consistent */          \
+               preempt_disable_notrace();                              \
+                                                                       \
+               /*                                                      \
+                * For rcuidle callers, use srcu since sched-rcu        \
+                * doesn't work from the idle path.                     \
+                */                                                     \
+               if (rcuidle) {                                          \
+                       idx = srcu_read_lock_notrace(&tracepoint_srcu); \
                        rcu_irq_enter_irqson();                         \
-               rcu_read_lock_sched_notrace();                          \
-               it_func_ptr = rcu_dereference_sched((tp)->funcs);       \
+               }                                                       \
+                                                                       \
+               it_func_ptr = rcu_dereference_raw((tp)->funcs);         \
+                                                                       \
                if (it_func_ptr) {                                      \
                        do {                                            \
                                it_func = (it_func_ptr)->func;          \
@@ -148,9 +172,13 @@ extern void syscall_unregfunc(void);
                                ((void(*)(proto))(it_func))(args);      \
                        } while ((++it_func_ptr)->func);                \
                }                                                       \
-               rcu_read_unlock_sched_notrace();                        \
-               if (rcucheck)                                           \
+                                                                       \
+               if (rcuidle) {                                          \
                        rcu_irq_exit_irqson();                          \
+                       srcu_read_unlock_notrace(&tracepoint_srcu, idx);\
+               }                                                       \
+                                                                       \
+               preempt_enable_notrace();                               \
        } while (0)
 
 #ifndef MODULE
@@ -225,6 +253,19 @@ extern void syscall_unregfunc(void);
                return static_key_false(&__tracepoint_##name.key);      \
        }
 
+#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
+#define __TRACEPOINT_ENTRY(name)                                       \
+       asm("   .section \"__tracepoints_ptrs\", \"a\"          \n"     \
+           "   .balign 4                                       \n"     \
+           "   .long   __tracepoint_" #name " - .              \n"     \
+           "   .previous                                       \n")
+#else
+#define __TRACEPOINT_ENTRY(name)                                        \
+       static struct tracepoint * const __tracepoint_ptr_##name __used  \
+       __attribute__((section("__tracepoints_ptrs"))) =                 \
+               &__tracepoint_##name
+#endif
+
 /*
  * We have no guarantee that gcc and the linker won't up-align the tracepoint
  * structures, so we create an array of pointers that will be used for iteration
@@ -234,11 +275,9 @@ extern void syscall_unregfunc(void);
        static const char __tpstrtab_##name[]                            \
        __attribute__((section("__tracepoints_strings"))) = #name;       \
        struct tracepoint __tracepoint_##name                            \
-       __attribute__((section("__tracepoints"))) =                      \
+       __attribute__((section("__tracepoints"), used)) =                \
                { __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL };\
-       static struct tracepoint * const __tracepoint_ptr_##name __used  \
-       __attribute__((section("__tracepoints_ptrs"))) =                 \
-               &__tracepoint_##name;
+       __TRACEPOINT_ENTRY(name);
 
 #define DEFINE_TRACE(name)                                             \
        DEFINE_TRACE_FN(name, NULL, NULL);
index 0a294e950df8400836cab893d0c32b5d6d06e726..bb9d2084af03a5d464abce0ad7c66ab59ed5cf9e 100644 (file)
@@ -121,7 +121,7 @@ extern bool is_swbp_insn(uprobe_opcode_t *insn);
 extern bool is_trap_insn(uprobe_opcode_t *insn);
 extern unsigned long uprobe_get_swbp_addr(struct pt_regs *regs);
 extern unsigned long uprobe_get_trap_addr(struct pt_regs *regs);
-extern int uprobe_write_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t);
+extern int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t);
 extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
 extern int uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool);
 extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
index e091f0a11b115dbd28c443706e4b6d0fccb97fa0..37c9eba75c983a7b2488f1a18c2c0f1d520a5425 100644 (file)
@@ -28,7 +28,7 @@
 #define UFFD_SHARED_FCNTL_FLAGS (O_CLOEXEC | O_NONBLOCK)
 #define UFFD_FLAGS_SET (EFD_SHARED_FCNTL_FLAGS)
 
-extern int handle_userfault(struct vm_fault *vmf, unsigned long reason);
+extern vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason);
 
 extern ssize_t mcopy_atomic(struct mm_struct *dst_mm, unsigned long dst_start,
                            unsigned long src_start, unsigned long len,
@@ -77,7 +77,8 @@ extern void userfaultfd_unmap_complete(struct mm_struct *mm,
 #else /* CONFIG_USERFAULTFD */
 
 /* mm helpers */
-static inline int handle_userfault(struct vm_fault *vmf, unsigned long reason)
+static inline vm_fault_t handle_userfault(struct vm_fault *vmf,
+                               unsigned long reason)
 {
        return VM_FAULT_SIGBUS;
 }
index 694101f744c7dca5fb5aa97cfa2bd88b002da322..3111585c371f5697c77fc21c77dc7eaa90ee39f3 100644 (file)
@@ -274,6 +274,8 @@ struct w1_family {
 
        struct w1_family_ops    *fops;
 
+       const struct of_device_id *of_match_table;
+
        atomic_t                refcnt;
 };
 
index d6ba7d39a62fecb497e87cbeca5a1f335675754b..e497e621dbb7f6e793f3e2e1230ab1da16daeb66 100644 (file)
@@ -40,6 +40,12 @@ struct wkup_m3_ipc {
        struct mbox_chan *mbox;
 
        struct wkup_m3_ipc_ops *ops;
+       int is_rtc_only;
+};
+
+struct wkup_m3_wakeup_src {
+       int irq_nr;
+       char src[10];
 };
 
 struct wkup_m3_ipc_ops {
@@ -48,8 +54,11 @@ struct wkup_m3_ipc_ops {
        int (*prepare_low_power)(struct wkup_m3_ipc *m3_ipc, int state);
        int (*finish_low_power)(struct wkup_m3_ipc *m3_ipc);
        int (*request_pm_status)(struct wkup_m3_ipc *m3_ipc);
+       const char *(*request_wake_src)(struct wkup_m3_ipc *m3_ipc);
+       void (*set_rtc_only)(struct wkup_m3_ipc *m3_ipc);
 };
 
 struct wkup_m3_ipc *wkup_m3_ipc_get(void);
 void wkup_m3_ipc_put(struct wkup_m3_ipc *m3_ipc);
+void wkup_m3_set_rtc_only_mode(void);
 #endif /* _LINUX_WKUP_M3_IPC_H */
index 1ad5b19e83a95d0a4ba17181f1f55134022791f1..970303448c9029e2aaab37e3735bc83e0490de04 100644 (file)
@@ -23,13 +23,11 @@ struct tc_action {
        const struct tc_action_ops      *ops;
        __u32                           type; /* for backward compat(TCA_OLD_COMPAT) */
        __u32                           order;
-       struct list_head                list;
        struct tcf_idrinfo              *idrinfo;
 
        u32                             tcfa_index;
        refcount_t                      tcfa_refcnt;
        atomic_t                        tcfa_bindcnt;
-       u32                             tcfa_capab;
        int                             tcfa_action;
        struct tcf_t                    tcfa_tm;
        struct gnet_stats_basic_packed  tcfa_bstats;
@@ -44,7 +42,6 @@ struct tc_action {
 #define tcf_index      common.tcfa_index
 #define tcf_refcnt     common.tcfa_refcnt
 #define tcf_bindcnt    common.tcfa_bindcnt
-#define tcf_capab      common.tcfa_capab
 #define tcf_action     common.tcfa_action
 #define tcf_tm         common.tcfa_tm
 #define tcf_bstats     common.tcfa_bstats
@@ -102,7 +99,6 @@ struct tc_action_ops {
        size_t  (*get_fill_size)(const struct tc_action *act);
        struct net_device *(*get_dev)(const struct tc_action *a);
        void    (*put_dev)(struct net_device *dev);
-       int     (*delete)(struct net *net, u32 index);
 };
 
 struct tc_action_net {
@@ -148,8 +144,6 @@ int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
                       const struct tc_action_ops *ops,
                       struct netlink_ext_ack *extack);
 int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index);
-bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a,
-                   int bind);
 int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
                   struct tc_action **a, const struct tc_action_ops *ops,
                   int bind, bool cpustats);
@@ -158,7 +152,6 @@ void tcf_idr_insert(struct tc_action_net *tn, struct tc_action *a);
 void tcf_idr_cleanup(struct tc_action_net *tn, u32 index);
 int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index,
                        struct tc_action **a, int bind);
-int tcf_idr_delete_index(struct tc_action_net *tn, u32 index);
 int __tcf_idr_release(struct tc_action *a, bool bind, bool strict);
 
 static inline int tcf_idr_release(struct tc_action *a, bool bind)
index 9a850973e09a739aaa72d5be951436640bc9c131..8ebabc9873d1593b46161697b53c8a8d14242000 100644 (file)
@@ -4865,8 +4865,8 @@ const char *reg_initiator_name(enum nl80211_reg_initiator initiator);
  *
  * Return: 0 on success. -ENODATA.
  */
-int reg_query_regdb_wmm(char *alpha2, int freq, u32 *ptr,
-                       struct ieee80211_wmm_rule *rule);
+int reg_query_regdb_wmm(char *alpha2, int freq,
+                       struct ieee80211_reg_rule *rule);
 
 /*
  * callbacks for asynchronous cfg80211 methods, notification
index ef727f71336e7e5f89d92000194bcfab4bacc5a8..75a3f3fdb3591720d266fd33d98c608fc673b6ca 100644 (file)
@@ -298,19 +298,13 @@ static inline void tcf_exts_put_net(struct tcf_exts *exts)
 #endif
 }
 
-static inline void tcf_exts_to_list(const struct tcf_exts *exts,
-                                   struct list_head *actions)
-{
 #ifdef CONFIG_NET_CLS_ACT
-       int i;
-
-       for (i = 0; i < exts->nr_actions; i++) {
-               struct tc_action *a = exts->actions[i];
-
-               list_add_tail(&a->list, actions);
-       }
+#define tcf_exts_for_each_action(i, a, exts) \
+       for (i = 0; i < TCA_ACT_MAX_PRIO && ((a) = (exts)->actions[i]); i++)
+#else
+#define tcf_exts_for_each_action(i, a, exts) \
+       for (; 0; (void)(i), (void)(a), (void)(exts))
 #endif
-}
 
 static inline void
 tcf_exts_stats_update(const struct tcf_exts *exts,
@@ -361,6 +355,15 @@ static inline bool tcf_exts_has_one_action(struct tcf_exts *exts)
 #endif
 }
 
+static inline struct tc_action *tcf_exts_first_action(struct tcf_exts *exts)
+{
+#ifdef CONFIG_NET_CLS_ACT
+       return exts->actions[0];
+#else
+       return NULL;
+#endif
+}
+
 /**
  * tcf_exts_exec - execute tc filter extensions
  * @skb: socket buffer
index 60f8cc86a44701c151c1f74ed6d7e5fb061c0fc2..3469750df0f44542bce0a97aa23360cbfe7079fc 100644 (file)
@@ -217,15 +217,15 @@ struct ieee80211_wmm_rule {
 struct ieee80211_reg_rule {
        struct ieee80211_freq_range freq_range;
        struct ieee80211_power_rule power_rule;
-       struct ieee80211_wmm_rule *wmm_rule;
+       struct ieee80211_wmm_rule wmm_rule;
        u32 flags;
        u32 dfs_cac_ms;
+       bool has_wmm;
 };
 
 struct ieee80211_regdomain {
        struct rcu_head rcu_head;
        u32 n_reg_rules;
-       u32 n_wmm_rules;
        char alpha2[3];
        enum nl80211_dfs_regions dfs_region;
        struct ieee80211_reg_rule reg_rules[];
index 903771c8d4e3398bdd886998d20e564d1f49169e..1ce365f4c25604b54eced20aec9a3e1ef78581a7 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/security.h>
 #include <linux/pid.h>
 #include <linux/nsproxy.h>
+#include <linux/sched/signal.h>
 
 /* Well, we should have at least one descriptor open
  * to accept passed FDs 8)
index 3e11e7cc60b7457befa97bc8f589a23ad0ef1457..62e990b620aaf7c17f54f696c1390dbc60c4c8bd 100644 (file)
@@ -133,28 +133,4 @@ const struct ib_gid_attr *rdma_get_gid_attr(struct ib_device *device,
 void rdma_put_gid_attr(const struct ib_gid_attr *attr);
 void rdma_hold_gid_attr(const struct ib_gid_attr *attr);
 
-/*
- * This is to be removed. It only exists to make merging rdma and smc simpler.
- */
-static inline __deprecated int ib_query_gid(struct ib_device *device,
-                                           u8 port_num, int index,
-                                           union ib_gid *gid,
-                                           struct ib_gid_attr *attr_out)
-{
-       const struct ib_gid_attr *attr;
-
-       memset(attr_out, 0, sizeof(*attr_out));
-       attr = rdma_get_gid_attr(device, port_num, index);
-       if (IS_ERR(attr))
-               return PTR_ERR(attr);
-
-       if (attr->ndev)
-               dev_hold(attr->ndev);
-       *attr_out = *attr;
-
-       rdma_put_gid_attr(attr);
-
-       return 0;
-}
-
 #endif /* _IB_CACHE_H */
index 6a17f856f8418b199f78108833d576e18daa142f..381cdf5a9bd1ea5da114e41c068f81c92c879c1e 100644 (file)
@@ -119,7 +119,8 @@ typedef int (*umem_call_back)(struct ib_umem *item, u64 start, u64 end,
  */
 int rbt_ib_umem_for_each_in_range(struct rb_root_cached *root,
                                  u64 start, u64 end,
-                                 umem_call_back cb, void *cookie);
+                                 umem_call_back cb,
+                                 bool blockable, void *cookie);
 
 /*
  * Find first region intersecting with address range.
index 8ee8991aa099af3a1c9d8435bab12821dfef8928..c4a5c9e9fb478133d3fa518b0503fc7f074a93a9 100644 (file)
@@ -75,6 +75,7 @@ enum rpi_firmware_property_tag {
        RPI_FIRMWARE_GET_EDID_BLOCK =                         0x00030020,
        RPI_FIRMWARE_GET_CUSTOMER_OTP =                       0x00030021,
        RPI_FIRMWARE_GET_DOMAIN_STATE =                       0x00030030,
+       RPI_FIRMWARE_GET_THROTTLED =                          0x00030046,
        RPI_FIRMWARE_SET_CLOCK_STATE =                        0x00038001,
        RPI_FIRMWARE_SET_CLOCK_RATE =                         0x00038002,
        RPI_FIRMWARE_SET_VOLTAGE =                            0x00038003,
diff --git a/include/soc/fsl/dpaa2-fd.h b/include/soc/fsl/dpaa2-fd.h
new file mode 100644 (file)
index 0000000..2576aba
--- /dev/null
@@ -0,0 +1,438 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/*
+ * Copyright 2014-2016 Freescale Semiconductor Inc.
+ * Copyright 2016 NXP
+ *
+ */
+#ifndef __FSL_DPAA2_FD_H
+#define __FSL_DPAA2_FD_H
+
+#include <linux/kernel.h>
+
+/**
+ * DOC: DPAA2 FD - Frame Descriptor APIs for DPAA2
+ *
+ * Frame Descriptors (FDs) are used to describe frame data in the DPAA2.
+ * Frames can be enqueued and dequeued to Frame Queues (FQs) which are consumed
+ * by the various DPAA accelerators (WRIOP, SEC, PME, DCE)
+ *
+ * There are three types of frames: single, scatter gather, and frame lists.
+ *
+ * The set of APIs in this file must be used to create, manipulate and
+ * query Frame Descriptors.
+ */
+
+/**
+ * struct dpaa2_fd - Struct describing FDs
+ * @words:         for easier/faster copying the whole FD structure
+ * @addr:          address in the FD
+ * @len:           length in the FD
+ * @bpid:          buffer pool ID
+ * @format_offset: format, offset, and short-length fields
+ * @frc:           frame context
+ * @ctrl:          control bits...including dd, sc, va, err, etc
+ * @flc:           flow context address
+ *
+ * This structure represents the basic Frame Descriptor used in the system.
+ */
+struct dpaa2_fd {
+       union {
+               u32 words[8];
+               struct dpaa2_fd_simple {
+                       __le64 addr;
+                       __le32 len;
+                       __le16 bpid;
+                       __le16 format_offset;
+                       __le32 frc;
+                       __le32 ctrl;
+                       __le64 flc;
+               } simple;
+       };
+};
+
+#define FD_SHORT_LEN_FLAG_MASK 0x1
+#define FD_SHORT_LEN_FLAG_SHIFT        14
+#define FD_SHORT_LEN_MASK      0x3FFFF
+#define FD_OFFSET_MASK         0x0FFF
+#define FD_FORMAT_MASK         0x3
+#define FD_FORMAT_SHIFT                12
+#define FD_BPID_MASK           0x3FFF
+#define SG_SHORT_LEN_FLAG_MASK 0x1
+#define SG_SHORT_LEN_FLAG_SHIFT        14
+#define SG_SHORT_LEN_MASK      0x1FFFF
+#define SG_OFFSET_MASK         0x0FFF
+#define SG_FORMAT_MASK         0x3
+#define SG_FORMAT_SHIFT                12
+#define SG_BPID_MASK           0x3FFF
+#define SG_FINAL_FLAG_MASK     0x1
+#define SG_FINAL_FLAG_SHIFT    15
+
+/* Error bits in FD CTRL */
+#define FD_CTRL_ERR_MASK       0x000000FF
+#define FD_CTRL_UFD            0x00000004
+#define FD_CTRL_SBE            0x00000008
+#define FD_CTRL_FLC            0x00000010
+#define FD_CTRL_FSE            0x00000020
+#define FD_CTRL_FAERR          0x00000040
+
+/* Annotation bits in FD CTRL */
+#define FD_CTRL_PTA            0x00800000
+#define FD_CTRL_PTV1           0x00400000
+
+enum dpaa2_fd_format {
+       dpaa2_fd_single = 0,
+       dpaa2_fd_list,
+       dpaa2_fd_sg
+};
+
+/**
+ * dpaa2_fd_get_addr() - get the addr field of frame descriptor
+ * @fd: the given frame descriptor
+ *
+ * Return the address in the frame descriptor.
+ */
+static inline dma_addr_t dpaa2_fd_get_addr(const struct dpaa2_fd *fd)
+{
+       return (dma_addr_t)le64_to_cpu(fd->simple.addr);
+}
+
+/**
+ * dpaa2_fd_set_addr() - Set the addr field of frame descriptor
+ * @fd: the given frame descriptor
+ * @addr: the address needs to be set in frame descriptor
+ */
+static inline void dpaa2_fd_set_addr(struct dpaa2_fd *fd, dma_addr_t addr)
+{
+       fd->simple.addr = cpu_to_le64(addr);
+}
+
+/**
+ * dpaa2_fd_get_frc() - Get the frame context in the frame descriptor
+ * @fd: the given frame descriptor
+ *
+ * Return the frame context field in the frame descriptor.
+ */
+static inline u32 dpaa2_fd_get_frc(const struct dpaa2_fd *fd)
+{
+       return le32_to_cpu(fd->simple.frc);
+}
+
+/**
+ * dpaa2_fd_set_frc() - Set the frame context in the frame descriptor
+ * @fd: the given frame descriptor
+ * @frc: the frame context needs to be set in frame descriptor
+ */
+static inline void dpaa2_fd_set_frc(struct dpaa2_fd *fd, u32 frc)
+{
+       fd->simple.frc = cpu_to_le32(frc);
+}
+
+/**
+ * dpaa2_fd_get_ctrl() - Get the control bits in the frame descriptor
+ * @fd: the given frame descriptor
+ *
+ * Return the control bits field in the frame descriptor.
+ */
+static inline u32 dpaa2_fd_get_ctrl(const struct dpaa2_fd *fd)
+{
+       return le32_to_cpu(fd->simple.ctrl);
+}
+
+/**
+ * dpaa2_fd_set_ctrl() - Set the control bits in the frame descriptor
+ * @fd: the given frame descriptor
+ * @ctrl: the control bits to be set in the frame descriptor
+ */
+static inline void dpaa2_fd_set_ctrl(struct dpaa2_fd *fd, u32 ctrl)
+{
+       fd->simple.ctrl = cpu_to_le32(ctrl);
+}
+
+/**
+ * dpaa2_fd_get_flc() - Get the flow context in the frame descriptor
+ * @fd: the given frame descriptor
+ *
+ * Return the flow context in the frame descriptor.
+ */
+static inline dma_addr_t dpaa2_fd_get_flc(const struct dpaa2_fd *fd)
+{
+       return (dma_addr_t)le64_to_cpu(fd->simple.flc);
+}
+
+/**
+ * dpaa2_fd_set_flc() - Set the flow context field of frame descriptor
+ * @fd: the given frame descriptor
+ * @flc_addr: the flow context needs to be set in frame descriptor
+ */
+static inline void dpaa2_fd_set_flc(struct dpaa2_fd *fd,  dma_addr_t flc_addr)
+{
+       fd->simple.flc = cpu_to_le64(flc_addr);
+}
+
+static inline bool dpaa2_fd_short_len(const struct dpaa2_fd *fd)
+{
+       return !!((le16_to_cpu(fd->simple.format_offset) >>
+                 FD_SHORT_LEN_FLAG_SHIFT) & FD_SHORT_LEN_FLAG_MASK);
+}
+
+/**
+ * dpaa2_fd_get_len() - Get the length in the frame descriptor
+ * @fd: the given frame descriptor
+ *
+ * Return the length field in the frame descriptor.
+ */
+static inline u32 dpaa2_fd_get_len(const struct dpaa2_fd *fd)
+{
+       if (dpaa2_fd_short_len(fd))
+               return le32_to_cpu(fd->simple.len) & FD_SHORT_LEN_MASK;
+
+       return le32_to_cpu(fd->simple.len);
+}
+
+/**
+ * dpaa2_fd_set_len() - Set the length field of frame descriptor
+ * @fd: the given frame descriptor
+ * @len: the length needs to be set in frame descriptor
+ */
+static inline void dpaa2_fd_set_len(struct dpaa2_fd *fd, u32 len)
+{
+       fd->simple.len = cpu_to_le32(len);
+}
+
+/**
+ * dpaa2_fd_get_offset() - Get the offset field in the frame descriptor
+ * @fd: the given frame descriptor
+ *
+ * Return the offset.
+ */
+static inline uint16_t dpaa2_fd_get_offset(const struct dpaa2_fd *fd)
+{
+       return le16_to_cpu(fd->simple.format_offset) & FD_OFFSET_MASK;
+}
+
+/**
+ * dpaa2_fd_set_offset() - Set the offset field of frame descriptor
+ * @fd: the given frame descriptor
+ * @offset: the offset needs to be set in frame descriptor
+ */
+static inline void dpaa2_fd_set_offset(struct dpaa2_fd *fd, uint16_t offset)
+{
+       fd->simple.format_offset &= cpu_to_le16(~FD_OFFSET_MASK);
+       fd->simple.format_offset |= cpu_to_le16(offset);
+}
+
+/**
+ * dpaa2_fd_get_format() - Get the format field in the frame descriptor
+ * @fd: the given frame descriptor
+ *
+ * Return the format.
+ */
+static inline enum dpaa2_fd_format dpaa2_fd_get_format(
+                                               const struct dpaa2_fd *fd)
+{
+       return (enum dpaa2_fd_format)((le16_to_cpu(fd->simple.format_offset)
+                                     >> FD_FORMAT_SHIFT) & FD_FORMAT_MASK);
+}
+
+/**
+ * dpaa2_fd_set_format() - Set the format field of frame descriptor
+ * @fd: the given frame descriptor
+ * @format: the format needs to be set in frame descriptor
+ */
+static inline void dpaa2_fd_set_format(struct dpaa2_fd *fd,
+                                      enum dpaa2_fd_format format)
+{
+       fd->simple.format_offset &=
+               cpu_to_le16(~(FD_FORMAT_MASK << FD_FORMAT_SHIFT));
+       fd->simple.format_offset |= cpu_to_le16(format << FD_FORMAT_SHIFT);
+}
+
+/**
+ * dpaa2_fd_get_bpid() - Get the bpid field in the frame descriptor
+ * @fd: the given frame descriptor
+ *
+ * Return the buffer pool id.
+ */
+static inline uint16_t dpaa2_fd_get_bpid(const struct dpaa2_fd *fd)
+{
+       return le16_to_cpu(fd->simple.bpid) & FD_BPID_MASK;
+}
+
+/**
+ * dpaa2_fd_set_bpid() - Set the bpid field of frame descriptor
+ * @fd: the given frame descriptor
+ * @bpid: buffer pool id to be set
+ */
+static inline void dpaa2_fd_set_bpid(struct dpaa2_fd *fd, uint16_t bpid)
+{
+       fd->simple.bpid &= cpu_to_le16(~(FD_BPID_MASK));
+       fd->simple.bpid |= cpu_to_le16(bpid);
+}
+
+/**
+ * struct dpaa2_sg_entry - the scatter-gathering structure
+ * @addr: address of the sg entry
+ * @len: length in this sg entry
+ * @bpid: buffer pool id
+ * @format_offset: format and offset fields
+ */
+struct dpaa2_sg_entry {
+       __le64 addr;
+       __le32 len;
+       __le16 bpid;
+       __le16 format_offset;
+};
+
+enum dpaa2_sg_format {
+       dpaa2_sg_single = 0,
+       dpaa2_sg_frame_data,
+       dpaa2_sg_sgt_ext
+};
+
+/* Accessors for SG entry fields */
+
+/**
+ * dpaa2_sg_get_addr() - Get the address from SG entry
+ * @sg: the given scatter-gathering object
+ *
+ * Return the address.
+ */
+static inline dma_addr_t dpaa2_sg_get_addr(const struct dpaa2_sg_entry *sg)
+{
+       return (dma_addr_t)le64_to_cpu(sg->addr);
+}
+
+/**
+ * dpaa2_sg_set_addr() - Set the address in SG entry
+ * @sg: the given scatter-gathering object
+ * @addr: the address to be set
+ */
+static inline void dpaa2_sg_set_addr(struct dpaa2_sg_entry *sg, dma_addr_t addr)
+{
+       sg->addr = cpu_to_le64(addr);
+}
+
+static inline bool dpaa2_sg_short_len(const struct dpaa2_sg_entry *sg)
+{
+       return !!((le16_to_cpu(sg->format_offset) >> SG_SHORT_LEN_FLAG_SHIFT)
+               & SG_SHORT_LEN_FLAG_MASK);
+}
+
+/**
+ * dpaa2_sg_get_len() - Get the length in SG entry
+ * @sg: the given scatter-gathering object
+ *
+ * Return the length.
+ */
+static inline u32 dpaa2_sg_get_len(const struct dpaa2_sg_entry *sg)
+{
+       if (dpaa2_sg_short_len(sg))
+               return le32_to_cpu(sg->len) & SG_SHORT_LEN_MASK;
+
+       return le32_to_cpu(sg->len);
+}
+
+/**
+ * dpaa2_sg_set_len() - Set the length in SG entry
+ * @sg: the given scatter-gathering object
+ * @len: the length to be set
+ */
+static inline void dpaa2_sg_set_len(struct dpaa2_sg_entry *sg, u32 len)
+{
+       sg->len = cpu_to_le32(len);
+}
+
+/**
+ * dpaa2_sg_get_offset() - Get the offset in SG entry
+ * @sg: the given scatter-gathering object
+ *
+ * Return the offset.
+ */
+static inline u16 dpaa2_sg_get_offset(const struct dpaa2_sg_entry *sg)
+{
+       return le16_to_cpu(sg->format_offset) & SG_OFFSET_MASK;
+}
+
+/**
+ * dpaa2_sg_set_offset() - Set the offset in SG entry
+ * @sg: the given scatter-gathering object
+ * @offset: the offset to be set
+ */
+static inline void dpaa2_sg_set_offset(struct dpaa2_sg_entry *sg,
+                                      u16 offset)
+{
+       sg->format_offset &= cpu_to_le16(~SG_OFFSET_MASK);
+       sg->format_offset |= cpu_to_le16(offset);
+}
+
+/**
+ * dpaa2_sg_get_format() - Get the SG format in SG entry
+ * @sg: the given scatter-gathering object
+ *
+ * Return the format.
+ */
+static inline enum dpaa2_sg_format
+       dpaa2_sg_get_format(const struct dpaa2_sg_entry *sg)
+{
+       return (enum dpaa2_sg_format)((le16_to_cpu(sg->format_offset)
+                                      >> SG_FORMAT_SHIFT) & SG_FORMAT_MASK);
+}
+
+/**
+ * dpaa2_sg_set_format() - Set the SG format in SG entry
+ * @sg: the given scatter-gathering object
+ * @format: the format to be set
+ */
+static inline void dpaa2_sg_set_format(struct dpaa2_sg_entry *sg,
+                                      enum dpaa2_sg_format format)
+{
+       sg->format_offset &= cpu_to_le16(~(SG_FORMAT_MASK << SG_FORMAT_SHIFT));
+       sg->format_offset |= cpu_to_le16(format << SG_FORMAT_SHIFT);
+}
+
+/**
+ * dpaa2_sg_get_bpid() - Get the buffer pool id in SG entry
+ * @sg: the given scatter-gathering object
+ *
+ * Return the bpid.
+ */
+static inline u16 dpaa2_sg_get_bpid(const struct dpaa2_sg_entry *sg)
+{
+       return le16_to_cpu(sg->bpid) & SG_BPID_MASK;
+}
+
+/**
+ * dpaa2_sg_set_bpid() - Set the buffer pool id in SG entry
+ * @sg: the given scatter-gathering object
+ * @bpid: the bpid to be set
+ */
+static inline void dpaa2_sg_set_bpid(struct dpaa2_sg_entry *sg, u16 bpid)
+{
+       sg->bpid &= cpu_to_le16(~(SG_BPID_MASK));
+       sg->bpid |= cpu_to_le16(bpid);
+}
+
+/**
+ * dpaa2_sg_is_final() - Check final bit in SG entry
+ * @sg: the given scatter-gathering object
+ *
+ * Return bool.
+ */
+static inline bool dpaa2_sg_is_final(const struct dpaa2_sg_entry *sg)
+{
+       return !!(le16_to_cpu(sg->format_offset) >> SG_FINAL_FLAG_SHIFT);
+}
+
+/**
+ * dpaa2_sg_set_final() - Set the final bit in SG entry
+ * @sg: the given scatter-gathering object
+ * @final: the final boolean to be set
+ */
+static inline void dpaa2_sg_set_final(struct dpaa2_sg_entry *sg, bool final)
+{
+       sg->format_offset &= cpu_to_le16((~(SG_FINAL_FLAG_MASK
+                                        << SG_FINAL_FLAG_SHIFT)) & 0xFFFF);
+       sg->format_offset |= cpu_to_le16(final << SG_FINAL_FLAG_SHIFT);
+}
+
+#endif /* __FSL_DPAA2_FD_H */
diff --git a/include/soc/fsl/dpaa2-global.h b/include/soc/fsl/dpaa2-global.h
new file mode 100644 (file)
index 0000000..9bc0713
--- /dev/null
@@ -0,0 +1,177 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/*
+ * Copyright 2014-2016 Freescale Semiconductor Inc.
+ * Copyright 2016 NXP
+ *
+ */
+#ifndef __FSL_DPAA2_GLOBAL_H
+#define __FSL_DPAA2_GLOBAL_H
+
+#include <linux/types.h>
+#include <linux/cpumask.h>
+#include "dpaa2-fd.h"
+
+struct dpaa2_dq {
+       union {
+               struct common {
+                       u8 verb;
+                       u8 reserved[63];
+               } common;
+               struct dq {
+                       u8 verb;
+                       u8 stat;
+                       __le16 seqnum;
+                       __le16 oprid;
+                       u8 reserved;
+                       u8 tok;
+                       __le32 fqid;
+                       u32 reserved2;
+                       __le32 fq_byte_cnt;
+                       __le32 fq_frm_cnt;
+                       __le64 fqd_ctx;
+                       u8 fd[32];
+               } dq;
+               struct scn {
+                       u8 verb;
+                       u8 stat;
+                       u8 state;
+                       u8 reserved;
+                       __le32 rid_tok;
+                       __le64 ctx;
+               } scn;
+       };
+};
+
+/* Parsing frame dequeue results */
+/* FQ empty */
+#define DPAA2_DQ_STAT_FQEMPTY       0x80
+/* FQ held active */
+#define DPAA2_DQ_STAT_HELDACTIVE    0x40
+/* FQ force eligible */
+#define DPAA2_DQ_STAT_FORCEELIGIBLE 0x20
+/* valid frame */
+#define DPAA2_DQ_STAT_VALIDFRAME    0x10
+/* FQ ODP enable */
+#define DPAA2_DQ_STAT_ODPVALID      0x04
+/* volatile dequeue */
+#define DPAA2_DQ_STAT_VOLATILE      0x02
+/* volatile dequeue command is expired */
+#define DPAA2_DQ_STAT_EXPIRED       0x01
+
+#define DQ_FQID_MASK           0x00FFFFFF
+#define DQ_FRAME_COUNT_MASK    0x00FFFFFF
+
+/**
+ * dpaa2_dq_flags() - Get the stat field of dequeue response
+ * @dq: the dequeue result.
+ */
+static inline u32 dpaa2_dq_flags(const struct dpaa2_dq *dq)
+{
+       return dq->dq.stat;
+}
+
+/**
+ * dpaa2_dq_is_pull() - Check whether the dq response is from a pull
+ *                      command.
+ * @dq: the dequeue result
+ *
+ * Return 1 for volatile(pull) dequeue, 0 for static dequeue.
+ */
+static inline int dpaa2_dq_is_pull(const struct dpaa2_dq *dq)
+{
+       return (int)(dpaa2_dq_flags(dq) & DPAA2_DQ_STAT_VOLATILE);
+}
+
+/**
+ * dpaa2_dq_is_pull_complete() - Check whether the pull command is completed.
+ * @dq: the dequeue result
+ *
+ * Return boolean.
+ */
+static inline bool dpaa2_dq_is_pull_complete(const struct dpaa2_dq *dq)
+{
+       return !!(dpaa2_dq_flags(dq) & DPAA2_DQ_STAT_EXPIRED);
+}
+
+/**
+ * dpaa2_dq_seqnum() - Get the seqnum field in dequeue response
+ * @dq: the dequeue result
+ *
+ * seqnum is valid only if VALIDFRAME flag is TRUE
+ *
+ * Return seqnum.
+ */
+static inline u16 dpaa2_dq_seqnum(const struct dpaa2_dq *dq)
+{
+       return le16_to_cpu(dq->dq.seqnum);
+}
+
+/**
+ * dpaa2_dq_odpid() - Get the odpid field in dequeue response
+ * @dq: the dequeue result
+ *
+ * odpid is valid only if ODPVALID flag is TRUE.
+ *
+ * Return odpid.
+ */
+static inline u16 dpaa2_dq_odpid(const struct dpaa2_dq *dq)
+{
+       return le16_to_cpu(dq->dq.oprid);
+}
+
+/**
+ * dpaa2_dq_fqid() - Get the fqid in dequeue response
+ * @dq: the dequeue result
+ *
+ * Return fqid.
+ */
+static inline u32 dpaa2_dq_fqid(const struct dpaa2_dq *dq)
+{
+       return le32_to_cpu(dq->dq.fqid) & DQ_FQID_MASK;
+}
+
+/**
+ * dpaa2_dq_byte_count() - Get the byte count in dequeue response
+ * @dq: the dequeue result
+ *
+ * Return the byte count remaining in the FQ.
+ */
+static inline u32 dpaa2_dq_byte_count(const struct dpaa2_dq *dq)
+{
+       return le32_to_cpu(dq->dq.fq_byte_cnt);
+}
+
+/**
+ * dpaa2_dq_frame_count() - Get the frame count in dequeue response
+ * @dq: the dequeue result
+ *
+ * Return the frame count remaining in the FQ.
+ */
+static inline u32 dpaa2_dq_frame_count(const struct dpaa2_dq *dq)
+{
+       return le32_to_cpu(dq->dq.fq_frm_cnt) & DQ_FRAME_COUNT_MASK;
+}
+
+/**
+ * dpaa2_dq_fd_ctx() - Get the frame queue context in dequeue response
+ * @dq: the dequeue result
+ *
+ * Return the frame queue context.
+ */
+static inline u64 dpaa2_dq_fqd_ctx(const struct dpaa2_dq *dq)
+{
+       return le64_to_cpu(dq->dq.fqd_ctx);
+}
+
+/**
+ * dpaa2_dq_fd() - Get the frame descriptor in dequeue response
+ * @dq: the dequeue result
+ *
+ * Return the frame descriptor.
+ */
+static inline const struct dpaa2_fd *dpaa2_dq_fd(const struct dpaa2_dq *dq)
+{
+       return (const struct dpaa2_fd *)&dq->dq.fd[0];
+}
+
+#endif /* __FSL_DPAA2_GLOBAL_H */
diff --git a/include/soc/fsl/dpaa2-io.h b/include/soc/fsl/dpaa2-io.h
new file mode 100644 (file)
index 0000000..ab51e40
--- /dev/null
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/*
+ * Copyright 2014-2016 Freescale Semiconductor Inc.
+ * Copyright NXP
+ *
+ */
+#ifndef __FSL_DPAA2_IO_H
+#define __FSL_DPAA2_IO_H
+
+#include <linux/types.h>
+#include <linux/cpumask.h>
+#include <linux/irqreturn.h>
+
+#include "dpaa2-fd.h"
+#include "dpaa2-global.h"
+
+struct dpaa2_io;
+struct dpaa2_io_store;
+struct device;
+
+/**
+ * DOC: DPIO Service
+ *
+ * The DPIO service provides APIs for users to interact with the datapath
+ * by enqueueing and dequeing frame descriptors.
+ *
+ * The following set of APIs can be used to enqueue and dequeue frames
+ * as well as producing notification callbacks when data is available
+ * for dequeue.
+ */
+
+#define DPAA2_IO_ANY_CPU       -1
+
+/**
+ * struct dpaa2_io_desc - The DPIO descriptor
+ * @receives_notifications: Use notificaton mode. Non-zero if the DPIO
+ *                  has a channel.
+ * @has_8prio:      Set to non-zero for channel with 8 priority WQs.  Ignored
+ *                  unless receives_notification is TRUE.
+ * @cpu:            The cpu index that at least interrupt handlers will
+ *                  execute on.
+ * @stash_affinity: The stash affinity for this portal favour 'cpu'
+ * @regs_cena:      The cache enabled regs.
+ * @regs_cinh:      The cache inhibited regs
+ * @dpio_id:        The dpio index
+ * @qman_version:   The qman version
+ *
+ * Describes the attributes and features of the DPIO object.
+ */
+struct dpaa2_io_desc {
+       int receives_notifications;
+       int has_8prio;
+       int cpu;
+       void *regs_cena;
+       void __iomem *regs_cinh;
+       int dpio_id;
+       u32 qman_version;
+};
+
+struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc);
+
+void dpaa2_io_down(struct dpaa2_io *d);
+
+irqreturn_t dpaa2_io_irq(struct dpaa2_io *obj);
+
+struct dpaa2_io *dpaa2_io_service_select(int cpu);
+
+/**
+ * struct dpaa2_io_notification_ctx - The DPIO notification context structure
+ * @cb:           The callback to be invoked when the notification arrives
+ * @is_cdan:      Zero for FQDAN, non-zero for CDAN
+ * @id:           FQID or channel ID, needed for rearm
+ * @desired_cpu:  The cpu on which the notifications will show up. Use
+ *                DPAA2_IO_ANY_CPU if don't care
+ * @dpio_id:      The dpio index
+ * @qman64:       The 64-bit context value shows up in the FQDAN/CDAN.
+ * @node:         The list node
+ * @dpio_private: The dpio object internal to dpio_service
+ *
+ * Used when a FQDAN/CDAN registration is made by drivers.
+ */
+struct dpaa2_io_notification_ctx {
+       void (*cb)(struct dpaa2_io_notification_ctx *ctx);
+       int is_cdan;
+       u32 id;
+       int desired_cpu;
+       int dpio_id;
+       u64 qman64;
+       struct list_head node;
+       void *dpio_private;
+};
+
+int dpaa2_io_service_register(struct dpaa2_io *service,
+                             struct dpaa2_io_notification_ctx *ctx);
+void dpaa2_io_service_deregister(struct dpaa2_io *service,
+                                struct dpaa2_io_notification_ctx *ctx);
+int dpaa2_io_service_rearm(struct dpaa2_io *service,
+                          struct dpaa2_io_notification_ctx *ctx);
+
+int dpaa2_io_service_pull_channel(struct dpaa2_io *d, u32 channelid,
+                                 struct dpaa2_io_store *s);
+
+int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d, u32 qdid, u8 prio,
+                               u16 qdbin, const struct dpaa2_fd *fd);
+int dpaa2_io_service_release(struct dpaa2_io *d, u32 bpid,
+                            const u64 *buffers, unsigned int num_buffers);
+int dpaa2_io_service_acquire(struct dpaa2_io *d, u32 bpid,
+                            u64 *buffers, unsigned int num_buffers);
+
+struct dpaa2_io_store *dpaa2_io_store_create(unsigned int max_frames,
+                                            struct device *dev);
+void dpaa2_io_store_destroy(struct dpaa2_io_store *s);
+struct dpaa2_dq *dpaa2_io_store_next(struct dpaa2_io_store *s, int *is_last);
+
+#endif /* __FSL_DPAA2_IO_H */
index d74722c2ac8b18d02dc1c943937144f674212f52..a401ff5e784711e574233e74eddb3aec974fe522 100644 (file)
@@ -53,24 +53,22 @@ DEFINE_EVENT(cgroup_root, cgroup_remount,
 
 DECLARE_EVENT_CLASS(cgroup,
 
-       TP_PROTO(struct cgroup *cgrp),
+       TP_PROTO(struct cgroup *cgrp, const char *path),
 
-       TP_ARGS(cgrp),
+       TP_ARGS(cgrp, path),
 
        TP_STRUCT__entry(
                __field(        int,            root                    )
                __field(        int,            id                      )
                __field(        int,            level                   )
-               __dynamic_array(char,           path,
-                               cgroup_path(cgrp, NULL, 0) + 1)
+               __string(       path,           path                    )
        ),
 
        TP_fast_assign(
                __entry->root = cgrp->root->hierarchy_id;
                __entry->id = cgrp->id;
                __entry->level = cgrp->level;
-               cgroup_path(cgrp, __get_dynamic_array(path),
-                                 __get_dynamic_array_len(path));
+               __assign_str(path, path);
        ),
 
        TP_printk("root=%d id=%d level=%d path=%s",
@@ -79,45 +77,45 @@ DECLARE_EVENT_CLASS(cgroup,
 
 DEFINE_EVENT(cgroup, cgroup_mkdir,
 
-       TP_PROTO(struct cgroup *cgroup),
+       TP_PROTO(struct cgroup *cgrp, const char *path),
 
-       TP_ARGS(cgroup)
+       TP_ARGS(cgrp, path)
 );
 
 DEFINE_EVENT(cgroup, cgroup_rmdir,
 
-       TP_PROTO(struct cgroup *cgroup),
+       TP_PROTO(struct cgroup *cgrp, const char *path),
 
-       TP_ARGS(cgroup)
+       TP_ARGS(cgrp, path)
 );
 
 DEFINE_EVENT(cgroup, cgroup_release,
 
-       TP_PROTO(struct cgroup *cgroup),
+       TP_PROTO(struct cgroup *cgrp, const char *path),
 
-       TP_ARGS(cgroup)
+       TP_ARGS(cgrp, path)
 );
 
 DEFINE_EVENT(cgroup, cgroup_rename,
 
-       TP_PROTO(struct cgroup *cgroup),
+       TP_PROTO(struct cgroup *cgrp, const char *path),
 
-       TP_ARGS(cgroup)
+       TP_ARGS(cgrp, path)
 );
 
 DECLARE_EVENT_CLASS(cgroup_migrate,
 
-       TP_PROTO(struct cgroup *dst_cgrp, struct task_struct *task, bool threadgroup),
+       TP_PROTO(struct cgroup *dst_cgrp, const char *path,
+                struct task_struct *task, bool threadgroup),
 
-       TP_ARGS(dst_cgrp, task, threadgroup),
+       TP_ARGS(dst_cgrp, path, task, threadgroup),
 
        TP_STRUCT__entry(
                __field(        int,            dst_root                )
                __field(        int,            dst_id                  )
                __field(        int,            dst_level               )
-               __dynamic_array(char,           dst_path,
-                               cgroup_path(dst_cgrp, NULL, 0) + 1)
                __field(        int,            pid                     )
+               __string(       dst_path,       path                    )
                __string(       comm,           task->comm              )
        ),
 
@@ -125,8 +123,7 @@ DECLARE_EVENT_CLASS(cgroup_migrate,
                __entry->dst_root = dst_cgrp->root->hierarchy_id;
                __entry->dst_id = dst_cgrp->id;
                __entry->dst_level = dst_cgrp->level;
-               cgroup_path(dst_cgrp, __get_dynamic_array(dst_path),
-                                     __get_dynamic_array_len(dst_path));
+               __assign_str(dst_path, path);
                __entry->pid = task->pid;
                __assign_str(comm, task->comm);
        ),
@@ -138,16 +135,18 @@ DECLARE_EVENT_CLASS(cgroup_migrate,
 
 DEFINE_EVENT(cgroup_migrate, cgroup_attach_task,
 
-       TP_PROTO(struct cgroup *dst_cgrp, struct task_struct *task, bool threadgroup),
+       TP_PROTO(struct cgroup *dst_cgrp, const char *path,
+                struct task_struct *task, bool threadgroup),
 
-       TP_ARGS(dst_cgrp, task, threadgroup)
+       TP_ARGS(dst_cgrp, path, task, threadgroup)
 );
 
 DEFINE_EVENT(cgroup_migrate, cgroup_transfer_tasks,
 
-       TP_PROTO(struct cgroup *dst_cgrp, struct task_struct *task, bool threadgroup),
+       TP_PROTO(struct cgroup *dst_cgrp, const char *path,
+                struct task_struct *task, bool threadgroup),
 
-       TP_ARGS(dst_cgrp, task, threadgroup)
+       TP_ARGS(dst_cgrp, path, task, threadgroup)
 );
 
 #endif /* _TRACE_CGROUP_H */
index 9c4eb33c5a1d35d9fcfa83b8386a7c4be3ef7c9e..9a0d4ceeb1662decd22cd6a8802927ebdc3acb00 100644 (file)
@@ -1,4 +1,4 @@
-#ifdef CONFIG_PREEMPTIRQ_EVENTS
+#ifdef CONFIG_PREEMPTIRQ_TRACEPOINTS
 
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM preemptirq
@@ -32,7 +32,7 @@ DECLARE_EVENT_CLASS(preemptirq_template,
                  (void *)((unsigned long)(_stext) + __entry->parent_offs))
 );
 
-#ifndef CONFIG_PROVE_LOCKING
+#ifdef CONFIG_TRACE_IRQFLAGS
 DEFINE_EVENT(preemptirq_template, irq_disable,
             TP_PROTO(unsigned long ip, unsigned long parent_ip),
             TP_ARGS(ip, parent_ip));
@@ -40,9 +40,14 @@ DEFINE_EVENT(preemptirq_template, irq_disable,
 DEFINE_EVENT(preemptirq_template, irq_enable,
             TP_PROTO(unsigned long ip, unsigned long parent_ip),
             TP_ARGS(ip, parent_ip));
+#else
+#define trace_irq_enable(...)
+#define trace_irq_disable(...)
+#define trace_irq_enable_rcuidle(...)
+#define trace_irq_disable_rcuidle(...)
 #endif
 
-#ifdef CONFIG_DEBUG_PREEMPT
+#ifdef CONFIG_TRACE_PREEMPT_TOGGLE
 DEFINE_EVENT(preemptirq_template, preempt_disable,
             TP_PROTO(unsigned long ip, unsigned long parent_ip),
             TP_ARGS(ip, parent_ip));
@@ -50,22 +55,22 @@ DEFINE_EVENT(preemptirq_template, preempt_disable,
 DEFINE_EVENT(preemptirq_template, preempt_enable,
             TP_PROTO(unsigned long ip, unsigned long parent_ip),
             TP_ARGS(ip, parent_ip));
+#else
+#define trace_preempt_enable(...)
+#define trace_preempt_disable(...)
+#define trace_preempt_enable_rcuidle(...)
+#define trace_preempt_disable_rcuidle(...)
 #endif
 
 #endif /* _TRACE_PREEMPTIRQ_H */
 
 #include <trace/define_trace.h>
 
-#endif /* !CONFIG_PREEMPTIRQ_EVENTS */
-
-#if !defined(CONFIG_PREEMPTIRQ_EVENTS) || defined(CONFIG_PROVE_LOCKING)
+#else /* !CONFIG_PREEMPTIRQ_TRACEPOINTS */
 #define trace_irq_enable(...)
 #define trace_irq_disable(...)
 #define trace_irq_enable_rcuidle(...)
 #define trace_irq_disable_rcuidle(...)
-#endif
-
-#if !defined(CONFIG_PREEMPTIRQ_EVENTS) || !defined(CONFIG_DEBUG_PREEMPT)
 #define trace_preempt_enable(...)
 #define trace_preempt_disable(...)
 #define trace_preempt_enable_rcuidle(...)
index e13eec3dfb2f86dca4a06830cc64b9ab91c62cf4..df31aa9c9a8c3abe699e5875d814eb354257bd25 100644 (file)
@@ -23,7 +23,7 @@
 #define AUTOFS_MIN_PROTO_VERSION       3
 #define AUTOFS_MAX_PROTO_VERSION       5
 
-#define AUTOFS_PROTO_SUBVERSION                2
+#define AUTOFS_PROTO_SUBVERSION                3
 
 /*
  * The wait_queue_token (autofs_wqt_t) is part of a structure which is passed
@@ -90,8 +90,10 @@ enum {
 /* autofs version 4 and later definitions */
 
 /* Mask for expire behaviour */
-#define AUTOFS_EXP_IMMEDIATE           1
-#define AUTOFS_EXP_LEAVES              2
+#define AUTOFS_EXP_NORMAL              0x00
+#define AUTOFS_EXP_IMMEDIATE           0x01
+#define AUTOFS_EXP_LEAVES              0x02
+#define AUTOFS_EXP_FORCED              0x04
 
 #define AUTOFS_TYPE_ANY                        0U
 #define AUTOFS_TYPE_INDIRECT           1U
index 8d19e02d752a513f7e5b4d030a288582bdf3016e..5d4f58e059fd5d8a352ce4506424f8081f2df2fd 100644 (file)
@@ -30,10 +30,10 @@ struct bkey {
        BITMASK(name, struct bkey, field, offset, size)
 
 #define PTR_FIELD(name, offset, size)                                  \
-static inline __u64 name(const struct bkey *k, unsigned i)             \
+static inline __u64 name(const struct bkey *k, unsigned int i)         \
 { return (k->ptr[i] >> offset) & ~(~0ULL << size); }                   \
                                                                        \
-static inline void SET_##name(struct bkey *k, unsigned i, __u64 v)     \
+static inline void SET_##name(struct bkey *k, unsigned int i, __u64 v) \
 {                                                                      \
        k->ptr[i] &= ~(~(~0ULL << size) << offset);                     \
        k->ptr[i] |= (v & ~(~0ULL << size)) << offset;                  \
@@ -117,12 +117,14 @@ static inline void bkey_copy_key(struct bkey *dest, const struct bkey *src)
 static inline struct bkey *bkey_next(const struct bkey *k)
 {
        __u64 *d = (void *) k;
+
        return (struct bkey *) (d + bkey_u64s(k));
 }
 
-static inline struct bkey *bkey_idx(const struct bkey *k, unsigned nr_keys)
+static inline struct bkey *bkey_idx(const struct bkey *k, unsigned int nr_keys)
 {
        __u64 *d = (void *) k;
+
        return (struct bkey *) (d + nr_keys);
 }
 /* Enough for a key with 6 pointers */
index 7b8c9e19bad1c2bf72c21dcf6b358559d5e4b4ea..910cc4334b21557f98298082b16e2359a6414e01 100644 (file)
@@ -65,7 +65,7 @@
 
 /* keyctl structures */
 struct keyctl_dh_params {
-       __s32 private;
+       __s32 dh_private;
        __s32 prime;
        __s32 base;
 };
index 3cf632839337b7cf0288971e2612376d52de636d..07548de5c9889f5bcd425a7273b2732003bf3c30 100644 (file)
@@ -951,6 +951,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_HYPERV_TLBFLUSH 155
 #define KVM_CAP_S390_HPAGE_1M 156
 #define KVM_CAP_NESTED_STATE 157
+#define KVM_CAP_ARM_INJECT_SERROR_ESR 158
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
index dc520e1a4123f7a60d4996b5d0df7d237199cdba..8b73cb603c5f32c78ff4ac78df4e78453a449cd9 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <linux/types.h>
 #include <linux/socket.h>              /* For __kernel_sockaddr_storage. */
+#include <linux/in6.h>                 /* For struct in6_addr. */
 
 #define RDS_IB_ABI_VERSION             0x301
 
index b1e22c40c4b68a0b39d0a8a567baea1f3b5403ed..84c3de89696a15c1a23e7226dea456a6232e2043 100644 (file)
@@ -176,7 +176,7 @@ struct vhost_memory {
 #define VHOST_BACKEND_F_IOTLB_MSG_V2 0x1
 
 #define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64)
-#define VHOST_GET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x26, __u64)
+#define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64)
 
 /* VHOST_NET specific defines */
 
index 5b04a494d139ee5647cea91427f2b69d00d3528b..aad3b6201fc06c1b5d792edec001bfe0bf96c2ba 100644 (file)
@@ -285,6 +285,20 @@ struct ubi_attach_req {
        __s8 padding[10];
 };
 
+/*
+ * UBI volume flags.
+ *
+ * @UBI_VOL_SKIP_CRC_CHECK_FLG: skip the CRC check done on a static volume at
+ *                             open time. Only valid for static volumes and
+ *                             should only be used if the volume user has a
+ *                             way to verify data integrity
+ */
+enum {
+       UBI_VOL_SKIP_CRC_CHECK_FLG = 0x1,
+};
+
+#define UBI_VOL_VALID_FLGS     (UBI_VOL_SKIP_CRC_CHECK_FLG)
+
 /**
  * struct ubi_mkvol_req - volume description data structure used in
  *                        volume creation requests.
@@ -292,7 +306,7 @@ struct ubi_attach_req {
  * @alignment: volume alignment
  * @bytes: volume size in bytes
  * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME)
- * @padding1: reserved for future, not used, has to be zeroed
+ * @flags: volume flags (%UBI_VOL_SKIP_CRC_CHECK_FLG)
  * @name_len: volume name length
  * @padding2: reserved for future, not used, has to be zeroed
  * @name: volume name
@@ -321,7 +335,7 @@ struct ubi_mkvol_req {
        __s32 alignment;
        __s64 bytes;
        __s8 vol_type;
-       __s8 padding1;
+       __u8 flags;
        __s16 name_len;
        __s8 padding2[4];
        char name[UBI_MAX_VOLUME_NAME + 1];
index 0cabe6b090954bd18ea2f246201a393f4a12a9f5..3abd327bada64c0fd089131192edcb88da26e916 100644 (file)
@@ -20,7 +20,6 @@ struct dloarea {
 struct urb_node {
        struct list_head entry;
        struct dlfb_data *dlfb;
-       struct delayed_work release_urb_work;
        struct urb *urb;
 };
 
@@ -52,11 +51,14 @@ struct dlfb_data {
        int base8;
        u32 pseudo_palette[256];
        int blank_mode; /*one of FB_BLANK_ */
+       struct fb_ops ops;
        /* blit-only rendering path metrics, exposed through sysfs */
        atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */
        atomic_t bytes_identical; /* saved effort with backbuffer comparison */
        atomic_t bytes_sent; /* to usb, after compression including overhead */
        atomic_t cpu_kcycles_used; /* transpired during pixel processing */
+       struct fb_var_screeninfo current_mode;
+       struct list_head deferred_free;
 };
 
 #define NR_USB_REQUEST_I2C_SUB_IO 0x02
@@ -87,7 +89,7 @@ struct dlfb_data {
 #define MIN_RAW_PIX_BYTES      2
 #define MIN_RAW_CMD_BYTES      (RAW_HEADER_BYTES + MIN_RAW_PIX_BYTES)
 
-#define DL_DEFIO_WRITE_DELAY    5 /* fb_deferred_io.delay in jiffies */
+#define DL_DEFIO_WRITE_DELAY    msecs_to_jiffies(HZ <= 300 ? 4 : 10) /* optimal value for 720p video */
 #define DL_DEFIO_WRITE_DISABLE  (HZ*60) /* "disable" with long delay */
 
 /* remove these once align.h patch is taken into kernel */
index 9bd50ba8253f73ef4c5d064416129f6ce09ac1ca..1e234e2f1cba7a0f1ca9e2ae18868d50e1fe4aaf 100644 (file)
@@ -436,7 +436,7 @@ config BSD_PROCESS_ACCT_V3
        help
          If you say Y here, the process accounting information is written
          in a new file format that also logs the process IDs of each
-         process and it's parent. Note that this file format is incompatible
+         process and its parent. Note that this file format is incompatible
          with previous v0/v1/v2 file formats, so you will need updated tools
          for processing it. A preliminary version of these tools is available
          at <http://www.gnu.org/software/acct/>.
@@ -967,6 +967,18 @@ config NET_NS
 
 endif # NAMESPACES
 
+config CHECKPOINT_RESTORE
+       bool "Checkpoint/restore support"
+       select PROC_CHILDREN
+       default n
+       help
+         Enables additional kernel features in a sake of checkpoint/restore.
+         In particular it adds auxiliary prctl codes to setup process text,
+         data and heap segment sizes, and a few additional /proc filesystem
+         entries.
+
+         If unsure, say N here.
+
 config SCHED_AUTOGROUP
        bool "Automatic process group scheduling"
        select CGROUPS
@@ -1085,6 +1097,8 @@ config LD_DEAD_CODE_DATA_ELIMINATION
        bool "Dead code and data elimination (EXPERIMENTAL)"
        depends on HAVE_LD_DEAD_CODE_DATA_ELIMINATION
        depends on EXPERT
+       depends on $(cc-option,-ffunction-sections -fdata-sections)
+       depends on $(ld-option,--gc-sections)
        help
          Enable this if you want to do dead code and data elimination with
          the linker by compiling with -ffunction-sections -fdata-sections,
@@ -1383,18 +1397,6 @@ config MEMBARRIER
 
          If unsure, say Y.
 
-config CHECKPOINT_RESTORE
-       bool "Checkpoint/restore support" if EXPERT
-       select PROC_CHILDREN
-       default n
-       help
-         Enables additional kernel features in a sake of checkpoint/restore.
-         In particular it adds auxiliary prctl codes to setup process text,
-         data and heap segment sizes, and a few additional /proc filesystem
-         entries.
-
-         If unsure, say N here.
-
 config KALLSYMS
         bool "Load all symbols for debugging/ksymoops" if EXPERT
         default y
@@ -1702,7 +1704,7 @@ config MMAP_ALLOW_UNINITIALIZED
        default n
        help
          Normally, and according to the Linux spec, anonymous memory obtained
-         from mmap() has it's contents cleared before it is passed to
+         from mmap() has its contents cleared before it is passed to
          userspace.  Enabling this config option allows you to request that
          mmap() skip that if it is given an MAP_UNINITIALIZED flag, thus
          providing a huge performance boost.  If this option is not enabled,
index 2c71dabe56260ee00283b78984f67ea9d5d61eba..e1c9afa9d8c9103fa1463a45a425c9468e4c1628 100644 (file)
@@ -1,13 +1,3 @@
-/*
- * Many of the syscalls used in this file expect some of the arguments
- * to be __user pointers not __kernel pointers.  To limit the sparse
- * noise, turn off sparse checking for this file.
- */
-#ifdef __CHECKER__
-#undef __CHECKER__
-#warning "Sparse checking disabled for this file"
-#endif
-
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/ctype.h>
index 5a91aefa7305b441328c613b8a8b10b740338e0d..d1a5d885ce13eb566667b5d32de782c6c4694944 100644 (file)
@@ -1,14 +1,4 @@
 // SPDX-License-Identifier: GPL-2.0
-/*
- * Many of the syscalls used in this file expect some of the arguments
- * to be __user pointers not __kernel pointers.  To limit the sparse
- * noise, turn off sparse checking for this file.
- */
-#ifdef __CHECKER__
-#undef __CHECKER__
-#warning "Sparse checking disabled for this file"
-#endif
-
 #include <linux/unistd.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
index 7d85d172bc7e265ae2e4541a95d495799ee6446e..b84031528dd4466541a4ac75890e39738fd4c589 100644 (file)
@@ -1,14 +1,4 @@
 // SPDX-License-Identifier: GPL-2.0
-/*
- * Many of the syscalls used in this file expect some of the arguments
- * to be __user pointers not __kernel pointers.  To limit the sparse
- * noise, turn off sparse checking for this file.
- */
-#ifdef __CHECKER__
-#undef __CHECKER__
-#warning "Sparse checking disabled for this file"
-#endif
-
 #include <linux/delay.h>
 #include <linux/raid/md_u.h>
 #include <linux/raid/md_p.h>
index 035a5f0ab26b9882d251784f2abd348d7eef2b9a..32fb049d18f9b40f95d000eb60e70bb7a87aa65c 100644 (file)
@@ -1,14 +1,4 @@
 // SPDX-License-Identifier: GPL-2.0
-/*
- * Many of the syscalls used in this file expect some of the arguments
- * to be __user pointers not __kernel pointers.  To limit the sparse
- * noise, turn off sparse checking for this file.
- */
-#ifdef __CHECKER__
-#undef __CHECKER__
-#warning "Sparse checking disabled for this file"
-#endif
-
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/minix_fs.h>
index 74f60baa2799dd95b14dfa03fb00bed8de33949d..5aebe3be4d7cd65ce1bed995c76b9293fea00b2d 100644 (file)
@@ -22,6 +22,7 @@ static struct signal_struct init_signals = {
                .list = LIST_HEAD_INIT(init_signals.shared_pending.list),
                .signal =  {{0}}
        },
+       .multiprocess   = HLIST_HEAD_INIT,
        .rlim           = INIT_RLIMITS,
        .cred_guard_mutex = __MUTEX_INITIALIZER(init_signals.cred_guard_mutex),
 #ifdef CONFIG_POSIX_TIMERS
@@ -33,6 +34,12 @@ static struct signal_struct init_signals = {
        },
 #endif
        INIT_CPU_TIMERS(init_signals)
+       .pids = {
+               [PIDTYPE_PID]   = &init_struct_pid,
+               [PIDTYPE_TGID]  = &init_struct_pid,
+               [PIDTYPE_PGID]  = &init_struct_pid,
+               [PIDTYPE_SID]   = &init_struct_pid,
+       },
        INIT_PREV_CPUTIME(init_signals)
 };
 
@@ -111,11 +118,7 @@ struct task_struct init_task
        INIT_CPU_TIMERS(init_task)
        .pi_lock        = __RAW_SPIN_LOCK_UNLOCKED(init_task.pi_lock),
        .timer_slack_ns = 50000, /* 50 usec default slack */
-       .pids = {
-               [PIDTYPE_PID]  = INIT_PID_LINK(PIDTYPE_PID),
-               [PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID),
-               [PIDTYPE_SID]  = INIT_PID_LINK(PIDTYPE_SID),
-       },
+       .thread_pid     = &init_struct_pid,
        .thread_group   = LIST_HEAD_INIT(init_task.thread_group),
        .thread_node    = LIST_HEAD_INIT(init_signals.thread_head),
 #ifdef CONFIG_AUDITSYSCALL
index 13643c46ebab2cc065b4bb8a985c2cc3756d0c1b..640557788026d8d947841c8da384056ec94ec4a0 100644 (file)
@@ -1,14 +1,4 @@
 // SPDX-License-Identifier: GPL-2.0
-/*
- * Many of the syscalls used in this file expect some of the arguments
- * to be __user pointers not __kernel pointers.  To limit the sparse
- * noise, turn off sparse checking for this file.
- */
-#ifdef __CHECKER__
-#undef __CHECKER__
-#warning "Sparse checking disabled for this file"
-#endif
-
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
index 38c68b593d0d704f103bec42d37b42ca4742673f..18f8f0140fa0351691b45f1152e64ee1b10e3f24 100644 (file)
@@ -647,6 +647,7 @@ asmlinkage __visible void __init start_kernel(void)
        profile_init();
        call_function_init();
        WARN(!irqs_disabled(), "Interrupts were enabled early\n");
+
        early_boot_irqs_disabled = false;
        local_irq_enable();
 
@@ -662,7 +663,7 @@ asmlinkage __visible void __init start_kernel(void)
                panic("Too many boot %s vars at `%s'", panic_later,
                      panic_param);
 
-       lockdep_info();
+       lockdep_init();
 
        /*
         * Need to run this when irqs are enabled, because it wants
@@ -901,18 +902,18 @@ int __init_or_module do_one_initcall(initcall_t fn)
 }
 
 
-extern initcall_t __initcall_start[];
-extern initcall_t __initcall0_start[];
-extern initcall_t __initcall1_start[];
-extern initcall_t __initcall2_start[];
-extern initcall_t __initcall3_start[];
-extern initcall_t __initcall4_start[];
-extern initcall_t __initcall5_start[];
-extern initcall_t __initcall6_start[];
-extern initcall_t __initcall7_start[];
-extern initcall_t __initcall_end[];
+extern initcall_entry_t __initcall_start[];
+extern initcall_entry_t __initcall0_start[];
+extern initcall_entry_t __initcall1_start[];
+extern initcall_entry_t __initcall2_start[];
+extern initcall_entry_t __initcall3_start[];
+extern initcall_entry_t __initcall4_start[];
+extern initcall_entry_t __initcall5_start[];
+extern initcall_entry_t __initcall6_start[];
+extern initcall_entry_t __initcall7_start[];
+extern initcall_entry_t __initcall_end[];
 
-static initcall_t *initcall_levels[] __initdata = {
+static initcall_entry_t *initcall_levels[] __initdata = {
        __initcall0_start,
        __initcall1_start,
        __initcall2_start,
@@ -938,7 +939,7 @@ static char *initcall_level_names[] __initdata = {
 
 static void __init do_initcall_level(int level)
 {
-       initcall_t *fn;
+       initcall_entry_t *fn;
 
        strcpy(initcall_command_line, saved_command_line);
        parse_args(initcall_level_names[level],
@@ -949,7 +950,7 @@ static void __init do_initcall_level(int level)
 
        trace_initcall_level(initcall_level_names[level]);
        for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
-               do_one_initcall(*fn);
+               do_one_initcall(initcall_from_entry(fn));
 }
 
 static void __init do_initcalls(void)
@@ -980,11 +981,11 @@ static void __init do_basic_setup(void)
 
 static void __init do_pre_smp_initcalls(void)
 {
-       initcall_t *fn;
+       initcall_entry_t *fn;
 
        trace_initcall_level("early");
        for (fn = __initcall_start; fn < __initcall0_start; fn++)
-               do_one_initcall(*fn);
+               do_one_initcall(initcall_from_entry(fn));
 }
 
 /*
@@ -1001,6 +1002,7 @@ void __init load_default_modules(void)
 static int run_init_process(const char *init_filename)
 {
        argv_init[0] = init_filename;
+       pr_info("Run %s as init process\n", init_filename);
        return do_execve(getname_kernel(init_filename),
                (const char __user *const __user *)argv_init,
                (const char __user *const __user *)envp_init);
index 203281198079c660c18f9cabf8b9b61c26caf7d4..883642cf2b2767ae7c05b9eb19841d5f16c230ca 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -163,7 +163,7 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params)
        /* ipc_addid() locks msq upon success. */
        retval = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni);
        if (retval < 0) {
-               call_rcu(&msq->q_perm.rcu, msg_rcu_free);
+               ipc_rcu_putref(&msq->q_perm, msg_rcu_free);
                return retval;
        }
 
@@ -386,7 +386,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
        down_write(&msg_ids(ns).rwsem);
        rcu_read_lock();
 
-       ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd,
+       ipcp = ipcctl_obtain_check(ns, &msg_ids(ns), msqid, cmd,
                                      &msqid64->msg_perm, msqid64->msg_qbytes);
        if (IS_ERR(ipcp)) {
                err = PTR_ERR(ipcp);
@@ -456,7 +456,7 @@ static int msgctl_info(struct ipc_namespace *ns, int msqid,
                         int cmd, struct msginfo *msginfo)
 {
        int err;
-       int max_id;
+       int max_idx;
 
        /*
         * We must not return kernel stack data.
@@ -483,16 +483,15 @@ static int msgctl_info(struct ipc_namespace *ns, int msqid,
                msginfo->msgpool = MSGPOOL;
                msginfo->msgtql = MSGTQL;
        }
-       max_id = ipc_get_maxid(&msg_ids(ns));
+       max_idx = ipc_get_maxidx(&msg_ids(ns));
        up_read(&msg_ids(ns).rwsem);
-       return (max_id < 0) ? 0 : max_id;
+       return (max_idx < 0) ? 0 : max_idx;
 }
 
 static int msgctl_stat(struct ipc_namespace *ns, int msqid,
                         int cmd, struct msqid64_ds *p)
 {
        struct msg_queue *msq;
-       int id = 0;
        int err;
 
        memset(p, 0, sizeof(*p));
@@ -504,7 +503,6 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
                        err = PTR_ERR(msq);
                        goto out_unlock;
                }
-               id = msq->q_perm.id;
        } else { /* IPC_STAT */
                msq = msq_obtain_object_check(ns, msqid);
                if (IS_ERR(msq)) {
@@ -549,10 +547,21 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
        p->msg_lspid  = pid_vnr(msq->q_lspid);
        p->msg_lrpid  = pid_vnr(msq->q_lrpid);
 
-       ipc_unlock_object(&msq->q_perm);
-       rcu_read_unlock();
-       return id;
+       if (cmd == IPC_STAT) {
+               /*
+                * As defined in SUS:
+                * Return 0 on success
+                */
+               err = 0;
+       } else {
+               /*
+                * MSG_STAT and MSG_STAT_ANY (both Linux specific)
+                * Return the full id, including the sequence number
+                */
+               err = msq->q_perm.id;
+       }
 
+       ipc_unlock_object(&msq->q_perm);
 out_unlock:
        rcu_read_unlock();
        return err;
@@ -1229,7 +1238,7 @@ COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
 }
 #endif
 
-int msg_init_ns(struct ipc_namespace *ns)
+void msg_init_ns(struct ipc_namespace *ns)
 {
        ns->msg_ctlmax = MSGMAX;
        ns->msg_ctlmnb = MSGMNB;
@@ -1237,7 +1246,7 @@ int msg_init_ns(struct ipc_namespace *ns)
 
        atomic_set(&ns->msg_bytes, 0);
        atomic_set(&ns->msg_hdrs, 0);
-       return ipc_init_ids(&ns->ids[IPC_MSG_IDS]);
+       ipc_init_ids(&ns->ids[IPC_MSG_IDS]);
 }
 
 #ifdef CONFIG_IPC_NS
@@ -1278,12 +1287,11 @@ static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
 }
 #endif
 
-int __init msg_init(void)
+void __init msg_init(void)
 {
-       const int err = msg_init_ns(&init_ipc_ns);
+       msg_init_ns(&init_ipc_ns);
 
        ipc_init_proc_interface("sysvipc/msg",
                                "       key      msqid perms      cbytes       qnum lspid lrpid   uid   gid  cuid  cgid      stime      rtime      ctime\n",
                                IPC_MSG_IDS, sysvipc_msg_proc_show);
-       return err;
 }
index f59a89966f923bc1c782504f708969c1e232a806..21607791d62c800a80275770ea7e7d175bfbc866 100644 (file)
@@ -55,28 +55,16 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
        ns->user_ns = get_user_ns(user_ns);
        ns->ucounts = ucounts;
 
-       err = sem_init_ns(ns);
+       err = mq_init_ns(ns);
        if (err)
                goto fail_put;
-       err = msg_init_ns(ns);
-       if (err)
-               goto fail_destroy_sem;
-       err = shm_init_ns(ns);
-       if (err)
-               goto fail_destroy_msg;
 
-       err = mq_init_ns(ns);
-       if (err)
-               goto fail_destroy_shm;
+       sem_init_ns(ns);
+       msg_init_ns(ns);
+       shm_init_ns(ns);
 
        return ns;
 
-fail_destroy_shm:
-       shm_exit_ns(ns);
-fail_destroy_msg:
-       msg_exit_ns(ns);
-fail_destroy_sem:
-       sem_exit_ns(ns);
 fail_put:
        put_user_ns(ns->user_ns);
        ns_free_inum(&ns->ns);
index 00ef2f743a628e0c11d33ed64da2295f9c2441ca..26f8e37fcdcbcf428e8f03396625272fae763023 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -221,14 +221,14 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it);
 #define sc_semopm      sem_ctls[2]
 #define sc_semmni      sem_ctls[3]
 
-int sem_init_ns(struct ipc_namespace *ns)
+void sem_init_ns(struct ipc_namespace *ns)
 {
        ns->sc_semmsl = SEMMSL;
        ns->sc_semmns = SEMMNS;
        ns->sc_semopm = SEMOPM;
        ns->sc_semmni = SEMMNI;
        ns->used_sems = 0;
-       return ipc_init_ids(&ns->ids[IPC_SEM_IDS]);
+       ipc_init_ids(&ns->ids[IPC_SEM_IDS]);
 }
 
 #ifdef CONFIG_IPC_NS
@@ -240,14 +240,12 @@ void sem_exit_ns(struct ipc_namespace *ns)
 }
 #endif
 
-int __init sem_init(void)
+void __init sem_init(void)
 {
-       const int err = sem_init_ns(&init_ipc_ns);
-
+       sem_init_ns(&init_ipc_ns);
        ipc_init_proc_interface("sysvipc/sem",
                                "       key      semid perms      nsems   uid   gid  cuid  cgid      otime      ctime\n",
                                IPC_SEM_IDS, sysvipc_sem_proc_show);
-       return err;
 }
 
 /**
@@ -557,7 +555,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
        /* ipc_addid() locks sma upon success. */
        retval = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni);
        if (retval < 0) {
-               call_rcu(&sma->sem_perm.rcu, sem_rcu_free);
+               ipc_rcu_putref(&sma->sem_perm, sem_rcu_free);
                return retval;
        }
        ns->used_sems += nsems;
@@ -1223,7 +1221,6 @@ static int semctl_stat(struct ipc_namespace *ns, int semid,
 {
        struct sem_array *sma;
        time64_t semotime;
-       int id = 0;
        int err;
 
        memset(semid64, 0, sizeof(*semid64));
@@ -1235,7 +1232,6 @@ static int semctl_stat(struct ipc_namespace *ns, int semid,
                        err = PTR_ERR(sma);
                        goto out_unlock;
                }
-               id = sma->sem_perm.id;
        } else { /* IPC_STAT */
                sma = sem_obtain_object_check(ns, semid);
                if (IS_ERR(sma)) {
@@ -1275,10 +1271,20 @@ static int semctl_stat(struct ipc_namespace *ns, int semid,
 #endif
        semid64->sem_nsems = sma->sem_nsems;
 
+       if (cmd == IPC_STAT) {
+               /*
+                * As defined in SUS:
+                * Return 0 on success
+                */
+               err = 0;
+       } else {
+               /*
+                * SEM_STAT and SEM_STAT_ANY (both Linux specific)
+                * Return the full id, including the sequence number
+                */
+               err = sma->sem_perm.id;
+       }
        ipc_unlock_object(&sma->sem_perm);
-       rcu_read_unlock();
-       return id;
-
 out_unlock:
        rcu_read_unlock();
        return err;
@@ -1288,7 +1294,7 @@ static int semctl_info(struct ipc_namespace *ns, int semid,
                         int cmd, void __user *p)
 {
        struct seminfo seminfo;
-       int max_id;
+       int max_idx;
        int err;
 
        err = security_sem_semctl(NULL, cmd);
@@ -1312,11 +1318,11 @@ static int semctl_info(struct ipc_namespace *ns, int semid,
                seminfo.semusz = SEMUSZ;
                seminfo.semaem = SEMAEM;
        }
-       max_id = ipc_get_maxid(&sem_ids(ns));
+       max_idx = ipc_get_maxidx(&sem_ids(ns));
        up_read(&sem_ids(ns).rwsem);
        if (copy_to_user(p, &seminfo, sizeof(struct seminfo)))
                return -EFAULT;
-       return (max_id < 0) ? 0 : max_id;
+       return (max_idx < 0) ? 0 : max_idx;
 }
 
 static int semctl_setval(struct ipc_namespace *ns, int semid, int semnum,
@@ -1588,7 +1594,7 @@ static int semctl_down(struct ipc_namespace *ns, int semid,
        down_write(&sem_ids(ns).rwsem);
        rcu_read_lock();
 
-       ipcp = ipcctl_pre_down_nolock(ns, &sem_ids(ns), semid, cmd,
+       ipcp = ipcctl_obtain_check(ns, &sem_ids(ns), semid, cmd,
                                      &semid64->sem_perm, 0);
        if (IS_ERR(ipcp)) {
                err = PTR_ERR(ipcp);
index b204feb3827402c7655aeef27bd655b0f426a011..4cd402e4cfeb603e2417a3796c3d9b22f3022f89 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -96,14 +96,14 @@ static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp);
 static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
 #endif
 
-int shm_init_ns(struct ipc_namespace *ns)
+void shm_init_ns(struct ipc_namespace *ns)
 {
        ns->shm_ctlmax = SHMMAX;
        ns->shm_ctlall = SHMALL;
        ns->shm_ctlmni = SHMMNI;
        ns->shm_rmid_forced = 0;
        ns->shm_tot = 0;
-       return ipc_init_ids(&shm_ids(ns));
+       ipc_init_ids(&shm_ids(ns));
 }
 
 /*
@@ -136,9 +136,8 @@ void shm_exit_ns(struct ipc_namespace *ns)
 
 static int __init ipc_ns_init(void)
 {
-       const int err = shm_init_ns(&init_ipc_ns);
-       WARN(err, "ipc: sysv shm_init_ns failed: %d\n", err);
-       return err;
+       shm_init_ns(&init_ipc_ns);
+       return 0;
 }
 
 pure_initcall(ipc_ns_init);
@@ -180,16 +179,34 @@ static inline struct shmid_kernel *shm_obtain_object_check(struct ipc_namespace
  */
 static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id)
 {
-       struct kern_ipc_perm *ipcp = ipc_lock(&shm_ids(ns), id);
+       struct kern_ipc_perm *ipcp;
+
+       rcu_read_lock();
+       ipcp = ipc_obtain_object_idr(&shm_ids(ns), id);
+       if (IS_ERR(ipcp))
+               goto err;
 
+       ipc_lock_object(ipcp);
+       /*
+        * ipc_rmid() may have already freed the ID while ipc_lock_object()
+        * was spinning: here verify that the structure is still valid.
+        * Upon races with RMID, return -EIDRM, thus indicating that
+        * the ID points to a removed identifier.
+        */
+       if (ipc_valid_object(ipcp)) {
+               /* return a locked ipc object upon success */
+               return container_of(ipcp, struct shmid_kernel, shm_perm);
+       }
+
+       ipc_unlock_object(ipcp);
+       ipcp = ERR_PTR(-EIDRM);
+err:
+       rcu_read_unlock();
        /*
         * Callers of shm_lock() must validate the status of the returned ipc
-        * object pointer (as returned by ipc_lock()), and error out as
-        * appropriate.
+        * object pointer and error out as appropriate.
         */
-       if (IS_ERR(ipcp))
-               return (void *)ipcp;
-       return container_of(ipcp, struct shmid_kernel, shm_perm);
+       return (void *)ipcp;
 }
 
 static inline void shm_lock_by_ptr(struct shmid_kernel *ipcp)
@@ -684,6 +701,8 @@ no_id:
        if (is_file_hugepages(file) && shp->mlock_user)
                user_shm_unlock(size, shp->mlock_user);
        fput(file);
+       ipc_rcu_putref(&shp->shm_perm, shm_rcu_free);
+       return error;
 no_file:
        call_rcu(&shp->shm_perm.rcu, shm_rcu_free);
        return error;
@@ -879,7 +898,7 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
        down_write(&shm_ids(ns).rwsem);
        rcu_read_lock();
 
-       ipcp = ipcctl_pre_down_nolock(ns, &shm_ids(ns), shmid, cmd,
+       ipcp = ipcctl_obtain_check(ns, &shm_ids(ns), shmid, cmd,
                                      &shmid64->shm_perm, 0);
        if (IS_ERR(ipcp)) {
                err = PTR_ERR(ipcp);
@@ -930,7 +949,7 @@ static int shmctl_ipc_info(struct ipc_namespace *ns,
                shminfo->shmall = ns->shm_ctlall;
                shminfo->shmmin = SHMMIN;
                down_read(&shm_ids(ns).rwsem);
-               err = ipc_get_maxid(&shm_ids(ns));
+               err = ipc_get_maxidx(&shm_ids(ns));
                up_read(&shm_ids(ns).rwsem);
                if (err < 0)
                        err = 0;
@@ -950,7 +969,7 @@ static int shmctl_shm_info(struct ipc_namespace *ns,
                shm_info->shm_tot = ns->shm_tot;
                shm_info->swap_attempts = 0;
                shm_info->swap_successes = 0;
-               err = ipc_get_maxid(&shm_ids(ns));
+               err = ipc_get_maxidx(&shm_ids(ns));
                up_read(&shm_ids(ns).rwsem);
                if (err < 0)
                        err = 0;
@@ -962,7 +981,6 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid,
                        int cmd, struct shmid64_ds *tbuf)
 {
        struct shmid_kernel *shp;
-       int id = 0;
        int err;
 
        memset(tbuf, 0, sizeof(*tbuf));
@@ -974,7 +992,6 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid,
                        err = PTR_ERR(shp);
                        goto out_unlock;
                }
-               id = shp->shm_perm.id;
        } else { /* IPC_STAT */
                shp = shm_obtain_object_check(ns, shmid);
                if (IS_ERR(shp)) {
@@ -1024,10 +1041,21 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid,
        tbuf->shm_lpid  = pid_vnr(shp->shm_lprid);
        tbuf->shm_nattch = shp->shm_nattch;
 
-       ipc_unlock_object(&shp->shm_perm);
-       rcu_read_unlock();
-       return id;
+       if (cmd == IPC_STAT) {
+               /*
+                * As defined in SUS:
+                * Return 0 on success
+                */
+               err = 0;
+       } else {
+               /*
+                * SHM_STAT and SHM_STAT_ANY (both Linux specific)
+                * Return the full id, including the sequence number
+                */
+               err = shp->shm_perm.id;
+       }
 
+       ipc_unlock_object(&shp->shm_perm);
 out_unlock:
        rcu_read_unlock();
        return err;
index fdffff41f65b546f66a5ee9b69297b39c445b8a0..0af05752969f1bc4641a591d717edd1b46a18b5a 100644 (file)
@@ -88,16 +88,12 @@ struct ipc_proc_iface {
  */
 static int __init ipc_init(void)
 {
-       int err_sem, err_msg;
-
        proc_mkdir("sysvipc", NULL);
-       err_sem = sem_init();
-       WARN(err_sem, "ipc: sysv sem_init failed: %d\n", err_sem);
-       err_msg = msg_init();
-       WARN(err_msg, "ipc: sysv msg_init failed: %d\n", err_msg);
+       sem_init();
+       msg_init();
        shm_init();
 
-       return err_msg ? err_msg : err_sem;
+       return 0;
 }
 device_initcall(ipc_init);
 
@@ -116,22 +112,17 @@ static const struct rhashtable_params ipc_kht_params = {
  * Set up the sequence range to use for the ipc identifier range (limited
  * below IPCMNI) then initialise the keys hashtable and ids idr.
  */
-int ipc_init_ids(struct ipc_ids *ids)
+void ipc_init_ids(struct ipc_ids *ids)
 {
-       int err;
        ids->in_use = 0;
        ids->seq = 0;
        init_rwsem(&ids->rwsem);
-       err = rhashtable_init(&ids->key_ht, &ipc_kht_params);
-       if (err)
-               return err;
+       rhashtable_init(&ids->key_ht, &ipc_kht_params);
        idr_init(&ids->ipcs_idr);
-       ids->tables_initialized = true;
-       ids->max_id = -1;
+       ids->max_idx = -1;
 #ifdef CONFIG_CHECKPOINT_RESTORE
        ids->next_id = -1;
 #endif
-       return 0;
 }
 
 #ifdef CONFIG_PROC_FS
@@ -179,61 +170,66 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
  */
 static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
 {
-       struct kern_ipc_perm *ipcp = NULL;
+       struct kern_ipc_perm *ipcp;
 
-       if (likely(ids->tables_initialized))
-               ipcp = rhashtable_lookup_fast(&ids->key_ht, &key,
+       ipcp = rhashtable_lookup_fast(&ids->key_ht, &key,
                                              ipc_kht_params);
+       if (!ipcp)
+               return NULL;
 
-       if (ipcp) {
-               rcu_read_lock();
-               ipc_lock_object(ipcp);
-               return ipcp;
-       }
-
-       return NULL;
+       rcu_read_lock();
+       ipc_lock_object(ipcp);
+       return ipcp;
 }
 
-#ifdef CONFIG_CHECKPOINT_RESTORE
 /*
- * Specify desired id for next allocated IPC object.
+ * Insert new IPC object into idr tree, and set sequence number and id
+ * in the correct order.
+ * Especially:
+ * - the sequence number must be set before inserting the object into the idr,
+ *   because the sequence number is accessed without a lock.
+ * - the id can/must be set after inserting the object into the idr.
+ *   All accesses must be done after getting kern_ipc_perm.lock.
+ *
+ * The caller must own kern_ipc_perm.lock.of the new object.
+ * On error, the function returns a (negative) error code.
  */
-#define ipc_idr_alloc(ids, new)                                                \
-       idr_alloc(&(ids)->ipcs_idr, (new),                              \
-                 (ids)->next_id < 0 ? 0 : ipcid_to_idx((ids)->next_id),\
-                 0, GFP_NOWAIT)
-
-static inline int ipc_buildid(int id, struct ipc_ids *ids,
-                             struct kern_ipc_perm *new)
+static inline int ipc_idr_alloc(struct ipc_ids *ids, struct kern_ipc_perm *new)
 {
-       if (ids->next_id < 0) { /* default, behave as !CHECKPOINT_RESTORE */
+       int idx, next_id = -1;
+
+#ifdef CONFIG_CHECKPOINT_RESTORE
+       next_id = ids->next_id;
+       ids->next_id = -1;
+#endif
+
+       /*
+        * As soon as a new object is inserted into the idr,
+        * ipc_obtain_object_idr() or ipc_obtain_object_check() can find it,
+        * and the lockless preparations for ipc operations can start.
+        * This means especially: permission checks, audit calls, allocation
+        * of undo structures, ...
+        *
+        * Thus the object must be fully initialized, and if something fails,
+        * then the full tear-down sequence must be followed.
+        * (i.e.: set new->deleted, reduce refcount, call_rcu())
+        */
+
+       if (next_id < 0) { /* !CHECKPOINT_RESTORE or next_id is unset */
                new->seq = ids->seq++;
                if (ids->seq > IPCID_SEQ_MAX)
                        ids->seq = 0;
+               idx = idr_alloc(&ids->ipcs_idr, new, 0, 0, GFP_NOWAIT);
        } else {
-               new->seq = ipcid_to_seqx(ids->next_id);
-               ids->next_id = -1;
+               new->seq = ipcid_to_seqx(next_id);
+               idx = idr_alloc(&ids->ipcs_idr, new, ipcid_to_idx(next_id),
+                               0, GFP_NOWAIT);
        }
-
-       return SEQ_MULTIPLIER * new->seq + id;
+       if (idx >= 0)
+               new->id = SEQ_MULTIPLIER * new->seq + idx;
+       return idx;
 }
 
-#else
-#define ipc_idr_alloc(ids, new)                                        \
-       idr_alloc(&(ids)->ipcs_idr, (new), 0, 0, GFP_NOWAIT)
-
-static inline int ipc_buildid(int id, struct ipc_ids *ids,
-                             struct kern_ipc_perm *new)
-{
-       new->seq = ids->seq++;
-       if (ids->seq > IPCID_SEQ_MAX)
-               ids->seq = 0;
-
-       return SEQ_MULTIPLIER * new->seq + id;
-}
-
-#endif /* CONFIG_CHECKPOINT_RESTORE */
-
 /**
  * ipc_addid - add an ipc identifier
  * @ids: ipc identifier set
@@ -241,9 +237,11 @@ static inline int ipc_buildid(int id, struct ipc_ids *ids,
  * @limit: limit for the number of used ids
  *
  * Add an entry 'new' to the ipc ids idr. The permissions object is
- * initialised and the first free entry is set up and the id assigned
+ * initialised and the first free entry is set up and the index assigned
  * is returned. The 'new' entry is returned in a locked state on success.
+ *
  * On failure the entry is not locked and a negative err-code is returned.
+ * The caller must use ipc_rcu_putref() to free the identifier.
  *
  * Called with writer ipc_ids.rwsem held.
  */
@@ -251,19 +249,20 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int limit)
 {
        kuid_t euid;
        kgid_t egid;
-       int id, err;
+       int idx, err;
+
+       /* 1) Initialize the refcount so that ipc_rcu_putref works */
+       refcount_set(&new->refcount, 1);
 
        if (limit > IPCMNI)
                limit = IPCMNI;
 
-       if (!ids->tables_initialized || ids->in_use >= limit)
+       if (ids->in_use >= limit)
                return -ENOSPC;
 
        idr_preload(GFP_KERNEL);
 
-       refcount_set(&new->refcount, 1);
        spin_lock_init(&new->lock);
-       new->deleted = false;
        rcu_read_lock();
        spin_lock(&new->lock);
 
@@ -271,30 +270,30 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int limit)
        new->cuid = new->uid = euid;
        new->gid = new->cgid = egid;
 
-       id = ipc_idr_alloc(ids, new);
+       new->deleted = false;
+
+       idx = ipc_idr_alloc(ids, new);
        idr_preload_end();
 
-       if (id >= 0 && new->key != IPC_PRIVATE) {
+       if (idx >= 0 && new->key != IPC_PRIVATE) {
                err = rhashtable_insert_fast(&ids->key_ht, &new->khtnode,
                                             ipc_kht_params);
                if (err < 0) {
-                       idr_remove(&ids->ipcs_idr, id);
-                       id = err;
+                       idr_remove(&ids->ipcs_idr, idx);
+                       idx = err;
                }
        }
-       if (id < 0) {
+       if (idx < 0) {
+               new->deleted = true;
                spin_unlock(&new->lock);
                rcu_read_unlock();
-               return id;
+               return idx;
        }
 
        ids->in_use++;
-       if (id > ids->max_id)
-               ids->max_id = id;
-
-       new->id = ipc_buildid(id, ids, new);
-
-       return id;
+       if (idx > ids->max_idx)
+               ids->max_idx = idx;
+       return idx;
 }
 
 /**
@@ -432,20 +431,20 @@ static void ipc_kht_remove(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)
  */
 void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)
 {
-       int lid = ipcid_to_idx(ipcp->id);
+       int idx = ipcid_to_idx(ipcp->id);
 
-       idr_remove(&ids->ipcs_idr, lid);
+       idr_remove(&ids->ipcs_idr, idx);
        ipc_kht_remove(ids, ipcp);
        ids->in_use--;
        ipcp->deleted = true;
 
-       if (unlikely(lid == ids->max_id)) {
+       if (unlikely(idx == ids->max_idx)) {
                do {
-                       lid--;
-                       if (lid == -1)
+                       idx--;
+                       if (idx == -1)
                                break;
-               } while (!idr_find(&ids->ipcs_idr, lid));
-               ids->max_id = lid;
+               } while (!idr_find(&ids->ipcs_idr, idx));
+               ids->max_idx = idx;
        }
 }
 
@@ -463,7 +462,7 @@ void ipc_set_key_private(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)
        ipcp->key = IPC_PRIVATE;
 }
 
-int ipc_rcu_getref(struct kern_ipc_perm *ptr)
+bool ipc_rcu_getref(struct kern_ipc_perm *ptr)
 {
        return refcount_inc_not_zero(&ptr->refcount);
 }
@@ -565,61 +564,22 @@ void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out)
 struct kern_ipc_perm *ipc_obtain_object_idr(struct ipc_ids *ids, int id)
 {
        struct kern_ipc_perm *out;
-       int lid = ipcid_to_idx(id);
-
-       if (unlikely(!ids->tables_initialized))
-               return ERR_PTR(-EINVAL);
+       int idx = ipcid_to_idx(id);
 
-       out = idr_find(&ids->ipcs_idr, lid);
+       out = idr_find(&ids->ipcs_idr, idx);
        if (!out)
                return ERR_PTR(-EINVAL);
 
        return out;
 }
 
-/**
- * ipc_lock - lock an ipc structure without rwsem held
- * @ids: ipc identifier set
- * @id: ipc id to look for
- *
- * Look for an id in the ipc ids idr and lock the associated ipc object.
- *
- * The ipc object is locked on successful exit.
- */
-struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id)
-{
-       struct kern_ipc_perm *out;
-
-       rcu_read_lock();
-       out = ipc_obtain_object_idr(ids, id);
-       if (IS_ERR(out))
-               goto err;
-
-       spin_lock(&out->lock);
-
-       /*
-        * ipc_rmid() may have already freed the ID while ipc_lock()
-        * was spinning: here verify that the structure is still valid.
-        * Upon races with RMID, return -EIDRM, thus indicating that
-        * the ID points to a removed identifier.
-        */
-       if (ipc_valid_object(out))
-               return out;
-
-       spin_unlock(&out->lock);
-       out = ERR_PTR(-EIDRM);
-err:
-       rcu_read_unlock();
-       return out;
-}
-
 /**
  * ipc_obtain_object_check
  * @ids: ipc identifier set
  * @id: ipc id to look for
  *
- * Similar to ipc_obtain_object_idr() but also checks
- * the ipc object reference counter.
+ * Similar to ipc_obtain_object_idr() but also checks the ipc object
+ * sequence number.
  *
  * Call inside the RCU critical section.
  * The ipc object is *not* locked on exit.
@@ -677,7 +637,7 @@ int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out)
 }
 
 /**
- * ipcctl_pre_down_nolock - retrieve an ipc and check permissions for some IPC_XXX cmd
+ * ipcctl_obtain_check - retrieve an ipc object and check permissions
  * @ns:  ipc namespace
  * @ids:  the table of ids where to look for the ipc
  * @id:   the id of the ipc to retrieve
@@ -687,16 +647,16 @@ int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out)
  *
  * This function does some common audit and permissions check for some IPC_XXX
  * cmd and is called from semctl_down, shmctl_down and msgctl_down.
- * It must be called without any lock held and:
  *
- *   - retrieves the ipc with the given id in the given table.
+ * It:
+ *   - retrieves the ipc object with the given id in the given table.
  *   - performs some audit and permission check, depending on the given cmd
  *   - returns a pointer to the ipc object or otherwise, the corresponding
  *     error.
  *
  * Call holding the both the rwsem and the rcu read lock.
  */
-struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
+struct kern_ipc_perm *ipcctl_obtain_check(struct ipc_namespace *ns,
                                        struct ipc_ids *ids, int id, int cmd,
                                        struct ipc64_perm *perm, int extra_perm)
 {
index 0aba3230d0070ca45285e5075154a352030b59fb..0a159f69b3bbeb82440268a263c33be8d0dc71dd 100644 (file)
@@ -18,8 +18,8 @@
 #define IPCMNI 32768  /* <= MAX_INT limit for ipc arrays (including sysctl changes) */
 #define SEQ_MULTIPLIER (IPCMNI)
 
-int sem_init(void);
-int msg_init(void);
+void sem_init(void);
+void msg_init(void);
 void shm_init(void);
 
 struct ipc_namespace;
@@ -34,17 +34,17 @@ static inline void mq_put_mnt(struct ipc_namespace *ns) { }
 #endif
 
 #ifdef CONFIG_SYSVIPC
-int sem_init_ns(struct ipc_namespace *ns);
-int msg_init_ns(struct ipc_namespace *ns);
-int shm_init_ns(struct ipc_namespace *ns);
+void sem_init_ns(struct ipc_namespace *ns);
+void msg_init_ns(struct ipc_namespace *ns);
+void shm_init_ns(struct ipc_namespace *ns);
 
 void sem_exit_ns(struct ipc_namespace *ns);
 void msg_exit_ns(struct ipc_namespace *ns);
 void shm_exit_ns(struct ipc_namespace *ns);
 #else
-static inline int sem_init_ns(struct ipc_namespace *ns) { return 0; }
-static inline int msg_init_ns(struct ipc_namespace *ns) { return 0; }
-static inline int shm_init_ns(struct ipc_namespace *ns) { return 0; }
+static inline void sem_init_ns(struct ipc_namespace *ns) { }
+static inline void msg_init_ns(struct ipc_namespace *ns) { }
+static inline void shm_init_ns(struct ipc_namespace *ns) { }
 
 static inline void sem_exit_ns(struct ipc_namespace *ns) { }
 static inline void msg_exit_ns(struct ipc_namespace *ns) { }
@@ -83,7 +83,7 @@ struct ipc_ops {
 struct seq_file;
 struct ipc_ids;
 
-int ipc_init_ids(struct ipc_ids *);
+void ipc_init_ids(struct ipc_ids *ids);
 #ifdef CONFIG_PROC_FS
 void __init ipc_init_proc_interface(const char *path, const char *header,
                int ids, int (*show)(struct seq_file *, void *));
@@ -113,12 +113,12 @@ void ipc_set_key_private(struct ipc_ids *, struct kern_ipc_perm *);
 int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flg);
 
 /**
- * ipc_get_maxid - get the last assigned id
+ * ipc_get_maxidx - get the highest assigned index
  * @ids: ipc identifier set
  *
  * Called with ipc_ids.rwsem held for reading.
  */
-static inline int ipc_get_maxid(struct ipc_ids *ids)
+static inline int ipc_get_maxidx(struct ipc_ids *ids)
 {
        if (ids->in_use == 0)
                return -1;
@@ -126,7 +126,7 @@ static inline int ipc_get_maxid(struct ipc_ids *ids)
        if (ids->in_use == IPCMNI)
                return IPCMNI - 1;
 
-       return ids->max_id;
+       return ids->max_idx;
 }
 
 /*
@@ -138,17 +138,16 @@ static inline int ipc_get_maxid(struct ipc_ids *ids)
  * refcount is initialized by ipc_addid(), before that point call_rcu()
  * must be used.
  */
-int ipc_rcu_getref(struct kern_ipc_perm *ptr);
+bool ipc_rcu_getref(struct kern_ipc_perm *ptr);
 void ipc_rcu_putref(struct kern_ipc_perm *ptr,
                        void (*func)(struct rcu_head *head));
 
-struct kern_ipc_perm *ipc_lock(struct ipc_ids *, int);
 struct kern_ipc_perm *ipc_obtain_object_idr(struct ipc_ids *ids, int id);
 
 void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out);
 void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out);
 int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out);
-struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
+struct kern_ipc_perm *ipcctl_obtain_check(struct ipc_namespace *ns,
                                             struct ipc_ids *ids, int id, int cmd,
                                             struct ipc64_perm *perm, int extra_perm);
 
@@ -173,9 +172,9 @@ extern struct msg_msg *load_msg(const void __user *src, size_t len);
 extern struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst);
 extern int store_msg(void __user *dest, struct msg_msg *msg, size_t len);
 
-static inline int ipc_checkid(struct kern_ipc_perm *ipcp, int uid)
+static inline int ipc_checkid(struct kern_ipc_perm *ipcp, int id)
 {
-       return uid / SEQ_MULTIPLIER != ipcp->seq;
+       return ipcid_to_seqx(id) != ipcp->seq;
 }
 
 static inline void ipc_lock_object(struct kern_ipc_perm *perm)
index 04b8eda94e7d5f3f6c5b89655d808653c7479bbd..03cc59ee9c9536b885d605027af093c3dd0634ee 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/jhash.h>
 #include <linux/filter.h>
 #include <linux/rculist_nulls.h>
+#include <linux/random.h>
 #include <uapi/linux/btf.h>
 #include "percpu_freelist.h"
 #include "bpf_lru_list.h"
@@ -41,6 +42,7 @@ struct bpf_htab {
        atomic_t count; /* number of elements in this hashtable */
        u32 n_buckets;  /* number of hash buckets */
        u32 elem_size;  /* size of each element in bytes */
+       u32 hashrnd;
 };
 
 /* each htab element is struct htab_elem + key + value */
@@ -371,6 +373,7 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr)
        if (!htab->buckets)
                goto free_htab;
 
+       htab->hashrnd = get_random_int();
        for (i = 0; i < htab->n_buckets; i++) {
                INIT_HLIST_NULLS_HEAD(&htab->buckets[i].head, i);
                raw_spin_lock_init(&htab->buckets[i].lock);
@@ -402,9 +405,9 @@ free_htab:
        return ERR_PTR(err);
 }
 
-static inline u32 htab_map_hash(const void *key, u32 key_len)
+static inline u32 htab_map_hash(const void *key, u32 key_len, u32 hashrnd)
 {
-       return jhash(key, key_len, 0);
+       return jhash(key, key_len, hashrnd);
 }
 
 static inline struct bucket *__select_bucket(struct bpf_htab *htab, u32 hash)
@@ -470,7 +473,7 @@ static void *__htab_map_lookup_elem(struct bpf_map *map, void *key)
 
        key_size = map->key_size;
 
-       hash = htab_map_hash(key, key_size);
+       hash = htab_map_hash(key, key_size, htab->hashrnd);
 
        head = select_bucket(htab, hash);
 
@@ -597,7 +600,7 @@ static int htab_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
        if (!key)
                goto find_first_elem;
 
-       hash = htab_map_hash(key, key_size);
+       hash = htab_map_hash(key, key_size, htab->hashrnd);
 
        head = select_bucket(htab, hash);
 
@@ -824,7 +827,7 @@ static int htab_map_update_elem(struct bpf_map *map, void *key, void *value,
 
        key_size = map->key_size;
 
-       hash = htab_map_hash(key, key_size);
+       hash = htab_map_hash(key, key_size, htab->hashrnd);
 
        b = __select_bucket(htab, hash);
        head = &b->head;
@@ -880,7 +883,7 @@ static int htab_lru_map_update_elem(struct bpf_map *map, void *key, void *value,
 
        key_size = map->key_size;
 
-       hash = htab_map_hash(key, key_size);
+       hash = htab_map_hash(key, key_size, htab->hashrnd);
 
        b = __select_bucket(htab, hash);
        head = &b->head;
@@ -945,7 +948,7 @@ static int __htab_percpu_map_update_elem(struct bpf_map *map, void *key,
 
        key_size = map->key_size;
 
-       hash = htab_map_hash(key, key_size);
+       hash = htab_map_hash(key, key_size, htab->hashrnd);
 
        b = __select_bucket(htab, hash);
        head = &b->head;
@@ -998,7 +1001,7 @@ static int __htab_lru_percpu_map_update_elem(struct bpf_map *map, void *key,
 
        key_size = map->key_size;
 
-       hash = htab_map_hash(key, key_size);
+       hash = htab_map_hash(key, key_size, htab->hashrnd);
 
        b = __select_bucket(htab, hash);
        head = &b->head;
@@ -1071,7 +1074,7 @@ static int htab_map_delete_elem(struct bpf_map *map, void *key)
 
        key_size = map->key_size;
 
-       hash = htab_map_hash(key, key_size);
+       hash = htab_map_hash(key, key_size, htab->hashrnd);
        b = __select_bucket(htab, hash);
        head = &b->head;
 
@@ -1103,7 +1106,7 @@ static int htab_lru_map_delete_elem(struct bpf_map *map, void *key)
 
        key_size = map->key_size;
 
-       hash = htab_map_hash(key, key_size);
+       hash = htab_map_hash(key, key_size, htab->hashrnd);
        b = __select_bucket(htab, hash);
        head = &b->head;
 
index 98e621a29e8e6953ec9dec5b4cb6f8559dd750d3..488ef9663c01f3b4d2cc44b9ca88863ced2860e7 100644 (file)
@@ -236,7 +236,7 @@ static int bpf_tcp_init(struct sock *sk)
 }
 
 static void smap_release_sock(struct smap_psock *psock, struct sock *sock);
-static int free_start_sg(struct sock *sk, struct sk_msg_buff *md);
+static int free_start_sg(struct sock *sk, struct sk_msg_buff *md, bool charge);
 
 static void bpf_tcp_release(struct sock *sk)
 {
@@ -248,7 +248,7 @@ static void bpf_tcp_release(struct sock *sk)
                goto out;
 
        if (psock->cork) {
-               free_start_sg(psock->sock, psock->cork);
+               free_start_sg(psock->sock, psock->cork, true);
                kfree(psock->cork);
                psock->cork = NULL;
        }
@@ -330,14 +330,14 @@ static void bpf_tcp_close(struct sock *sk, long timeout)
        close_fun = psock->save_close;
 
        if (psock->cork) {
-               free_start_sg(psock->sock, psock->cork);
+               free_start_sg(psock->sock, psock->cork, true);
                kfree(psock->cork);
                psock->cork = NULL;
        }
 
        list_for_each_entry_safe(md, mtmp, &psock->ingress, list) {
                list_del(&md->list);
-               free_start_sg(psock->sock, md);
+               free_start_sg(psock->sock, md, true);
                kfree(md);
        }
 
@@ -369,7 +369,7 @@ static void bpf_tcp_close(struct sock *sk, long timeout)
                        /* If another thread deleted this object skip deletion.
                         * The refcnt on psock may or may not be zero.
                         */
-                       if (l) {
+                       if (l && l == link) {
                                hlist_del_rcu(&link->hash_node);
                                smap_release_sock(psock, link->sk);
                                free_htab_elem(htab, link);
@@ -570,14 +570,16 @@ static void free_bytes_sg(struct sock *sk, int bytes,
        md->sg_start = i;
 }
 
-static int free_sg(struct sock *sk, int start, struct sk_msg_buff *md)
+static int free_sg(struct sock *sk, int start,
+                  struct sk_msg_buff *md, bool charge)
 {
        struct scatterlist *sg = md->sg_data;
        int i = start, free = 0;
 
        while (sg[i].length) {
                free += sg[i].length;
-               sk_mem_uncharge(sk, sg[i].length);
+               if (charge)
+                       sk_mem_uncharge(sk, sg[i].length);
                if (!md->skb)
                        put_page(sg_page(&sg[i]));
                sg[i].length = 0;
@@ -594,9 +596,9 @@ static int free_sg(struct sock *sk, int start, struct sk_msg_buff *md)
        return free;
 }
 
-static int free_start_sg(struct sock *sk, struct sk_msg_buff *md)
+static int free_start_sg(struct sock *sk, struct sk_msg_buff *md, bool charge)
 {
-       int free = free_sg(sk, md->sg_start, md);
+       int free = free_sg(sk, md->sg_start, md, charge);
 
        md->sg_start = md->sg_end;
        return free;
@@ -604,7 +606,7 @@ static int free_start_sg(struct sock *sk, struct sk_msg_buff *md)
 
 static int free_curr_sg(struct sock *sk, struct sk_msg_buff *md)
 {
-       return free_sg(sk, md->sg_curr, md);
+       return free_sg(sk, md->sg_curr, md, true);
 }
 
 static int bpf_map_msg_verdict(int _rc, struct sk_msg_buff *md)
@@ -718,7 +720,7 @@ static int bpf_tcp_ingress(struct sock *sk, int apply_bytes,
                list_add_tail(&r->list, &psock->ingress);
                sk->sk_data_ready(sk);
        } else {
-               free_start_sg(sk, r);
+               free_start_sg(sk, r, true);
                kfree(r);
        }
 
@@ -752,14 +754,10 @@ static int bpf_tcp_sendmsg_do_redirect(struct sock *sk, int send,
                release_sock(sk);
        }
        smap_release_sock(psock, sk);
-       if (unlikely(err))
-               goto out;
-       return 0;
+       return err;
 out_rcu:
        rcu_read_unlock();
-out:
-       free_bytes_sg(NULL, send, md, false);
-       return err;
+       return 0;
 }
 
 static inline void bpf_md_init(struct smap_psock *psock)
@@ -822,7 +820,7 @@ more_data:
        case __SK_PASS:
                err = bpf_tcp_push(sk, send, m, flags, true);
                if (unlikely(err)) {
-                       *copied -= free_start_sg(sk, m);
+                       *copied -= free_start_sg(sk, m, true);
                        break;
                }
 
@@ -845,16 +843,17 @@ more_data:
                lock_sock(sk);
 
                if (unlikely(err < 0)) {
-                       free_start_sg(sk, m);
+                       int free = free_start_sg(sk, m, false);
+
                        psock->sg_size = 0;
                        if (!cork)
-                               *copied -= send;
+                               *copied -= free;
                } else {
                        psock->sg_size -= send;
                }
 
                if (cork) {
-                       free_start_sg(sk, m);
+                       free_start_sg(sk, m, true);
                        psock->sg_size = 0;
                        kfree(m);
                        m = NULL;
@@ -912,6 +911,8 @@ static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 
        if (unlikely(flags & MSG_ERRQUEUE))
                return inet_recv_error(sk, msg, len, addr_len);
+       if (!skb_queue_empty(&sk->sk_receive_queue))
+               return tcp_recvmsg(sk, msg, len, nonblock, flags, addr_len);
 
        rcu_read_lock();
        psock = smap_psock_sk(sk);
@@ -922,9 +923,6 @@ static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
                goto out;
        rcu_read_unlock();
 
-       if (!skb_queue_empty(&sk->sk_receive_queue))
-               return tcp_recvmsg(sk, msg, len, nonblock, flags, addr_len);
-
        lock_sock(sk);
 bytes_ready:
        while (copied != len) {
@@ -1122,7 +1120,7 @@ wait_for_memory:
                err = sk_stream_wait_memory(sk, &timeo);
                if (err) {
                        if (m && m != psock->cork)
-                               free_start_sg(sk, m);
+                               free_start_sg(sk, m, true);
                        goto out_err;
                }
        }
@@ -1427,12 +1425,15 @@ out:
 static void smap_write_space(struct sock *sk)
 {
        struct smap_psock *psock;
+       void (*write_space)(struct sock *sk);
 
        rcu_read_lock();
        psock = smap_psock_sk(sk);
        if (likely(psock && test_bit(SMAP_TX_RUNNING, &psock->state)))
                schedule_work(&psock->tx_work);
+       write_space = psock->save_write_space;
        rcu_read_unlock();
+       write_space(sk);
 }
 
 static void smap_stop_sock(struct smap_psock *psock, struct sock *sk)
@@ -1461,10 +1462,16 @@ static void smap_destroy_psock(struct rcu_head *rcu)
        schedule_work(&psock->gc_work);
 }
 
+static bool psock_is_smap_sk(struct sock *sk)
+{
+       return inet_csk(sk)->icsk_ulp_ops == &bpf_tcp_ulp_ops;
+}
+
 static void smap_release_sock(struct smap_psock *psock, struct sock *sock)
 {
        if (refcount_dec_and_test(&psock->refcnt)) {
-               tcp_cleanup_ulp(sock);
+               if (psock_is_smap_sk(sock))
+                       tcp_cleanup_ulp(sock);
                write_lock_bh(&sock->sk_callback_lock);
                smap_stop_sock(psock, sock);
                write_unlock_bh(&sock->sk_callback_lock);
@@ -1578,13 +1585,13 @@ static void smap_gc_work(struct work_struct *w)
                bpf_prog_put(psock->bpf_tx_msg);
 
        if (psock->cork) {
-               free_start_sg(psock->sock, psock->cork);
+               free_start_sg(psock->sock, psock->cork, true);
                kfree(psock->cork);
        }
 
        list_for_each_entry_safe(md, mtmp, &psock->ingress, list) {
                list_del(&md->list);
-               free_start_sg(psock->sock, md);
+               free_start_sg(psock->sock, md, true);
                kfree(md);
        }
 
@@ -1891,6 +1898,10 @@ static int __sock_map_ctx_update_elem(struct bpf_map *map,
         * doesn't update user data.
         */
        if (psock) {
+               if (!psock_is_smap_sk(sock)) {
+                       err = -EBUSY;
+                       goto out_progs;
+               }
                if (READ_ONCE(psock->bpf_parse) && parse) {
                        err = -EBUSY;
                        goto out_progs;
@@ -2140,7 +2151,9 @@ static struct bpf_map *sock_hash_alloc(union bpf_attr *attr)
                return ERR_PTR(-EPERM);
 
        /* check sanity of attributes */
-       if (attr->max_entries == 0 || attr->value_size != 4 ||
+       if (attr->max_entries == 0 ||
+           attr->key_size == 0 ||
+           attr->value_size != 4 ||
            attr->map_flags & ~SOCK_CREATE_FLAG_MASK)
                return ERR_PTR(-EINVAL);
 
@@ -2267,8 +2280,10 @@ static struct htab_elem *alloc_sock_hash_elem(struct bpf_htab *htab,
        }
        l_new = kmalloc_node(htab->elem_size, GFP_ATOMIC | __GFP_NOWARN,
                             htab->map.numa_node);
-       if (!l_new)
+       if (!l_new) {
+               atomic_dec(&htab->count);
                return ERR_PTR(-ENOMEM);
+       }
 
        memcpy(l_new->key, key, key_size);
        l_new->sk = sk;
index 77ff1cd6a25234c5b2f412c74da8e95eb539b8b6..75568fcf2180dd577f5e8e4903e30516d3c987db 100644 (file)
@@ -8,6 +8,32 @@
 #include <linux/list.h>
 #include <linux/refcount.h>
 
+#define TRACE_CGROUP_PATH_LEN 1024
+extern spinlock_t trace_cgroup_path_lock;
+extern char trace_cgroup_path[TRACE_CGROUP_PATH_LEN];
+
+/*
+ * cgroup_path() takes a spin lock. It is good practice not to take
+ * spin locks within trace point handlers, as they are mostly hidden
+ * from normal view. As cgroup_path() can take the kernfs_rename_lock
+ * spin lock, it is best to not call that function from the trace event
+ * handler.
+ *
+ * Note: trace_cgroup_##type##_enabled() is a static branch that will only
+ *       be set when the trace event is enabled.
+ */
+#define TRACE_CGROUP_PATH(type, cgrp, ...)                             \
+       do {                                                            \
+               if (trace_cgroup_##type##_enabled()) {                  \
+                       spin_lock(&trace_cgroup_path_lock);             \
+                       cgroup_path(cgrp, trace_cgroup_path,            \
+                                   TRACE_CGROUP_PATH_LEN);             \
+                       trace_cgroup_##type(cgrp, trace_cgroup_path,    \
+                                           ##__VA_ARGS__);             \
+                       spin_unlock(&trace_cgroup_path_lock);           \
+               }                                                       \
+       } while (0)
+
 /*
  * A cgroup can be associated with multiple css_sets as different tasks may
  * belong to different cgroups on different hierarchies.  In the other
index 8b4f0768efd62244d3939b985059963371e04d63..51063e7a93c28a7c0ad5f8cca34072dffb85e650 100644 (file)
@@ -135,7 +135,7 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from)
                if (task) {
                        ret = cgroup_migrate(task, false, &mgctx);
                        if (!ret)
-                               trace_cgroup_transfer_tasks(to, task, false);
+                               TRACE_CGROUP_PATH(transfer_tasks, to, task, false);
                        put_task_struct(task);
                }
        } while (task && !ret);
@@ -865,7 +865,7 @@ static int cgroup1_rename(struct kernfs_node *kn, struct kernfs_node *new_parent
 
        ret = kernfs_rename(kn, new_parent, new_name_str);
        if (!ret)
-               trace_cgroup_rename(cgrp);
+               TRACE_CGROUP_PATH(rename, cgrp);
 
        mutex_unlock(&cgroup_mutex);
 
index 35cf3d71f8aaf4b7efcdc241953abe2108b58f6a..aae10baf1902af2099292856bf2e299f14edfd1f 100644 (file)
@@ -83,6 +83,9 @@ EXPORT_SYMBOL_GPL(cgroup_mutex);
 EXPORT_SYMBOL_GPL(css_set_lock);
 #endif
 
+DEFINE_SPINLOCK(trace_cgroup_path_lock);
+char trace_cgroup_path[TRACE_CGROUP_PATH_LEN];
+
 /*
  * Protects cgroup_idr and css_idr so that IDs can be released without
  * grabbing cgroup_mutex.
@@ -2638,7 +2641,7 @@ int cgroup_attach_task(struct cgroup *dst_cgrp, struct task_struct *leader,
        cgroup_migrate_finish(&mgctx);
 
        if (!ret)
-               trace_cgroup_attach_task(dst_cgrp, leader, threadgroup);
+               TRACE_CGROUP_PATH(attach_task, dst_cgrp, leader, threadgroup);
 
        return ret;
 }
@@ -4636,7 +4639,7 @@ static void css_release_work_fn(struct work_struct *work)
                struct cgroup *tcgrp;
 
                /* cgroup release path */
-               trace_cgroup_release(cgrp);
+               TRACE_CGROUP_PATH(release, cgrp);
 
                if (cgroup_on_dfl(cgrp))
                        cgroup_rstat_flush(cgrp);
@@ -4979,7 +4982,7 @@ int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name, umode_t mode)
        if (ret)
                goto out_destroy;
 
-       trace_cgroup_mkdir(cgrp);
+       TRACE_CGROUP_PATH(mkdir, cgrp);
 
        /* let's create and online css's */
        kernfs_activate(kn);
@@ -5167,9 +5170,8 @@ int cgroup_rmdir(struct kernfs_node *kn)
                return 0;
 
        ret = cgroup_destroy_locked(cgrp);
-
        if (!ret)
-               trace_cgroup_rmdir(cgrp);
+               TRACE_CGROUP_PATH(rmdir, cgrp);
 
        cgroup_kn_unlock(kn);
        return ret;
index ed44d7d34c2d9bfc08093af4854dc78bf7232b21..0097acec1c717dee6948e50b57ab4c4bb0c15ac7 100644 (file)
@@ -102,8 +102,6 @@ static inline void cpuhp_lock_release(bool bringup) { }
  * @name:      Name of the step
  * @startup:   Startup function of the step
  * @teardown:  Teardown function of the step
- * @skip_onerr:        Do not invoke the functions on error rollback
- *             Will go away once the notifiers are gone
  * @cant_stop: Bringup/teardown can't be stopped at this step
  */
 struct cpuhp_step {
@@ -119,7 +117,6 @@ struct cpuhp_step {
                                         struct hlist_node *node);
        } teardown;
        struct hlist_head       list;
-       bool                    skip_onerr;
        bool                    cant_stop;
        bool                    multi_instance;
 };
@@ -550,12 +547,8 @@ static int bringup_cpu(unsigned int cpu)
 
 static void undo_cpu_up(unsigned int cpu, struct cpuhp_cpu_state *st)
 {
-       for (st->state--; st->state > st->target; st->state--) {
-               struct cpuhp_step *step = cpuhp_get_step(st->state);
-
-               if (!step->skip_onerr)
-                       cpuhp_invoke_callback(cpu, st->state, false, NULL, NULL);
-       }
+       for (st->state--; st->state > st->target; st->state--)
+               cpuhp_invoke_callback(cpu, st->state, false, NULL, NULL);
 }
 
 static int cpuhp_up_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,
@@ -614,15 +607,15 @@ static void cpuhp_thread_fun(unsigned int cpu)
        bool bringup = st->bringup;
        enum cpuhp_state state;
 
+       if (WARN_ON_ONCE(!st->should_run))
+               return;
+
        /*
         * ACQUIRE for the cpuhp_should_run() load of ->should_run. Ensures
         * that if we see ->should_run we also see the rest of the state.
         */
        smp_mb();
 
-       if (WARN_ON_ONCE(!st->should_run))
-               return;
-
        cpuhp_lock_acquire(bringup);
 
        if (st->single) {
@@ -644,12 +637,6 @@ static void cpuhp_thread_fun(unsigned int cpu)
 
        WARN_ON_ONCE(!cpuhp_is_ap_state(state));
 
-       if (st->rollback) {
-               struct cpuhp_step *step = cpuhp_get_step(state);
-               if (step->skip_onerr)
-                       goto next;
-       }
-
        if (cpuhp_is_atomic_state(state)) {
                local_irq_disable();
                st->result = cpuhp_invoke_callback(cpu, state, bringup, st->node, &st->last);
@@ -673,7 +660,6 @@ static void cpuhp_thread_fun(unsigned int cpu)
                st->should_run = false;
        }
 
-next:
        cpuhp_lock_release(bringup);
 
        if (!st->should_run)
@@ -916,12 +902,8 @@ void cpuhp_report_idle_dead(void)
 
 static void undo_cpu_down(unsigned int cpu, struct cpuhp_cpu_state *st)
 {
-       for (st->state++; st->state < st->target; st->state++) {
-               struct cpuhp_step *step = cpuhp_get_step(st->state);
-
-               if (!step->skip_onerr)
-                       cpuhp_invoke_callback(cpu, st->state, true, NULL, NULL);
-       }
+       for (st->state++; st->state < st->target; st->state++)
+               cpuhp_invoke_callback(cpu, st->state, true, NULL, NULL);
 }
 
 static int cpuhp_down_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,
@@ -934,7 +916,8 @@ static int cpuhp_down_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,
                ret = cpuhp_invoke_callback(cpu, st->state, false, NULL, NULL);
                if (ret) {
                        st->target = prev_state;
-                       undo_cpu_down(cpu, st);
+                       if (st->state < prev_state)
+                               undo_cpu_down(cpu, st);
                        break;
                }
        }
@@ -987,7 +970,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen,
         * to do the further cleanups.
         */
        ret = cpuhp_down_callbacks(cpu, st, target);
-       if (ret && st->state > CPUHP_TEARDOWN_CPU && st->state < prev_state) {
+       if (ret && st->state == CPUHP_TEARDOWN_CPU && st->state < prev_state) {
                cpuhp_reset_state(st, prev_state);
                __cpuhp_kick_ap(st);
        }
index b66aced5e8c2e3479efe16df7cdfc73044d4e77b..933cb3e45b987df1ba52d7fa4afc312823d3d745 100644 (file)
@@ -14,8 +14,8 @@
 #include <asm/sections.h>
 
 /* vmcoreinfo stuff */
-static unsigned char *vmcoreinfo_data;
-static size_t vmcoreinfo_size;
+unsigned char *vmcoreinfo_data;
+size_t vmcoreinfo_size;
 u32 *vmcoreinfo_note;
 
 /* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
@@ -344,7 +344,7 @@ void crash_save_vmcoreinfo(void)
        if (vmcoreinfo_data_safecopy)
                vmcoreinfo_data = vmcoreinfo_data_safecopy;
 
-       vmcoreinfo_append_str("CRASHTIME=%ld\n", get_seconds());
+       vmcoreinfo_append_str("CRASHTIME=%lld\n", ktime_get_real_seconds());
        update_vmcoreinfo_note();
 }
 
@@ -401,7 +401,7 @@ static int __init crash_save_vmcoreinfo_init(void)
        VMCOREINFO_SYMBOL(init_uts_ns);
        VMCOREINFO_SYMBOL(node_online_map);
 #ifdef CONFIG_MMU
-       VMCOREINFO_SYMBOL(swapper_pg_dir);
+       VMCOREINFO_SYMBOL_ARRAY(swapper_pg_dir);
 #endif
        VMCOREINFO_SYMBOL(_stext);
        VMCOREINFO_SYMBOL(vmap_area_list);
index 1c35b7b945d034d320fb942109bb218c9c1eff8c..de87b0282e7420feaf4282e7ba835074b61512a7 100644 (file)
@@ -168,7 +168,7 @@ int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
 int dma_direct_supported(struct device *dev, u64 mask)
 {
 #ifdef CONFIG_ZONE_DMA
-       if (mask < DMA_BIT_MASK(ARCH_ZONE_DMA_BITS))
+       if (mask < phys_to_dma(dev, DMA_BIT_MASK(ARCH_ZONE_DMA_BITS)))
                return 0;
 #else
        /*
@@ -177,7 +177,7 @@ int dma_direct_supported(struct device *dev, u64 mask)
         * memory, or by providing a ZONE_DMA32.  If neither is the case, the
         * architecture needs to use an IOMMU instead of the direct mapping.
         */
-       if (mask < DMA_BIT_MASK(32))
+       if (mask < phys_to_dma(dev, DMA_BIT_MASK(32)))
                return 0;
 #endif
        /*
index c187aa3df3c8b789c23cceaf5214bc033fa3e2c9..24a77c34e9adbcda4bcb7bd6991b1bc2efbaf3e5 100644 (file)
@@ -4,7 +4,7 @@
  *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
  *  Copyright (C) 2008-2011 Red Hat, Inc., Ingo Molnar
  *  Copyright (C) 2008-2011 Red Hat, Inc., Peter Zijlstra
- *  Copyright  ©  2009 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
+ *  Copyright  Â©  2009 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
  *
  * For licensing details see kernel-base/COPYING
  */
index 80f456ec5d89013ac1d2477f5e38d9fdde739739..2a62b96600ad91dede076a2dc8ad4e7fc16afe09 100644 (file)
@@ -1334,7 +1334,7 @@ static u32 perf_event_pid_type(struct perf_event *event, struct task_struct *p,
 
 static u32 perf_event_pid(struct perf_event *event, struct task_struct *p)
 {
-       return perf_event_pid_type(event, p, __PIDTYPE_TGID);
+       return perf_event_pid_type(event, p, PIDTYPE_TGID);
 }
 
 static u32 perf_event_tid(struct perf_event *event, struct task_struct *p)
index aed1ba56995440b6640c530f0332f1f4ce28b220..3207a4d26849ec3e31b0bee98a8ed8db111e8cfd 100644 (file)
@@ -299,8 +299,8 @@ static int verify_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t
  * Called with mm->mmap_sem held for write.
  * Return 0 (success) or a negative errno.
  */
-int uprobe_write_opcode(struct mm_struct *mm, unsigned long vaddr,
-                       uprobe_opcode_t opcode)
+int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
+                       unsigned long vaddr, uprobe_opcode_t opcode)
 {
        struct page *old_page, *new_page;
        struct vm_area_struct *vma;
@@ -351,7 +351,7 @@ put_old:
  */
 int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr)
 {
-       return uprobe_write_opcode(mm, vaddr, UPROBE_SWBP_INSN);
+       return uprobe_write_opcode(auprobe, mm, vaddr, UPROBE_SWBP_INSN);
 }
 
 /**
@@ -366,7 +366,8 @@ int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned
 int __weak
 set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr)
 {
-       return uprobe_write_opcode(mm, vaddr, *(uprobe_opcode_t *)&auprobe->insn);
+       return uprobe_write_opcode(auprobe, mm, vaddr,
+                       *(uprobe_opcode_t *)&auprobe->insn);
 }
 
 static struct uprobe *get_uprobe(struct uprobe *uprobe)
@@ -840,13 +841,8 @@ register_for_each_vma(struct uprobe *uprobe, struct uprobe_consumer *new)
        return err;
 }
 
-static int __uprobe_register(struct uprobe *uprobe, struct uprobe_consumer *uc)
-{
-       consumer_add(uprobe, uc);
-       return register_for_each_vma(uprobe, uc);
-}
-
-static void __uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *uc)
+static void
+__uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *uc)
 {
        int err;
 
@@ -860,24 +856,46 @@ static void __uprobe_unregister(struct uprobe *uprobe, struct uprobe_consumer *u
 }
 
 /*
- * uprobe_register - register a probe
+ * uprobe_unregister - unregister an already registered probe.
+ * @inode: the file in which the probe has to be removed.
+ * @offset: offset from the start of the file.
+ * @uc: identify which probe if multiple probes are colocated.
+ */
+void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)
+{
+       struct uprobe *uprobe;
+
+       uprobe = find_uprobe(inode, offset);
+       if (WARN_ON(!uprobe))
+               return;
+
+       down_write(&uprobe->register_rwsem);
+       __uprobe_unregister(uprobe, uc);
+       up_write(&uprobe->register_rwsem);
+       put_uprobe(uprobe);
+}
+EXPORT_SYMBOL_GPL(uprobe_unregister);
+
+/*
+ * __uprobe_register - register a probe
  * @inode: the file in which the probe has to be placed.
  * @offset: offset from the start of the file.
  * @uc: information on howto handle the probe..
  *
- * Apart from the access refcount, uprobe_register() takes a creation
+ * Apart from the access refcount, __uprobe_register() takes a creation
  * refcount (thro alloc_uprobe) if and only if this @uprobe is getting
  * inserted into the rbtree (i.e first consumer for a @inode:@offset
  * tuple).  Creation refcount stops uprobe_unregister from freeing the
  * @uprobe even before the register operation is complete. Creation
  * refcount is released when the last @uc for the @uprobe
- * unregisters. Caller of uprobe_register() is required to keep @inode
+ * unregisters. Caller of __uprobe_register() is required to keep @inode
  * (and the containing mount) referenced.
  *
  * Return errno if it cannot successully install probes
  * else return 0 (success)
  */
-int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)
+static int __uprobe_register(struct inode *inode, loff_t offset,
+                            struct uprobe_consumer *uc)
 {
        struct uprobe *uprobe;
        int ret;
@@ -904,7 +922,8 @@ int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *
        down_write(&uprobe->register_rwsem);
        ret = -EAGAIN;
        if (likely(uprobe_is_active(uprobe))) {
-               ret = __uprobe_register(uprobe, uc);
+               consumer_add(uprobe, uc);
+               ret = register_for_each_vma(uprobe, uc);
                if (ret)
                        __uprobe_unregister(uprobe, uc);
        }
@@ -915,6 +934,12 @@ int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *
                goto retry;
        return ret;
 }
+
+int uprobe_register(struct inode *inode, loff_t offset,
+                   struct uprobe_consumer *uc)
+{
+       return __uprobe_register(inode, offset, uc);
+}
 EXPORT_SYMBOL_GPL(uprobe_register);
 
 /*
@@ -946,27 +971,6 @@ int uprobe_apply(struct inode *inode, loff_t offset,
        return ret;
 }
 
-/*
- * uprobe_unregister - unregister an already registered probe.
- * @inode: the file in which the probe has to be removed.
- * @offset: offset from the start of the file.
- * @uc: identify which probe if multiple probes are colocated.
- */
-void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)
-{
-       struct uprobe *uprobe;
-
-       uprobe = find_uprobe(inode, offset);
-       if (WARN_ON(!uprobe))
-               return;
-
-       down_write(&uprobe->register_rwsem);
-       __uprobe_unregister(uprobe, uc);
-       up_write(&uprobe->register_rwsem);
-       put_uprobe(uprobe);
-}
-EXPORT_SYMBOL_GPL(uprobe_unregister);
-
 static int unapply_uprobe(struct uprobe *uprobe, struct mm_struct *mm)
 {
        struct vm_area_struct *vma;
index c3c7ac5601140961563534441908b52ced5a557c..0e21e6d21f35f884f5b89b4237bd0be4f2b8a085 100644 (file)
@@ -73,6 +73,7 @@ static void __unhash_process(struct task_struct *p, bool group_dead)
        nr_threads--;
        detach_pid(p, PIDTYPE_PID);
        if (group_dead) {
+               detach_pid(p, PIDTYPE_TGID);
                detach_pid(p, PIDTYPE_PGID);
                detach_pid(p, PIDTYPE_SID);
 
@@ -680,7 +681,8 @@ static void forget_original_parent(struct task_struct *father,
                                t->parent = t->real_parent;
                        if (t->pdeath_signal)
                                group_send_sig_info(t->pdeath_signal,
-                                                   SEND_SIG_NOINFO, t);
+                                                   SEND_SIG_NOINFO, t,
+                                                   PIDTYPE_TGID);
                }
                /*
                 * If this is a threaded reparent there is no need to
@@ -1001,14 +1003,6 @@ struct wait_opts {
        int                     notask_error;
 };
 
-static inline
-struct pid *task_pid_type(struct task_struct *task, enum pid_type type)
-{
-       if (type != PIDTYPE_PID)
-               task = task->group_leader;
-       return task->pids[type].pid;
-}
-
 static int eligible_pid(struct wait_opts *wo, struct task_struct *p)
 {
        return  wo->wo_type == PIDTYPE_MAX ||
index 5ee74c113381b1959b27bb24940ff05c9221bbc2..f0b58479534f07dfd55d57a117b4055d80c829b5 100644 (file)
@@ -310,8 +310,9 @@ static struct kmem_cache *mm_cachep;
 
 struct vm_area_struct *vm_area_alloc(struct mm_struct *mm)
 {
-       struct vm_area_struct *vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
+       struct vm_area_struct *vma;
 
+       vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
        if (vma)
                vma_init(vma, mm);
        return vma;
@@ -549,8 +550,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
                        goto out;
        }
        /* a new mm has just been created */
-       arch_dup_mmap(oldmm, mm);
-       retval = 0;
+       retval = arch_dup_mmap(oldmm, mm);
 out:
        up_write(&mm->mmap_sem);
        flush_tlb_mm(oldmm);
@@ -1301,6 +1301,7 @@ static int copy_mm(unsigned long clone_flags, struct task_struct *tsk)
        tsk->nvcsw = tsk->nivcsw = 0;
 #ifdef CONFIG_DETECT_HUNG_TASK
        tsk->last_switch_count = tsk->nvcsw + tsk->nivcsw;
+       tsk->last_switch_time = 0;
 #endif
 
        tsk->mm = NULL;
@@ -1425,7 +1426,9 @@ static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)
                return -ENOMEM;
 
        atomic_set(&sig->count, 1);
+       spin_lock_irq(&current->sighand->siglock);
        memcpy(sig->action, current->sighand->action, sizeof(sig->action));
+       spin_unlock_irq(&current->sighand->siglock);
        return 0;
 }
 
@@ -1487,6 +1490,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
        init_waitqueue_head(&sig->wait_chldexit);
        sig->curr_target = tsk;
        init_sigpending(&sig->shared_pending);
+       INIT_HLIST_HEAD(&sig->multiprocess);
        seqlock_init(&sig->stats_lock);
        prev_cputime_init(&sig->prev_cputime);
 
@@ -1580,10 +1584,22 @@ static void posix_cpu_timers_init(struct task_struct *tsk)
 static inline void posix_cpu_timers_init(struct task_struct *tsk) { }
 #endif
 
+static inline void init_task_pid_links(struct task_struct *task)
+{
+       enum pid_type type;
+
+       for (type = PIDTYPE_PID; type < PIDTYPE_MAX; ++type) {
+               INIT_HLIST_NODE(&task->pid_links[type]);
+       }
+}
+
 static inline void
 init_task_pid(struct task_struct *task, enum pid_type type, struct pid *pid)
 {
-        task->pids[type].pid = pid;
+       if (type == PIDTYPE_PID)
+               task->thread_pid = pid;
+       else
+               task->signal->pids[type] = pid;
 }
 
 static inline void rcu_copy_process(struct task_struct *p)
@@ -1621,6 +1637,7 @@ static __latent_entropy struct task_struct *copy_process(
 {
        int retval;
        struct task_struct *p;
+       struct multiprocess_signals delayed;
 
        /*
         * Don't allow sharing the root directory with processes in a different
@@ -1668,6 +1685,24 @@ static __latent_entropy struct task_struct *copy_process(
                        return ERR_PTR(-EINVAL);
        }
 
+       /*
+        * Force any signals received before this point to be delivered
+        * before the fork happens.  Collect up signals sent to multiple
+        * processes that happen during the fork and delay them so that
+        * they appear to happen after the fork.
+        */
+       sigemptyset(&delayed.signal);
+       INIT_HLIST_NODE(&delayed.node);
+
+       spin_lock_irq(&current->sighand->siglock);
+       if (!(clone_flags & CLONE_THREAD))
+               hlist_add_head(&delayed.node, &current->signal->multiprocess);
+       recalc_sigpending();
+       spin_unlock_irq(&current->sighand->siglock);
+       retval = -ERESTARTNOINTR;
+       if (signal_pending(current))
+               goto fork_out;
+
        retval = -ENOMEM;
        p = dup_task_struct(current, node);
        if (!p)
@@ -1941,29 +1976,26 @@ static __latent_entropy struct task_struct *copy_process(
 
        rseq_fork(p, clone_flags);
 
-       /*
-        * Process group and session signals need to be delivered to just the
-        * parent before the fork or both the parent and the child after the
-        * fork. Restart if a signal comes in before we add the new process to
-        * it's process group.
-        * A fatal signal pending means that current will exit, so the new
-        * thread can't slip out of an OOM kill (or normal SIGKILL).
-       */
-       recalc_sigpending();
-       if (signal_pending(current)) {
-               retval = -ERESTARTNOINTR;
-               goto bad_fork_cancel_cgroup;
-       }
+       /* Don't start children in a dying pid namespace */
        if (unlikely(!(ns_of_pid(pid)->pid_allocated & PIDNS_ADDING))) {
                retval = -ENOMEM;
                goto bad_fork_cancel_cgroup;
        }
 
+       /* Let kill terminate clone/fork in the middle */
+       if (fatal_signal_pending(current)) {
+               retval = -EINTR;
+               goto bad_fork_cancel_cgroup;
+       }
+
+
+       init_task_pid_links(p);
        if (likely(p->pid)) {
                ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
 
                init_task_pid(p, PIDTYPE_PID, pid);
                if (thread_group_leader(p)) {
+                       init_task_pid(p, PIDTYPE_TGID, pid);
                        init_task_pid(p, PIDTYPE_PGID, task_pgrp(current));
                        init_task_pid(p, PIDTYPE_SID, task_session(current));
 
@@ -1971,8 +2003,7 @@ static __latent_entropy struct task_struct *copy_process(
                                ns_of_pid(pid)->child_reaper = p;
                                p->signal->flags |= SIGNAL_UNKILLABLE;
                        }
-
-                       p->signal->leader_pid = pid;
+                       p->signal->shared_pending.signal = delayed.signal;
                        p->signal->tty = tty_kref_get(current->signal->tty);
                        /*
                         * Inherit has_child_subreaper flag under the same
@@ -1983,6 +2014,7 @@ static __latent_entropy struct task_struct *copy_process(
                                                         p->real_parent->signal->is_child_subreaper;
                        list_add_tail(&p->sibling, &p->real_parent->children);
                        list_add_tail_rcu(&p->tasks, &init_task.tasks);
+                       attach_pid(p, PIDTYPE_TGID);
                        attach_pid(p, PIDTYPE_PGID);
                        attach_pid(p, PIDTYPE_SID);
                        __this_cpu_inc(process_counts);
@@ -1990,6 +2022,7 @@ static __latent_entropy struct task_struct *copy_process(
                        current->signal->nr_threads++;
                        atomic_inc(&current->signal->live);
                        atomic_inc(&current->signal->sigcnt);
+                       task_join_group_stop(p);
                        list_add_tail_rcu(&p->thread_group,
                                          &p->group_leader->thread_group);
                        list_add_tail_rcu(&p->thread_node,
@@ -1998,8 +2031,8 @@ static __latent_entropy struct task_struct *copy_process(
                attach_pid(p, PIDTYPE_PID);
                nr_threads++;
        }
-
        total_forks++;
+       hlist_del_init(&delayed.node);
        spin_unlock(&current->sighand->siglock);
        syscall_tracepoint_update(p);
        write_unlock_irq(&tasklist_lock);
@@ -2064,16 +2097,19 @@ bad_fork_free:
        put_task_stack(p);
        free_task(p);
 fork_out:
+       spin_lock_irq(&current->sighand->siglock);
+       hlist_del_init(&delayed.node);
+       spin_unlock_irq(&current->sighand->siglock);
        return ERR_PTR(retval);
 }
 
-static inline void init_idle_pids(struct pid_link *links)
+static inline void init_idle_pids(struct task_struct *idle)
 {
        enum pid_type type;
 
        for (type = PIDTYPE_PID; type < PIDTYPE_MAX; ++type) {
-               INIT_HLIST_NODE(&links[type].node); /* not really needed */
-               links[type].pid = &init_struct_pid;
+               INIT_HLIST_NODE(&idle->pid_links[type]); /* not really needed */
+               init_task_pid(idle, type, &init_struct_pid);
        }
 }
 
@@ -2083,7 +2119,7 @@ struct task_struct *fork_idle(int cpu)
        task = copy_process(CLONE_VM, 0, 0, NULL, &init_struct_pid, 0, 0,
                            cpu_to_node(cpu));
        if (!IS_ERR(task)) {
-               init_idle_pids(task->pids);
+               init_idle_pids(task);
                init_idle(task, cpu);
        }
 
index 1f450e092c7416e3d43aba84da7b73b9a2a47b3d..11fc3bb456d65d666d1f80d062a11d3e00d41a3f 100644 (file)
@@ -3523,10 +3523,12 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
        switch (cmd) {
        case FUTEX_WAIT:
                val3 = FUTEX_BITSET_MATCH_ANY;
+               /* fall through */
        case FUTEX_WAIT_BITSET:
                return futex_wait(uaddr, flags, val, timeout, val3);
        case FUTEX_WAKE:
                val3 = FUTEX_BITSET_MATCH_ANY;
+               /* fall through */
        case FUTEX_WAKE_BITSET:
                return futex_wake(uaddr, flags, val, val3);
        case FUTEX_REQUEUE:
index 32b479468e4d50d69530ad766ba7e3897afa5cc3..b9132d1269ef1967950a804f7e21f3922cb491c8 100644 (file)
@@ -40,6 +40,11 @@ int __read_mostly sysctl_hung_task_check_count = PID_MAX_LIMIT;
  */
 unsigned long __read_mostly sysctl_hung_task_timeout_secs = CONFIG_DEFAULT_HUNG_TASK_TIMEOUT;
 
+/*
+ * Zero (default value) means use sysctl_hung_task_timeout_secs:
+ */
+unsigned long __read_mostly sysctl_hung_task_check_interval_secs;
+
 int __read_mostly sysctl_hung_task_warnings = 10;
 
 static int __read_mostly did_panic;
@@ -98,8 +103,11 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout)
 
        if (switch_count != t->last_switch_count) {
                t->last_switch_count = switch_count;
+               t->last_switch_time = jiffies;
                return;
        }
+       if (time_is_after_jiffies(t->last_switch_time + timeout * HZ))
+               return;
 
        trace_sched_process_hang(t);
 
@@ -245,8 +253,13 @@ static int watchdog(void *dummy)
 
        for ( ; ; ) {
                unsigned long timeout = sysctl_hung_task_timeout_secs;
-               long t = hung_timeout_jiffies(hung_last_checked, timeout);
+               unsigned long interval = sysctl_hung_task_check_interval_secs;
+               long t;
 
+               if (interval == 0)
+                       interval = timeout;
+               interval = min_t(unsigned long, interval, timeout);
+               t = hung_timeout_jiffies(hung_last_checked, interval);
                if (t <= 0) {
                        if (!atomic_xchg(&reset_hung_task, 0))
                                check_hung_uninterruptible_tasks(timeout);
index a23e21ada81b9dc6cbc8cd21c04805072bb98438..02a0b01380d8ef678bf544054cacf586292fb0e1 100644 (file)
@@ -432,6 +432,7 @@ int sprint_backtrace(char *buffer, unsigned long address)
 /* To avoid using get_symbol_offset for every symbol, we carry prefix along. */
 struct kallsym_iter {
        loff_t pos;
+       loff_t pos_arch_end;
        loff_t pos_mod_end;
        loff_t pos_ftrace_mod_end;
        unsigned long value;
@@ -443,9 +444,29 @@ struct kallsym_iter {
        int show_value;
 };
 
+int __weak arch_get_kallsym(unsigned int symnum, unsigned long *value,
+                           char *type, char *name)
+{
+       return -EINVAL;
+}
+
+static int get_ksymbol_arch(struct kallsym_iter *iter)
+{
+       int ret = arch_get_kallsym(iter->pos - kallsyms_num_syms,
+                                  &iter->value, &iter->type,
+                                  iter->name);
+
+       if (ret < 0) {
+               iter->pos_arch_end = iter->pos;
+               return 0;
+       }
+
+       return 1;
+}
+
 static int get_ksymbol_mod(struct kallsym_iter *iter)
 {
-       int ret = module_get_kallsym(iter->pos - kallsyms_num_syms,
+       int ret = module_get_kallsym(iter->pos - iter->pos_arch_end,
                                     &iter->value, &iter->type,
                                     iter->name, iter->module_name,
                                     &iter->exported);
@@ -501,32 +522,34 @@ static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
        iter->nameoff = get_symbol_offset(new_pos);
        iter->pos = new_pos;
        if (new_pos == 0) {
+               iter->pos_arch_end = 0;
                iter->pos_mod_end = 0;
                iter->pos_ftrace_mod_end = 0;
        }
 }
 
+/*
+ * The end position (last + 1) of each additional kallsyms section is recorded
+ * in iter->pos_..._end as each section is added, and so can be used to
+ * determine which get_ksymbol_...() function to call next.
+ */
 static int update_iter_mod(struct kallsym_iter *iter, loff_t pos)
 {
        iter->pos = pos;
 
-       if (iter->pos_ftrace_mod_end > 0 &&
-           iter->pos_ftrace_mod_end < iter->pos)
-               return get_ksymbol_bpf(iter);
+       if ((!iter->pos_arch_end || iter->pos_arch_end > pos) &&
+           get_ksymbol_arch(iter))
+               return 1;
 
-       if (iter->pos_mod_end > 0 &&
-           iter->pos_mod_end < iter->pos) {
-               if (!get_ksymbol_ftrace_mod(iter))
-                       return get_ksymbol_bpf(iter);
+       if ((!iter->pos_mod_end || iter->pos_mod_end > pos) &&
+           get_ksymbol_mod(iter))
                return 1;
-       }
 
-       if (!get_ksymbol_mod(iter)) {
-               if (!get_ksymbol_ftrace_mod(iter))
-                       return get_ksymbol_bpf(iter);
-       }
+       if ((!iter->pos_ftrace_mod_end || iter->pos_ftrace_mod_end > pos) &&
+           get_ksymbol_ftrace_mod(iter))
+               return 1;
 
-       return 1;
+       return get_ksymbol_bpf(iter);
 }
 
 /* Returns false if pos at or past end of file. */
index 3a4656fb7047c24bde87c644cb79902df2a6adba..5b77a7314e01919a4c6d4eddc50ba62ea9e89151 100644 (file)
@@ -678,6 +678,9 @@ static int klp_init_func(struct klp_object *obj, struct klp_func *func)
        if (!func->old_name || !func->new_func)
                return -EINVAL;
 
+       if (strlen(func->old_name) >= KSYM_NAME_LEN)
+               return -EINVAL;
+
        INIT_LIST_HEAD(&func->stack_node);
        func->patched = false;
        func->transition = false;
@@ -751,6 +754,9 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj)
        if (!obj->funcs)
                return -EINVAL;
 
+       if (klp_is_module(obj) && strlen(obj->name) >= MODULE_NAME_LEN)
+               return -EINVAL;
+
        obj->patched = false;
        obj->mod = NULL;
 
index 7c6631e693bc6969983f2e3c0b3ecf84d68f7a79..5bc349805e033fbfdbf5fb811026044695289d0b 100644 (file)
@@ -309,13 +309,6 @@ static bool klp_try_switch_task(struct task_struct *task)
        if (task->patch_state == klp_target_state)
                return true;
 
-       /*
-        * For arches which don't have reliable stack traces, we have to rely
-        * on other methods (e.g., switching tasks at kernel exit).
-        */
-       if (!klp_have_reliable_stack())
-               return false;
-
        /*
         * Now try to check the stack for any to-be-patched or to-be-unpatched
         * functions.  If all goes well, switch the task to the target patch
index 5fa4d3138bf106cd87f822636652c144e846f3aa..e406c5fdb41e9423aca5fd8db32ec8e692983d3b 100644 (file)
@@ -55,6 +55,7 @@
 
 #include "lockdep_internals.h"
 
+#include <trace/events/preemptirq.h>
 #define CREATE_TRACE_POINTS
 #include <trace/events/lock.h>
 
@@ -248,12 +249,7 @@ void clear_lock_stats(struct lock_class *class)
 
 static struct lock_class_stats *get_lock_stats(struct lock_class *class)
 {
-       return &get_cpu_var(cpu_lock_stats)[class - lock_classes];
-}
-
-static void put_lock_stats(struct lock_class_stats *stats)
-{
-       put_cpu_var(cpu_lock_stats);
+       return &this_cpu_ptr(cpu_lock_stats)[class - lock_classes];
 }
 
 static void lock_release_holdtime(struct held_lock *hlock)
@@ -271,7 +267,6 @@ static void lock_release_holdtime(struct held_lock *hlock)
                lock_time_inc(&stats->read_holdtime, holdtime);
        else
                lock_time_inc(&stats->write_holdtime, holdtime);
-       put_lock_stats(stats);
 }
 #else
 static inline void lock_release_holdtime(struct held_lock *hlock)
@@ -2845,10 +2840,8 @@ static void __trace_hardirqs_on_caller(unsigned long ip)
        debug_atomic_inc(hardirqs_on_events);
 }
 
-__visible void trace_hardirqs_on_caller(unsigned long ip)
+void lockdep_hardirqs_on(unsigned long ip)
 {
-       time_hardirqs_on(CALLER_ADDR0, ip);
-
        if (unlikely(!debug_locks || current->lockdep_recursion))
                return;
 
@@ -2887,23 +2880,14 @@ __visible void trace_hardirqs_on_caller(unsigned long ip)
        __trace_hardirqs_on_caller(ip);
        current->lockdep_recursion = 0;
 }
-EXPORT_SYMBOL(trace_hardirqs_on_caller);
-
-void trace_hardirqs_on(void)
-{
-       trace_hardirqs_on_caller(CALLER_ADDR0);
-}
-EXPORT_SYMBOL(trace_hardirqs_on);
 
 /*
  * Hardirqs were disabled:
  */
-__visible void trace_hardirqs_off_caller(unsigned long ip)
+void lockdep_hardirqs_off(unsigned long ip)
 {
        struct task_struct *curr = current;
 
-       time_hardirqs_off(CALLER_ADDR0, ip);
-
        if (unlikely(!debug_locks || current->lockdep_recursion))
                return;
 
@@ -2925,13 +2909,6 @@ __visible void trace_hardirqs_off_caller(unsigned long ip)
        } else
                debug_atomic_inc(redundant_hardirqs_off);
 }
-EXPORT_SYMBOL(trace_hardirqs_off_caller);
-
-void trace_hardirqs_off(void)
-{
-       trace_hardirqs_off_caller(CALLER_ADDR0);
-}
-EXPORT_SYMBOL(trace_hardirqs_off);
 
 /*
  * Softirqs will be enabled:
@@ -4090,7 +4067,6 @@ __lock_contended(struct lockdep_map *lock, unsigned long ip)
                stats->contending_point[contending_point]++;
        if (lock->cpu != smp_processor_id())
                stats->bounces[bounce_contended + !!hlock->read]++;
-       put_lock_stats(stats);
 }
 
 static void
@@ -4138,7 +4114,6 @@ __lock_acquired(struct lockdep_map *lock, unsigned long ip)
        }
        if (lock->cpu != cpu)
                stats->bounces[bounce_acquired + !!hlock->read]++;
-       put_lock_stats(stats);
 
        lock->cpu = cpu;
        lock->ip = ip;
@@ -4338,7 +4313,7 @@ out_restore:
        raw_local_irq_restore(flags);
 }
 
-void __init lockdep_info(void)
+void __init lockdep_init(void)
 {
        printk("Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar\n");
 
index 1f87ea6b6545af0866baaf252380f35a2ab8c3d2..5b8600d39931964adcef966b9660aceac5918124 100644 (file)
@@ -43,7 +43,7 @@ static unsigned long order_at(struct resource *res, unsigned long pgoff)
                        pgoff += 1UL << order, order = order_at((res), pgoff))
 
 #if IS_ENABLED(CONFIG_DEVICE_PRIVATE)
-int device_private_entry_fault(struct vm_area_struct *vma,
+vm_fault_t device_private_entry_fault(struct vm_area_struct *vma,
                       unsigned long addr,
                       swp_entry_t entry,
                       unsigned int flags,
@@ -365,7 +365,6 @@ void __put_devmap_managed_page(struct page *page)
                __ClearPageActive(page);
                __ClearPageWaiters(page);
 
-               page->mapping = NULL;
                mem_cgroup_uncharge(page);
 
                page->pgmap->page_free(page, page->pgmap->data);
index b046a32520d83aeeed519a72ae61972b4cc9870c..6746c85511fefe40f335207245df81d3e246a0c8 100644 (file)
@@ -529,12 +529,30 @@ static bool check_symbol(const struct symsearch *syms,
        return true;
 }
 
+static unsigned long kernel_symbol_value(const struct kernel_symbol *sym)
+{
+#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
+       return (unsigned long)offset_to_ptr(&sym->value_offset);
+#else
+       return sym->value;
+#endif
+}
+
+static const char *kernel_symbol_name(const struct kernel_symbol *sym)
+{
+#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
+       return offset_to_ptr(&sym->name_offset);
+#else
+       return sym->name;
+#endif
+}
+
 static int cmp_name(const void *va, const void *vb)
 {
        const char *a;
        const struct kernel_symbol *b;
        a = va; b = vb;
-       return strcmp(a, b->name);
+       return strcmp(a, kernel_symbol_name(b));
 }
 
 static bool find_symbol_in_section(const struct symsearch *syms,
@@ -2170,7 +2188,7 @@ void *__symbol_get(const char *symbol)
                sym = NULL;
        preempt_enable();
 
-       return sym ? (void *)sym->value : NULL;
+       return sym ? (void *)kernel_symbol_value(sym) : NULL;
 }
 EXPORT_SYMBOL_GPL(__symbol_get);
 
@@ -2200,10 +2218,12 @@ static int verify_export_symbols(struct module *mod)
 
        for (i = 0; i < ARRAY_SIZE(arr); i++) {
                for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {
-                       if (find_symbol(s->name, &owner, NULL, true, false)) {
+                       if (find_symbol(kernel_symbol_name(s), &owner, NULL,
+                                       true, false)) {
                                pr_err("%s: exports duplicate symbol %s"
                                       " (owned by %s)\n",
-                                      mod->name, s->name, module_name(owner));
+                                      mod->name, kernel_symbol_name(s),
+                                      module_name(owner));
                                return -ENOEXEC;
                        }
                }
@@ -2252,7 +2272,7 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
                        ksym = resolve_symbol_wait(mod, info, name);
                        /* Ok if resolved.  */
                        if (ksym && !IS_ERR(ksym)) {
-                               sym[i].st_value = ksym->value;
+                               sym[i].st_value = kernel_symbol_value(ksym);
                                break;
                        }
 
@@ -2516,7 +2536,7 @@ static int is_exported(const char *name, unsigned long value,
                ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab);
        else
                ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms);
-       return ks != NULL && ks->value == value;
+       return ks != NULL && kernel_symbol_value(ks) == value;
 }
 
 /* As per nm */
index 157fe4b199713b65cb62c6d591225306cd5289f9..de1cfc4f75a2eb8df16e3d1018122226a1a30f14 100644 (file)
@@ -265,27 +265,33 @@ struct pid *find_vpid(int nr)
 }
 EXPORT_SYMBOL_GPL(find_vpid);
 
+static struct pid **task_pid_ptr(struct task_struct *task, enum pid_type type)
+{
+       return (type == PIDTYPE_PID) ?
+               &task->thread_pid :
+               &task->signal->pids[type];
+}
+
 /*
  * attach_pid() must be called with the tasklist_lock write-held.
  */
 void attach_pid(struct task_struct *task, enum pid_type type)
 {
-       struct pid_link *link = &task->pids[type];
-       hlist_add_head_rcu(&link->node, &link->pid->tasks[type]);
+       struct pid *pid = *task_pid_ptr(task, type);
+       hlist_add_head_rcu(&task->pid_links[type], &pid->tasks[type]);
 }
 
 static void __change_pid(struct task_struct *task, enum pid_type type,
                        struct pid *new)
 {
-       struct pid_link *link;
+       struct pid **pid_ptr = task_pid_ptr(task, type);
        struct pid *pid;
        int tmp;
 
-       link = &task->pids[type];
-       pid = link->pid;
+       pid = *pid_ptr;
 
-       hlist_del_rcu(&link->node);
-       link->pid = new;
+       hlist_del_rcu(&task->pid_links[type]);
+       *pid_ptr = new;
 
        for (tmp = PIDTYPE_MAX; --tmp >= 0; )
                if (!hlist_empty(&pid->tasks[tmp]))
@@ -310,8 +316,9 @@ void change_pid(struct task_struct *task, enum pid_type type,
 void transfer_pid(struct task_struct *old, struct task_struct *new,
                           enum pid_type type)
 {
-       new->pids[type].pid = old->pids[type].pid;
-       hlist_replace_rcu(&old->pids[type].node, &new->pids[type].node);
+       if (type == PIDTYPE_PID)
+               new->thread_pid = old->thread_pid;
+       hlist_replace_rcu(&old->pid_links[type], &new->pid_links[type]);
 }
 
 struct task_struct *pid_task(struct pid *pid, enum pid_type type)
@@ -322,7 +329,7 @@ struct task_struct *pid_task(struct pid *pid, enum pid_type type)
                first = rcu_dereference_check(hlist_first_rcu(&pid->tasks[type]),
                                              lockdep_tasklist_lock_is_held());
                if (first)
-                       result = hlist_entry(first, struct task_struct, pids[(type)].node);
+                       result = hlist_entry(first, struct task_struct, pid_links[(type)]);
        }
        return result;
 }
@@ -360,9 +367,7 @@ struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
 {
        struct pid *pid;
        rcu_read_lock();
-       if (type != PIDTYPE_PID)
-               task = task->group_leader;
-       pid = get_pid(rcu_dereference(task->pids[type].pid));
+       pid = get_pid(rcu_dereference(*task_pid_ptr(task, type)));
        rcu_read_unlock();
        return pid;
 }
@@ -420,15 +425,8 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
        rcu_read_lock();
        if (!ns)
                ns = task_active_pid_ns(current);
-       if (likely(pid_alive(task))) {
-               if (type != PIDTYPE_PID) {
-                       if (type == __PIDTYPE_TGID)
-                               type = PIDTYPE_PID;
-
-                       task = task->group_leader;
-               }
-               nr = pid_nr_ns(rcu_dereference(task->pids[type].pid), ns);
-       }
+       if (likely(pid_alive(task)))
+               nr = pid_nr_ns(rcu_dereference(*task_pid_ptr(task, type)), ns);
        rcu_read_unlock();
 
        return nr;
index e880ca22c5a589127b5c7f7023434e99e090972b..3a6c2f87699e355e1772aa1320aa556e7201743b 100644 (file)
@@ -105,6 +105,7 @@ config PM_SLEEP
        def_bool y
        depends on SUSPEND || HIBERNATE_CALLBACKS
        select PM
+       select SRCU
 
 config PM_SLEEP_SMP
        def_bool y
index 90b6ab01db59cadbaf6e92283e982cb3ae820289..fd6f8ed28e010a0808c8e67a698372ce5fc411da 100644 (file)
@@ -38,7 +38,6 @@
 #include <linux/kmsg_dump.h>
 #include <linux/syslog.h>
 #include <linux/cpu.h>
-#include <linux/notifier.h>
 #include <linux/rculist.h>
 #include <linux/poll.h>
 #include <linux/irq_work.h>
@@ -66,6 +65,9 @@ int console_printk[4] = {
        CONSOLE_LOGLEVEL_DEFAULT,       /* default_console_loglevel */
 };
 
+atomic_t ignore_console_lock_warning __read_mostly = ATOMIC_INIT(0);
+EXPORT_SYMBOL(ignore_console_lock_warning);
+
 /*
  * Low level drivers may need that to know if they can schedule in
  * their unblank() callback or not. So let's export it.
@@ -2788,7 +2790,8 @@ EXPORT_SYMBOL(unregister_console);
 void __init console_init(void)
 {
        int ret;
-       initcall_t *call;
+       initcall_t call;
+       initcall_entry_t *ce;
 
        /* Setup the default TTY line discipline. */
        n_tty_init();
@@ -2797,13 +2800,14 @@ void __init console_init(void)
         * set up the console device so that later boot sequences can
         * inform about problems etc..
         */
-       call = __con_initcall_start;
+       ce = __con_initcall_start;
        trace_initcall_level("console");
-       while (call < __con_initcall_end) {
-               trace_initcall_start((*call));
-               ret = (*call)();
-               trace_initcall_finish((*call), ret);
-               call++;
+       while (ce < __con_initcall_end) {
+               call = initcall_from_entry(ce);
+               trace_initcall_start(call);
+               ret = call();
+               trace_initcall_finish(call, ret);
+               ce++;
        }
 }
 
index a0a74c533e4b755ea73b876b51e3839c272c19cf..0913b4d385de307049eead641cf0bba8ea9e7695 100644 (file)
@@ -306,12 +306,12 @@ static __printf(1, 0) int vprintk_nmi(const char *fmt, va_list args)
        return printk_safe_log_store(s, fmt, args);
 }
 
-void printk_nmi_enter(void)
+void notrace printk_nmi_enter(void)
 {
        this_cpu_or(printk_context, PRINTK_NMI_CONTEXT_MASK);
 }
 
-void printk_nmi_exit(void)
+void notrace printk_nmi_exit(void)
 {
        this_cpu_and(printk_context, ~PRINTK_NMI_CONTEXT_MASK);
 }
index 454adf9f81802007ef7165a5b1f79898bc537451..625bc9897f628bec7abacd797a05bff4b4f2cd85 100644 (file)
@@ -2774,6 +2774,8 @@ asmlinkage __visible void schedule_tail(struct task_struct *prev)
 
        if (current->set_child_tid)
                put_user(task_pid_vnr(current), current->set_child_tid);
+
+       calculate_sigpending();
 }
 
 /*
@@ -3159,7 +3161,7 @@ static inline void sched_tick_stop(int cpu) { }
 #endif
 
 #if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \
-                               defined(CONFIG_PREEMPT_TRACER))
+                               defined(CONFIG_TRACE_PREEMPT_TOGGLE))
 /*
  * If the value passed in is equal to the current preempt count
  * then we just disabled preemption. Start timing the latency.
index 1a3e9bddd17b67955f5f0446310a090872d7eacf..16f84142f2f492633b6068f8f7536cdae40c6e0d 100644 (file)
@@ -190,7 +190,7 @@ static void cpuidle_idle_call(void)
                 */
                next_state = cpuidle_select(drv, dev, &stop_tick);
 
-               if (stop_tick)
+               if (stop_tick || tick_nohz_tick_stopped())
                        tick_nohz_idle_stop_tick();
                else
                        tick_nohz_idle_retain_tick();
index 870f97b313e3891003b30982603cf333a879d4a8..5dd47f1103d18bd769cace68b753088574e02f27 100644 (file)
@@ -69,6 +69,8 @@ static int __wake_up_common(struct wait_queue_head *wq_head, unsigned int mode,
        wait_queue_entry_t *curr, *next;
        int cnt = 0;
 
+       lockdep_assert_held(&wq_head->lock);
+
        if (bookmark && (bookmark->flags & WQ_FLAG_BOOKMARK)) {
                curr = list_next_entry(bookmark, entry);
 
index 8d8a940422a8e0d7758a46fecff34b26782e1787..5843c541fda9c30bb8e4165facc07a3df114f57b 100644 (file)
@@ -65,14 +65,14 @@ static void __user *sig_handler(struct task_struct *t, int sig)
        return t->sighand->action[sig - 1].sa.sa_handler;
 }
 
-static int sig_handler_ignored(void __user *handler, int sig)
+static inline bool sig_handler_ignored(void __user *handler, int sig)
 {
        /* Is it explicitly or implicitly ignored? */
        return handler == SIG_IGN ||
-               (handler == SIG_DFL && sig_kernel_ignore(sig));
+              (handler == SIG_DFL && sig_kernel_ignore(sig));
 }
 
-static int sig_task_ignored(struct task_struct *t, int sig, bool force)
+static bool sig_task_ignored(struct task_struct *t, int sig, bool force)
 {
        void __user *handler;
 
@@ -80,12 +80,12 @@ static int sig_task_ignored(struct task_struct *t, int sig, bool force)
 
        if (unlikely(t->signal->flags & SIGNAL_UNKILLABLE) &&
            handler == SIG_DFL && !(force && sig_kernel_only(sig)))
-               return 1;
+               return true;
 
        return sig_handler_ignored(handler, sig);
 }
 
-static int sig_ignored(struct task_struct *t, int sig, bool force)
+static bool sig_ignored(struct task_struct *t, int sig, bool force)
 {
        /*
         * Blocked signals are never ignored, since the
@@ -93,7 +93,7 @@ static int sig_ignored(struct task_struct *t, int sig, bool force)
         * unblocked.
         */
        if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig))
-               return 0;
+               return false;
 
        /*
         * Tracers may want to know about even ignored signal unless it
@@ -101,7 +101,7 @@ static int sig_ignored(struct task_struct *t, int sig, bool force)
         * by SIGNAL_UNKILLABLE task.
         */
        if (t->ptrace && sig != SIGKILL)
-               return 0;
+               return false;
 
        return sig_task_ignored(t, sig, force);
 }
@@ -110,7 +110,7 @@ static int sig_ignored(struct task_struct *t, int sig, bool force)
  * Re-calculate pending state from the set of locally pending
  * signals, globally pending signals, and blocked signals.
  */
-static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked)
+static inline bool has_pending_signals(sigset_t *signal, sigset_t *blocked)
 {
        unsigned long ready;
        long i;
@@ -138,20 +138,21 @@ static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked)
 
 #define PENDING(p,b) has_pending_signals(&(p)->signal, (b))
 
-static int recalc_sigpending_tsk(struct task_struct *t)
+static bool recalc_sigpending_tsk(struct task_struct *t)
 {
        if ((t->jobctl & JOBCTL_PENDING_MASK) ||
            PENDING(&t->pending, &t->blocked) ||
            PENDING(&t->signal->shared_pending, &t->blocked)) {
                set_tsk_thread_flag(t, TIF_SIGPENDING);
-               return 1;
+               return true;
        }
+
        /*
         * We must never clear the flag in another thread, or in current
         * when it's possible the current syscall is returning -ERESTART*.
         * So we don't clear it here, and only callers who know they should do.
         */
-       return 0;
+       return false;
 }
 
 /*
@@ -172,6 +173,17 @@ void recalc_sigpending(void)
 
 }
 
+void calculate_sigpending(void)
+{
+       /* Have any signals or users of TIF_SIGPENDING been delayed
+        * until after fork?
+        */
+       spin_lock_irq(&current->sighand->siglock);
+       set_tsk_thread_flag(current, TIF_SIGPENDING);
+       recalc_sigpending();
+       spin_unlock_irq(&current->sighand->siglock);
+}
+
 /* Given the mask, find the first available signal that should be serviced. */
 
 #define SYNCHRONOUS_MASK \
@@ -362,6 +374,20 @@ static bool task_participate_group_stop(struct task_struct *task)
        return false;
 }
 
+void task_join_group_stop(struct task_struct *task)
+{
+       /* Have the new thread join an on-going signal group stop */
+       unsigned long jobctl = current->jobctl;
+       if (jobctl & JOBCTL_STOP_PENDING) {
+               struct signal_struct *sig = current->signal;
+               unsigned long signr = jobctl & JOBCTL_STOP_SIGMASK;
+               unsigned long gstop = JOBCTL_STOP_PENDING | JOBCTL_STOP_CONSUME;
+               if (task_set_jobctl_pending(task, signr | gstop)) {
+                       sig->group_stop_count++;
+               }
+       }
+}
+
 /*
  * allocate a new signal queue record
  * - this may be called without locks if and only if t == current, otherwise an
@@ -504,13 +530,15 @@ flush_signal_handlers(struct task_struct *t, int force_default)
        }
 }
 
-int unhandled_signal(struct task_struct *tsk, int sig)
+bool unhandled_signal(struct task_struct *tsk, int sig)
 {
        void __user *handler = tsk->sighand->action[sig-1].sa.sa_handler;
        if (is_global_init(tsk))
-               return 1;
+               return true;
+
        if (handler != SIG_IGN && handler != SIG_DFL)
-               return 0;
+               return false;
+
        /* if ptraced, let the tracer determine */
        return !tsk->ptrace;
 }
@@ -684,14 +712,14 @@ void signal_wake_up_state(struct task_struct *t, unsigned int state)
  *
  * All callers must be holding the siglock.
  */
-static int flush_sigqueue_mask(sigset_t *mask, struct sigpending *s)
+static void flush_sigqueue_mask(sigset_t *mask, struct sigpending *s)
 {
        struct sigqueue *q, *n;
        sigset_t m;
 
        sigandsets(&m, mask, &s->signal);
        if (sigisemptyset(&m))
-               return 0;
+               return;
 
        sigandnsets(&s->signal, &s->signal, mask);
        list_for_each_entry_safe(q, n, &s->list, list) {
@@ -700,7 +728,6 @@ static int flush_sigqueue_mask(sigset_t *mask, struct sigpending *s)
                        __sigqueue_free(q);
                }
        }
-       return 1;
 }
 
 static inline int is_si_special(const struct siginfo *info)
@@ -717,21 +744,16 @@ static inline bool si_fromuser(const struct siginfo *info)
 /*
  * called with RCU read lock from check_kill_permission()
  */
-static int kill_ok_by_cred(struct task_struct *t)
+static bool kill_ok_by_cred(struct task_struct *t)
 {
        const struct cred *cred = current_cred();
        const struct cred *tcred = __task_cred(t);
 
-       if (uid_eq(cred->euid, tcred->suid) ||
-           uid_eq(cred->euid, tcred->uid)  ||
-           uid_eq(cred->uid,  tcred->suid) ||
-           uid_eq(cred->uid,  tcred->uid))
-               return 1;
-
-       if (ns_capable(tcred->user_ns, CAP_KILL))
-               return 1;
-
-       return 0;
+       return uid_eq(cred->euid, tcred->suid) ||
+              uid_eq(cred->euid, tcred->uid) ||
+              uid_eq(cred->uid, tcred->suid) ||
+              uid_eq(cred->uid, tcred->uid) ||
+              ns_capable(tcred->user_ns, CAP_KILL);
 }
 
 /*
@@ -882,20 +904,24 @@ static bool prepare_signal(int sig, struct task_struct *p, bool force)
  * as soon as they're available, so putting the signal on the shared queue
  * will be equivalent to sending it to one such thread.
  */
-static inline int wants_signal(int sig, struct task_struct *p)
+static inline bool wants_signal(int sig, struct task_struct *p)
 {
        if (sigismember(&p->blocked, sig))
-               return 0;
+               return false;
+
        if (p->flags & PF_EXITING)
-               return 0;
+               return false;
+
        if (sig == SIGKILL)
-               return 1;
+               return true;
+
        if (task_is_stopped_or_traced(p))
-               return 0;
+               return false;
+
        return task_curr(p) || !signal_pending(p);
 }
 
-static void complete_signal(int sig, struct task_struct *p, int group)
+static void complete_signal(int sig, struct task_struct *p, enum pid_type type)
 {
        struct signal_struct *signal = p->signal;
        struct task_struct *t;
@@ -908,7 +934,7 @@ static void complete_signal(int sig, struct task_struct *p, int group)
         */
        if (wants_signal(sig, p))
                t = p;
-       else if (!group || thread_group_empty(p))
+       else if ((type == PIDTYPE_PID) || thread_group_empty(p))
                /*
                 * There is just one thread and it does not need to be woken.
                 * It will dequeue unblocked signals before it runs again.
@@ -971,7 +997,7 @@ static void complete_signal(int sig, struct task_struct *p, int group)
        return;
 }
 
-static inline int legacy_queue(struct sigpending *signals, int sig)
+static inline bool legacy_queue(struct sigpending *signals, int sig)
 {
        return (sig < SIGRTMIN) && sigismember(&signals->signal, sig);
 }
@@ -998,7 +1024,7 @@ static inline void userns_fixup_signal_uid(struct siginfo *info, struct task_str
 #endif
 
 static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
-                       int group, int from_ancestor_ns)
+                       enum pid_type type, int from_ancestor_ns)
 {
        struct sigpending *pending;
        struct sigqueue *q;
@@ -1012,7 +1038,7 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
                        from_ancestor_ns || (info == SEND_SIG_FORCED)))
                goto ret;
 
-       pending = group ? &t->signal->shared_pending : &t->pending;
+       pending = (type != PIDTYPE_PID) ? &t->signal->shared_pending : &t->pending;
        /*
         * Short-circuit ignored signals and support queuing
         * exactly one non-rt signal, so that we can get more
@@ -1096,14 +1122,29 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
 out_set:
        signalfd_notify(t, sig);
        sigaddset(&pending->signal, sig);
-       complete_signal(sig, t, group);
+
+       /* Let multiprocess signals appear after on-going forks */
+       if (type > PIDTYPE_TGID) {
+               struct multiprocess_signals *delayed;
+               hlist_for_each_entry(delayed, &t->signal->multiprocess, node) {
+                       sigset_t *signal = &delayed->signal;
+                       /* Can't queue both a stop and a continue signal */
+                       if (sig == SIGCONT)
+                               sigdelsetmask(signal, SIG_KERNEL_STOP_MASK);
+                       else if (sig_kernel_stop(sig))
+                               sigdelset(signal, SIGCONT);
+                       sigaddset(signal, sig);
+               }
+       }
+
+       complete_signal(sig, t, type);
 ret:
-       trace_signal_generate(sig, info, t, group, result);
+       trace_signal_generate(sig, info, t, type != PIDTYPE_PID, result);
        return ret;
 }
 
 static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
-                       int group)
+                       enum pid_type type)
 {
        int from_ancestor_ns = 0;
 
@@ -1112,7 +1153,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
                           !task_pid_nr_ns(current, task_active_pid_ns(t));
 #endif
 
-       return __send_signal(sig, info, t, group, from_ancestor_ns);
+       return __send_signal(sig, info, t, type, from_ancestor_ns);
 }
 
 static void print_fatal_signal(int signr)
@@ -1151,23 +1192,23 @@ __setup("print-fatal-signals=", setup_print_fatal_signals);
 int
 __group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
 {
-       return send_signal(sig, info, p, 1);
+       return send_signal(sig, info, p, PIDTYPE_TGID);
 }
 
 static int
 specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
 {
-       return send_signal(sig, info, t, 0);
+       return send_signal(sig, info, t, PIDTYPE_PID);
 }
 
 int do_send_sig_info(int sig, struct siginfo *info, struct task_struct *p,
-                       bool group)
+                       enum pid_type type)
 {
        unsigned long flags;
        int ret = -ESRCH;
 
        if (lock_task_sighand(p, &flags)) {
-               ret = send_signal(sig, info, p, group);
+               ret = send_signal(sig, info, p, type);
                unlock_task_sighand(p, &flags);
        }
 
@@ -1274,7 +1315,8 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk,
 /*
  * send signal info to all the members of a group
  */
-int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
+int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p,
+                       enum pid_type type)
 {
        int ret;
 
@@ -1283,7 +1325,7 @@ int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
        rcu_read_unlock();
 
        if (!ret && sig)
-               ret = do_send_sig_info(sig, info, p, true);
+               ret = do_send_sig_info(sig, info, p, type);
 
        return ret;
 }
@@ -1301,7 +1343,7 @@ int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp)
        success = 0;
        retval = -ESRCH;
        do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
-               int err = group_send_sig_info(sig, info, p);
+               int err = group_send_sig_info(sig, info, p, PIDTYPE_PGID);
                success |= !err;
                retval = err;
        } while_each_pid_task(pgrp, PIDTYPE_PGID, p);
@@ -1317,7 +1359,7 @@ int kill_pid_info(int sig, struct siginfo *info, struct pid *pid)
                rcu_read_lock();
                p = pid_task(pid, PIDTYPE_PID);
                if (p)
-                       error = group_send_sig_info(sig, info, p);
+                       error = group_send_sig_info(sig, info, p, PIDTYPE_TGID);
                rcu_read_unlock();
                if (likely(!p || error != -ESRCH))
                        return error;
@@ -1339,14 +1381,15 @@ static int kill_proc_info(int sig, struct siginfo *info, pid_t pid)
        return error;
 }
 
-static int kill_as_cred_perm(const struct cred *cred,
-                            struct task_struct *target)
+static inline bool kill_as_cred_perm(const struct cred *cred,
+                                    struct task_struct *target)
 {
        const struct cred *pcred = __task_cred(target);
-       if (!uid_eq(cred->euid, pcred->suid) && !uid_eq(cred->euid, pcred->uid) &&
-           !uid_eq(cred->uid,  pcred->suid) && !uid_eq(cred->uid,  pcred->uid))
-               return 0;
-       return 1;
+
+       return uid_eq(cred->euid, pcred->suid) ||
+              uid_eq(cred->euid, pcred->uid) ||
+              uid_eq(cred->uid, pcred->suid) ||
+              uid_eq(cred->uid, pcred->uid);
 }
 
 /* like kill_pid_info(), but doesn't use uid/euid of "current" */
@@ -1376,7 +1419,7 @@ int kill_pid_info_as_cred(int sig, struct siginfo *info, struct pid *pid,
 
        if (sig) {
                if (lock_task_sighand(p, &flags)) {
-                       ret = __send_signal(sig, info, p, 1, 0);
+                       ret = __send_signal(sig, info, p, PIDTYPE_TGID, 0);
                        unlock_task_sighand(p, &flags);
                } else
                        ret = -ESRCH;
@@ -1420,7 +1463,8 @@ static int kill_something_info(int sig, struct siginfo *info, pid_t pid)
                for_each_process(p) {
                        if (task_pid_vnr(p) > 1 &&
                                        !same_thread_group(p, current)) {
-                               int err = group_send_sig_info(sig, info, p);
+                               int err = group_send_sig_info(sig, info, p,
+                                                             PIDTYPE_MAX);
                                ++count;
                                if (err != -EPERM)
                                        retval = err;
@@ -1446,7 +1490,7 @@ int send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
        if (!valid_signal(sig))
                return -EINVAL;
 
-       return do_send_sig_info(sig, info, p, false);
+       return do_send_sig_info(sig, info, p, PIDTYPE_PID);
 }
 
 #define __si_special(priv) \
@@ -1458,8 +1502,7 @@ send_sig(int sig, struct task_struct *p, int priv)
        return send_sig_info(sig, __si_special(priv), p);
 }
 
-void
-force_sig(int sig, struct task_struct *p)
+void force_sig(int sig, struct task_struct *p)
 {
        force_sig_info(sig, SEND_SIG_PRIV, p);
 }
@@ -1470,8 +1513,7 @@ force_sig(int sig, struct task_struct *p)
  * the problem was already a SIGSEGV, we'll want to
  * make sure we don't even try to deliver the signal..
  */
-int
-force_sigsegv(int sig, struct task_struct *p)
+void force_sigsegv(int sig, struct task_struct *p)
 {
        if (sig == SIGSEGV) {
                unsigned long flags;
@@ -1480,7 +1522,6 @@ force_sigsegv(int sig, struct task_struct *p)
                spin_unlock_irqrestore(&p->sighand->siglock, flags);
        }
        force_sig(SIGSEGV, p);
-       return 0;
 }
 
 int force_sig_fault(int sig, int code, void __user *addr
@@ -1664,17 +1705,20 @@ void sigqueue_free(struct sigqueue *q)
                __sigqueue_free(q);
 }
 
-int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
+int send_sigqueue(struct sigqueue *q, struct pid *pid, enum pid_type type)
 {
        int sig = q->info.si_signo;
        struct sigpending *pending;
+       struct task_struct *t;
        unsigned long flags;
        int ret, result;
 
        BUG_ON(!(q->flags & SIGQUEUE_PREALLOC));
 
        ret = -1;
-       if (!likely(lock_task_sighand(t, &flags)))
+       rcu_read_lock();
+       t = pid_task(pid, type);
+       if (!t || !likely(lock_task_sighand(t, &flags)))
                goto ret;
 
        ret = 1; /* the signal is ignored */
@@ -1696,15 +1740,16 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
        q->info.si_overrun = 0;
 
        signalfd_notify(t, sig);
-       pending = group ? &t->signal->shared_pending : &t->pending;
+       pending = (type != PIDTYPE_PID) ? &t->signal->shared_pending : &t->pending;
        list_add_tail(&q->list, &pending->list);
        sigaddset(&pending->signal, sig);
-       complete_signal(sig, t, group);
+       complete_signal(sig, t, type);
        result = TRACE_SIGNAL_DELIVERED;
 out:
-       trace_signal_generate(sig, &q->info, t, group, result);
+       trace_signal_generate(sig, &q->info, t, type != PIDTYPE_PID, result);
        unlock_task_sighand(t, &flags);
 ret:
+       rcu_read_unlock();
        return ret;
 }
 
@@ -1877,10 +1922,10 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
        spin_unlock_irqrestore(&sighand->siglock, flags);
 }
 
-static inline int may_ptrace_stop(void)
+static inline bool may_ptrace_stop(void)
 {
        if (!likely(current->ptrace))
-               return 0;
+               return false;
        /*
         * Are we in the middle of do_coredump?
         * If so and our tracer is also part of the coredump stopping
@@ -1896,19 +1941,19 @@ static inline int may_ptrace_stop(void)
         */
        if (unlikely(current->mm->core_state) &&
            unlikely(current->mm == current->parent->mm))
-               return 0;
+               return false;
 
-       return 1;
+       return true;
 }
 
 /*
  * Return non-zero if there is a SIGKILL that should be waking us up.
  * Called with the siglock held.
  */
-static int sigkill_pending(struct task_struct *tsk)
+static bool sigkill_pending(struct task_struct *tsk)
 {
-       return  sigismember(&tsk->pending.signal, SIGKILL) ||
-               sigismember(&tsk->signal->shared_pending.signal, SIGKILL);
+       return sigismember(&tsk->pending.signal, SIGKILL) ||
+              sigismember(&tsk->signal->shared_pending.signal, SIGKILL);
 }
 
 /*
@@ -2288,7 +2333,7 @@ static int ptrace_signal(int signr, siginfo_t *info)
        return signr;
 }
 
-int get_signal(struct ksignal *ksig)
+bool get_signal(struct ksignal *ksig)
 {
        struct sighand_struct *sighand = current->sighand;
        struct signal_struct *signal = current->signal;
@@ -2298,7 +2343,7 @@ int get_signal(struct ksignal *ksig)
                task_work_run();
 
        if (unlikely(uprobe_deny_signal()))
-               return 0;
+               return false;
 
        /*
         * Do this once, we can't return to user-mode if freezing() == T.
@@ -2755,7 +2800,7 @@ COMPAT_SYSCALL_DEFINE4(rt_sigprocmask, int, how, compat_sigset_t __user *, nset,
 }
 #endif
 
-static int do_sigpending(sigset_t *set)
+static void do_sigpending(sigset_t *set)
 {
        spin_lock_irq(&current->sighand->siglock);
        sigorsets(set, &current->pending.signal,
@@ -2764,7 +2809,6 @@ static int do_sigpending(sigset_t *set)
 
        /* Outside the lock because only this thread touches it.  */
        sigandsets(set, &current->blocked, set);
-       return 0;
 }
 
 /**
@@ -2776,15 +2820,16 @@ static int do_sigpending(sigset_t *set)
 SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, uset, size_t, sigsetsize)
 {
        sigset_t set;
-       int err;
 
        if (sigsetsize > sizeof(*uset))
                return -EINVAL;
 
-       err = do_sigpending(&set);
-       if (!err && copy_to_user(uset, &set, sigsetsize))
-               err = -EFAULT;
-       return err;
+       do_sigpending(&set);
+
+       if (copy_to_user(uset, &set, sigsetsize))
+               return -EFAULT;
+
+       return 0;
 }
 
 #ifdef CONFIG_COMPAT
@@ -2792,15 +2837,13 @@ COMPAT_SYSCALL_DEFINE2(rt_sigpending, compat_sigset_t __user *, uset,
                compat_size_t, sigsetsize)
 {
        sigset_t set;
-       int err;
 
        if (sigsetsize > sizeof(*uset))
                return -EINVAL;
 
-       err = do_sigpending(&set);
-       if (!err)
-               err = put_compat_sigset(uset, &set, sigsetsize);
-       return err;
+       do_sigpending(&set);
+
+       return put_compat_sigset(uset, &set, sigsetsize);
 }
 #endif
 
@@ -3193,7 +3236,7 @@ do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info)
                 * probe.  No signal is actually delivered.
                 */
                if (!error && sig) {
-                       error = do_send_sig_info(sig, info, p, false);
+                       error = do_send_sig_info(sig, info, p, PIDTYPE_PID);
                        /*
                         * If lock_task_sighand() failed we pretend the task
                         * dies after receiving the signal. The window is tiny,
@@ -3562,25 +3605,26 @@ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
 SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, uset)
 {
        sigset_t set;
-       int err;
 
        if (sizeof(old_sigset_t) > sizeof(*uset))
                return -EINVAL;
 
-       err = do_sigpending(&set);
-       if (!err && copy_to_user(uset, &set, sizeof(old_sigset_t)))
-               err = -EFAULT;
-       return err;
+       do_sigpending(&set);
+
+       if (copy_to_user(uset, &set, sizeof(old_sigset_t)))
+               return -EFAULT;
+
+       return 0;
 }
 
 #ifdef CONFIG_COMPAT
 COMPAT_SYSCALL_DEFINE1(sigpending, compat_old_sigset_t __user *, set32)
 {
        sigset_t set;
-       int err = do_sigpending(&set);
-       if (!err)
-               err = put_user(set.sig[0], set32);
-       return err;
+
+       do_sigpending(&set);
+
+       return put_user(set.sig[0], set32);
 }
 #endif
 
@@ -3651,25 +3695,23 @@ SYSCALL_DEFINE4(rt_sigaction, int, sig,
                size_t, sigsetsize)
 {
        struct k_sigaction new_sa, old_sa;
-       int ret = -EINVAL;
+       int ret;
 
        /* XXX: Don't preclude handling different sized sigset_t's.  */
        if (sigsetsize != sizeof(sigset_t))
-               goto out;
+               return -EINVAL;
 
-       if (act) {
-               if (copy_from_user(&new_sa.sa, act, sizeof(new_sa.sa)))
-                       return -EFAULT;
-       }
+       if (act && copy_from_user(&new_sa.sa, act, sizeof(new_sa.sa)))
+               return -EFAULT;
 
        ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
+       if (ret)
+               return ret;
 
-       if (!ret && oact) {
-               if (copy_to_user(oact, &old_sa.sa, sizeof(old_sa.sa)))
-                       return -EFAULT;
-       }
-out:
-       return ret;
+       if (oact && copy_to_user(oact, &old_sa.sa, sizeof(old_sa.sa)))
+               return -EFAULT;
+
+       return 0;
 }
 #ifdef CONFIG_COMPAT
 COMPAT_SYSCALL_DEFINE4(rt_sigaction, int, sig,
@@ -3960,7 +4002,7 @@ void kdb_send_sig(struct task_struct *t, int sig)
                           "the deadlock.\n");
                return;
        }
-       ret = send_signal(sig, SEND_SIG_PRIV, t, false);
+       ret = send_signal(sig, SEND_SIG_PRIV, t, PIDTYPE_PID);
        spin_unlock(&t->sighand->siglock);
        if (ret)
                kdb_printf("Fail to deliver Signal %d to process %d.\n",
index e27b51d3facdb5c617b4eecbaa2ff030dbf22acd..cf5c67533ff1e1c02e296ed34d19501dd5f794dd 100644 (file)
@@ -1237,18 +1237,19 @@ static int override_release(char __user *release, size_t len)
 
 SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
 {
-       int errno = 0;
+       struct new_utsname tmp;
 
        down_read(&uts_sem);
-       if (copy_to_user(name, utsname(), sizeof *name))
-               errno = -EFAULT;
+       memcpy(&tmp, utsname(), sizeof(tmp));
        up_read(&uts_sem);
+       if (copy_to_user(name, &tmp, sizeof(tmp)))
+               return -EFAULT;
 
-       if (!errno && override_release(name->release, sizeof(name->release)))
-               errno = -EFAULT;
-       if (!errno && override_architecture(name))
-               errno = -EFAULT;
-       return errno;
+       if (override_release(name->release, sizeof(name->release)))
+               return -EFAULT;
+       if (override_architecture(name))
+               return -EFAULT;
+       return 0;
 }
 
 #ifdef __ARCH_WANT_SYS_OLD_UNAME
@@ -1257,55 +1258,46 @@ SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
  */
 SYSCALL_DEFINE1(uname, struct old_utsname __user *, name)
 {
-       int error = 0;
+       struct old_utsname tmp;
 
        if (!name)
                return -EFAULT;
 
        down_read(&uts_sem);
-       if (copy_to_user(name, utsname(), sizeof(*name)))
-               error = -EFAULT;
+       memcpy(&tmp, utsname(), sizeof(tmp));
        up_read(&uts_sem);
+       if (copy_to_user(name, &tmp, sizeof(tmp)))
+               return -EFAULT;
 
-       if (!error && override_release(name->release, sizeof(name->release)))
-               error = -EFAULT;
-       if (!error && override_architecture(name))
-               error = -EFAULT;
-       return error;
+       if (override_release(name->release, sizeof(name->release)))
+               return -EFAULT;
+       if (override_architecture(name))
+               return -EFAULT;
+       return 0;
 }
 
 SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name)
 {
-       int error;
+       struct oldold_utsname tmp = {};
 
        if (!name)
                return -EFAULT;
-       if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
-               return -EFAULT;
 
        down_read(&uts_sem);
-       error = __copy_to_user(&name->sysname, &utsname()->sysname,
-                              __OLD_UTS_LEN);
-       error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
-       error |= __copy_to_user(&name->nodename, &utsname()->nodename,
-                               __OLD_UTS_LEN);
-       error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
-       error |= __copy_to_user(&name->release, &utsname()->release,
-                               __OLD_UTS_LEN);
-       error |= __put_user(0, name->release + __OLD_UTS_LEN);
-       error |= __copy_to_user(&name->version, &utsname()->version,
-                               __OLD_UTS_LEN);
-       error |= __put_user(0, name->version + __OLD_UTS_LEN);
-       error |= __copy_to_user(&name->machine, &utsname()->machine,
-                               __OLD_UTS_LEN);
-       error |= __put_user(0, name->machine + __OLD_UTS_LEN);
+       memcpy(&tmp.sysname, &utsname()->sysname, __OLD_UTS_LEN);
+       memcpy(&tmp.nodename, &utsname()->nodename, __OLD_UTS_LEN);
+       memcpy(&tmp.release, &utsname()->release, __OLD_UTS_LEN);
+       memcpy(&tmp.version, &utsname()->version, __OLD_UTS_LEN);
+       memcpy(&tmp.machine, &utsname()->machine, __OLD_UTS_LEN);
        up_read(&uts_sem);
+       if (copy_to_user(name, &tmp, sizeof(tmp)))
+               return -EFAULT;
 
-       if (!error && override_architecture(name))
-               error = -EFAULT;
-       if (!error && override_release(name->release, sizeof(name->release)))
-               error = -EFAULT;
-       return error ? -EFAULT : 0;
+       if (override_architecture(name))
+               return -EFAULT;
+       if (override_release(name->release, sizeof(name->release)))
+               return -EFAULT;
+       return 0;
 }
 #endif
 
@@ -1319,17 +1311,18 @@ SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
 
        if (len < 0 || len > __NEW_UTS_LEN)
                return -EINVAL;
-       down_write(&uts_sem);
        errno = -EFAULT;
        if (!copy_from_user(tmp, name, len)) {
-               struct new_utsname *u = utsname();
+               struct new_utsname *u;
 
+               down_write(&uts_sem);
+               u = utsname();
                memcpy(u->nodename, tmp, len);
                memset(u->nodename + len, 0, sizeof(u->nodename) - len);
                errno = 0;
                uts_proc_notify(UTS_PROC_HOSTNAME);
+               up_write(&uts_sem);
        }
-       up_write(&uts_sem);
        return errno;
 }
 
@@ -1337,8 +1330,9 @@ SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
 
 SYSCALL_DEFINE2(gethostname, char __user *, name, int, len)
 {
-       int i, errno;
+       int i;
        struct new_utsname *u;
+       char tmp[__NEW_UTS_LEN + 1];
 
        if (len < 0)
                return -EINVAL;
@@ -1347,11 +1341,11 @@ SYSCALL_DEFINE2(gethostname, char __user *, name, int, len)
        i = 1 + strlen(u->nodename);
        if (i > len)
                i = len;
-       errno = 0;
-       if (copy_to_user(name, u->nodename, i))
-               errno = -EFAULT;
+       memcpy(tmp, u->nodename, i);
        up_read(&uts_sem);
-       return errno;
+       if (copy_to_user(name, tmp, i))
+               return -EFAULT;
+       return 0;
 }
 
 #endif
@@ -1370,17 +1364,18 @@ SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len)
        if (len < 0 || len > __NEW_UTS_LEN)
                return -EINVAL;
 
-       down_write(&uts_sem);
        errno = -EFAULT;
        if (!copy_from_user(tmp, name, len)) {
-               struct new_utsname *u = utsname();
+               struct new_utsname *u;
 
+               down_write(&uts_sem);
+               u = utsname();
                memcpy(u->domainname, tmp, len);
                memset(u->domainname + len, 0, sizeof(u->domainname) - len);
                errno = 0;
                uts_proc_notify(UTS_PROC_DOMAINNAME);
+               up_write(&uts_sem);
        }
-       up_write(&uts_sem);
        return errno;
 }
 
index f22f76b7a138ceedcc5392a24f493ec04366bc1b..cc02050fd0c493378228eb6960e15449754f1387 100644 (file)
@@ -145,7 +145,10 @@ static int minolduid;
 static int ngroups_max = NGROUPS_MAX;
 static const int cap_last_cap = CAP_LAST_CAP;
 
-/*this is needed for proc_doulongvec_minmax of sysctl_hung_task_timeout_secs */
+/*
+ * This is needed for proc_doulongvec_minmax of sysctl_hung_task_timeout_secs
+ * and hung_task_check_interval_secs
+ */
 #ifdef CONFIG_DETECT_HUNG_TASK
 static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
 #endif
@@ -222,7 +225,7 @@ static int proc_dopipe_max_size(struct ctl_table *table, int write,
                void __user *buffer, size_t *lenp, loff_t *ppos);
 
 #ifdef CONFIG_MAGIC_SYSRQ
-/* Note: sysrq code uses it's own private copy */
+/* Note: sysrq code uses its own private copy */
 static int __sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE;
 
 static int sysrq_sysctl_handler(struct ctl_table *table, int write,
@@ -1090,6 +1093,14 @@ static struct ctl_table kern_table[] = {
                .proc_handler   = proc_dohung_task_timeout_secs,
                .extra2         = &hung_task_timeout_max,
        },
+       {
+               .procname       = "hung_task_check_interval_secs",
+               .data           = &sysctl_hung_task_check_interval_secs,
+               .maxlen         = sizeof(unsigned long),
+               .mode           = 0644,
+               .proc_handler   = proc_dohung_task_timeout_secs,
+               .extra2         = &hung_task_timeout_max,
+       },
        {
                .procname       = "hung_task_warnings",
                .data           = &sysctl_hung_task_warnings,
@@ -1796,6 +1807,24 @@ static struct ctl_table fs_table[] = {
                .extra1         = &zero,
                .extra2         = &one,
        },
+       {
+               .procname       = "protected_fifos",
+               .data           = &sysctl_protected_fifos,
+               .maxlen         = sizeof(int),
+               .mode           = 0600,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &zero,
+               .extra2         = &two,
+       },
+       {
+               .procname       = "protected_regular",
+               .data           = &sysctl_protected_regular,
+               .maxlen         = sizeof(int),
+               .mode           = 0600,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &zero,
+               .extra2         = &two,
+       },
        {
                .procname       = "suid_dumpable",
                .data           = &suid_dumpable,
@@ -1965,13 +1994,13 @@ static void warn_sysctl_write(struct ctl_table *table)
 }
 
 /**
- * proc_first_pos_non_zero_ignore - check if firs position is allowed
+ * proc_first_pos_non_zero_ignore - check if first position is allowed
  * @ppos: file position
  * @table: the sysctl table
  *
  * Returns true if the first position is non-zero and the sysctl_writes_strict
  * mode indicates this is not allowed for numeric input types. String proc
- * hadlers can ignore the return value.
+ * handlers can ignore the return value.
  */
 static bool proc_first_pos_non_zero_ignore(loff_t *ppos,
                                           struct ctl_table *table)
index f74fb00d806444739f9d8ee1611a98c694325f95..0e6e97a01942d956e6135025003371537ca28ab0 100644 (file)
@@ -133,19 +133,40 @@ static void inline clocksource_watchdog_unlock(unsigned long *flags)
        spin_unlock_irqrestore(&watchdog_lock, *flags);
 }
 
+static int clocksource_watchdog_kthread(void *data);
+static void __clocksource_change_rating(struct clocksource *cs, int rating);
+
 /*
  * Interval: 0.5sec Threshold: 0.0625s
  */
 #define WATCHDOG_INTERVAL (HZ >> 1)
 #define WATCHDOG_THRESHOLD (NSEC_PER_SEC >> 4)
 
+static void clocksource_watchdog_work(struct work_struct *work)
+{
+       /*
+        * We cannot directly run clocksource_watchdog_kthread() here, because
+        * clocksource_select() calls timekeeping_notify() which uses
+        * stop_machine(). One cannot use stop_machine() from a workqueue() due
+        * lock inversions wrt CPU hotplug.
+        *
+        * Also, we only ever run this work once or twice during the lifetime
+        * of the kernel, so there is no point in creating a more permanent
+        * kthread for this.
+        *
+        * If kthread_run fails the next watchdog scan over the
+        * watchdog_list will find the unstable clock again.
+        */
+       kthread_run(clocksource_watchdog_kthread, NULL, "kwatchdog");
+}
+
 static void __clocksource_unstable(struct clocksource *cs)
 {
        cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG);
        cs->flags |= CLOCK_SOURCE_UNSTABLE;
 
        /*
-        * If the clocksource is registered clocksource_watchdog_work() will
+        * If the clocksource is registered clocksource_watchdog_kthread() will
         * re-rate and re-select.
         */
        if (list_empty(&cs->list)) {
@@ -156,7 +177,7 @@ static void __clocksource_unstable(struct clocksource *cs)
        if (cs->mark_unstable)
                cs->mark_unstable(cs);
 
-       /* kick clocksource_watchdog_work() */
+       /* kick clocksource_watchdog_kthread() */
        if (finished_booting)
                schedule_work(&watchdog_work);
 }
@@ -166,7 +187,7 @@ static void __clocksource_unstable(struct clocksource *cs)
  * @cs:                clocksource to be marked unstable
  *
  * This function is called by the x86 TSC code to mark clocksources as unstable;
- * it defers demotion and re-selection to a work.
+ * it defers demotion and re-selection to a kthread.
  */
 void clocksource_mark_unstable(struct clocksource *cs)
 {
@@ -391,9 +412,7 @@ static void clocksource_dequeue_watchdog(struct clocksource *cs)
        }
 }
 
-static void __clocksource_change_rating(struct clocksource *cs, int rating);
-
-static int __clocksource_watchdog_work(void)
+static int __clocksource_watchdog_kthread(void)
 {
        struct clocksource *cs, *tmp;
        unsigned long flags;
@@ -418,12 +437,13 @@ static int __clocksource_watchdog_work(void)
        return select;
 }
 
-static void clocksource_watchdog_work(struct work_struct *work)
+static int clocksource_watchdog_kthread(void *data)
 {
        mutex_lock(&clocksource_mutex);
-       if (__clocksource_watchdog_work())
+       if (__clocksource_watchdog_kthread())
                clocksource_select();
        mutex_unlock(&clocksource_mutex);
+       return 0;
 }
 
 static bool clocksource_is_watchdog(struct clocksource *cs)
@@ -442,7 +462,7 @@ static void clocksource_enqueue_watchdog(struct clocksource *cs)
 static void clocksource_select_watchdog(bool fallback) { }
 static inline void clocksource_dequeue_watchdog(struct clocksource *cs) { }
 static inline void clocksource_resume_watchdog(void) { }
-static inline int __clocksource_watchdog_work(void) { return 0; }
+static inline int __clocksource_watchdog_kthread(void) { return 0; }
 static bool clocksource_is_watchdog(struct clocksource *cs) { return false; }
 void clocksource_mark_unstable(struct clocksource *cs) { }
 
@@ -810,7 +830,7 @@ static int __init clocksource_done_booting(void)
        /*
         * Run the watchdog first to eliminate unstable clock sources
         */
-       __clocksource_watchdog_work();
+       __clocksource_watchdog_kthread();
        clocksource_select();
        mutex_unlock(&clocksource_mutex);
        return 0;
index f26acef5d7b485ad397c21bb5466f0a332006087..9a65713c83093f343466bd4ed0c5435d4077309c 100644 (file)
@@ -139,9 +139,10 @@ enum hrtimer_restart it_real_fn(struct hrtimer *timer)
 {
        struct signal_struct *sig =
                container_of(timer, struct signal_struct, real_timer);
+       struct pid *leader_pid = sig->pids[PIDTYPE_TGID];
 
-       trace_itimer_expire(ITIMER_REAL, sig->leader_pid, 0);
-       kill_pid_info(SIGALRM, SEND_SIG_PRIV, sig->leader_pid);
+       trace_itimer_expire(ITIMER_REAL, leader_pid, 0);
+       kill_pid_info(SIGALRM, SEND_SIG_PRIV, leader_pid);
 
        return HRTIMER_NORESTART;
 }
index 294d7b65af33638bd978d279bf4fa53448efd7a8..ce32cf741b250939de562ab05bd598fb30f10986 100644 (file)
@@ -894,7 +894,7 @@ static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it,
 
                trace_itimer_expire(signo == SIGPROF ?
                                    ITIMER_PROF : ITIMER_VIRTUAL,
-                                   tsk->signal->leader_pid, cur_time);
+                                   task_tgid(tsk), cur_time);
                __group_send_sig_info(signo, SEND_SIG_PRIV, tsk);
        }
 
index f23cc46ecf3ed10bbd0bd940c87f3e813dd5bf4c..4b9127e95430b7acb097747e3a8552b2cff68d81 100644 (file)
@@ -333,8 +333,8 @@ void posixtimer_rearm(struct siginfo *info)
 
 int posix_timer_event(struct k_itimer *timr, int si_private)
 {
-       struct task_struct *task;
-       int shared, ret = -1;
+       enum pid_type type;
+       int ret = -1;
        /*
         * FIXME: if ->sigq is queued we can race with
         * dequeue_signal()->posixtimer_rearm().
@@ -348,13 +348,8 @@ int posix_timer_event(struct k_itimer *timr, int si_private)
         */
        timr->sigq->info.si_sys_private = si_private;
 
-       rcu_read_lock();
-       task = pid_task(timr->it_pid, PIDTYPE_PID);
-       if (task) {
-               shared = !(timr->it_sigev_notify & SIGEV_THREAD_ID);
-               ret = send_sigqueue(timr->sigq, task, shared);
-       }
-       rcu_read_unlock();
+       type = !(timr->it_sigev_notify & SIGEV_THREAD_ID) ? PIDTYPE_TGID : PIDTYPE_PID;
+       ret = send_sigqueue(timr->sigq, timr->it_pid, type);
        /* If we failed to send the signal the timer stops. */
        return ret > 0;
 }
@@ -433,11 +428,13 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
 
 static struct pid *good_sigevent(sigevent_t * event)
 {
-       struct task_struct *rtn = current->group_leader;
+       struct pid *pid = task_tgid(current);
+       struct task_struct *rtn;
 
        switch (event->sigev_notify) {
        case SIGEV_SIGNAL | SIGEV_THREAD_ID:
-               rtn = find_task_by_vpid(event->sigev_notify_thread_id);
+               pid = find_vpid(event->sigev_notify_thread_id);
+               rtn = pid_task(pid, PIDTYPE_PID);
                if (!rtn || !same_thread_group(rtn, current))
                        return NULL;
                /* FALLTHRU */
@@ -447,7 +444,7 @@ static struct pid *good_sigevent(sigevent_t * event)
                        return NULL;
                /* FALLTHRU */
        case SIGEV_NONE:
-               return task_pid(rtn);
+               return pid;
        default:
                return NULL;
        }
index 9a27f146fa1c4b897b5fbe3a47fee40d81a50cd9..5e3de28c7677396aaa4360dcf2f51fb9b365b626 100644 (file)
@@ -47,6 +47,11 @@ config HAVE_FENTRY
        help
          Arch supports the gcc options -pg with -mfentry
 
+config HAVE_NOP_MCOUNT
+       bool
+       help
+         Arch supports the gcc options -pg with -mrecord-mcount and -nop-mcount
+
 config HAVE_C_RECORDMCOUNT
        bool
        help
@@ -82,6 +87,15 @@ config RING_BUFFER_ALLOW_SWAP
         Allow the use of ring_buffer_swap_cpu.
         Adds a very slight overhead to tracing when enabled.
 
+config PREEMPTIRQ_TRACEPOINTS
+       bool
+       depends on TRACE_PREEMPT_TOGGLE || TRACE_IRQFLAGS
+       select TRACING
+       default y
+       help
+         Create preempt/irq toggle tracepoints if needed, so that other parts
+         of the kernel can use them to generate or add hooks to them.
+
 # All tracer options should select GENERIC_TRACER. For those options that are
 # enabled by all tracers (context switch and event tracer) they select TRACING.
 # This allows those options to appear when no other tracer is selected. But the
@@ -155,18 +169,20 @@ config FUNCTION_GRAPH_TRACER
          the return value. This is done by setting the current return
          address on the current task structure into a stack of calls.
 
+config TRACE_PREEMPT_TOGGLE
+       bool
+       help
+         Enables hooks which will be called when preemption is first disabled,
+         and last enabled.
 
 config PREEMPTIRQ_EVENTS
        bool "Enable trace events for preempt and irq disable/enable"
        select TRACE_IRQFLAGS
-       depends on DEBUG_PREEMPT || !PROVE_LOCKING
-       depends on TRACING
+       select TRACE_PREEMPT_TOGGLE if PREEMPT
+       select GENERIC_TRACER
        default n
        help
          Enable tracing of disable and enable events for preemption and irqs.
-         For tracing preempt disable/enable events, DEBUG_PREEMPT must be
-         enabled. For tracing irq disable/enable events, PROVE_LOCKING must
-         be disabled.
 
 config IRQSOFF_TRACER
        bool "Interrupts-off Latency Tracer"
@@ -203,6 +219,7 @@ config PREEMPT_TRACER
        select RING_BUFFER_ALLOW_SWAP
        select TRACER_SNAPSHOT
        select TRACER_SNAPSHOT_PER_CPU_SWAP
+       select TRACE_PREEMPT_TOGGLE
        help
          This option measures the time spent in preemption-off critical
          sections, with microsecond accuracy.
@@ -456,6 +473,26 @@ config KPROBE_EVENTS
          This option is also required by perf-probe subcommand of perf tools.
          If you want to use perf tools, this option is strongly recommended.
 
+config KPROBE_EVENTS_ON_NOTRACE
+       bool "Do NOT protect notrace function from kprobe events"
+       depends on KPROBE_EVENTS
+       depends on KPROBES_ON_FTRACE
+       default n
+       help
+         This is only for the developers who want to debug ftrace itself
+         using kprobe events.
+
+         If kprobes can use ftrace instead of breakpoint, ftrace related
+         functions are protected from kprobe-events to prevent an infinit
+         recursion or any unexpected execution path which leads to a kernel
+         crash.
+
+         This option disables such protection and allows you to put kprobe
+         events on ftrace functions for debugging ftrace by itself.
+         Note that this might let you shoot yourself in the foot.
+
+         If unsure, say N.
+
 config UPROBE_EVENTS
        bool "Enable uprobes-based dynamic events"
        depends on ARCH_SUPPORTS_UPROBES
@@ -687,6 +724,21 @@ config RING_BUFFER_STARTUP_TEST
 
         If unsure, say N
 
+config PREEMPTIRQ_DELAY_TEST
+       tristate "Preempt / IRQ disable delay thread to test latency tracers"
+       depends on m
+       help
+         Select this option to build a test module that can help test latency
+         tracers by executing a preempt or irq disable section with a user
+         configurable delay. The module busy waits for the duration of the
+         critical section.
+
+         For example, the following invocation forces a one-time irq-disabled
+         critical section for 500us:
+         modprobe preemptirq_delay_test test_mode=irq delay=500000
+
+         If unsure, say N
+
 config TRACE_EVAL_MAP_FILE
        bool "Show eval mappings for trace events"
        depends on TRACING
@@ -722,6 +774,18 @@ config TRACING_EVENTS_GPIO
        help
          Enable tracing events for gpio subsystem
 
+config GCOV_PROFILE_FTRACE
+       bool "Enable GCOV profiling on ftrace subsystem"
+       depends on GCOV_KERNEL
+       help
+         Enable GCOV profiling on ftrace subsystem for checking
+         which functions/lines are tested.
+
+         If unsure, say N.
+
+         Note that on a kernel compiled with this config, ftrace will
+         run significantly slower.
+
 endif # FTRACE
 
 endif # TRACING_SUPPORT
index e2538c7638d44d635542382a11df6d803d6af1c5..f81dadbc7c4ac3ef35c031d1164edf1b3b82d034 100644 (file)
@@ -13,11 +13,21 @@ obj-y += trace_selftest_dynamic.o
 endif
 endif
 
+ifdef CONFIG_FTRACE_STARTUP_TEST
+CFLAGS_trace_kprobe_selftest.o = $(CC_FLAGS_FTRACE)
+obj-$(CONFIG_KPROBE_EVENTS) += trace_kprobe_selftest.o
+endif
+
 # If unlikely tracing is enabled, do not trace these files
 ifdef CONFIG_TRACING_BRANCHES
 KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
 endif
 
+# for GCOV coverage profiling
+ifdef CONFIG_GCOV_PROFILE_FTRACE
+GCOV_PROFILE := y
+endif
+
 CFLAGS_trace_benchmark.o := -I$(src)
 CFLAGS_trace_events_filter.o := -I$(src)
 
@@ -33,9 +43,10 @@ obj-$(CONFIG_TRACING) += trace_seq.o
 obj-$(CONFIG_TRACING) += trace_stat.o
 obj-$(CONFIG_TRACING) += trace_printk.o
 obj-$(CONFIG_TRACING_MAP) += tracing_map.o
+obj-$(CONFIG_PREEMPTIRQ_DELAY_TEST) += preemptirq_delay_test.o
 obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o
 obj-$(CONFIG_FUNCTION_TRACER) += trace_functions.o
-obj-$(CONFIG_PREEMPTIRQ_EVENTS) += trace_irqsoff.o
+obj-$(CONFIG_PREEMPTIRQ_TRACEPOINTS) += trace_preemptirq.o
 obj-$(CONFIG_IRQSOFF_TRACER) += trace_irqsoff.o
 obj-$(CONFIG_PREEMPT_TRACER) += trace_irqsoff.o
 obj-$(CONFIG_SCHED_TRACER) += trace_sched_wakeup.o
index b951aa1fac6177cbed5e7a8d19de6a938bc2c241..2868d85f1fb1d3286984c4727f0519957ac069a9 100644 (file)
@@ -1,19 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2006 Jens Axboe <axboe@kernel.dk>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
  */
 #include <linux/kernel.h>
 #include <linux/blkdev.h>
@@ -1841,6 +1829,10 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
        mutex_lock(&q->blk_trace_mutex);
 
        if (attr == &dev_attr_enable) {
+               if (!!value == !!q->blk_trace) {
+                       ret = 0;
+                       goto out_unlock_bdev;
+               }
                if (value)
                        ret = blk_trace_setup_queue(q, bdev);
                else
index 0ae6829804bc8eb4df935c043efe4d49e254f406..08fcfe440c6374e336b02c1dde33a478fc58615a 100644 (file)
@@ -1,9 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /* Copyright (c) 2011-2015 PLUMgrid, http://plumgrid.com
  * Copyright (c) 2016 Facebook
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
  */
 #include <linux/kernel.h>
 #include <linux/types.h>
index caf9cbf3581683ace69577fd2f365ba039138cea..f536f601bd46e321a5ae77b2fbb0f3d642edb13e 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Infrastructure for profiling code inserted by 'gcc -pg'.
  *
@@ -157,30 +158,6 @@ static inline void ftrace_ops_init(struct ftrace_ops *ops)
 #endif
 }
 
-/**
- * ftrace_nr_registered_ops - return number of ops registered
- *
- * Returns the number of ftrace_ops registered and tracing functions
- */
-int ftrace_nr_registered_ops(void)
-{
-       struct ftrace_ops *ops;
-       int cnt = 0;
-
-       mutex_lock(&ftrace_lock);
-
-       for (ops = rcu_dereference_protected(ftrace_ops_list,
-                                            lockdep_is_held(&ftrace_lock));
-            ops != &ftrace_list_end;
-            ops = rcu_dereference_protected(ops->next,
-                                            lockdep_is_held(&ftrace_lock)))
-               cnt++;
-
-       mutex_unlock(&ftrace_lock);
-
-       return cnt;
-}
-
 static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip,
                            struct ftrace_ops *op, struct pt_regs *regs)
 {
@@ -313,11 +290,6 @@ static void update_ftrace_function(void)
        ftrace_trace_function = func;
 }
 
-int using_ftrace_ops_list_func(void)
-{
-       return ftrace_trace_function == ftrace_ops_list_func;
-}
-
 static void add_ftrace_ops(struct ftrace_ops __rcu **list,
                           struct ftrace_ops *ops)
 {
@@ -1049,8 +1021,6 @@ static __init void ftrace_profile_tracefs(struct dentry *d_tracer)
 }
 #endif /* CONFIG_FUNCTION_PROFILER */
 
-static struct pid * const ftrace_swapper_pid = &init_struct_pid;
-
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 static int ftrace_graph_active;
 #else
@@ -2927,22 +2897,22 @@ ops_references_rec(struct ftrace_ops *ops, struct dyn_ftrace *rec)
 {
        /* If ops isn't enabled, ignore it */
        if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
-               return 0;
+               return false;
 
        /* If ops traces all then it includes this function */
        if (ops_traces_mod(ops))
-               return 1;
+               return true;
 
        /* The function must be in the filter */
        if (!ftrace_hash_empty(ops->func_hash->filter_hash) &&
            !__ftrace_lookup_ip(ops->func_hash->filter_hash, rec->ip))
-               return 0;
+               return false;
 
        /* If in notrace hash, we ignore it too */
        if (ftrace_lookup_ip(ops->func_hash->notrace_hash, rec->ip))
-               return 0;
+               return false;
 
-       return 1;
+       return true;
 }
 
 static int ftrace_update_code(struct module *mod, struct ftrace_page *new_pgs)
@@ -2981,12 +2951,14 @@ static int ftrace_update_code(struct module *mod, struct ftrace_page *new_pgs)
                        p = &pg->records[i];
                        p->flags = rec_flags;
 
+#ifndef CC_USING_NOP_MCOUNT
                        /*
                         * Do the initial record conversion from mcount jump
                         * to the NOP instructions.
                         */
                        if (!ftrace_code_disable(mod, p))
                                break;
+#endif
 
                        update_cnt++;
                }
diff --git a/kernel/trace/preemptirq_delay_test.c b/kernel/trace/preemptirq_delay_test.c
new file mode 100644 (file)
index 0000000..f704390
--- /dev/null
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Preempt / IRQ disable delay thread to test latency tracers
+ *
+ * Copyright (C) 2018 Joel Fernandes (Google) <joel@joelfernandes.org>
+ */
+
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/ktime.h>
+#include <linux/module.h>
+#include <linux/printk.h>
+#include <linux/string.h>
+
+static ulong delay = 100;
+static char test_mode[10] = "irq";
+
+module_param_named(delay, delay, ulong, S_IRUGO);
+module_param_string(test_mode, test_mode, 10, S_IRUGO);
+MODULE_PARM_DESC(delay, "Period in microseconds (100 uS default)");
+MODULE_PARM_DESC(test_mode, "Mode of the test such as preempt or irq (default irq)");
+
+static void busy_wait(ulong time)
+{
+       ktime_t start, end;
+       start = ktime_get();
+       do {
+               end = ktime_get();
+               if (kthread_should_stop())
+                       break;
+       } while (ktime_to_ns(ktime_sub(end, start)) < (time * 1000));
+}
+
+static int preemptirq_delay_run(void *data)
+{
+       unsigned long flags;
+
+       if (!strcmp(test_mode, "irq")) {
+               local_irq_save(flags);
+               busy_wait(delay);
+               local_irq_restore(flags);
+       } else if (!strcmp(test_mode, "preempt")) {
+               preempt_disable();
+               busy_wait(delay);
+               preempt_enable();
+       }
+
+       return 0;
+}
+
+static int __init preemptirq_delay_init(void)
+{
+       char task_name[50];
+       struct task_struct *test_task;
+
+       snprintf(task_name, sizeof(task_name), "%s_test", test_mode);
+
+       test_task = kthread_run(preemptirq_delay_run, NULL, task_name);
+       return PTR_ERR_OR_ZERO(test_task);
+}
+
+static void __exit preemptirq_delay_exit(void)
+{
+       return;
+}
+
+module_init(preemptirq_delay_init)
+module_exit(preemptirq_delay_exit)
+MODULE_LICENSE("GPL v2");
index 0b0b688ea166f29bd73b22ef302f3cb3776ea424..1d92d4a982fd468385b4b81b145d6e6353a766d4 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Generic ring buffer
  *
@@ -3221,7 +3222,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_record_on);
  *
  * Returns true if the ring buffer is in a state that it accepts writes.
  */
-int ring_buffer_record_is_on(struct ring_buffer *buffer)
+bool ring_buffer_record_is_on(struct ring_buffer *buffer)
 {
        return !atomic_read(&buffer->record_disabled);
 }
@@ -3237,7 +3238,7 @@ int ring_buffer_record_is_on(struct ring_buffer *buffer)
  * ring_buffer_record_disable(), as that is a temporary disabling of
  * the ring buffer.
  */
-int ring_buffer_record_is_set_on(struct ring_buffer *buffer)
+bool ring_buffer_record_is_set_on(struct ring_buffer *buffer)
 {
        return !(atomic_read(&buffer->record_disabled) & RB_BUFFER_OFF);
 }
index 68ee79afe31c223218e8fab1ffd829b7be1226d3..ffba6789c0e2442044ee24a5176982d86d7ac625 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * ring buffer tester and benchmark
  *
index 176debd3481b330b17b4a83e1bfa511887441ca2..bf6f1d70484dc02a449fa71b73b753649b698715 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * ring buffer based function tracer
  *
@@ -1087,7 +1088,7 @@ void disable_trace_on_warning(void)
  *
  * Shows real state of the ring buffer if it is enabled or not.
  */
-int tracer_tracing_is_on(struct trace_array *tr)
+bool tracer_tracing_is_on(struct trace_array *tr)
 {
        if (tr->trace_buffer.buffer)
                return ring_buffer_record_is_on(tr->trace_buffer.buffer);
@@ -7628,7 +7629,9 @@ rb_simple_write(struct file *filp, const char __user *ubuf,
 
        if (buffer) {
                mutex_lock(&trace_types_lock);
-               if (val) {
+               if (!!val == tracer_tracing_is_on(tr)) {
+                       val = 0; /* do nothing */
+               } else if (val) {
                        tracer_tracing_on(tr);
                        if (tr->current_trace->start)
                                tr->current_trace->start(tr);
index f8f86231ad90e48b73b7eb2dc8d1def48071219a..3b8c0e24ab306f5f1ca1d6194749a266baa14fc5 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+// SPDX-License-Identifier: GPL-2.0
 
 #ifndef _LINUX_KERNEL_TRACE_H
 #define _LINUX_KERNEL_TRACE_H
@@ -594,7 +594,7 @@ void tracing_reset_current(int cpu);
 void tracing_reset_all_online_cpus(void);
 int tracing_open_generic(struct inode *inode, struct file *filp);
 bool tracing_is_disabled(void);
-int tracer_tracing_is_on(struct trace_array *tr);
+bool tracer_tracing_is_on(struct trace_array *tr);
 void tracer_tracing_on(struct trace_array *tr);
 void tracer_tracing_off(struct trace_array *tr);
 struct dentry *trace_create_file(const char *name,
@@ -937,7 +937,6 @@ void ftrace_destroy_function_files(struct trace_array *tr);
 void ftrace_init_global_array_ops(struct trace_array *tr);
 void ftrace_init_array_ops(struct trace_array *tr, ftrace_func_t func);
 void ftrace_reset_array_ops(struct trace_array *tr);
-int using_ftrace_ops_list_func(void);
 void ftrace_init_tracefs(struct trace_array *tr, struct dentry *d_tracer);
 void ftrace_init_tracefs_toplevel(struct trace_array *tr,
                                  struct dentry *d_tracer);
@@ -1533,9 +1532,6 @@ extern int event_trigger_init(struct event_trigger_ops *ops,
 extern int trace_event_trigger_enable_disable(struct trace_event_file *file,
                                              int trigger_enable);
 extern void update_cond_flag(struct trace_event_file *file);
-extern void unregister_trigger(char *glob, struct event_trigger_ops *ops,
-                              struct event_trigger_data *test,
-                              struct trace_event_file *file);
 extern int set_trigger_filter(char *filter_str,
                              struct event_trigger_data *trigger_data,
                              struct trace_event_file *file);
@@ -1831,6 +1827,21 @@ static inline int tracing_alloc_snapshot_instance(struct trace_array *tr)
 }
 #endif
 
+#ifdef CONFIG_PREEMPT_TRACER
+void tracer_preempt_on(unsigned long a0, unsigned long a1);
+void tracer_preempt_off(unsigned long a0, unsigned long a1);
+#else
+static inline void tracer_preempt_on(unsigned long a0, unsigned long a1) { }
+static inline void tracer_preempt_off(unsigned long a0, unsigned long a1) { }
+#endif
+#ifdef CONFIG_IRQSOFF_TRACER
+void tracer_hardirqs_on(unsigned long a0, unsigned long a1);
+void tracer_hardirqs_off(unsigned long a0, unsigned long a1);
+#else
+static inline void tracer_hardirqs_on(unsigned long a0, unsigned long a1) { }
+static inline void tracer_hardirqs_off(unsigned long a0, unsigned long a1) { }
+#endif
+
 extern struct trace_iterator *tracepoint_print_iter;
 
 #endif /* _LINUX_KERNEL_TRACE_H */
index be1d86ff753d05d8621912ae4ad926454cd270bf..79e6fbe5b3658d8cc2fc392e0208c7a773ea4e31 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+// SPDX-License-Identifier: GPL-2.0
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM benchmark
 
index d8a188e0418aa9ad31798d9fb5cb3320a409d1b2..aaf6793ededaa2b4a1aab5ea6653bd82c110ba4f 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * tracing clocks
  *
index 1d67464ed95ed4f63795562727e9d58fd8d845d9..06bb2fd9a56c596c00c4c5e1a93c081e10dd8bc8 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+// SPDX-License-Identifier: GPL-2.0
 /*
  * This file defines the trace event structures that go into the ring
  * buffer directly. They are created via macros so that changes for them
index c79193e598f54fe928d331588d7169c6e0154de1..69a3fe926e8cf9aeb28bb3d4fb712398fe12d2d5 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * trace event based perf event profiling/tracing
  *
index 14ff4ff3caab8a4e8948de05489b5c4b1cb35a30..f94be0c2827b0e04aa78fdde06c78674647cc4f7 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * event tracer
  *
@@ -239,7 +240,7 @@ bool trace_event_ignore_this_pid(struct trace_event_file *trace_file)
        struct trace_array_cpu *data;
        struct trace_pid_list *pid_list;
 
-       pid_list = rcu_dereference_sched(tr->filtered_pids);
+       pid_list = rcu_dereference_raw(tr->filtered_pids);
        if (!pid_list)
                return false;
 
@@ -512,7 +513,7 @@ event_filter_pid_sched_process_exit(void *data, struct task_struct *task)
        struct trace_pid_list *pid_list;
        struct trace_array *tr = data;
 
-       pid_list = rcu_dereference_sched(tr->filtered_pids);
+       pid_list = rcu_dereference_raw(tr->filtered_pids);
        trace_filter_add_remove_task(pid_list, NULL, task);
 }
 
@@ -636,7 +637,7 @@ static void __ftrace_clear_event_pids(struct trace_array *tr)
        rcu_assign_pointer(tr->filtered_pids, NULL);
 
        /* Wait till all users are no longer using pid filtering */
-       synchronize_sched();
+       tracepoint_synchronize_unregister();
 
        trace_free_pid_list(pid_list);
 }
@@ -1622,7 +1623,7 @@ ftrace_event_pid_write(struct file *filp, const char __user *ubuf,
        }
 
        if (filtered_pids) {
-               synchronize_sched();
+               tracepoint_synchronize_unregister();
                trace_free_pid_list(filtered_pids);
        } else if (pid_list) {
                /*
@@ -3036,8 +3037,8 @@ int event_trace_del_tracer(struct trace_array *tr)
        /* Disable any running events */
        __ftrace_set_clr_event_nolock(tr, NULL, NULL, NULL, 0);
 
-       /* Access to events are within rcu_read_lock_sched() */
-       synchronize_sched();
+       /* Make sure no more events are being executed */
+       tracepoint_synchronize_unregister();
 
        down_write(&trace_event_sem);
        __trace_remove_event_dirs(tr);
index 893a206bcba4f76dd504e246d9667475fd7ed456..84a65173b1e91dc347e5d98b1a831da42c1bd7bb 100644 (file)
@@ -1,20 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * trace_events_filter - generic event filtering
  *
- * This program is free software; 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 (C) 2009 Tom Zanussi <tzanussi@gmail.com>
  */
 
@@ -899,7 +886,8 @@ int filter_match_preds(struct event_filter *filter, void *rec)
        if (!filter)
                return 1;
 
-       prog = rcu_dereference_sched(filter->prog);
+       /* Protected by either SRCU(tracepoint_srcu) or preempt_disable */
+       prog = rcu_dereference_raw(filter->prog);
        if (!prog)
                return 1;
 
@@ -1626,10 +1614,10 @@ static int process_system_preds(struct trace_subsystem_dir *dir,
 
        /*
         * The calls can still be using the old filters.
-        * Do a synchronize_sched() to ensure all calls are
+        * Do a synchronize_sched() and to ensure all calls are
         * done with them before we free them.
         */
-       synchronize_sched();
+       tracepoint_synchronize_unregister();
        list_for_each_entry_safe(filter_item, tmp, &filter_list, list) {
                __free_filter(filter_item->filter);
                list_del(&filter_item->list);
@@ -1648,7 +1636,7 @@ static int process_system_preds(struct trace_subsystem_dir *dir,
        kfree(filter);
        /* If any call succeeded, we still need to sync */
        if (!fail)
-               synchronize_sched();
+               tracepoint_synchronize_unregister();
        list_for_each_entry_safe(filter_item, tmp, &filter_list, list) {
                __free_filter(filter_item->filter);
                list_del(&filter_item->list);
@@ -1790,7 +1778,7 @@ int apply_event_filter(struct trace_event_file *file, char *filter_string)
                event_clear_filter(file);
 
                /* Make sure the filter is not being used */
-               synchronize_sched();
+               tracepoint_synchronize_unregister();
                __free_filter(filter);
 
                return 0;
@@ -1817,7 +1805,7 @@ int apply_event_filter(struct trace_event_file *file, char *filter_string)
 
                if (tmp) {
                        /* Make sure the call is done with the filter */
-                       synchronize_sched();
+                       tracepoint_synchronize_unregister();
                        __free_filter(tmp);
                }
        }
@@ -1847,7 +1835,7 @@ int apply_subsystem_event_filter(struct trace_subsystem_dir *dir,
                filter = system->filter;
                system->filter = NULL;
                /* Ensure all filters are no longer used */
-               synchronize_sched();
+               tracepoint_synchronize_unregister();
                filter_free_subsystem_filters(dir, tr);
                __free_filter(filter);
                goto out_unlock;
index 39d7ef4f57cb0678b487276dce5546dcfe550990..e651dfbd345e63ffd5ce091bce9062d8739fb263 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+// SPDX-License-Identifier: GPL-2.0
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM test
 
index aae18af94c94e61967063ac7534fe2979fdcec45..85f6b01431c766e342f3a4db2c6e859702f16dbf 100644 (file)
@@ -1,16 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * trace_events_hist - trace event hist triggers
  *
- * This program is free software; 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.
- *
  * Copyright (C) 2015 Tom Zanussi <tom.zanussi@linux.intel.com>
  */
 
@@ -5141,7 +5132,7 @@ static void hist_clear(struct event_trigger_data *data)
        if (data->name)
                pause_named_trigger(data);
 
-       synchronize_sched();
+       tracepoint_synchronize_unregister();
 
        tracing_map_clear(hist_data->map);
 
index 5dea177cef53120129c7d4a4d76eacb67ad66db0..2152d1e530cb5e8b8b1020840b1613b3099caebe 100644 (file)
@@ -1,20 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * trace_events_trigger - trace event triggers
  *
- * This program is free software; 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 (C) 2013 Tom Zanussi <tom.zanussi@linux.intel.com>
  */
 
@@ -34,7 +21,9 @@ void trigger_data_free(struct event_trigger_data *data)
        if (data->cmd_ops->set_filter)
                data->cmd_ops->set_filter(NULL, data, NULL);
 
-       synchronize_sched(); /* make sure current triggers exit before free */
+       /* make sure current triggers exit before free */
+       tracepoint_synchronize_unregister();
+
        kfree(data);
 }
 
@@ -579,9 +568,9 @@ out:
  * Usually used directly as the @unreg method in event command
  * implementations.
  */
-void unregister_trigger(char *glob, struct event_trigger_ops *ops,
-                       struct event_trigger_data *test,
-                       struct trace_event_file *file)
+static void unregister_trigger(char *glob, struct event_trigger_ops *ops,
+                              struct event_trigger_data *test,
+                              struct trace_event_file *file)
 {
        struct event_trigger_data *data;
        bool unregistered = false;
@@ -752,7 +741,7 @@ int set_trigger_filter(char *filter_str,
 
        if (tmp) {
                /* Make sure the call is done with the filter */
-               synchronize_sched();
+               tracepoint_synchronize_unregister();
                free_event_filter(tmp);
        }
 
index d7c8e4ec3d9d6cd92b6d78a2c66c984cbbc6fb6c..1e6db9cbe4dc518b0f0a482cf1c7e5eeffa0a3c4 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * trace_hwlatdetect.c - A simple Hardware Latency detector.
  *
@@ -35,9 +36,6 @@
  *
  * Includes useful feedback from Clark Williams <clark@redhat.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/kthread.h>
 #include <linux/tracefs.h>
@@ -354,6 +352,9 @@ static int start_kthread(struct trace_array *tr)
        struct task_struct *kthread;
        int next_cpu;
 
+       if (WARN_ON(hwlat_kthread))
+               return 0;
+
        /* Just pick the first CPU on first iteration */
        current_mask = &save_cpumask;
        get_online_cpus();
index 03ecb4465ee4587290e0474143f425f892771140..b7357f9f82a35456e4a51acf443b2b2019ea3d83 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * trace irqs off critical timings
  *
@@ -16,7 +17,6 @@
 
 #include "trace.h"
 
-#define CREATE_TRACE_POINTS
 #include <trace/events/preemptirq.h>
 
 #if defined(CONFIG_IRQSOFF_TRACER) || defined(CONFIG_PREEMPT_TRACER)
@@ -41,12 +41,12 @@ static int start_irqsoff_tracer(struct trace_array *tr, int graph);
 
 #ifdef CONFIG_PREEMPT_TRACER
 static inline int
-preempt_trace(void)
+preempt_trace(int pc)
 {
-       return ((trace_type & TRACER_PREEMPT_OFF) && preempt_count());
+       return ((trace_type & TRACER_PREEMPT_OFF) && pc);
 }
 #else
-# define preempt_trace() (0)
+# define preempt_trace(pc) (0)
 #endif
 
 #ifdef CONFIG_IRQSOFF_TRACER
@@ -367,7 +367,7 @@ out:
 }
 
 static inline void
-start_critical_timing(unsigned long ip, unsigned long parent_ip)
+start_critical_timing(unsigned long ip, unsigned long parent_ip, int pc)
 {
        int cpu;
        struct trace_array *tr = irqsoff_trace;
@@ -395,7 +395,7 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip)
 
        local_save_flags(flags);
 
-       __trace_function(tr, ip, parent_ip, flags, preempt_count());
+       __trace_function(tr, ip, parent_ip, flags, pc);
 
        per_cpu(tracing_cpu, cpu) = 1;
 
@@ -403,7 +403,7 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip)
 }
 
 static inline void
-stop_critical_timing(unsigned long ip, unsigned long parent_ip)
+stop_critical_timing(unsigned long ip, unsigned long parent_ip, int pc)
 {
        int cpu;
        struct trace_array *tr = irqsoff_trace;
@@ -429,7 +429,7 @@ stop_critical_timing(unsigned long ip, unsigned long parent_ip)
        atomic_inc(&data->disabled);
 
        local_save_flags(flags);
-       __trace_function(tr, ip, parent_ip, flags, preempt_count());
+       __trace_function(tr, ip, parent_ip, flags, pc);
        check_critical_timing(tr, data, parent_ip ? : ip, cpu);
        data->critical_start = 0;
        atomic_dec(&data->disabled);
@@ -438,77 +438,21 @@ stop_critical_timing(unsigned long ip, unsigned long parent_ip)
 /* start and stop critical timings used to for stoppage (in idle) */
 void start_critical_timings(void)
 {
-       if (preempt_trace() || irq_trace())
-               start_critical_timing(CALLER_ADDR0, CALLER_ADDR1);
+       int pc = preempt_count();
+
+       if (preempt_trace(pc) || irq_trace())
+               start_critical_timing(CALLER_ADDR0, CALLER_ADDR1, pc);
 }
 EXPORT_SYMBOL_GPL(start_critical_timings);
 
 void stop_critical_timings(void)
 {
-       if (preempt_trace() || irq_trace())
-               stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1);
-}
-EXPORT_SYMBOL_GPL(stop_critical_timings);
-
-#ifdef CONFIG_IRQSOFF_TRACER
-#ifdef CONFIG_PROVE_LOCKING
-void time_hardirqs_on(unsigned long a0, unsigned long a1)
-{
-       if (!preempt_trace() && irq_trace())
-               stop_critical_timing(a0, a1);
-}
-
-void time_hardirqs_off(unsigned long a0, unsigned long a1)
-{
-       if (!preempt_trace() && irq_trace())
-               start_critical_timing(a0, a1);
-}
-
-#else /* !CONFIG_PROVE_LOCKING */
-
-/*
- * We are only interested in hardirq on/off events:
- */
-static inline void tracer_hardirqs_on(void)
-{
-       if (!preempt_trace() && irq_trace())
-               stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1);
-}
+       int pc = preempt_count();
 
-static inline void tracer_hardirqs_off(void)
-{
-       if (!preempt_trace() && irq_trace())
-               start_critical_timing(CALLER_ADDR0, CALLER_ADDR1);
-}
-
-static inline void tracer_hardirqs_on_caller(unsigned long caller_addr)
-{
-       if (!preempt_trace() && irq_trace())
-               stop_critical_timing(CALLER_ADDR0, caller_addr);
-}
-
-static inline void tracer_hardirqs_off_caller(unsigned long caller_addr)
-{
-       if (!preempt_trace() && irq_trace())
-               start_critical_timing(CALLER_ADDR0, caller_addr);
-}
-
-#endif /* CONFIG_PROVE_LOCKING */
-#endif /*  CONFIG_IRQSOFF_TRACER */
-
-#ifdef CONFIG_PREEMPT_TRACER
-static inline void tracer_preempt_on(unsigned long a0, unsigned long a1)
-{
-       if (preempt_trace() && !irq_trace())
-               stop_critical_timing(a0, a1);
-}
-
-static inline void tracer_preempt_off(unsigned long a0, unsigned long a1)
-{
-       if (preempt_trace() && !irq_trace())
-               start_critical_timing(a0, a1);
+       if (preempt_trace(pc) || irq_trace())
+               stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1, pc);
 }
-#endif /* CONFIG_PREEMPT_TRACER */
+EXPORT_SYMBOL_GPL(stop_critical_timings);
 
 #ifdef CONFIG_FUNCTION_TRACER
 static bool function_enabled;
@@ -634,7 +578,7 @@ static int __irqsoff_tracer_init(struct trace_array *tr)
        return 0;
 }
 
-static void irqsoff_tracer_reset(struct trace_array *tr)
+static void __irqsoff_tracer_reset(struct trace_array *tr)
 {
        int lat_flag = save_flags & TRACE_ITER_LATENCY_FMT;
        int overwrite_flag = save_flags & TRACE_ITER_OVERWRITE;
@@ -659,12 +603,37 @@ static void irqsoff_tracer_stop(struct trace_array *tr)
 }
 
 #ifdef CONFIG_IRQSOFF_TRACER
+/*
+ * We are only interested in hardirq on/off events:
+ */
+void tracer_hardirqs_on(unsigned long a0, unsigned long a1)
+{
+       unsigned int pc = preempt_count();
+
+       if (!preempt_trace(pc) && irq_trace())
+               stop_critical_timing(a0, a1, pc);
+}
+
+void tracer_hardirqs_off(unsigned long a0, unsigned long a1)
+{
+       unsigned int pc = preempt_count();
+
+       if (!preempt_trace(pc) && irq_trace())
+               start_critical_timing(a0, a1, pc);
+}
+
 static int irqsoff_tracer_init(struct trace_array *tr)
 {
        trace_type = TRACER_IRQS_OFF;
 
        return __irqsoff_tracer_init(tr);
 }
+
+static void irqsoff_tracer_reset(struct trace_array *tr)
+{
+       __irqsoff_tracer_reset(tr);
+}
+
 static struct tracer irqsoff_tracer __read_mostly =
 {
        .name           = "irqsoff",
@@ -684,12 +653,25 @@ static struct tracer irqsoff_tracer __read_mostly =
        .allow_instances = true,
        .use_max_tr     = true,
 };
-# define register_irqsoff(trace) register_tracer(&trace)
-#else
-# define register_irqsoff(trace) do { } while (0)
-#endif
+#endif /*  CONFIG_IRQSOFF_TRACER */
 
 #ifdef CONFIG_PREEMPT_TRACER
+void tracer_preempt_on(unsigned long a0, unsigned long a1)
+{
+       int pc = preempt_count();
+
+       if (preempt_trace(pc) && !irq_trace())
+               stop_critical_timing(a0, a1, pc);
+}
+
+void tracer_preempt_off(unsigned long a0, unsigned long a1)
+{
+       int pc = preempt_count();
+
+       if (preempt_trace(pc) && !irq_trace())
+               start_critical_timing(a0, a1, pc);
+}
+
 static int preemptoff_tracer_init(struct trace_array *tr)
 {
        trace_type = TRACER_PREEMPT_OFF;
@@ -697,11 +679,16 @@ static int preemptoff_tracer_init(struct trace_array *tr)
        return __irqsoff_tracer_init(tr);
 }
 
+static void preemptoff_tracer_reset(struct trace_array *tr)
+{
+       __irqsoff_tracer_reset(tr);
+}
+
 static struct tracer preemptoff_tracer __read_mostly =
 {
        .name           = "preemptoff",
        .init           = preemptoff_tracer_init,
-       .reset          = irqsoff_tracer_reset,
+       .reset          = preemptoff_tracer_reset,
        .start          = irqsoff_tracer_start,
        .stop           = irqsoff_tracer_stop,
        .print_max      = true,
@@ -716,13 +703,9 @@ static struct tracer preemptoff_tracer __read_mostly =
        .allow_instances = true,
        .use_max_tr     = true,
 };
-# define register_preemptoff(trace) register_tracer(&trace)
-#else
-# define register_preemptoff(trace) do { } while (0)
-#endif
+#endif /* CONFIG_PREEMPT_TRACER */
 
-#if defined(CONFIG_IRQSOFF_TRACER) && \
-       defined(CONFIG_PREEMPT_TRACER)
+#if defined(CONFIG_IRQSOFF_TRACER) && defined(CONFIG_PREEMPT_TRACER)
 
 static int preemptirqsoff_tracer_init(struct trace_array *tr)
 {
@@ -731,11 +714,16 @@ static int preemptirqsoff_tracer_init(struct trace_array *tr)
        return __irqsoff_tracer_init(tr);
 }
 
+static void preemptirqsoff_tracer_reset(struct trace_array *tr)
+{
+       __irqsoff_tracer_reset(tr);
+}
+
 static struct tracer preemptirqsoff_tracer __read_mostly =
 {
        .name           = "preemptirqsoff",
        .init           = preemptirqsoff_tracer_init,
-       .reset          = irqsoff_tracer_reset,
+       .reset          = preemptirqsoff_tracer_reset,
        .start          = irqsoff_tracer_start,
        .stop           = irqsoff_tracer_stop,
        .print_max      = true,
@@ -750,115 +738,21 @@ static struct tracer preemptirqsoff_tracer __read_mostly =
        .allow_instances = true,
        .use_max_tr     = true,
 };
-
-# define register_preemptirqsoff(trace) register_tracer(&trace)
-#else
-# define register_preemptirqsoff(trace) do { } while (0)
 #endif
 
 __init static int init_irqsoff_tracer(void)
 {
-       register_irqsoff(irqsoff_tracer);
-       register_preemptoff(preemptoff_tracer);
-       register_preemptirqsoff(preemptirqsoff_tracer);
-
-       return 0;
-}
-core_initcall(init_irqsoff_tracer);
-#endif /* IRQSOFF_TRACER || PREEMPTOFF_TRACER */
-
-#ifndef CONFIG_IRQSOFF_TRACER
-static inline void tracer_hardirqs_on(void) { }
-static inline void tracer_hardirqs_off(void) { }
-static inline void tracer_hardirqs_on_caller(unsigned long caller_addr) { }
-static inline void tracer_hardirqs_off_caller(unsigned long caller_addr) { }
+#ifdef CONFIG_IRQSOFF_TRACER
+       register_tracer(&irqsoff_tracer);
 #endif
-
-#ifndef CONFIG_PREEMPT_TRACER
-static inline void tracer_preempt_on(unsigned long a0, unsigned long a1) { }
-static inline void tracer_preempt_off(unsigned long a0, unsigned long a1) { }
+#ifdef CONFIG_PREEMPT_TRACER
+       register_tracer(&preemptoff_tracer);
 #endif
-
-#if defined(CONFIG_TRACE_IRQFLAGS) && !defined(CONFIG_PROVE_LOCKING)
-/* Per-cpu variable to prevent redundant calls when IRQs already off */
-static DEFINE_PER_CPU(int, tracing_irq_cpu);
-
-void trace_hardirqs_on(void)
-{
-       if (!this_cpu_read(tracing_irq_cpu))
-               return;
-
-       trace_irq_enable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
-       tracer_hardirqs_on();
-
-       this_cpu_write(tracing_irq_cpu, 0);
-}
-EXPORT_SYMBOL(trace_hardirqs_on);
-
-void trace_hardirqs_off(void)
-{
-       if (this_cpu_read(tracing_irq_cpu))
-               return;
-
-       this_cpu_write(tracing_irq_cpu, 1);
-
-       trace_irq_disable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
-       tracer_hardirqs_off();
-}
-EXPORT_SYMBOL(trace_hardirqs_off);
-
-__visible void trace_hardirqs_on_caller(unsigned long caller_addr)
-{
-       if (!this_cpu_read(tracing_irq_cpu))
-               return;
-
-       trace_irq_enable_rcuidle(CALLER_ADDR0, caller_addr);
-       tracer_hardirqs_on_caller(caller_addr);
-
-       this_cpu_write(tracing_irq_cpu, 0);
-}
-EXPORT_SYMBOL(trace_hardirqs_on_caller);
-
-__visible void trace_hardirqs_off_caller(unsigned long caller_addr)
-{
-       if (this_cpu_read(tracing_irq_cpu))
-               return;
-
-       this_cpu_write(tracing_irq_cpu, 1);
-
-       trace_irq_disable_rcuidle(CALLER_ADDR0, caller_addr);
-       tracer_hardirqs_off_caller(caller_addr);
-}
-EXPORT_SYMBOL(trace_hardirqs_off_caller);
-
-/*
- * Stubs:
- */
-
-void trace_softirqs_on(unsigned long ip)
-{
-}
-
-void trace_softirqs_off(unsigned long ip)
-{
-}
-
-inline void print_irqtrace_events(struct task_struct *curr)
-{
-}
+#if defined(CONFIG_IRQSOFF_TRACER) && defined(CONFIG_PREEMPT_TRACER)
+       register_tracer(&preemptirqsoff_tracer);
 #endif
 
-#if defined(CONFIG_PREEMPT_TRACER) || \
-       (defined(CONFIG_DEBUG_PREEMPT) && defined(CONFIG_PREEMPTIRQ_EVENTS))
-void trace_preempt_on(unsigned long a0, unsigned long a1)
-{
-       trace_preempt_enable_rcuidle(a0, a1);
-       tracer_preempt_on(a0, a1);
-}
-
-void trace_preempt_off(unsigned long a0, unsigned long a1)
-{
-       trace_preempt_disable_rcuidle(a0, a1);
-       tracer_preempt_off(a0, a1);
+       return 0;
 }
-#endif
+core_initcall(init_irqsoff_tracer);
+#endif /* IRQSOFF_TRACER || PREEMPTOFF_TRACER */
index e9d99463e5dffe82bcc42f0ea75392d0528ce2fe..c30032367aab4a5c83a013d615830cda97a82f8a 100644 (file)
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Kprobes-based tracing events
  *
  * Created by Masami Hiramatsu <mhiramat@redhat.com>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT 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 pr_fmt(fmt)    "trace_kprobe: " fmt
 
@@ -23,6 +12,7 @@
 #include <linux/rculist.h>
 #include <linux/error-injection.h>
 
+#include "trace_kprobe_selftest.h"
 #include "trace_probe.h"
 
 #define KPROBE_EVENT_SYSTEM "kprobes"
@@ -87,6 +77,23 @@ static nokprobe_inline unsigned long trace_kprobe_nhit(struct trace_kprobe *tk)
        return nhit;
 }
 
+/* Return 0 if it fails to find the symbol address */
+static nokprobe_inline
+unsigned long trace_kprobe_address(struct trace_kprobe *tk)
+{
+       unsigned long addr;
+
+       if (tk->symbol) {
+               addr = (unsigned long)
+                       kallsyms_lookup_name(trace_kprobe_symbol(tk));
+               if (addr)
+                       addr += tk->rp.kp.offset;
+       } else {
+               addr = (unsigned long)tk->rp.kp.addr;
+       }
+       return addr;
+}
+
 bool trace_kprobe_on_func_entry(struct trace_event_call *call)
 {
        struct trace_kprobe *tk = (struct trace_kprobe *)call->data;
@@ -99,16 +106,8 @@ bool trace_kprobe_on_func_entry(struct trace_event_call *call)
 bool trace_kprobe_error_injectable(struct trace_event_call *call)
 {
        struct trace_kprobe *tk = (struct trace_kprobe *)call->data;
-       unsigned long addr;
 
-       if (tk->symbol) {
-               addr = (unsigned long)
-                       kallsyms_lookup_name(trace_kprobe_symbol(tk));
-               addr += tk->rp.kp.offset;
-       } else {
-               addr = (unsigned long)tk->rp.kp.addr;
-       }
-       return within_error_injection_list(addr);
+       return within_error_injection_list(trace_kprobe_address(tk));
 }
 
 static int register_kprobe_event(struct trace_kprobe *tk);
@@ -393,6 +392,20 @@ static struct trace_kprobe *find_trace_kprobe(const char *event,
        return NULL;
 }
 
+static inline int __enable_trace_kprobe(struct trace_kprobe *tk)
+{
+       int ret = 0;
+
+       if (trace_probe_is_registered(&tk->tp) && !trace_kprobe_has_gone(tk)) {
+               if (trace_kprobe_is_return(tk))
+                       ret = enable_kretprobe(&tk->rp);
+               else
+                       ret = enable_kprobe(&tk->rp.kp);
+       }
+
+       return ret;
+}
+
 /*
  * Enable trace_probe
  * if the file is NULL, enable "perf" handler, or enable "trace" handler.
@@ -400,7 +413,7 @@ static struct trace_kprobe *find_trace_kprobe(const char *event,
 static int
 enable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file)
 {
-       struct event_file_link *link = NULL;
+       struct event_file_link *link;
        int ret = 0;
 
        if (file) {
@@ -414,26 +427,18 @@ enable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file)
                list_add_tail_rcu(&link->list, &tk->tp.files);
 
                tk->tp.flags |= TP_FLAG_TRACE;
-       } else
-               tk->tp.flags |= TP_FLAG_PROFILE;
-
-       if (trace_probe_is_registered(&tk->tp) && !trace_kprobe_has_gone(tk)) {
-               if (trace_kprobe_is_return(tk))
-                       ret = enable_kretprobe(&tk->rp);
-               else
-                       ret = enable_kprobe(&tk->rp.kp);
-       }
-
-       if (ret) {
-               if (file) {
-                       /* Notice the if is true on not WARN() */
-                       if (!WARN_ON_ONCE(!link))
-                               list_del_rcu(&link->list);
+               ret = __enable_trace_kprobe(tk);
+               if (ret) {
+                       list_del_rcu(&link->list);
                        kfree(link);
                        tk->tp.flags &= ~TP_FLAG_TRACE;
-               } else {
-                       tk->tp.flags &= ~TP_FLAG_PROFILE;
                }
+
+       } else {
+               tk->tp.flags |= TP_FLAG_PROFILE;
+               ret = __enable_trace_kprobe(tk);
+               if (ret)
+                       tk->tp.flags &= ~TP_FLAG_PROFILE;
        }
  out:
        return ret;
@@ -498,6 +503,29 @@ disable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file)
        return ret;
 }
 
+#if defined(CONFIG_KPROBES_ON_FTRACE) && \
+       !defined(CONFIG_KPROBE_EVENTS_ON_NOTRACE)
+static bool within_notrace_func(struct trace_kprobe *tk)
+{
+       unsigned long offset, size, addr;
+
+       addr = trace_kprobe_address(tk);
+       if (!addr || !kallsyms_lookup_size_offset(addr, &size, &offset))
+               return false;
+
+       /* Get the entry address of the target function */
+       addr -= offset;
+
+       /*
+        * Since ftrace_location_range() does inclusive range check, we need
+        * to subtract 1 byte from the end address.
+        */
+       return !ftrace_location_range(addr, addr + size - 1);
+}
+#else
+#define within_notrace_func(tk)        (false)
+#endif
+
 /* Internal register function - just handle k*probes and flags */
 static int __register_trace_kprobe(struct trace_kprobe *tk)
 {
@@ -506,6 +534,12 @@ static int __register_trace_kprobe(struct trace_kprobe *tk)
        if (trace_probe_is_registered(&tk->tp))
                return -EINVAL;
 
+       if (within_notrace_func(tk)) {
+               pr_warn("Could not probe notrace function %s\n",
+                       trace_kprobe_symbol(tk));
+               return -EINVAL;
+       }
+
        for (i = 0; i < tk->tp.nr_args; i++)
                traceprobe_update_arg(&tk->tp.args[i]);
 
@@ -1547,17 +1581,6 @@ fs_initcall(init_kprobe_trace);
 
 
 #ifdef CONFIG_FTRACE_STARTUP_TEST
-/*
- * The "__used" keeps gcc from removing the function symbol
- * from the kallsyms table. 'noinline' makes sure that there
- * isn't an inlined version used by the test method below
- */
-static __used __init noinline int
-kprobe_trace_selftest_target(int a1, int a2, int a3, int a4, int a5, int a6)
-{
-       return a1 + a2 + a3 + a4 + a5 + a6;
-}
-
 static __init struct trace_event_file *
 find_trace_probe_file(struct trace_kprobe *tk, struct trace_array *tr)
 {
diff --git a/kernel/trace/trace_kprobe_selftest.c b/kernel/trace/trace_kprobe_selftest.c
new file mode 100644 (file)
index 0000000..16548ee
--- /dev/null
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Function used during the kprobe self test. This function is in a separate
+ * compile unit so it can be compile with CC_FLAGS_FTRACE to ensure that it
+ * can be probed by the selftests.
+ */
+int kprobe_trace_selftest_target(int a1, int a2, int a3, int a4, int a5, int a6)
+{
+       return a1 + a2 + a3 + a4 + a5 + a6;
+}
diff --git a/kernel/trace/trace_kprobe_selftest.h b/kernel/trace/trace_kprobe_selftest.h
new file mode 100644 (file)
index 0000000..c4fc726
--- /dev/null
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Function used during the kprobe self test. This function is in a separate
+ * compile unit so it can be compile with CC_FLAGS_FTRACE to ensure that it
+ * can be probed by the selftests.
+ */
+int kprobe_trace_selftest_target(int a1, int a2, int a3, int a4, int a5, int a6);
index 1c8e30fda46a8a4abab5c748868e52c06a8b30ea..6e6cc64faa389b72012f58912a32114ad45cf704 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * trace_output.c
  *
index dbba03ed96dee0dbb947d8c298e10776f6180fbb..2f742b74e7e6b2fda9ae28c362a7e00aae828c31 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+// SPDX-License-Identifier: GPL-2.0
 #ifndef __TRACE_EVENTS_H
 #define __TRACE_EVENTS_H
 
diff --git a/kernel/trace/trace_preemptirq.c b/kernel/trace/trace_preemptirq.c
new file mode 100644 (file)
index 0000000..71f553c
--- /dev/null
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * preemptoff and irqoff tracepoints
+ *
+ * Copyright (C) Joel Fernandes (Google) <joel@joelfernandes.org>
+ */
+
+#include <linux/kallsyms.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/ftrace.h>
+#include "trace.h"
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/preemptirq.h>
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+/* Per-cpu variable to prevent redundant calls when IRQs already off */
+static DEFINE_PER_CPU(int, tracing_irq_cpu);
+
+void trace_hardirqs_on(void)
+{
+       if (this_cpu_read(tracing_irq_cpu)) {
+               if (!in_nmi())
+                       trace_irq_enable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
+               tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1);
+               this_cpu_write(tracing_irq_cpu, 0);
+       }
+
+       lockdep_hardirqs_on(CALLER_ADDR0);
+}
+EXPORT_SYMBOL(trace_hardirqs_on);
+
+void trace_hardirqs_off(void)
+{
+       if (!this_cpu_read(tracing_irq_cpu)) {
+               this_cpu_write(tracing_irq_cpu, 1);
+               tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1);
+               if (!in_nmi())
+                       trace_irq_disable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
+       }
+
+       lockdep_hardirqs_off(CALLER_ADDR0);
+}
+EXPORT_SYMBOL(trace_hardirqs_off);
+
+__visible void trace_hardirqs_on_caller(unsigned long caller_addr)
+{
+       if (this_cpu_read(tracing_irq_cpu)) {
+               if (!in_nmi())
+                       trace_irq_enable_rcuidle(CALLER_ADDR0, caller_addr);
+               tracer_hardirqs_on(CALLER_ADDR0, caller_addr);
+               this_cpu_write(tracing_irq_cpu, 0);
+       }
+
+       lockdep_hardirqs_on(CALLER_ADDR0);
+}
+EXPORT_SYMBOL(trace_hardirqs_on_caller);
+
+__visible void trace_hardirqs_off_caller(unsigned long caller_addr)
+{
+       if (!this_cpu_read(tracing_irq_cpu)) {
+               this_cpu_write(tracing_irq_cpu, 1);
+               tracer_hardirqs_off(CALLER_ADDR0, caller_addr);
+               if (!in_nmi())
+                       trace_irq_disable_rcuidle(CALLER_ADDR0, caller_addr);
+       }
+
+       lockdep_hardirqs_off(CALLER_ADDR0);
+}
+EXPORT_SYMBOL(trace_hardirqs_off_caller);
+#endif /* CONFIG_TRACE_IRQFLAGS */
+
+#ifdef CONFIG_TRACE_PREEMPT_TOGGLE
+
+void trace_preempt_on(unsigned long a0, unsigned long a1)
+{
+       if (!in_nmi())
+               trace_preempt_enable_rcuidle(a0, a1);
+       tracer_preempt_on(a0, a1);
+}
+
+void trace_preempt_off(unsigned long a0, unsigned long a1)
+{
+       if (!in_nmi())
+               trace_preempt_disable_rcuidle(a0, a1);
+       tracer_preempt_off(a0, a1);
+}
+#endif
index 50f44b7b2b326c85945f562ea20850e07b769058..b0875b327f5c3d5c733f79337bef40d5d600fbd1 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * trace binary printk
  *
index daf54bda4dc8d7a86419e5107a2075d8df5095dc..e99c3ce7aa6541144da74e50a011e230bd25e0b0 100644 (file)
@@ -1,19 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Common code for probe-based Dynamic events.
  *
- * This program is free software; you can 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
- *
  * This code was copied from kernel/trace/trace_kprobe.c written by
  * Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
  *
index 75daff22ccea062d808282e6fd473f27470ea760..5f52668e165d9f8dfa3c0e0737b8c6495007fa9b 100644 (file)
@@ -1,19 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Common header file for probe-based Dynamic events.
  *
- * This program is free software; you can 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
- *
  * This code was copied from kernel/trace/trace_kprobe.h written by
  * Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
  *
index e694c9f9efa496e58d343778721658ea3f9dbad8..6b1c562ffdaf0f0be1549e5eb34b8a199c11b273 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * trace_seq.c
  *
index 76d30b4ebe83efdb97761b7bcd0a6125197e15da..8786d17caf490ccaea3e107306aec6deda2ca8d7 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+// SPDX-License-Identifier: GPL-2.0
 #ifndef __TRACE_STAT_H
 #define __TRACE_STAT_H
 
index bf89a51e740dd402dd82e066083b9462f48bafad..e696667da29a49aa2f94372fa301b8ab1e7ec373 100644 (file)
@@ -1,19 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * uprobes-based tracing events
  *
- * This program is free software; you can 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
- *
  * Copyright (C) IBM Corporation, 2010-2012
  * Author:     Srikar Dronamraju <srikar@linux.vnet.ibm.com>
  */
@@ -952,7 +940,7 @@ probe_event_disable(struct trace_uprobe *tu, struct trace_event_file *file)
 
                list_del_rcu(&link->list);
                /* synchronize with u{,ret}probe_trace_func */
-               synchronize_sched();
+               synchronize_rcu();
                kfree(link);
 
                if (!list_empty(&tu->tp.files))
index 752d8042bad4e5acf0589f7ebf2771b05d0b34ed..9a1c22310323d0a4bcf97f75a49d7cdfc859c7fe 100644 (file)
@@ -1,16 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * tracing_map - lock-free map for tracing
  *
- * This program is free software; 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.
- *
  * Copyright (C) 2015 Tom Zanussi <tom.zanussi@linux.intel.com>
  *
  * tracing_map implementation inspired by lock-free map algorithms
index 053eb92b2d31309924a1f3fd2c068935aedaf0c4..a6de61fc22dec1da7cee9b39f3d886360621f806 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+// SPDX-License-Identifier: GPL-2.0
 #ifndef __TRACING_MAP_H
 #define __TRACING_MAP_H
 
index 6dc6356c3327c8a1d4958d686f84d5fb804f02d2..bf2c06ef9afc3d5c2a5eecb620aa9acb07a7bba5 100644 (file)
@@ -31,6 +31,9 @@
 extern struct tracepoint * const __start___tracepoints_ptrs[];
 extern struct tracepoint * const __stop___tracepoints_ptrs[];
 
+DEFINE_SRCU(tracepoint_srcu);
+EXPORT_SYMBOL_GPL(tracepoint_srcu);
+
 /* Set to 1 to enable tracepoint debug output */
 static const int tracepoint_debug;
 
@@ -50,6 +53,9 @@ static LIST_HEAD(tracepoint_module_list);
  */
 static DEFINE_MUTEX(tracepoints_mutex);
 
+static struct rcu_head *early_probes;
+static bool ok_to_free_tracepoints;
+
 /*
  * Note about RCU :
  * It is used to delay the free of multiple probes array until a quiescent
@@ -67,16 +73,56 @@ static inline void *allocate_probes(int count)
        return p == NULL ? NULL : p->probes;
 }
 
-static void rcu_free_old_probes(struct rcu_head *head)
+static void srcu_free_old_probes(struct rcu_head *head)
 {
        kfree(container_of(head, struct tp_probes, rcu));
 }
 
+static void rcu_free_old_probes(struct rcu_head *head)
+{
+       call_srcu(&tracepoint_srcu, head, srcu_free_old_probes);
+}
+
+static __init int release_early_probes(void)
+{
+       struct rcu_head *tmp;
+
+       ok_to_free_tracepoints = true;
+
+       while (early_probes) {
+               tmp = early_probes;
+               early_probes = tmp->next;
+               call_rcu_sched(tmp, rcu_free_old_probes);
+       }
+
+       return 0;
+}
+
+/* SRCU is initialized at core_initcall */
+postcore_initcall(release_early_probes);
+
 static inline void release_probes(struct tracepoint_func *old)
 {
        if (old) {
                struct tp_probes *tp_probes = container_of(old,
                        struct tp_probes, probes[0]);
+
+               /*
+                * We can't free probes if SRCU is not initialized yet.
+                * Postpone the freeing till after SRCU is initialized.
+                */
+               if (unlikely(!ok_to_free_tracepoints)) {
+                       tp_probes->rcu.next = early_probes;
+                       early_probes = &tp_probes->rcu;
+                       return;
+               }
+
+               /*
+                * Tracepoint probes are protected by both sched RCU and SRCU,
+                * by calling the SRCU callback in the sched RCU callback we
+                * cover both cases. So let us chain the SRCU and sched RCU
+                * callbacks to wait for both grace periods.
+                */
                call_rcu_sched(&tp_probes->rcu, rcu_free_old_probes);
        }
 }
@@ -325,6 +371,27 @@ int tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data)
 }
 EXPORT_SYMBOL_GPL(tracepoint_probe_unregister);
 
+static void for_each_tracepoint_range(struct tracepoint * const *begin,
+               struct tracepoint * const *end,
+               void (*fct)(struct tracepoint *tp, void *priv),
+               void *priv)
+{
+       if (!begin)
+               return;
+
+       if (IS_ENABLED(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)) {
+               const int *iter;
+
+               for (iter = (const int *)begin; iter < (const int *)end; iter++)
+                       fct(offset_to_ptr(iter), priv);
+       } else {
+               struct tracepoint * const *iter;
+
+               for (iter = begin; iter < end; iter++)
+                       fct(*iter, priv);
+       }
+}
+
 #ifdef CONFIG_MODULES
 bool trace_module_has_bad_taint(struct module *mod)
 {
@@ -389,15 +456,9 @@ EXPORT_SYMBOL_GPL(unregister_tracepoint_module_notifier);
  * Ensure the tracer unregistered the module's probes before the module
  * teardown is performed. Prevents leaks of probe and data pointers.
  */
-static void tp_module_going_check_quiescent(struct tracepoint * const *begin,
-               struct tracepoint * const *end)
+static void tp_module_going_check_quiescent(struct tracepoint *tp, void *priv)
 {
-       struct tracepoint * const *iter;
-
-       if (!begin)
-               return;
-       for (iter = begin; iter < end; iter++)
-               WARN_ON_ONCE((*iter)->funcs);
+       WARN_ON_ONCE(tp->funcs);
 }
 
 static int tracepoint_module_coming(struct module *mod)
@@ -448,8 +509,9 @@ static void tracepoint_module_going(struct module *mod)
                         * Called the going notifier before checking for
                         * quiescence.
                         */
-                       tp_module_going_check_quiescent(mod->tracepoints_ptrs,
-                               mod->tracepoints_ptrs + mod->num_tracepoints);
+                       for_each_tracepoint_range(mod->tracepoints_ptrs,
+                               mod->tracepoints_ptrs + mod->num_tracepoints,
+                               tp_module_going_check_quiescent, NULL);
                        break;
                }
        }
@@ -501,19 +563,6 @@ static __init int init_tracepoints(void)
 __initcall(init_tracepoints);
 #endif /* CONFIG_MODULES */
 
-static void for_each_tracepoint_range(struct tracepoint * const *begin,
-               struct tracepoint * const *end,
-               void (*fct)(struct tracepoint *tp, void *priv),
-               void *priv)
-{
-       struct tracepoint * const *iter;
-
-       if (!begin)
-               return;
-       for (iter = begin; iter < end; iter++)
-               fct(*iter, priv);
-}
-
 /**
  * for_each_kernel_tracepoint - iteration on all kernel tracepoints
  * @fct: callback
index 36288d8406756400f5008ee0631b810301504e0d..0df9b1640b2af5d4ade21a376172fdfd6d097694 100644 (file)
@@ -96,7 +96,7 @@ static DEFINE_SPINLOCK(uidhash_lock);
 
 /* root_user.__count is 1, for init task cred */
 struct user_struct root_user = {
-       .__count        = ATOMIC_INIT(1),
+       .__count        = REFCOUNT_INIT(1),
        .processes      = ATOMIC_INIT(1),
        .sigpending     = ATOMIC_INIT(0),
        .locked_shm     = 0,
@@ -123,7 +123,7 @@ static struct user_struct *uid_hash_find(kuid_t uid, struct hlist_head *hashent)
 
        hlist_for_each_entry(user, hashent, uidhash_node) {
                if (uid_eq(user->uid, uid)) {
-                       atomic_inc(&user->__count);
+                       refcount_inc(&user->__count);
                        return user;
                }
        }
@@ -169,11 +169,8 @@ void free_uid(struct user_struct *up)
        if (!up)
                return;
 
-       local_irq_save(flags);
-       if (atomic_dec_and_lock(&up->__count, &uidhash_lock))
+       if (refcount_dec_and_lock_irqsave(&up->__count, &uidhash_lock, &flags))
                free_user(up, flags);
-       else
-               local_irq_restore(flags);
 }
 
 struct user_struct *alloc_uid(kuid_t uid)
@@ -191,7 +188,7 @@ struct user_struct *alloc_uid(kuid_t uid)
                        goto out_unlock;
 
                new->uid = uid;
-               atomic_set(&new->__count, 1);
+               refcount_set(&new->__count, 1);
                ratelimit_state_init(&new->ratelimit, HZ, 100);
                ratelimit_set_flags(&new->ratelimit, RATELIMIT_MSG_ON_RELEASE);
 
index c3d7583fcd216d6f0b44b8d38c65ecc60c3e6fde..e5222b5fb4fe6c3868c78ee3602518ce835c85e3 100644 (file)
@@ -859,7 +859,16 @@ static ssize_t map_write(struct file *file, const char __user *buf,
        unsigned idx;
        struct uid_gid_extent extent;
        char *kbuf = NULL, *pos, *next_line;
-       ssize_t ret = -EINVAL;
+       ssize_t ret;
+
+       /* Only allow < page size writes at the beginning of the file */
+       if ((*ppos != 0) || (count >= PAGE_SIZE))
+               return -EINVAL;
+
+       /* Slurp in the user data */
+       kbuf = memdup_user_nul(buf, count);
+       if (IS_ERR(kbuf))
+               return PTR_ERR(kbuf);
 
        /*
         * The userns_state_mutex serializes all writes to any given map.
@@ -895,19 +904,6 @@ static ssize_t map_write(struct file *file, const char __user *buf,
        if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN))
                goto out;
 
-       /* Only allow < page size writes at the beginning of the file */
-       ret = -EINVAL;
-       if ((*ppos != 0) || (count >= PAGE_SIZE))
-               goto out;
-
-       /* Slurp in the user data */
-       kbuf = memdup_user_nul(buf, count);
-       if (IS_ERR(kbuf)) {
-               ret = PTR_ERR(kbuf);
-               kbuf = NULL;
-               goto out;
-       }
-
        /* Parse the user data */
        ret = -EINVAL;
        pos = kbuf;
index 233cd8fc691082363d6c324f1555aa1dd1f33c21..258033d62cb3a4ae8da270df003bb8444f409eeb 100644 (file)
@@ -18,7 +18,7 @@
 
 #ifdef CONFIG_PROC_SYSCTL
 
-static void *get_uts(struct ctl_table *table, int write)
+static void *get_uts(struct ctl_table *table)
 {
        char *which = table->data;
        struct uts_namespace *uts_ns;
@@ -26,21 +26,9 @@ static void *get_uts(struct ctl_table *table, int write)
        uts_ns = current->nsproxy->uts_ns;
        which = (which - (char *)&init_uts_ns) + (char *)uts_ns;
 
-       if (!write)
-               down_read(&uts_sem);
-       else
-               down_write(&uts_sem);
        return which;
 }
 
-static void put_uts(struct ctl_table *table, int write, void *which)
-{
-       if (!write)
-               up_read(&uts_sem);
-       else
-               up_write(&uts_sem);
-}
-
 /*
  *     Special case of dostring for the UTS structure. This has locks
  *     to observe. Should this be in kernel/sys.c ????
@@ -50,13 +38,34 @@ static int proc_do_uts_string(struct ctl_table *table, int write,
 {
        struct ctl_table uts_table;
        int r;
+       char tmp_data[__NEW_UTS_LEN + 1];
+
        memcpy(&uts_table, table, sizeof(uts_table));
-       uts_table.data = get_uts(table, write);
+       uts_table.data = tmp_data;
+
+       /*
+        * Buffer the value in tmp_data so that proc_dostring() can be called
+        * without holding any locks.
+        * We also need to read the original value in the write==1 case to
+        * support partial writes.
+        */
+       down_read(&uts_sem);
+       memcpy(tmp_data, get_uts(table), sizeof(tmp_data));
+       up_read(&uts_sem);
        r = proc_dostring(&uts_table, write, buffer, lenp, ppos);
-       put_uts(table, write, uts_table.data);
 
-       if (write)
+       if (write) {
+               /*
+                * Write back the new value.
+                * Note that, since we dropped uts_sem, the result can
+                * theoretically be incorrect if there are two parallel writes
+                * at non-zero offsets to the same sysctl.
+                */
+               down_write(&uts_sem);
+               memcpy(get_uts(table), tmp_data, sizeof(tmp_data));
+               up_write(&uts_sem);
                proc_sys_poll_notify(table->poll);
+       }
 
        return r;
 }
index 5470dce212c0dbc9861d5d2108b926a473f89de4..977918d5d3501b1447781c91aedbe8fadad05ada 100644 (file)
@@ -261,7 +261,7 @@ static void __touch_watchdog(void)
  * entering idle state.  This should only be used for scheduler events.
  * Use touch_softlockup_watchdog() for everything else.
  */
-void touch_softlockup_watchdog_sched(void)
+notrace void touch_softlockup_watchdog_sched(void)
 {
        /*
         * Preemption can be enabled.  It doesn't matter which CPU's timestamp
@@ -270,7 +270,7 @@ void touch_softlockup_watchdog_sched(void)
        raw_cpu_write(watchdog_touch_ts, 0);
 }
 
-void touch_softlockup_watchdog(void)
+notrace void touch_softlockup_watchdog(void)
 {
        touch_softlockup_watchdog_sched();
        wq_watchdog_touch(raw_smp_processor_id());
index 1f7020d65d0aa2963708d3e44057e08ce2305ead..71381168dedef4e88382a1849412f554a4cb4a56 100644 (file)
@@ -29,7 +29,7 @@ static struct cpumask dead_events_mask;
 static unsigned long hardlockup_allcpu_dumped;
 static atomic_t watchdog_cpus = ATOMIC_INIT(0);
 
-void arch_touch_nmi_watchdog(void)
+notrace void arch_touch_nmi_watchdog(void)
 {
        /*
         * Using __raw here because some code paths have
index 78b192071ef7b58a4d92bbc65943fdaad7ccf735..0280deac392e25c833cda56a0d193507998b6de4 100644 (file)
@@ -2652,6 +2652,9 @@ void flush_workqueue(struct workqueue_struct *wq)
        if (WARN_ON(!wq_online))
                return;
 
+       lock_map_acquire(&wq->lockdep_map);
+       lock_map_release(&wq->lockdep_map);
+
        mutex_lock(&wq->mutex);
 
        /*
@@ -2843,7 +2846,8 @@ reflush:
 }
 EXPORT_SYMBOL_GPL(drain_workqueue);
 
-static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr)
+static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr,
+                            bool from_cancel)
 {
        struct worker *worker = NULL;
        struct worker_pool *pool;
@@ -2885,7 +2889,8 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr)
         * workqueues the deadlock happens when the rescuer stalls, blocking
         * forward progress.
         */
-       if (pwq->wq->saved_max_active == 1 || pwq->wq->rescuer) {
+       if (!from_cancel &&
+           (pwq->wq->saved_max_active == 1 || pwq->wq->rescuer)) {
                lock_map_acquire(&pwq->wq->lockdep_map);
                lock_map_release(&pwq->wq->lockdep_map);
        }
@@ -2896,6 +2901,27 @@ already_gone:
        return false;
 }
 
+static bool __flush_work(struct work_struct *work, bool from_cancel)
+{
+       struct wq_barrier barr;
+
+       if (WARN_ON(!wq_online))
+               return false;
+
+       if (!from_cancel) {
+               lock_map_acquire(&work->lockdep_map);
+               lock_map_release(&work->lockdep_map);
+       }
+
+       if (start_flush_work(work, &barr, from_cancel)) {
+               wait_for_completion(&barr.done);
+               destroy_work_on_stack(&barr.work);
+               return true;
+       } else {
+               return false;
+       }
+}
+
 /**
  * flush_work - wait for a work to finish executing the last queueing instance
  * @work: the work to flush
@@ -2909,18 +2935,7 @@ already_gone:
  */
 bool flush_work(struct work_struct *work)
 {
-       struct wq_barrier barr;
-
-       if (WARN_ON(!wq_online))
-               return false;
-
-       if (start_flush_work(work, &barr)) {
-               wait_for_completion(&barr.done);
-               destroy_work_on_stack(&barr.work);
-               return true;
-       } else {
-               return false;
-       }
+       return __flush_work(work, false);
 }
 EXPORT_SYMBOL_GPL(flush_work);
 
@@ -2986,7 +3001,7 @@ static bool __cancel_work_timer(struct work_struct *work, bool is_dwork)
         * isn't executing.
         */
        if (wq_online)
-               flush_work(work);
+               __flush_work(work, true);
 
        clear_work_data(work);
 
@@ -5559,7 +5574,7 @@ static void wq_watchdog_timer_fn(struct timer_list *unused)
        mod_timer(&wq_watchdog_timer, jiffies + thresh);
 }
 
-void wq_watchdog_touch(int cpu)
+notrace void wq_watchdog_touch(int cpu)
 {
        if (cpu >= 0)
                per_cpu(wq_watchdog_touched_cpu, cpu) = jiffies;
index 09aae85418ab92218f330f3bad18e8e96cb31055..f2a39c9e54853262c8f8d566775fbae6062d4480 100644 (file)
@@ -2,5 +2,7 @@
 # Generated files
 #
 gen_crc32table
+gen_crc64table
 crc32table.h
+crc64table.h
 oid_registry_data.c
index 706836ec314d2add83b84ebe59dec8fd7e13a7ad..a3928d4438b5008c1fa01470de11245d1557bc33 100644 (file)
@@ -170,6 +170,14 @@ config CRC32_BIT
 
 endchoice
 
+config CRC64
+       tristate "CRC64 functions"
+       help
+         This option is provided for the case where no in-kernel-tree
+         modules require CRC64 functions, but a module built outside
+         the kernel tree does. Such modules that use library CRC64
+         functions require M here.
+
 config CRC4
        tristate "CRC4 functions"
        help
@@ -223,7 +231,6 @@ config AUDIT_COMPAT_GENERIC
 
 config RANDOM32_SELFTEST
        bool "PRNG perform self test on init"
-       default n
        help
          This option enables the 32 bit PRNG library functions to perform a
          self test on initialization.
index ab1b599202bca7f5ba8b690a92df177a3b8c1282..4966c4fbe7f735a1eae8d7e5de7e96022cb02862 100644 (file)
@@ -1220,7 +1220,6 @@ config LOCK_TORTURE_TEST
        tristate "torture tests for locking"
        depends on DEBUG_KERNEL
        select TORTURE_TEST
-       default n
        help
          This option provides a kernel module that runs torture tests
          on kernel locking primitives.  The kernel module may be built
@@ -1278,13 +1277,13 @@ config WARN_ALL_UNSEEDED_RANDOM
          time.  This is really bad from a security perspective, and
          so architecture maintainers really need to do what they can
          to get the CRNG seeded sooner after the system is booted.
-         However, since users can not do anything actionble to
+         However, since users cannot do anything actionable to
          address this, by default the kernel will issue only a single
          warning for the first use of unseeded randomness.
 
          Say Y here if you want to receive warnings for all uses of
          unseeded randomness.  This will be of use primarily for
-         those developers interersted in improving the security of
+         those developers interested in improving the security of
          Linux kernels running on their architecture (or
          subarchitecture).
 
@@ -1687,7 +1686,6 @@ config LKDTM
        tristate "Linux Kernel Dump Test Tool Module"
        depends on DEBUG_FS
        depends on BLOCK
-       default n
        help
        This module enables testing of the different dumping mechanisms by
        inducing system failures at predefined crash points.
@@ -1721,7 +1719,6 @@ config KPROBES_SANITY_TEST
        bool "Kprobes sanity tests"
        depends on DEBUG_KERNEL
        depends on KPROBES
-       default n
        help
          This option provides for testing basic kprobes functionality on
          boot. Samples of kprobe and kretprobe are inserted and
@@ -1732,7 +1729,6 @@ config KPROBES_SANITY_TEST
 config BACKTRACE_SELF_TEST
        tristate "Self test for the backtrace code"
        depends on DEBUG_KERNEL
-       default n
        help
          This option provides a kernel module that can be used to test
          the kernel stack backtrace code. This option is not useful
@@ -1802,7 +1798,6 @@ config TEST_PRINTF
 
 config TEST_BITMAP
        tristate "Test bitmap_*() family of functions at runtime"
-       default n
        help
          Enable this option to test the bitmap functions at boot.
 
@@ -1823,7 +1818,6 @@ config TEST_OVERFLOW
 
 config TEST_RHASHTABLE
        tristate "Perform selftest on resizable hash table"
-       default n
        help
          Enable this option to test the rhashtable functions at boot.
 
@@ -1831,7 +1825,6 @@ config TEST_RHASHTABLE
 
 config TEST_HASH
        tristate "Perform selftest on hash functions"
-       default n
        help
          Enable this option to test the kernel's integer (<linux/hash.h>),
          string (<linux/stringhash.h>), and siphash (<linux/siphash.h>)
@@ -1840,9 +1833,11 @@ config TEST_HASH
          This is intended to help people writing architecture-specific
          optimized versions.  If unsure, say N.
 
+config TEST_IDA
+       tristate "Perform selftest on IDA functions"
+
 config TEST_PARMAN
        tristate "Perform selftest on priority array manager"
-       default n
        depends on PARMAN
        help
          Enable this option to test priority array manager on boot
@@ -1852,7 +1847,6 @@ config TEST_PARMAN
 
 config TEST_LKM
        tristate "Test module loading with 'hello world' module"
-       default n
        depends on m
        help
          This builds the "test_module" module that emits "Hello, world"
@@ -1866,7 +1860,6 @@ config TEST_LKM
 
 config TEST_USER_COPY
        tristate "Test user/kernel boundary protections"
-       default n
        depends on m
        help
          This builds the "test_user_copy" module that runs sanity checks
@@ -1879,7 +1872,6 @@ config TEST_USER_COPY
 
 config TEST_BPF
        tristate "Test BPF filter functionality"
-       default n
        depends on m && NET
        help
          This builds the "test_bpf" module that runs various test vectors
@@ -1893,7 +1885,6 @@ config TEST_BPF
 
 config FIND_BIT_BENCHMARK
        tristate "Test find_bit functions"
-       default n
        help
          This builds the "test_find_bit" module that measure find_*_bit()
          functions performance.
@@ -1902,7 +1893,6 @@ config FIND_BIT_BENCHMARK
 
 config TEST_FIRMWARE
        tristate "Test firmware loading via userspace interface"
-       default n
        depends on FW_LOADER
        help
          This builds the "test_firmware" module that creates a userspace
@@ -1915,7 +1905,6 @@ config TEST_FIRMWARE
 
 config TEST_SYSCTL
        tristate "sysctl test driver"
-       default n
        depends on PROC_SYSCTL
        help
          This builds the "test_sysctl" module. This driver enables to test the
@@ -1926,7 +1915,6 @@ config TEST_SYSCTL
 
 config TEST_UDELAY
        tristate "udelay test driver"
-       default n
        help
          This builds the "udelay_test" module that helps to make sure
          that udelay() is working properly.
@@ -1935,7 +1923,6 @@ config TEST_UDELAY
 
 config TEST_STATIC_KEYS
        tristate "Test static keys"
-       default n
        depends on m
        help
          Test the static key interfaces.
@@ -1944,7 +1931,6 @@ config TEST_STATIC_KEYS
 
 config TEST_KMOD
        tristate "kmod stress tester"
-       default n
        depends on m
        depends on BLOCK && (64BIT || LBDAF)      # for XFS, BTRFS
        depends on NETDEVICES && NET_CORE && INET # for TUN
index d95bb252510169816ae0ce67c1e92a1e1ec9ce87..ca3f7ebb900d8eba9397fcc4c112dff9a6bdb05d 100644 (file)
@@ -50,6 +50,7 @@ obj-$(CONFIG_TEST_BPF) += test_bpf.o
 obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o
 obj-$(CONFIG_TEST_SYSCTL) += test_sysctl.o
 obj-$(CONFIG_TEST_HASH) += test_hash.o test_siphash.o
+obj-$(CONFIG_TEST_IDA) += test_ida.o
 obj-$(CONFIG_TEST_KASAN) += test_kasan.o
 CFLAGS_test_kasan.o += -fno-builtin
 obj-$(CONFIG_TEST_UBSAN) += test_ubsan.o
@@ -103,6 +104,7 @@ obj-$(CONFIG_CRC16) += crc16.o
 obj-$(CONFIG_CRC_T10DIF)+= crc-t10dif.o
 obj-$(CONFIG_CRC_ITU_T)        += crc-itu-t.o
 obj-$(CONFIG_CRC32)    += crc32.o
+obj-$(CONFIG_CRC64)     += crc64.o
 obj-$(CONFIG_CRC32_SELFTEST)   += crc32test.o
 obj-$(CONFIG_CRC4)     += crc4.o
 obj-$(CONFIG_CRC7)     += crc7.o
@@ -217,7 +219,9 @@ obj-$(CONFIG_FONT_SUPPORT) += fonts/
 obj-$(CONFIG_PRIME_NUMBERS) += prime_numbers.o
 
 hostprogs-y    := gen_crc32table
+hostprogs-y    += gen_crc64table
 clean-files    := crc32table.h
+clean-files    += crc64table.h
 
 $(obj)/crc32.o: $(obj)/crc32table.h
 
@@ -227,6 +231,14 @@ quiet_cmd_crc32 = GEN     $@
 $(obj)/crc32table.h: $(obj)/gen_crc32table
        $(call cmd,crc32)
 
+$(obj)/crc64.o: $(obj)/crc64table.h
+
+quiet_cmd_crc64 = GEN     $@
+      cmd_crc64 = $< > $@
+
+$(obj)/crc64table.h: $(obj)/gen_crc64table
+       $(call cmd,crc64)
+
 #
 # Build a fast OID lookip registry from include/linux/oid_registry.h
 #
index 730969c681cbaf6228e5f8a78bd56e3e547b7122..2fd07f6df0b85e417f340576f530878a9d6ddcfc 100644 (file)
@@ -1152,14 +1152,10 @@ EXPORT_SYMBOL(bitmap_free);
  *     @buf: array of u32 (in host byte order), the source bitmap
  *     @nbits: number of bits in @bitmap
  */
-void bitmap_from_arr32(unsigned long *bitmap, const u32 *buf,
-                                               unsigned int nbits)
+void bitmap_from_arr32(unsigned long *bitmap, const u32 *buf, unsigned int nbits)
 {
        unsigned int i, halfwords;
 
-       if (!nbits)
-               return;
-
        halfwords = DIV_ROUND_UP(nbits, 32);
        for (i = 0; i < halfwords; i++) {
                bitmap[i/2] = (unsigned long) buf[i];
@@ -1183,9 +1179,6 @@ void bitmap_to_arr32(u32 *buf, const unsigned long *bitmap, unsigned int nbits)
 {
        unsigned int i, halfwords;
 
-       if (!nbits)
-               return;
-
        halfwords = DIV_ROUND_UP(nbits, 32);
        for (i = 0; i < halfwords; i++) {
                buf[i] = (u32) (bitmap[i/2] & UINT_MAX);
diff --git a/lib/crc64.c b/lib/crc64.c
new file mode 100644 (file)
index 0000000..0ef8ae6
--- /dev/null
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Normal 64-bit CRC calculation.
+ *
+ * This is a basic crc64 implementation following ECMA-182 specification,
+ * which can be found from,
+ * http://www.ecma-international.org/publications/standards/Ecma-182.htm
+ *
+ * Dr. Ross N. Williams has a great document to introduce the idea of CRC
+ * algorithm, here the CRC64 code is also inspired by the table-driven
+ * algorithm and detail example from this paper. This paper can be found
+ * from,
+ * http://www.ross.net/crc/download/crc_v3.txt
+ *
+ * crc64table[256] is the lookup table of a table-driven 64-bit CRC
+ * calculation, which is generated by gen_crc64table.c in kernel build
+ * time. The polynomial of crc64 arithmetic is from ECMA-182 specification
+ * as well, which is defined as,
+ *
+ * x^64 + x^62 + x^57 + x^55 + x^54 + x^53 + x^52 + x^47 + x^46 + x^45 +
+ * x^40 + x^39 + x^38 + x^37 + x^35 + x^33 + x^32 + x^31 + x^29 + x^27 +
+ * x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 +
+ * x^7 + x^4 + x + 1
+ *
+ * Copyright 2018 SUSE Linux.
+ *   Author: Coly Li <colyli@suse.de>
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include "crc64table.h"
+
+MODULE_DESCRIPTION("CRC64 calculations");
+MODULE_LICENSE("GPL v2");
+
+/**
+ * crc64_be - Calculate bitwise big-endian ECMA-182 CRC64
+ * @crc: seed value for computation. 0 or (u64)~0 for a new CRC calculation,
+       or the previous crc64 value if computing incrementally.
+ * @p: pointer to buffer over which CRC64 is run
+ * @len: length of buffer @p
+ */
+u64 __pure crc64_be(u64 crc, const void *p, size_t len)
+{
+       size_t i, t;
+
+       const unsigned char *_p = p;
+
+       for (i = 0; i < len; i++) {
+               t = ((crc >> 56) ^ (*_p++)) & 0xFF;
+               crc = crc64table[t] ^ (crc << 8);
+       }
+
+       return crc;
+}
+EXPORT_SYMBOL_GPL(crc64_be);
index 9ae5b62c8a0dba2f0bb3f7fe61031c2a7eaff558..89752d0b23e8b04c0ec0b6c55887de1fb90464b6 100644 (file)
@@ -2058,7 +2058,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 128 0x80 '\80' */
+       /* 128 0x80 'Ç' */
        0x00, /* 0000000 */
        0x38, /* 0011100 */
        0x6c, /* 0110110 */
@@ -2074,7 +2074,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x70, /* 0111000 */
        0x00, /* 0000000 */
 
-       /* 129 0x81 '\81' */
+       /* 129 0x81 'ü' */
        0x00, /* 0000000 */
        0xcc, /* 1100110 */
        0x00, /* 0000000 */
@@ -2090,7 +2090,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 130 0x82 '\82' */
+       /* 130 0x82 'é' */
        0x0c, /* 0000110 */
        0x18, /* 0001100 */
        0x30, /* 0011000 */
@@ -2106,7 +2106,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 131 0x83 '\83' */
+       /* 131 0x83 'â' */
        0x10, /* 0001000 */
        0x38, /* 0011100 */
        0x6c, /* 0110110 */
@@ -2122,7 +2122,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 132 0x84 '\84' */
+       /* 132 0x84 'ä' */
        0x00, /* 0000000 */
        0xcc, /* 1100110 */
        0x00, /* 0000000 */
@@ -2138,7 +2138,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 133 0x85 '\85' */
+       /* 133 0x85 'à' */
        0x60, /* 0110000 */
        0x30, /* 0011000 */
        0x18, /* 0001100 */
@@ -2154,7 +2154,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 134 0x86 '\86' */
+       /* 134 0x86 'å' */
        0x38, /* 0011100 */
        0x6c, /* 0110110 */
        0x38, /* 0011100 */
@@ -2170,7 +2170,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 135 0x87 '\87' */
+       /* 135 0x87 'ç' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -2186,7 +2186,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x30, /* 0011000 */
        0xe0, /* 1110000 */
 
-       /* 136 0x88 '\88' */
+       /* 136 0x88 'ê' */
        0x10, /* 0001000 */
        0x38, /* 0011100 */
        0x6c, /* 0110110 */
@@ -2202,7 +2202,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 137 0x89 '\89' */
+       /* 137 0x89 'ë' */
        0x00, /* 0000000 */
        0xcc, /* 1100110 */
        0x00, /* 0000000 */
@@ -2218,7 +2218,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 138 0x8a '\8a' */
+       /* 138 0x8a 'è' */
        0xc0, /* 1100000 */
        0x60, /* 0110000 */
        0x30, /* 0011000 */
@@ -2234,7 +2234,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 139 0x8b '\8b' */
+       /* 139 0x8b 'ï' */
        0x00, /* 0000000 */
        0x6c, /* 0110110 */
        0x00, /* 0000000 */
@@ -2250,7 +2250,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 140 0x8c '\8c' */
+       /* 140 0x8c 'î' */
        0x30, /* 0011000 */
        0x78, /* 0111100 */
        0xcc, /* 1100110 */
@@ -2266,7 +2266,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 141 0x8d '\8d' */
+       /* 141 0x8d 'ì' */
        0xc0, /* 1100000 */
        0x60, /* 0110000 */
        0x30, /* 0011000 */
@@ -2282,7 +2282,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 142 0x8e '\8e' */
+       /* 142 0x8e 'Ä' */
        0x00, /* 0000000 */
        0xcc, /* 1100110 */
        0x00, /* 0000000 */
@@ -2298,7 +2298,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 143 0x8f '\8f' */
+       /* 143 0x8f 'Å' */
        0x30, /* 0011000 */
        0x48, /* 0100100 */
        0x48, /* 0100100 */
@@ -2314,7 +2314,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 144 0x90 '\90' */
+       /* 144 0x90 'É' */
        0x18, /* 0001100 */
        0x30, /* 0011000 */
        0xfc, /* 1111110 */
@@ -2330,7 +2330,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 145 0x91 '\91' */
+       /* 145 0x91 'æ' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -2346,7 +2346,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 146 0x92 '\92' */
+       /* 146 0x92 'Æ' */
        0x00, /* 0000000 */
        0x3e, /* 0011111 */
        0x6c, /* 0110110 */
@@ -2362,7 +2362,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 147 0x93 '\93' */
+       /* 147 0x93 'ô' */
        0x10, /* 0001000 */
        0x38, /* 0011100 */
        0x6c, /* 0110110 */
@@ -2378,7 +2378,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 148 0x94 '\94' */
+       /* 148 0x94 'ö' */
        0x00, /* 0000000 */
        0xcc, /* 1100110 */
        0x00, /* 0000000 */
@@ -2394,7 +2394,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 149 0x95 '\95' */
+       /* 149 0x95 'ò' */
        0xc0, /* 1100000 */
        0x60, /* 0110000 */
        0x30, /* 0011000 */
@@ -2410,7 +2410,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 150 0x96 '\96' */
+       /* 150 0x96 'û' */
        0x30, /* 0011000 */
        0x78, /* 0111100 */
        0xcc, /* 1100110 */
@@ -2426,7 +2426,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 151 0x97 '\97' */
+       /* 151 0x97 'ù' */
        0x60, /* 0110000 */
        0x30, /* 0011000 */
        0x18, /* 0001100 */
@@ -2442,7 +2442,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 152 0x98 '\98' */
+       /* 152 0x98 'ÿ' */
        0x00, /* 0000000 */
        0xcc, /* 1100110 */
        0x00, /* 0000000 */
@@ -2458,7 +2458,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x18, /* 0001100 */
        0x70, /* 0111000 */
 
-       /* 153 0x99 '\99' */
+       /* 153 0x99 'Ö' */
        0xcc, /* 1100110 */
        0x00, /* 0000000 */
        0x78, /* 0111100 */
@@ -2474,7 +2474,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 154 0x9a '\9a' */
+       /* 154 0x9a 'Ü' */
        0xcc, /* 1100110 */
        0x00, /* 0000000 */
        0xcc, /* 1100110 */
@@ -2490,7 +2490,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 155 0x9b '\9b' */
+       /* 155 0x9b '¢' */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
        0x7c, /* 0111110 */
@@ -2506,7 +2506,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 156 0x9c '\9c' */
+       /* 156 0x9c '£' */
        0x38, /* 0011100 */
        0x6c, /* 0110110 */
        0x64, /* 0110010 */
@@ -2522,7 +2522,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 157 0x9d '\9d' */
+       /* 157 0x9d '¥' */
        0x00, /* 0000000 */
        0xcc, /* 1100110 */
        0xcc, /* 1100110 */
@@ -2538,7 +2538,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 158 0x9e '\9e' */
+       /* 158 0x9e '' */
        0xf8, /* 1111100 */
        0xcc, /* 1100110 */
        0xcc, /* 1100110 */
@@ -2554,7 +2554,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 159 0x9f '\9f' */
+       /* 159 0x9f 'ƒ' */
        0x1c, /* 0001110 */
        0x36, /* 0011011 */
        0x30, /* 0011000 */
@@ -2570,7 +2570,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 160 0xa0 ' ' */
+       /* 160 0xa0 'á' */
        0x18, /* 0001100 */
        0x30, /* 0011000 */
        0x60, /* 0110000 */
@@ -2586,7 +2586,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 161 0xa1 '¡' */
+       /* 161 0xa1 'í' */
        0x18, /* 0001100 */
        0x30, /* 0011000 */
        0x60, /* 0110000 */
@@ -2602,7 +2602,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 162 0xa2 '¢' */
+       /* 162 0xa2 'ó' */
        0x18, /* 0001100 */
        0x30, /* 0011000 */
        0x60, /* 0110000 */
@@ -2618,7 +2618,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 163 0xa3 '£' */
+       /* 163 0xa3 'ú' */
        0x18, /* 0001100 */
        0x30, /* 0011000 */
        0x60, /* 0110000 */
@@ -2634,7 +2634,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 164 0xa4 '¤' */
+       /* 164 0xa4 'ñ' */
        0x00, /* 0000000 */
        0x76, /* 0111011 */
        0xdc, /* 1101110 */
@@ -2650,7 +2650,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 165 0xa5 '¥' */
+       /* 165 0xa5 'Ñ' */
        0x76, /* 0111011 */
        0xdc, /* 1101110 */
        0x00, /* 0000000 */
@@ -2666,7 +2666,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 166 0xa6 '¦' */
+       /* 166 0xa6 'ª' */
        0x00, /* 0000000 */
        0x78, /* 0111100 */
        0xd8, /* 1101100 */
@@ -2682,7 +2682,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 167 0xa7 '§' */
+       /* 167 0xa7 'º' */
        0x00, /* 0000000 */
        0x70, /* 0111000 */
        0xd8, /* 1101100 */
@@ -2698,7 +2698,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 168 0xa8 '¨' */
+       /* 168 0xa8 '¿' */
        0x00, /* 0000000 */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
@@ -2714,7 +2714,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 169 0xa9 '©' */
+       /* 169 0xa9 '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -2730,7 +2730,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 170 0xaa 'ª' */
+       /* 170 0xaa '¬' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -2746,7 +2746,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 171 0xab '«' */
+       /* 171 0xab '½' */
        0x60, /* 0110000 */
        0xe0, /* 1110000 */
        0x62, /* 0110001 */
@@ -2762,7 +2762,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x30, /* 0011000 */
        0x7c, /* 0111110 */
 
-       /* 172 0xac '¬' */
+       /* 172 0xac '¼' */
        0x60, /* 0110000 */
        0xe0, /* 1110000 */
        0x62, /* 0110001 */
@@ -2778,7 +2778,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x0c, /* 0000110 */
        0x00, /* 0000000 */
 
-       /* 173 0xad '­' */
+       /* 173 0xad '¡' */
        0x00, /* 0000000 */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
@@ -2794,7 +2794,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 174 0xae '®' */
+       /* 174 0xae '«' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -2810,7 +2810,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 175 0xaf '¯' */
+       /* 175 0xaf '»' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -2826,7 +2826,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 176 0xb0 '°' */
+       /* 176 0xb0 '' */
        0x88, /* 1000100 */
        0x22, /* 0010001 */
        0x88, /* 1000100 */
@@ -2842,7 +2842,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x88, /* 1000100 */
        0x22, /* 0010001 */
 
-       /* 177 0xb1 '±' */
+       /* 177 0xb1 '' */
        0x54, /* 0101010 */
        0xaa, /* 1010101 */
        0x54, /* 0101010 */
@@ -2858,7 +2858,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x54, /* 0101010 */
        0xaa, /* 1010101 */
 
-       /* 178 0xb2 '²' */
+       /* 178 0xb2 '' */
        0xee, /* 1110111 */
        0xba, /* 1011101 */
        0xee, /* 1110111 */
@@ -2874,7 +2874,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0xee, /* 1110111 */
        0xba, /* 1011101 */
 
-       /* 179 0xb3 '³' */
+       /* 179 0xb3 '' */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
@@ -2890,7 +2890,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x30, /* 0011000 */
        0x30, /* 0011000 */
 
-       /* 180 0xb4 '´' */
+       /* 180 0xb4 '' */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
@@ -2906,7 +2906,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x30, /* 0011000 */
        0x30, /* 0011000 */
 
-       /* 181 0xb5 'µ' */
+       /* 181 0xb5 '' */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
@@ -2922,7 +2922,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x30, /* 0011000 */
        0x30, /* 0011000 */
 
-       /* 182 0xb6 '' */
+       /* 182 0xb6 '' */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
@@ -2938,7 +2938,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
 
-       /* 183 0xb7 '·' */
+       /* 183 0xb7 '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -2954,7 +2954,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
 
-       /* 184 0xb8 '¸' */
+       /* 184 0xb8 '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -2970,7 +2970,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x30, /* 0011000 */
        0x30, /* 0011000 */
 
-       /* 185 0xb9 '¹' */
+       /* 185 0xb9 '' */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
@@ -2986,7 +2986,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
 
-       /* 186 0xba 'º' */
+       /* 186 0xba '' */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
@@ -3002,7 +3002,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
 
-       /* 187 0xbb '»' */
+       /* 187 0xbb '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3018,7 +3018,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
 
-       /* 188 0xbc '¼' */
+       /* 188 0xbc '' */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
@@ -3034,7 +3034,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 189 0xbd '½' */
+       /* 189 0xbd '' */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
@@ -3050,7 +3050,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 190 0xbe '¾' */
+       /* 190 0xbe '' */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
@@ -3066,7 +3066,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 191 0xbf '¿' */
+       /* 191 0xbf '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3082,7 +3082,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x30, /* 0011000 */
        0x30, /* 0011000 */
 
-       /* 192 0xc0 'À' */
+       /* 192 0xc0 '' */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
@@ -3098,7 +3098,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 193 0xc1 'Á' */
+       /* 193 0xc1 '' */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
@@ -3114,7 +3114,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 194 0xc2 'Â' */
+       /* 194 0xc2 '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3130,7 +3130,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x30, /* 0011000 */
        0x30, /* 0011000 */
 
-       /* 195 0xc3 'Ã' */
+       /* 195 0xc3 '' */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
@@ -3146,7 +3146,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x30, /* 0011000 */
        0x30, /* 0011000 */
 
-       /* 196 0xc4 'Ä' */
+       /* 196 0xc4 '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3162,7 +3162,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 197 0xc5 'Å' */
+       /* 197 0xc5 '' */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
@@ -3178,7 +3178,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x30, /* 0011000 */
        0x30, /* 0011000 */
 
-       /* 198 0xc6 'Æ' */
+       /* 198 0xc6 '' */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
@@ -3194,7 +3194,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x30, /* 0011000 */
        0x30, /* 0011000 */
 
-       /* 199 0xc7 'Ç' */
+       /* 199 0xc7 '' */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
@@ -3210,7 +3210,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
 
-       /* 200 0xc8 'È' */
+       /* 200 0xc8 '' */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
@@ -3226,7 +3226,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 201 0xc9 'É' */
+       /* 201 0xc9 '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3242,7 +3242,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
 
-       /* 202 0xca 'Ê' */
+       /* 202 0xca '' */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
@@ -3258,7 +3258,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 203 0xcb 'Ë' */
+       /* 203 0xcb '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3274,7 +3274,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
 
-       /* 204 0xcc 'Ì' */
+       /* 204 0xcc '' */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
@@ -3290,7 +3290,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
 
-       /* 205 0xcd 'Í' */
+       /* 205 0xcd '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3306,7 +3306,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 206 0xce 'Î' */
+       /* 206 0xce '' */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
@@ -3322,7 +3322,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
 
-       /* 207 0xcf 'Ï' */
+       /* 207 0xcf '' */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
@@ -3338,7 +3338,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 208 0xd0 'Ð' */
+       /* 208 0xd0 '' */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
@@ -3354,7 +3354,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 209 0xd1 'Ñ' */
+       /* 209 0xd1 '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3370,7 +3370,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x30, /* 0011000 */
        0x30, /* 0011000 */
 
-       /* 210 0xd2 'Ò' */
+       /* 210 0xd2 '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3386,7 +3386,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
 
-       /* 211 0xd3 'Ó' */
+       /* 211 0xd3 '' */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
@@ -3402,7 +3402,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 212 0xd4 'Ô' */
+       /* 212 0xd4 '' */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
@@ -3418,7 +3418,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 213 0xd5 'Õ' */
+       /* 213 0xd5 '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3434,7 +3434,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x30, /* 0011000 */
        0x30, /* 0011000 */
 
-       /* 214 0xd6 'Ö' */
+       /* 214 0xd6 '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3450,7 +3450,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
 
-       /* 215 0xd7 '×' */
+       /* 215 0xd7 '' */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
@@ -3466,7 +3466,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
 
-       /* 216 0xd8 'Ø' */
+       /* 216 0xd8 '' */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
@@ -3482,7 +3482,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x30, /* 0011000 */
        0x30, /* 0011000 */
 
-       /* 217 0xd9 'Ù' */
+       /* 217 0xd9 '' */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
        0x30, /* 0011000 */
@@ -3498,7 +3498,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 218 0xda 'Ú' */
+       /* 218 0xda '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3514,7 +3514,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x30, /* 0011000 */
        0x30, /* 0011000 */
 
-       /* 219 0xdb 'Û' */
+       /* 219 0xdb '' */
        0xfe, /* 1111111 */
        0xfe, /* 1111111 */
        0xfe, /* 1111111 */
@@ -3530,7 +3530,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0xfe, /* 1111111 */
        0xfe, /* 1111111 */
 
-       /* 220 0xdc 'Ü' */
+       /* 220 0xdc '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3546,7 +3546,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0xfe, /* 1111111 */
        0xfe, /* 1111111 */
 
-       /* 221 0xdd 'Ý' */
+       /* 221 0xdd '' */
        0xe0, /* 1110000 */
        0xe0, /* 1110000 */
        0xe0, /* 1110000 */
@@ -3562,7 +3562,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0xe0, /* 1110000 */
        0xe0, /* 1110000 */
 
-       /* 222 0xde 'Þ' */
+       /* 222 0xde '' */
        0x1e, /* 0001111 */
        0x1e, /* 0001111 */
        0x1e, /* 0001111 */
@@ -3578,7 +3578,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x1e, /* 0001111 */
        0x1e, /* 0001111 */
 
-       /* 223 0xdf 'ß' */
+       /* 223 0xdf '' */
        0xfe, /* 1111111 */
        0xfe, /* 1111111 */
        0xfe, /* 1111111 */
@@ -3594,7 +3594,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 224 0xe0 'à' */
+       /* 224 0xe0 'α' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3610,7 +3610,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 225 0xe1 'á' */
+       /* 225 0xe1 'ß' */
        0x00, /* 0000000 */
        0x78, /* 0111100 */
        0xcc, /* 1100110 */
@@ -3626,7 +3626,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 226 0xe2 'â' */
+       /* 226 0xe2 'Γ' */
        0x00, /* 0000000 */
        0xfc, /* 1111110 */
        0xcc, /* 1100110 */
@@ -3642,7 +3642,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 227 0xe3 'ã' */
+       /* 227 0xe3 'π' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0xfe, /* 1111111 */
@@ -3658,7 +3658,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 228 0xe4 'ä' */
+       /* 228 0xe4 'Σ' */
        0x00, /* 0000000 */
        0xfc, /* 1111110 */
        0xcc, /* 1100110 */
@@ -3674,7 +3674,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 229 0xe5 'å' */
+       /* 229 0xe5 'σ' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3690,7 +3690,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 230 0xe6 'æ' */
+       /* 230 0xe6 'µ' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3706,7 +3706,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0xc0, /* 1100000 */
        0x80, /* 1000000 */
 
-       /* 231 0xe7 'ç' */
+       /* 231 0xe7 'τ' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3722,7 +3722,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 232 0xe8 'è' */
+       /* 232 0xe8 'Φ' */
        0x00, /* 0000000 */
        0xfc, /* 1111110 */
        0x30, /* 0011000 */
@@ -3738,7 +3738,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 233 0xe9 'é' */
+       /* 233 0xe9 'Θ' */
        0x00, /* 0000000 */
        0x38, /* 0011100 */
        0x6c, /* 0110110 */
@@ -3754,7 +3754,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 234 0xea 'ê' */
+       /* 234 0xea 'Ω' */
        0x00, /* 0000000 */
        0x38, /* 0011100 */
        0x6c, /* 0110110 */
@@ -3770,7 +3770,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 235 0xeb 'ë' */
+       /* 235 0xeb 'δ' */
        0x00, /* 0000000 */
        0x3c, /* 0011110 */
        0x60, /* 0110000 */
@@ -3786,7 +3786,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 236 0xec 'ì' */
+       /* 236 0xec '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3802,7 +3802,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 237 0xed 'í' */
+       /* 237 0xed 'φ' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x06, /* 0000011 */
@@ -3818,7 +3818,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 238 0xee 'î' */
+       /* 238 0xee 'ε' */
        0x00, /* 0000000 */
        0x1c, /* 0001110 */
        0x30, /* 0011000 */
@@ -3834,7 +3834,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 239 0xef 'ï' */
+       /* 239 0xef '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x78, /* 0111100 */
@@ -3850,7 +3850,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 240 0xf0 'ð' */
+       /* 240 0xf0 '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3866,7 +3866,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 241 0xf1 'ñ' */
+       /* 241 0xf1 '±' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3882,7 +3882,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 242 0xf2 'ò' */
+       /* 242 0xf2 '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x60, /* 0110000 */
@@ -3898,7 +3898,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 243 0xf3 'ó' */
+       /* 243 0xf3 '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x18, /* 0001100 */
@@ -3914,7 +3914,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 244 0xf4 'ô' */
+       /* 244 0xf4 '' */
        0x00, /* 0000000 */
        0x1c, /* 0001110 */
        0x36, /* 0011011 */
@@ -3930,7 +3930,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x30, /* 0011000 */
        0x30, /* 0011000 */
 
-       /* 245 0xf5 'õ' */
+       /* 245 0xf5 '' */
        0x18, /* 0001100 */
        0x18, /* 0001100 */
        0x18, /* 0001100 */
@@ -3946,7 +3946,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 246 0xf6 'ö' */
+       /* 246 0xf6 '÷' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3962,7 +3962,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 247 0xf7 '÷' */
+       /* 247 0xf7 '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -3978,7 +3978,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 248 0xf8 'ø' */
+       /* 248 0xf8 '°' */
        0x38, /* 0011100 */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
@@ -3994,7 +3994,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 249 0xf9 'ù' */
+       /* 249 0xf9 '·' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -4010,7 +4010,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 250 0xfa 'ú' */
+       /* 250 0xfa '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -4026,7 +4026,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 251 0xfb 'û' */
+       /* 251 0xfb '' */
        0x1e, /* 0001111 */
        0x18, /* 0001100 */
        0x18, /* 0001100 */
@@ -4042,7 +4042,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 252 0xfc 'ü' */
+       /* 252 0xfc '' */
        0xd8, /* 1101100 */
        0x6c, /* 0110110 */
        0x6c, /* 0110110 */
@@ -4058,7 +4058,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 253 0xfd 'ý' */
+       /* 253 0xfd '²' */
        0x78, /* 0111100 */
        0xcc, /* 1100110 */
        0x18, /* 0001100 */
@@ -4074,7 +4074,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 254 0xfe 'þ' */
+       /* 254 0xfe '' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
@@ -4090,7 +4090,7 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
        0x00, /* 0000000 */
        0x00, /* 0000000 */
 
-       /* 255 0xff 'ÿ' */
+       /* 255 0xff ' ' */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
        0x00, /* 0000000 */
index 34292cdfaa23253b41ae6260fb67b0e4a2acc112..b7ab1f5fbdb8a523b37b7e9fc23e0a7534adabe5 100644 (file)
@@ -2316,7 +2316,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 128 0x80 '\80' */
+       /* 128 0x80 'Ç' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x3c, /* 00111100 */
@@ -2334,7 +2334,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 129 0x81 '\81' */
+       /* 129 0x81 'ü' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0xcc, /* 11001100 */
@@ -2352,7 +2352,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 130 0x82 '\82' */
+       /* 130 0x82 'é' */
        0x00, /* 00000000 */
        0x0c, /* 00001100 */
        0x18, /* 00011000 */
@@ -2370,7 +2370,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 131 0x83 '\83' */
+       /* 131 0x83 'â' */
        0x00, /* 00000000 */
        0x10, /* 00010000 */
        0x38, /* 00111000 */
@@ -2388,7 +2388,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 132 0x84 '\84' */
+       /* 132 0x84 'ä' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0xcc, /* 11001100 */
@@ -2406,7 +2406,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 133 0x85 '\85' */
+       /* 133 0x85 'à' */
        0x00, /* 00000000 */
        0x60, /* 01100000 */
        0x30, /* 00110000 */
@@ -2424,7 +2424,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 134 0x86 '\86' */
+       /* 134 0x86 'å' */
        0x00, /* 00000000 */
        0x38, /* 00111000 */
        0x6c, /* 01101100 */
@@ -2442,7 +2442,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 135 0x87 '\87' */
+       /* 135 0x87 'ç' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -2460,7 +2460,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 136 0x88 '\88' */
+       /* 136 0x88 'ê' */
        0x00, /* 00000000 */
        0x10, /* 00010000 */
        0x38, /* 00111000 */
@@ -2478,7 +2478,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 137 0x89 '\89' */
+       /* 137 0x89 'ë' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0xc6, /* 11000110 */
@@ -2496,7 +2496,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 138 0x8a '\8a' */
+       /* 138 0x8a 'è' */
        0x00, /* 00000000 */
        0x60, /* 01100000 */
        0x30, /* 00110000 */
@@ -2514,7 +2514,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 139 0x8b '\8b' */
+       /* 139 0x8b 'ï' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x66, /* 01100110 */
@@ -2532,7 +2532,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 140 0x8c '\8c' */
+       /* 140 0x8c 'î' */
        0x00, /* 00000000 */
        0x18, /* 00011000 */
        0x3c, /* 00111100 */
@@ -2550,7 +2550,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 141 0x8d '\8d' */
+       /* 141 0x8d 'ì' */
        0x00, /* 00000000 */
        0x60, /* 01100000 */
        0x30, /* 00110000 */
@@ -2568,7 +2568,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 142 0x8e '\8e' */
+       /* 142 0x8e 'Ä' */
        0x00, /* 00000000 */
        0xc6, /* 11000110 */
        0x00, /* 00000000 */
@@ -2586,7 +2586,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 143 0x8f '\8f' */
+       /* 143 0x8f 'Å' */
        0x38, /* 00111000 */
        0x6c, /* 01101100 */
        0x38, /* 00111000 */
@@ -2604,7 +2604,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 144 0x90 '\90' */
+       /* 144 0x90 'É' */
        0x0c, /* 00001100 */
        0x18, /* 00011000 */
        0x00, /* 00000000 */
@@ -2622,7 +2622,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 145 0x91 '\91' */
+       /* 145 0x91 'æ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -2640,7 +2640,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 146 0x92 '\92' */
+       /* 146 0x92 'Æ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x3e, /* 00111110 */
@@ -2658,7 +2658,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 147 0x93 '\93' */
+       /* 147 0x93 'ô' */
        0x00, /* 00000000 */
        0x10, /* 00010000 */
        0x38, /* 00111000 */
@@ -2676,7 +2676,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 148 0x94 '\94' */
+       /* 148 0x94 'ö' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0xc6, /* 11000110 */
@@ -2694,7 +2694,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 149 0x95 '\95' */
+       /* 149 0x95 'ò' */
        0x00, /* 00000000 */
        0x60, /* 01100000 */
        0x30, /* 00110000 */
@@ -2712,7 +2712,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 150 0x96 '\96' */
+       /* 150 0x96 'û' */
        0x00, /* 00000000 */
        0x30, /* 00110000 */
        0x78, /* 01111000 */
@@ -2730,7 +2730,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 151 0x97 '\97' */
+       /* 151 0x97 'ù' */
        0x00, /* 00000000 */
        0x60, /* 01100000 */
        0x30, /* 00110000 */
@@ -2748,7 +2748,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 152 0x98 '\98' */
+       /* 152 0x98 'ÿ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0xc6, /* 11000110 */
@@ -2766,7 +2766,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x78, /* 01111000 */
        0x00, /* 00000000 */
 
-       /* 153 0x99 '\99' */
+       /* 153 0x99 'Ö' */
        0x00, /* 00000000 */
        0xc6, /* 11000110 */
        0x00, /* 00000000 */
@@ -2784,7 +2784,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 154 0x9a '\9a' */
+       /* 154 0x9a 'Ü' */
        0x00, /* 00000000 */
        0xc6, /* 11000110 */
        0x00, /* 00000000 */
@@ -2802,7 +2802,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 155 0x9b '\9b' */
+       /* 155 0x9b '¢' */
        0x00, /* 00000000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -2820,7 +2820,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 156 0x9c '\9c' */
+       /* 156 0x9c '£' */
        0x00, /* 00000000 */
        0x38, /* 00111000 */
        0x6c, /* 01101100 */
@@ -2838,7 +2838,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 157 0x9d '\9d' */
+       /* 157 0x9d '¥' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x66, /* 01100110 */
@@ -2856,7 +2856,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 158 0x9e '\9e' */
+       /* 158 0x9e '' */
        0x00, /* 00000000 */
        0xf8, /* 11111000 */
        0xcc, /* 11001100 */
@@ -2874,7 +2874,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 159 0x9f '\9f' */
+       /* 159 0x9f 'ƒ' */
        0x00, /* 00000000 */
        0x0e, /* 00001110 */
        0x1b, /* 00011011 */
@@ -2892,7 +2892,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 160 0xa0 ' ' */
+       /* 160 0xa0 'á' */
        0x00, /* 00000000 */
        0x18, /* 00011000 */
        0x30, /* 00110000 */
@@ -2910,7 +2910,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 161 0xa1 '¡' */
+       /* 161 0xa1 'í' */
        0x00, /* 00000000 */
        0x0c, /* 00001100 */
        0x18, /* 00011000 */
@@ -2928,7 +2928,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 162 0xa2 '¢' */
+       /* 162 0xa2 'ó' */
        0x00, /* 00000000 */
        0x18, /* 00011000 */
        0x30, /* 00110000 */
@@ -2946,7 +2946,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 163 0xa3 '£' */
+       /* 163 0xa3 'ú' */
        0x00, /* 00000000 */
        0x18, /* 00011000 */
        0x30, /* 00110000 */
@@ -2964,7 +2964,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 164 0xa4 '¤' */
+       /* 164 0xa4 'ñ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x76, /* 01110110 */
@@ -2982,7 +2982,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 165 0xa5 '¥' */
+       /* 165 0xa5 'Ñ' */
        0x76, /* 01110110 */
        0xdc, /* 11011100 */
        0x00, /* 00000000 */
@@ -3000,7 +3000,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 166 0xa6 '¦' */
+       /* 166 0xa6 'ª' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x3c, /* 00111100 */
@@ -3018,7 +3018,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 167 0xa7 '§' */
+       /* 167 0xa7 'º' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x38, /* 00111000 */
@@ -3036,7 +3036,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 168 0xa8 '¨' */
+       /* 168 0xa8 '¿' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x30, /* 00110000 */
@@ -3054,7 +3054,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 169 0xa9 '©' */
+       /* 169 0xa9 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3072,7 +3072,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 170 0xaa 'ª' */
+       /* 170 0xaa '¬' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3090,7 +3090,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 171 0xab '«' */
+       /* 171 0xab '½' */
        0x00, /* 00000000 */
        0x60, /* 01100000 */
        0xe0, /* 11100000 */
@@ -3108,7 +3108,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 172 0xac '¬' */
+       /* 172 0xac '¼' */
        0x00, /* 00000000 */
        0x60, /* 01100000 */
        0xe0, /* 11100000 */
@@ -3126,7 +3126,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 173 0xad '­' */
+       /* 173 0xad '¡' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x18, /* 00011000 */
@@ -3144,7 +3144,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 174 0xae '®' */
+       /* 174 0xae '«' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3162,7 +3162,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 175 0xaf '¯' */
+       /* 175 0xaf '»' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3180,7 +3180,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 176 0xb0 '°' */
+       /* 176 0xb0 '' */
        0x11, /* 00010001 */
        0x44, /* 01000100 */
        0x11, /* 00010001 */
@@ -3198,7 +3198,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x11, /* 00010001 */
        0x44, /* 01000100 */
 
-       /* 177 0xb1 '±' */
+       /* 177 0xb1 '' */
        0x55, /* 01010101 */
        0xaa, /* 10101010 */
        0x55, /* 01010101 */
@@ -3216,7 +3216,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x55, /* 01010101 */
        0xaa, /* 10101010 */
 
-       /* 178 0xb2 '²' */
+       /* 178 0xb2 '' */
        0xdd, /* 11011101 */
        0x77, /* 01110111 */
        0xdd, /* 11011101 */
@@ -3234,7 +3234,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0xdd, /* 11011101 */
        0x77, /* 01110111 */
 
-       /* 179 0xb3 '³' */
+       /* 179 0xb3 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -3252,7 +3252,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 180 0xb4 '´' */
+       /* 180 0xb4 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -3270,7 +3270,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 181 0xb5 'µ' */
+       /* 181 0xb5 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -3288,7 +3288,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 182 0xb6 '' */
+       /* 182 0xb6 '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -3306,7 +3306,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 183 0xb7 '·' */
+       /* 183 0xb7 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3324,7 +3324,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 184 0xb8 '¸' */
+       /* 184 0xb8 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3342,7 +3342,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 185 0xb9 '¹' */
+       /* 185 0xb9 '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -3360,7 +3360,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 186 0xba 'º' */
+       /* 186 0xba '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -3378,7 +3378,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 187 0xbb '»' */
+       /* 187 0xbb '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3396,7 +3396,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 188 0xbc '¼' */
+       /* 188 0xbc '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -3414,7 +3414,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 189 0xbd '½' */
+       /* 189 0xbd '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -3432,7 +3432,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 190 0xbe '¾' */
+       /* 190 0xbe '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -3450,7 +3450,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 191 0xbf '¿' */
+       /* 191 0xbf '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3468,7 +3468,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 192 0xc0 'À' */
+       /* 192 0xc0 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -3486,7 +3486,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 193 0xc1 'Á' */
+       /* 193 0xc1 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -3504,7 +3504,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 194 0xc2 'Â' */
+       /* 194 0xc2 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3522,7 +3522,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 195 0xc3 'Ã' */
+       /* 195 0xc3 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -3540,7 +3540,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 196 0xc4 'Ä' */
+       /* 196 0xc4 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3558,7 +3558,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 197 0xc5 'Å' */
+       /* 197 0xc5 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -3576,7 +3576,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 198 0xc6 'Æ' */
+       /* 198 0xc6 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -3594,7 +3594,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 199 0xc7 'Ç' */
+       /* 199 0xc7 '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -3612,7 +3612,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 200 0xc8 'È' */
+       /* 200 0xc8 '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -3630,7 +3630,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 201 0xc9 'É' */
+       /* 201 0xc9 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3648,7 +3648,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 202 0xca 'Ê' */
+       /* 202 0xca '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -3666,7 +3666,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 203 0xcb 'Ë' */
+       /* 203 0xcb '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3684,7 +3684,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 204 0xcc 'Ì' */
+       /* 204 0xcc '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -3702,7 +3702,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 205 0xcd 'Í' */
+       /* 205 0xcd '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3720,7 +3720,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 206 0xce 'Î' */
+       /* 206 0xce '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -3738,7 +3738,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 207 0xcf 'Ï' */
+       /* 207 0xcf '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -3756,7 +3756,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 208 0xd0 'Ð' */
+       /* 208 0xd0 '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -3774,7 +3774,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 209 0xd1 'Ñ' */
+       /* 209 0xd1 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3792,7 +3792,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 210 0xd2 'Ò' */
+       /* 210 0xd2 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3810,7 +3810,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 211 0xd3 'Ó' */
+       /* 211 0xd3 '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -3828,7 +3828,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 212 0xd4 'Ô' */
+       /* 212 0xd4 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -3846,7 +3846,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 213 0xd5 'Õ' */
+       /* 213 0xd5 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3864,7 +3864,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 214 0xd6 'Ö' */
+       /* 214 0xd6 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3882,7 +3882,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 215 0xd7 '×' */
+       /* 215 0xd7 '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -3900,7 +3900,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 216 0xd8 'Ø' */
+       /* 216 0xd8 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -3918,7 +3918,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 217 0xd9 'Ù' */
+       /* 217 0xd9 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -3936,7 +3936,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 218 0xda 'Ú' */
+       /* 218 0xda '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3954,7 +3954,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 219 0xdb 'Û' */
+       /* 219 0xdb '' */
        0xff, /* 11111111 */
        0xff, /* 11111111 */
        0xff, /* 11111111 */
@@ -3972,7 +3972,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0xff, /* 11111111 */
        0xff, /* 11111111 */
 
-       /* 220 0xdc 'Ü' */
+       /* 220 0xdc '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -3990,7 +3990,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0xff, /* 11111111 */
        0xff, /* 11111111 */
 
-       /* 221 0xdd 'Ý' */
+       /* 221 0xdd '' */
        0xf0, /* 11110000 */
        0xf0, /* 11110000 */
        0xf0, /* 11110000 */
@@ -4008,7 +4008,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0xf0, /* 11110000 */
        0xf0, /* 11110000 */
 
-       /* 222 0xde 'Þ' */
+       /* 222 0xde '' */
        0x0f, /* 00001111 */
        0x0f, /* 00001111 */
        0x0f, /* 00001111 */
@@ -4026,7 +4026,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x0f, /* 00001111 */
        0x0f, /* 00001111 */
 
-       /* 223 0xdf 'ß' */
+       /* 223 0xdf '' */
        0xff, /* 11111111 */
        0xff, /* 11111111 */
        0xff, /* 11111111 */
@@ -4044,7 +4044,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 224 0xe0 'à' */
+       /* 224 0xe0 'α' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4062,7 +4062,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 225 0xe1 'á' */
+       /* 225 0xe1 'ß' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x78, /* 01111000 */
@@ -4080,7 +4080,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 226 0xe2 'â' */
+       /* 226 0xe2 'Γ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0xfe, /* 11111110 */
@@ -4098,7 +4098,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 227 0xe3 'ã' */
+       /* 227 0xe3 'π' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4116,7 +4116,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 228 0xe4 'ä' */
+       /* 228 0xe4 'Σ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0xfe, /* 11111110 */
@@ -4134,7 +4134,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 229 0xe5 'å' */
+       /* 229 0xe5 'σ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4152,7 +4152,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 230 0xe6 'æ' */
+       /* 230 0xe6 'µ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4170,7 +4170,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0xc0, /* 11000000 */
        0x00, /* 00000000 */
 
-       /* 231 0xe7 'ç' */
+       /* 231 0xe7 'τ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4188,7 +4188,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 232 0xe8 'è' */
+       /* 232 0xe8 'Φ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x7e, /* 01111110 */
@@ -4206,7 +4206,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 233 0xe9 'é' */
+       /* 233 0xe9 'Θ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x38, /* 00111000 */
@@ -4224,7 +4224,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 234 0xea 'ê' */
+       /* 234 0xea 'Ω' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x38, /* 00111000 */
@@ -4242,7 +4242,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 235 0xeb 'ë' */
+       /* 235 0xeb 'δ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x1e, /* 00011110 */
@@ -4260,7 +4260,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 236 0xec 'ì' */
+       /* 236 0xec '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4278,7 +4278,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 237 0xed 'í' */
+       /* 237 0xed 'φ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4296,7 +4296,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 238 0xee 'î' */
+       /* 238 0xee 'ε' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x1c, /* 00011100 */
@@ -4314,7 +4314,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 239 0xef 'ï' */
+       /* 239 0xef '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4332,7 +4332,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 240 0xf0 'ð' */
+       /* 240 0xf0 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4350,7 +4350,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 241 0xf1 'ñ' */
+       /* 241 0xf1 '±' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4368,7 +4368,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 242 0xf2 'ò' */
+       /* 242 0xf2 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4386,7 +4386,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 243 0xf3 'ó' */
+       /* 243 0xf3 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4404,7 +4404,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 244 0xf4 'ô' */
+       /* 244 0xf4 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x0e, /* 00001110 */
@@ -4422,7 +4422,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 245 0xf5 'õ' */
+       /* 245 0xf5 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -4440,7 +4440,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 246 0xf6 'ö' */
+       /* 246 0xf6 '÷' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4458,7 +4458,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 247 0xf7 '÷' */
+       /* 247 0xf7 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4476,7 +4476,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 248 0xf8 'ø' */
+       /* 248 0xf8 '°' */
        0x00, /* 00000000 */
        0x38, /* 00111000 */
        0x6c, /* 01101100 */
@@ -4494,7 +4494,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 249 0xf9 'ù' */
+       /* 249 0xf9 '·' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4512,7 +4512,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 250 0xfa 'ú' */
+       /* 250 0xfa '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4530,7 +4530,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 251 0xfb 'û' */
+       /* 251 0xfb '' */
        0x00, /* 00000000 */
        0x0f, /* 00001111 */
        0x0c, /* 00001100 */
@@ -4548,7 +4548,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 252 0xfc 'ü' */
+       /* 252 0xfc '' */
        0x00, /* 00000000 */
        0x6c, /* 01101100 */
        0x36, /* 00110110 */
@@ -4566,7 +4566,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 253 0xfd 'ý' */
+       /* 253 0xfd '²' */
        0x00, /* 00000000 */
        0x3c, /* 00111100 */
        0x66, /* 01100110 */
@@ -4584,7 +4584,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 254 0xfe 'þ' */
+       /* 254 0xfe '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -4602,7 +4602,7 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 255 0xff 'ÿ' */
+       /* 255 0xff ' ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
index 751becf3c521e11d01167cd214684cf338b0aa39..2328ebc8bab5d7a4cab1f7d600f48200b11c9712 100644 (file)
@@ -1291,7 +1291,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xfe, /* 11111110 */
        0x00, /* 00000000 */
 
-       /* 128 0x80 '\80' */
+       /* 128 0x80 'Ç' */
        0x7c, /* 01111100 */
        0xc6, /* 11000110 */
        0xc0, /* 11000000 */
@@ -1301,7 +1301,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x0c, /* 00001100 */
        0x78, /* 01111000 */
 
-       /* 129 0x81 '\81' */
+       /* 129 0x81 'ü' */
        0xcc, /* 11001100 */
        0x00, /* 00000000 */
        0xcc, /* 11001100 */
@@ -1311,7 +1311,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x76, /* 01110110 */
        0x00, /* 00000000 */
 
-       /* 130 0x82 '\82' */
+       /* 130 0x82 'é' */
        0x0c, /* 00001100 */
        0x18, /* 00011000 */
        0x7c, /* 01111100 */
@@ -1321,7 +1321,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x7c, /* 01111100 */
        0x00, /* 00000000 */
 
-       /* 131 0x83 '\83' */
+       /* 131 0x83 'â' */
        0x7c, /* 01111100 */
        0x82, /* 10000010 */
        0x78, /* 01111000 */
@@ -1331,7 +1331,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x76, /* 01110110 */
        0x00, /* 00000000 */
 
-       /* 132 0x84 '\84' */
+       /* 132 0x84 'ä' */
        0xc6, /* 11000110 */
        0x00, /* 00000000 */
        0x78, /* 01111000 */
@@ -1341,7 +1341,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x76, /* 01110110 */
        0x00, /* 00000000 */
 
-       /* 133 0x85 '\85' */
+       /* 133 0x85 'à' */
        0x30, /* 00110000 */
        0x18, /* 00011000 */
        0x78, /* 01111000 */
@@ -1351,7 +1351,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x76, /* 01110110 */
        0x00, /* 00000000 */
 
-       /* 134 0x86 '\86' */
+       /* 134 0x86 'å' */
        0x30, /* 00110000 */
        0x30, /* 00110000 */
        0x78, /* 01111000 */
@@ -1361,7 +1361,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x76, /* 01110110 */
        0x00, /* 00000000 */
 
-       /* 135 0x87 '\87' */
+       /* 135 0x87 'ç' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x7e, /* 01111110 */
@@ -1371,7 +1371,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x0c, /* 00001100 */
        0x38, /* 00111000 */
 
-       /* 136 0x88 '\88' */
+       /* 136 0x88 'ê' */
        0x7c, /* 01111100 */
        0x82, /* 10000010 */
        0x7c, /* 01111100 */
@@ -1381,7 +1381,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x7c, /* 01111100 */
        0x00, /* 00000000 */
 
-       /* 137 0x89 '\89' */
+       /* 137 0x89 'ë' */
        0xc6, /* 11000110 */
        0x00, /* 00000000 */
        0x7c, /* 01111100 */
@@ -1391,7 +1391,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x7c, /* 01111100 */
        0x00, /* 00000000 */
 
-       /* 138 0x8a '\8a' */
+       /* 138 0x8a 'è' */
        0x30, /* 00110000 */
        0x18, /* 00011000 */
        0x7c, /* 01111100 */
@@ -1401,7 +1401,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x7c, /* 01111100 */
        0x00, /* 00000000 */
 
-       /* 139 0x8b '\8b' */
+       /* 139 0x8b 'ï' */
        0x66, /* 01100110 */
        0x00, /* 00000000 */
        0x38, /* 00111000 */
@@ -1411,7 +1411,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x3c, /* 00111100 */
        0x00, /* 00000000 */
 
-       /* 140 0x8c '\8c' */
+       /* 140 0x8c 'î' */
        0x7c, /* 01111100 */
        0x82, /* 10000010 */
        0x38, /* 00111000 */
@@ -1421,7 +1421,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x3c, /* 00111100 */
        0x00, /* 00000000 */
 
-       /* 141 0x8d '\8d' */
+       /* 141 0x8d 'ì' */
        0x30, /* 00110000 */
        0x18, /* 00011000 */
        0x00, /* 00000000 */
@@ -1431,7 +1431,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x3c, /* 00111100 */
        0x00, /* 00000000 */
 
-       /* 142 0x8e '\8e' */
+       /* 142 0x8e 'Ä' */
        0xc6, /* 11000110 */
        0x38, /* 00111000 */
        0x6c, /* 01101100 */
@@ -1441,7 +1441,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xc6, /* 11000110 */
        0x00, /* 00000000 */
 
-       /* 143 0x8f '\8f' */
+       /* 143 0x8f 'Å' */
        0x38, /* 00111000 */
        0x6c, /* 01101100 */
        0x7c, /* 01111100 */
@@ -1451,7 +1451,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xc6, /* 11000110 */
        0x00, /* 00000000 */
 
-       /* 144 0x90 '\90' */
+       /* 144 0x90 'É' */
        0x18, /* 00011000 */
        0x30, /* 00110000 */
        0xfe, /* 11111110 */
@@ -1461,7 +1461,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xfe, /* 11111110 */
        0x00, /* 00000000 */
 
-       /* 145 0x91 '\91' */
+       /* 145 0x91 'æ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x7e, /* 01111110 */
@@ -1471,7 +1471,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x7e, /* 01111110 */
        0x00, /* 00000000 */
 
-       /* 146 0x92 '\92' */
+       /* 146 0x92 'Æ' */
        0x3e, /* 00111110 */
        0x6c, /* 01101100 */
        0xcc, /* 11001100 */
@@ -1481,7 +1481,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xce, /* 11001110 */
        0x00, /* 00000000 */
 
-       /* 147 0x93 '\93' */
+       /* 147 0x93 'ô' */
        0x7c, /* 01111100 */
        0x82, /* 10000010 */
        0x7c, /* 01111100 */
@@ -1491,7 +1491,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x7c, /* 01111100 */
        0x00, /* 00000000 */
 
-       /* 148 0x94 '\94' */
+       /* 148 0x94 'ö' */
        0xc6, /* 11000110 */
        0x00, /* 00000000 */
        0x7c, /* 01111100 */
@@ -1501,7 +1501,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x7c, /* 01111100 */
        0x00, /* 00000000 */
 
-       /* 149 0x95 '\95' */
+       /* 149 0x95 'ò' */
        0x30, /* 00110000 */
        0x18, /* 00011000 */
        0x7c, /* 01111100 */
@@ -1511,7 +1511,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x7c, /* 01111100 */
        0x00, /* 00000000 */
 
-       /* 150 0x96 '\96' */
+       /* 150 0x96 'û' */
        0x78, /* 01111000 */
        0x84, /* 10000100 */
        0x00, /* 00000000 */
@@ -1521,7 +1521,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x76, /* 01110110 */
        0x00, /* 00000000 */
 
-       /* 151 0x97 '\97' */
+       /* 151 0x97 'ù' */
        0x60, /* 01100000 */
        0x30, /* 00110000 */
        0xcc, /* 11001100 */
@@ -1531,7 +1531,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x76, /* 01110110 */
        0x00, /* 00000000 */
 
-       /* 152 0x98 '\98' */
+       /* 152 0x98 'ÿ' */
        0xc6, /* 11000110 */
        0x00, /* 00000000 */
        0xc6, /* 11000110 */
@@ -1541,7 +1541,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x06, /* 00000110 */
        0xfc, /* 11111100 */
 
-       /* 153 0x99 '\99' */
+       /* 153 0x99 'Ö' */
        0xc6, /* 11000110 */
        0x38, /* 00111000 */
        0x6c, /* 01101100 */
@@ -1551,7 +1551,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x38, /* 00111000 */
        0x00, /* 00000000 */
 
-       /* 154 0x9a '\9a' */
+       /* 154 0x9a 'Ü' */
        0xc6, /* 11000110 */
        0x00, /* 00000000 */
        0xc6, /* 11000110 */
@@ -1561,7 +1561,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x7c, /* 01111100 */
        0x00, /* 00000000 */
 
-       /* 155 0x9b '\9b' */
+       /* 155 0x9b '¢' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x7e, /* 01111110 */
@@ -1571,7 +1571,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 156 0x9c '\9c' */
+       /* 156 0x9c '£' */
        0x38, /* 00111000 */
        0x6c, /* 01101100 */
        0x64, /* 01100100 */
@@ -1581,7 +1581,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xfc, /* 11111100 */
        0x00, /* 00000000 */
 
-       /* 157 0x9d '\9d' */
+       /* 157 0x9d '¥' */
        0x66, /* 01100110 */
        0x66, /* 01100110 */
        0x3c, /* 00111100 */
@@ -1591,7 +1591,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 158 0x9e '\9e' */
+       /* 158 0x9e '' */
        0xf8, /* 11111000 */
        0xcc, /* 11001100 */
        0xcc, /* 11001100 */
@@ -1601,7 +1601,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xc6, /* 11000110 */
        0xc7, /* 11000111 */
 
-       /* 159 0x9f '\9f' */
+       /* 159 0x9f 'ƒ' */
        0x0e, /* 00001110 */
        0x1b, /* 00011011 */
        0x18, /* 00011000 */
@@ -1611,7 +1611,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x70, /* 01110000 */
        0x00, /* 00000000 */
 
-       /* 160 0xa0 ' ' */
+       /* 160 0xa0 'á' */
        0x18, /* 00011000 */
        0x30, /* 00110000 */
        0x78, /* 01111000 */
@@ -1621,7 +1621,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x76, /* 01110110 */
        0x00, /* 00000000 */
 
-       /* 161 0xa1 '¡' */
+       /* 161 0xa1 'í' */
        0x0c, /* 00001100 */
        0x18, /* 00011000 */
        0x00, /* 00000000 */
@@ -1631,7 +1631,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x3c, /* 00111100 */
        0x00, /* 00000000 */
 
-       /* 162 0xa2 '¢' */
+       /* 162 0xa2 'ó' */
        0x0c, /* 00001100 */
        0x18, /* 00011000 */
        0x7c, /* 01111100 */
@@ -1641,7 +1641,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x7c, /* 01111100 */
        0x00, /* 00000000 */
 
-       /* 163 0xa3 '£' */
+       /* 163 0xa3 'ú' */
        0x18, /* 00011000 */
        0x30, /* 00110000 */
        0xcc, /* 11001100 */
@@ -1651,7 +1651,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x76, /* 01110110 */
        0x00, /* 00000000 */
 
-       /* 164 0xa4 '¤' */
+       /* 164 0xa4 'ñ' */
        0x76, /* 01110110 */
        0xdc, /* 11011100 */
        0x00, /* 00000000 */
@@ -1661,7 +1661,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x66, /* 01100110 */
        0x00, /* 00000000 */
 
-       /* 165 0xa5 '¥' */
+       /* 165 0xa5 'Ñ' */
        0x76, /* 01110110 */
        0xdc, /* 11011100 */
        0x00, /* 00000000 */
@@ -1671,7 +1671,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xce, /* 11001110 */
        0x00, /* 00000000 */
 
-       /* 166 0xa6 '¦' */
+       /* 166 0xa6 'ª' */
        0x3c, /* 00111100 */
        0x6c, /* 01101100 */
        0x6c, /* 01101100 */
@@ -1681,7 +1681,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 167 0xa7 '§' */
+       /* 167 0xa7 'º' */
        0x38, /* 00111000 */
        0x6c, /* 01101100 */
        0x6c, /* 01101100 */
@@ -1691,7 +1691,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 168 0xa8 '¨' */
+       /* 168 0xa8 '¿' */
        0x18, /* 00011000 */
        0x00, /* 00000000 */
        0x18, /* 00011000 */
@@ -1701,7 +1701,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x3e, /* 00111110 */
        0x00, /* 00000000 */
 
-       /* 169 0xa9 '©' */
+       /* 169 0xa9 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -1711,7 +1711,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 170 0xaa 'ª' */
+       /* 170 0xaa '¬' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -1721,7 +1721,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 171 0xab '«' */
+       /* 171 0xab '½' */
        0x63, /* 01100011 */
        0xe6, /* 11100110 */
        0x6c, /* 01101100 */
@@ -1731,7 +1731,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xcc, /* 11001100 */
        0x0f, /* 00001111 */
 
-       /* 172 0xac '¬' */
+       /* 172 0xac '¼' */
        0x63, /* 01100011 */
        0xe6, /* 11100110 */
        0x6c, /* 01101100 */
@@ -1741,7 +1741,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xdf, /* 11011111 */
        0x06, /* 00000110 */
 
-       /* 173 0xad '­' */
+       /* 173 0xad '¡' */
        0x18, /* 00011000 */
        0x00, /* 00000000 */
        0x18, /* 00011000 */
@@ -1751,7 +1751,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x00, /* 00000000 */
 
-       /* 174 0xae '®' */
+       /* 174 0xae '«' */
        0x00, /* 00000000 */
        0x33, /* 00110011 */
        0x66, /* 01100110 */
@@ -1761,7 +1761,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 175 0xaf '¯' */
+       /* 175 0xaf '»' */
        0x00, /* 00000000 */
        0xcc, /* 11001100 */
        0x66, /* 01100110 */
@@ -1771,7 +1771,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 176 0xb0 '°' */
+       /* 176 0xb0 '' */
        0x22, /* 00100010 */
        0x88, /* 10001000 */
        0x22, /* 00100010 */
@@ -1781,7 +1781,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x22, /* 00100010 */
        0x88, /* 10001000 */
 
-       /* 177 0xb1 '±' */
+       /* 177 0xb1 '' */
        0x55, /* 01010101 */
        0xaa, /* 10101010 */
        0x55, /* 01010101 */
@@ -1791,7 +1791,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x55, /* 01010101 */
        0xaa, /* 10101010 */
 
-       /* 178 0xb2 '²' */
+       /* 178 0xb2 '' */
        0x77, /* 01110111 */
        0xdd, /* 11011101 */
        0x77, /* 01110111 */
@@ -1801,7 +1801,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x77, /* 01110111 */
        0xdd, /* 11011101 */
 
-       /* 179 0xb3 '³' */
+       /* 179 0xb3 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -1811,7 +1811,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 180 0xb4 '´' */
+       /* 180 0xb4 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -1821,7 +1821,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 181 0xb5 'µ' */
+       /* 181 0xb5 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0xf8, /* 11111000 */
@@ -1831,7 +1831,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 182 0xb6 '' */
+       /* 182 0xb6 '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -1841,7 +1841,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 183 0xb7 '·' */
+       /* 183 0xb7 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -1851,7 +1851,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 184 0xb8 '¸' */
+       /* 184 0xb8 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0xf8, /* 11111000 */
@@ -1861,7 +1861,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 185 0xb9 '¹' */
+       /* 185 0xb9 '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0xf6, /* 11110110 */
@@ -1871,7 +1871,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 186 0xba 'º' */
+       /* 186 0xba '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -1881,7 +1881,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 187 0xbb '»' */
+       /* 187 0xbb '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0xfe, /* 11111110 */
@@ -1891,7 +1891,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 188 0xbc '¼' */
+       /* 188 0xbc '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0xf6, /* 11110110 */
@@ -1901,7 +1901,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 189 0xbd '½' */
+       /* 189 0xbd '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -1911,7 +1911,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 190 0xbe '¾' */
+       /* 190 0xbe '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0xf8, /* 11111000 */
@@ -1921,7 +1921,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 191 0xbf '¿' */
+       /* 191 0xbf '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -1931,7 +1931,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 192 0xc0 'À' */
+       /* 192 0xc0 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -1941,7 +1941,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 193 0xc1 'Á' */
+       /* 193 0xc1 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -1951,7 +1951,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 194 0xc2 'Â' */
+       /* 194 0xc2 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -1961,7 +1961,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 195 0xc3 'Ã' */
+       /* 195 0xc3 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -1971,7 +1971,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 196 0xc4 'Ä' */
+       /* 196 0xc4 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -1981,7 +1981,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 197 0xc5 'Å' */
+       /* 197 0xc5 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -1991,7 +1991,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 198 0xc6 'Æ' */
+       /* 198 0xc6 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x1f, /* 00011111 */
@@ -2001,7 +2001,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 199 0xc7 'Ç' */
+       /* 199 0xc7 '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -2011,7 +2011,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 200 0xc8 'È' */
+       /* 200 0xc8 '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x37, /* 00110111 */
@@ -2021,7 +2021,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 201 0xc9 'É' */
+       /* 201 0xc9 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x3f, /* 00111111 */
@@ -2031,7 +2031,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 202 0xca 'Ê' */
+       /* 202 0xca '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0xf7, /* 11110111 */
@@ -2041,7 +2041,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 203 0xcb 'Ë' */
+       /* 203 0xcb '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0xff, /* 11111111 */
@@ -2051,7 +2051,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 204 0xcc 'Ì' */
+       /* 204 0xcc '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x37, /* 00110111 */
@@ -2061,7 +2061,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 205 0xcd 'Í' */
+       /* 205 0xcd '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0xff, /* 11111111 */
@@ -2071,7 +2071,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 206 0xce 'Î' */
+       /* 206 0xce '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0xf7, /* 11110111 */
@@ -2081,7 +2081,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 207 0xcf 'Ï' */
+       /* 207 0xcf '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0xff, /* 11111111 */
@@ -2091,7 +2091,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 208 0xd0 'Ð' */
+       /* 208 0xd0 '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -2101,7 +2101,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 209 0xd1 'Ñ' */
+       /* 209 0xd1 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0xff, /* 11111111 */
@@ -2111,7 +2111,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 210 0xd2 'Ò' */
+       /* 210 0xd2 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -2121,7 +2121,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 211 0xd3 'Ó' */
+       /* 211 0xd3 '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -2131,7 +2131,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 212 0xd4 'Ô' */
+       /* 212 0xd4 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x1f, /* 00011111 */
@@ -2141,7 +2141,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 213 0xd5 'Õ' */
+       /* 213 0xd5 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x1f, /* 00011111 */
@@ -2151,7 +2151,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 214 0xd6 'Ö' */
+       /* 214 0xd6 '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -2161,7 +2161,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 215 0xd7 '×' */
+       /* 215 0xd7 '' */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -2171,7 +2171,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x36, /* 00110110 */
        0x36, /* 00110110 */
 
-       /* 216 0xd8 'Ø' */
+       /* 216 0xd8 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0xff, /* 11111111 */
@@ -2181,7 +2181,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 217 0xd9 'Ù' */
+       /* 217 0xd9 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -2191,7 +2191,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 218 0xda 'Ú' */
+       /* 218 0xda '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -2201,7 +2201,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 219 0xdb 'Û' */
+       /* 219 0xdb '' */
        0xff, /* 11111111 */
        0xff, /* 11111111 */
        0xff, /* 11111111 */
@@ -2211,7 +2211,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xff, /* 11111111 */
        0xff, /* 11111111 */
 
-       /* 220 0xdc 'Ü' */
+       /* 220 0xdc '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -2221,7 +2221,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xff, /* 11111111 */
        0xff, /* 11111111 */
 
-       /* 221 0xdd 'Ý' */
+       /* 221 0xdd '' */
        0xf0, /* 11110000 */
        0xf0, /* 11110000 */
        0xf0, /* 11110000 */
@@ -2231,7 +2231,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xf0, /* 11110000 */
        0xf0, /* 11110000 */
 
-       /* 222 0xde 'Þ' */
+       /* 222 0xde '' */
        0x0f, /* 00001111 */
        0x0f, /* 00001111 */
        0x0f, /* 00001111 */
@@ -2241,7 +2241,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x0f, /* 00001111 */
        0x0f, /* 00001111 */
 
-       /* 223 0xdf 'ß' */
+       /* 223 0xdf '' */
        0xff, /* 11111111 */
        0xff, /* 11111111 */
        0xff, /* 11111111 */
@@ -2251,7 +2251,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 224 0xe0 'à' */
+       /* 224 0xe0 'α' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x76, /* 01110110 */
@@ -2261,7 +2261,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x76, /* 01110110 */
        0x00, /* 00000000 */
 
-       /* 225 0xe1 'á' */
+       /* 225 0xe1 'ß' */
        0x78, /* 01111000 */
        0xcc, /* 11001100 */
        0xcc, /* 11001100 */
@@ -2271,7 +2271,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xcc, /* 11001100 */
        0x00, /* 00000000 */
 
-       /* 226 0xe2 'â' */
+       /* 226 0xe2 'Γ' */
        0xfe, /* 11111110 */
        0xc6, /* 11000110 */
        0xc0, /* 11000000 */
@@ -2281,7 +2281,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xc0, /* 11000000 */
        0x00, /* 00000000 */
 
-       /* 227 0xe3 'ã' */
+       /* 227 0xe3 'π' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0xfe, /* 11111110 */
@@ -2291,7 +2291,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x6c, /* 01101100 */
        0x00, /* 00000000 */
 
-       /* 228 0xe4 'ä' */
+       /* 228 0xe4 'Σ' */
        0xfe, /* 11111110 */
        0xc6, /* 11000110 */
        0x60, /* 01100000 */
@@ -2301,7 +2301,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xfe, /* 11111110 */
        0x00, /* 00000000 */
 
-       /* 229 0xe5 'å' */
+       /* 229 0xe5 'σ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x7e, /* 01111110 */
@@ -2311,7 +2311,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x70, /* 01110000 */
        0x00, /* 00000000 */
 
-       /* 230 0xe6 'æ' */
+       /* 230 0xe6 'µ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x66, /* 01100110 */
@@ -2321,7 +2321,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x7c, /* 01111100 */
        0xc0, /* 11000000 */
 
-       /* 231 0xe7 'ç' */
+       /* 231 0xe7 'τ' */
        0x00, /* 00000000 */
        0x76, /* 01110110 */
        0xdc, /* 11011100 */
@@ -2331,7 +2331,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x00, /* 00000000 */
 
-       /* 232 0xe8 'è' */
+       /* 232 0xe8 'Φ' */
        0x7e, /* 01111110 */
        0x18, /* 00011000 */
        0x3c, /* 00111100 */
@@ -2341,7 +2341,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x7e, /* 01111110 */
 
-       /* 233 0xe9 'é' */
+       /* 233 0xe9 'Θ' */
        0x38, /* 00111000 */
        0x6c, /* 01101100 */
        0xc6, /* 11000110 */
@@ -2351,7 +2351,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x38, /* 00111000 */
        0x00, /* 00000000 */
 
-       /* 234 0xea 'ê' */
+       /* 234 0xea 'Ω' */
        0x38, /* 00111000 */
        0x6c, /* 01101100 */
        0xc6, /* 11000110 */
@@ -2361,7 +2361,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xee, /* 11101110 */
        0x00, /* 00000000 */
 
-       /* 235 0xeb 'ë' */
+       /* 235 0xeb 'δ' */
        0x0e, /* 00001110 */
        0x18, /* 00011000 */
        0x0c, /* 00001100 */
@@ -2371,7 +2371,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x3c, /* 00111100 */
        0x00, /* 00000000 */
 
-       /* 236 0xec 'ì' */
+       /* 236 0xec '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x7e, /* 01111110 */
@@ -2381,7 +2381,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 237 0xed 'í' */
+       /* 237 0xed 'φ' */
        0x06, /* 00000110 */
        0x0c, /* 00001100 */
        0x7e, /* 01111110 */
@@ -2391,7 +2391,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x60, /* 01100000 */
        0xc0, /* 11000000 */
 
-       /* 238 0xee 'î' */
+       /* 238 0xee 'ε' */
        0x1e, /* 00011110 */
        0x30, /* 00110000 */
        0x60, /* 01100000 */
@@ -2401,7 +2401,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x1e, /* 00011110 */
        0x00, /* 00000000 */
 
-       /* 239 0xef 'ï' */
+       /* 239 0xef '' */
        0x00, /* 00000000 */
        0x7c, /* 01111100 */
        0xc6, /* 11000110 */
@@ -2411,7 +2411,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xc6, /* 11000110 */
        0x00, /* 00000000 */
 
-       /* 240 0xf0 'ð' */
+       /* 240 0xf0 '' */
        0x00, /* 00000000 */
        0xfe, /* 11111110 */
        0x00, /* 00000000 */
@@ -2421,7 +2421,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 241 0xf1 'ñ' */
+       /* 241 0xf1 '±' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x7e, /* 01111110 */
@@ -2431,7 +2431,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x7e, /* 01111110 */
        0x00, /* 00000000 */
 
-       /* 242 0xf2 'ò' */
+       /* 242 0xf2 '' */
        0x30, /* 00110000 */
        0x18, /* 00011000 */
        0x0c, /* 00001100 */
@@ -2441,7 +2441,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x7e, /* 01111110 */
        0x00, /* 00000000 */
 
-       /* 243 0xf3 'ó' */
+       /* 243 0xf3 '' */
        0x0c, /* 00001100 */
        0x18, /* 00011000 */
        0x30, /* 00110000 */
@@ -2451,7 +2451,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x7e, /* 01111110 */
        0x00, /* 00000000 */
 
-       /* 244 0xf4 'ô' */
+       /* 244 0xf4 '' */
        0x0e, /* 00001110 */
        0x1b, /* 00011011 */
        0x1b, /* 00011011 */
@@ -2461,7 +2461,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x18, /* 00011000 */
        0x18, /* 00011000 */
 
-       /* 245 0xf5 'õ' */
+       /* 245 0xf5 '' */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
        0x18, /* 00011000 */
@@ -2471,7 +2471,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0xd8, /* 11011000 */
        0x70, /* 01110000 */
 
-       /* 246 0xf6 'ö' */
+       /* 246 0xf6 '÷' */
        0x00, /* 00000000 */
        0x18, /* 00011000 */
        0x00, /* 00000000 */
@@ -2481,7 +2481,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 247 0xf7 '÷' */
+       /* 247 0xf7 '' */
        0x00, /* 00000000 */
        0x76, /* 01110110 */
        0xdc, /* 11011100 */
@@ -2491,7 +2491,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 248 0xf8 'ø' */
+       /* 248 0xf8 '°' */
        0x38, /* 00111000 */
        0x6c, /* 01101100 */
        0x6c, /* 01101100 */
@@ -2501,7 +2501,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 249 0xf9 'ù' */
+       /* 249 0xf9 '·' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -2511,7 +2511,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 250 0xfa 'ú' */
+       /* 250 0xfa '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
@@ -2521,7 +2521,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 251 0xfb 'û' */
+       /* 251 0xfb '' */
        0x0f, /* 00001111 */
        0x0c, /* 00001100 */
        0x0c, /* 00001100 */
@@ -2531,7 +2531,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x3c, /* 00111100 */
        0x1c, /* 00011100 */
 
-       /* 252 0xfc 'ü' */
+       /* 252 0xfc '' */
        0x6c, /* 01101100 */
        0x36, /* 00110110 */
        0x36, /* 00110110 */
@@ -2541,7 +2541,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 253 0xfd 'ý' */
+       /* 253 0xfd '²' */
        0x78, /* 01111000 */
        0x0c, /* 00001100 */
        0x18, /* 00011000 */
@@ -2551,7 +2551,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 254 0xfe 'þ' */
+       /* 254 0xfe '' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x3c, /* 00111100 */
@@ -2561,7 +2561,7 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
        0x00, /* 00000000 */
        0x00, /* 00000000 */
 
-       /* 255 0xff 'ÿ' */
+       /* 255 0xff ' ' */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
        0x00, /* 00000000 */
index b0514c0a74451f77916942e4f971ad76b8be8de9..b15d3c342c5bbc9682b12ccb081b6b9c66b83cdf 100644 (file)
@@ -1296,7 +1296,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xfe, /* 11111110 */
    0x00, /* 00000000 */
 
-   /* 128 0x80 '\80' */
+   /* 128 0x80 'Ç' */
    0x7c, /* 01111100 */
    0xc6, /* 11000110 */
    0xc0, /* 11000000 */
@@ -1306,7 +1306,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x0c, /* 00001100 */
    0x78, /* 01111000 */
 
-   /* 129 0x81 '\81' */
+   /* 129 0x81 'ü' */
    0xcc, /* 11001100 */
    0x00, /* 00000000 */
    0xcc, /* 11001100 */
@@ -1316,7 +1316,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x76, /* 01110110 */
    0x00, /* 00000000 */
 
-   /* 130 0x82 '\82' */
+   /* 130 0x82 'é' */
    0x0c, /* 00001100 */
    0x18, /* 00011000 */
    0x7c, /* 01111100 */
@@ -1326,7 +1326,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x7c, /* 01111100 */
    0x00, /* 00000000 */
 
-   /* 131 0x83 '\83' */
+   /* 131 0x83 'â' */
    0x7c, /* 01111100 */
    0x82, /* 10000010 */
    0x78, /* 01111000 */
@@ -1336,7 +1336,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x76, /* 01110110 */
    0x00, /* 00000000 */
 
-   /* 132 0x84 '\84' */
+   /* 132 0x84 'ä' */
    0xc6, /* 11000110 */
    0x00, /* 00000000 */
    0x78, /* 01111000 */
@@ -1346,7 +1346,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x76, /* 01110110 */
    0x00, /* 00000000 */
 
-   /* 133 0x85 '\85' */
+   /* 133 0x85 'à' */
    0x30, /* 00110000 */
    0x18, /* 00011000 */
    0x78, /* 01111000 */
@@ -1356,7 +1356,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x76, /* 01110110 */
    0x00, /* 00000000 */
 
-   /* 134 0x86 '\86' */
+   /* 134 0x86 'å' */
    0x30, /* 00110000 */
    0x30, /* 00110000 */
    0x78, /* 01111000 */
@@ -1366,7 +1366,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x76, /* 01110110 */
    0x00, /* 00000000 */
 
-   /* 135 0x87 '\87' */
+   /* 135 0x87 'ç' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x7e, /* 01111110 */
@@ -1376,7 +1376,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x0c, /* 00001100 */
    0x38, /* 00111000 */
 
-   /* 136 0x88 '\88' */
+   /* 136 0x88 'ê' */
    0x7c, /* 01111100 */
    0x82, /* 10000010 */
    0x7c, /* 01111100 */
@@ -1386,7 +1386,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x7c, /* 01111100 */
    0x00, /* 00000000 */
 
-   /* 137 0x89 '\89' */
+   /* 137 0x89 'ë' */
    0xc6, /* 11000110 */
    0x00, /* 00000000 */
    0x7c, /* 01111100 */
@@ -1396,7 +1396,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x7c, /* 01111100 */
    0x00, /* 00000000 */
 
-   /* 138 0x8a '\8a' */
+   /* 138 0x8a 'è' */
    0x30, /* 00110000 */
    0x18, /* 00011000 */
    0x7c, /* 01111100 */
@@ -1406,7 +1406,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x7c, /* 01111100 */
    0x00, /* 00000000 */
 
-   /* 139 0x8b '\8b' */
+   /* 139 0x8b 'ï' */
    0x66, /* 01100110 */
    0x00, /* 00000000 */
    0x38, /* 00111000 */
@@ -1416,7 +1416,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x3c, /* 00111100 */
    0x00, /* 00000000 */
 
-   /* 140 0x8c '\8c' */
+   /* 140 0x8c 'î' */
    0x7c, /* 01111100 */
    0x82, /* 10000010 */
    0x38, /* 00111000 */
@@ -1426,7 +1426,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x3c, /* 00111100 */
    0x00, /* 00000000 */
 
-   /* 141 0x8d '\8d' */
+   /* 141 0x8d 'ì' */
    0x30, /* 00110000 */
    0x18, /* 00011000 */
    0x00, /* 00000000 */
@@ -1436,7 +1436,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x3c, /* 00111100 */
    0x00, /* 00000000 */
 
-   /* 142 0x8e '\8e' */
+   /* 142 0x8e 'Ä' */
    0xc6, /* 11000110 */
    0x38, /* 00111000 */
    0x6c, /* 01101100 */
@@ -1446,7 +1446,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xc6, /* 11000110 */
    0x00, /* 00000000 */
 
-   /* 143 0x8f '\8f' */
+   /* 143 0x8f 'Å' */
    0x38, /* 00111000 */
    0x6c, /* 01101100 */
    0x7c, /* 01111100 */
@@ -1456,7 +1456,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xc6, /* 11000110 */
    0x00, /* 00000000 */
 
-   /* 144 0x90 '\90' */
+   /* 144 0x90 'É' */
    0x18, /* 00011000 */
    0x30, /* 00110000 */
    0xfe, /* 11111110 */
@@ -1466,7 +1466,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xfe, /* 11111110 */
    0x00, /* 00000000 */
 
-   /* 145 0x91 '\91' */
+   /* 145 0x91 'æ' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x7e, /* 01111110 */
@@ -1476,7 +1476,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x7e, /* 01111110 */
    0x00, /* 00000000 */
 
-   /* 146 0x92 '\92' */
+   /* 146 0x92 'Æ' */
    0x3e, /* 00111110 */
    0x6c, /* 01101100 */
    0xcc, /* 11001100 */
@@ -1486,7 +1486,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xce, /* 11001110 */
    0x00, /* 00000000 */
 
-   /* 147 0x93 '\93' */
+   /* 147 0x93 'ô' */
    0x7c, /* 01111100 */
    0x82, /* 10000010 */
    0x7c, /* 01111100 */
@@ -1496,7 +1496,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x7c, /* 01111100 */
    0x00, /* 00000000 */
 
-   /* 148 0x94 '\94' */
+   /* 148 0x94 'ö' */
    0xc6, /* 11000110 */
    0x00, /* 00000000 */
    0x7c, /* 01111100 */
@@ -1506,7 +1506,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x7c, /* 01111100 */
    0x00, /* 00000000 */
 
-   /* 149 0x95 '\95' */
+   /* 149 0x95 'ò' */
    0x30, /* 00110000 */
    0x18, /* 00011000 */
    0x7c, /* 01111100 */
@@ -1516,7 +1516,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x7c, /* 01111100 */
    0x00, /* 00000000 */
 
-   /* 150 0x96 '\96' */
+   /* 150 0x96 'û' */
    0x78, /* 01111000 */
    0x84, /* 10000100 */
    0x00, /* 00000000 */
@@ -1526,7 +1526,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x76, /* 01110110 */
    0x00, /* 00000000 */
 
-   /* 151 0x97 '\97' */
+   /* 151 0x97 'ù' */
    0x60, /* 01100000 */
    0x30, /* 00110000 */
    0xcc, /* 11001100 */
@@ -1536,7 +1536,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x76, /* 01110110 */
    0x00, /* 00000000 */
 
-   /* 152 0x98 '\98' */
+   /* 152 0x98 'ÿ' */
    0xc6, /* 11000110 */
    0x00, /* 00000000 */
    0xc6, /* 11000110 */
@@ -1546,7 +1546,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x06, /* 00000110 */
    0xfc, /* 11111100 */
 
-   /* 153 0x99 '\99' */
+   /* 153 0x99 'Ö' */
    0xc6, /* 11000110 */
    0x38, /* 00111000 */
    0x6c, /* 01101100 */
@@ -1556,7 +1556,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x38, /* 00111000 */
    0x00, /* 00000000 */
 
-   /* 154 0x9a '\9a' */
+   /* 154 0x9a 'Ü' */
    0xc6, /* 11000110 */
    0x00, /* 00000000 */
    0xc6, /* 11000110 */
@@ -1566,7 +1566,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x7c, /* 01111100 */
    0x00, /* 00000000 */
 
-   /* 155 0x9b '\9b' */
+   /* 155 0x9b '¢' */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
    0x7e, /* 01111110 */
@@ -1576,7 +1576,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x18, /* 00011000 */
 
-   /* 156 0x9c '\9c' */
+   /* 156 0x9c '£' */
    0x38, /* 00111000 */
    0x6c, /* 01101100 */
    0x64, /* 01100100 */
@@ -1586,7 +1586,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xfc, /* 11111100 */
    0x00, /* 00000000 */
 
-   /* 157 0x9d '\9d' */
+   /* 157 0x9d '¥' */
    0x66, /* 01100110 */
    0x66, /* 01100110 */
    0x3c, /* 00111100 */
@@ -1596,7 +1596,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x18, /* 00011000 */
 
-   /* 158 0x9e '\9e' */
+   /* 158 0x9e '' */
    0xf8, /* 11111000 */
    0xcc, /* 11001100 */
    0xcc, /* 11001100 */
@@ -1606,7 +1606,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xc6, /* 11000110 */
    0xc7, /* 11000111 */
 
-   /* 159 0x9f '\9f' */
+   /* 159 0x9f 'ƒ' */
    0x0e, /* 00001110 */
    0x1b, /* 00011011 */
    0x18, /* 00011000 */
@@ -1616,7 +1616,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x70, /* 01110000 */
    0x00, /* 00000000 */
 
-   /* 160 0xa0 ' ' */
+   /* 160 0xa0 'á' */
    0x18, /* 00011000 */
    0x30, /* 00110000 */
    0x78, /* 01111000 */
@@ -1626,7 +1626,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x76, /* 01110110 */
    0x00, /* 00000000 */
 
-   /* 161 0xa1 '¡' */
+   /* 161 0xa1 'í' */
    0x0c, /* 00001100 */
    0x18, /* 00011000 */
    0x00, /* 00000000 */
@@ -1636,7 +1636,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x3c, /* 00111100 */
    0x00, /* 00000000 */
 
-   /* 162 0xa2 '¢' */
+   /* 162 0xa2 'ó' */
    0x0c, /* 00001100 */
    0x18, /* 00011000 */
    0x7c, /* 01111100 */
@@ -1646,7 +1646,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x7c, /* 01111100 */
    0x00, /* 00000000 */
 
-   /* 163 0xa3 '£' */
+   /* 163 0xa3 'ú' */
    0x18, /* 00011000 */
    0x30, /* 00110000 */
    0xcc, /* 11001100 */
@@ -1656,7 +1656,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x76, /* 01110110 */
    0x00, /* 00000000 */
 
-   /* 164 0xa4 '¤' */
+   /* 164 0xa4 'ñ' */
    0x76, /* 01110110 */
    0xdc, /* 11011100 */
    0x00, /* 00000000 */
@@ -1666,7 +1666,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x66, /* 01100110 */
    0x00, /* 00000000 */
 
-   /* 165 0xa5 '¥' */
+   /* 165 0xa5 'Ñ' */
    0x76, /* 01110110 */
    0xdc, /* 11011100 */
    0x00, /* 00000000 */
@@ -1676,7 +1676,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xce, /* 11001110 */
    0x00, /* 00000000 */
 
-   /* 166 0xa6 '¦' */
+   /* 166 0xa6 'ª' */
    0x3c, /* 00111100 */
    0x6c, /* 01101100 */
    0x6c, /* 01101100 */
@@ -1686,7 +1686,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 167 0xa7 '§' */
+   /* 167 0xa7 'º' */
    0x38, /* 00111000 */
    0x6c, /* 01101100 */
    0x6c, /* 01101100 */
@@ -1696,7 +1696,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 168 0xa8 '¨' */
+   /* 168 0xa8 '¿' */
    0x18, /* 00011000 */
    0x00, /* 00000000 */
    0x18, /* 00011000 */
@@ -1706,7 +1706,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x3e, /* 00111110 */
    0x00, /* 00000000 */
 
-   /* 169 0xa9 '©' */
+   /* 169 0xa9 '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
@@ -1716,7 +1716,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 170 0xaa 'ª' */
+   /* 170 0xaa '¬' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
@@ -1726,7 +1726,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 171 0xab '«' */
+   /* 171 0xab '½' */
    0x63, /* 01100011 */
    0xe6, /* 11100110 */
    0x6c, /* 01101100 */
@@ -1736,7 +1736,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xcc, /* 11001100 */
    0x0f, /* 00001111 */
 
-   /* 172 0xac '¬' */
+   /* 172 0xac '¼' */
    0x63, /* 01100011 */
    0xe6, /* 11100110 */
    0x6c, /* 01101100 */
@@ -1746,7 +1746,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xdf, /* 11011111 */
    0x06, /* 00000110 */
 
-   /* 173 0xad '­' */
+   /* 173 0xad '¡' */
    0x18, /* 00011000 */
    0x00, /* 00000000 */
    0x18, /* 00011000 */
@@ -1756,7 +1756,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x00, /* 00000000 */
 
-   /* 174 0xae '®' */
+   /* 174 0xae '«' */
    0x00, /* 00000000 */
    0x33, /* 00110011 */
    0x66, /* 01100110 */
@@ -1766,7 +1766,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 175 0xaf '¯' */
+   /* 175 0xaf '»' */
    0x00, /* 00000000 */
    0xcc, /* 11001100 */
    0x66, /* 01100110 */
@@ -1776,7 +1776,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 176 0xb0 '°' */
+   /* 176 0xb0 '' */
    0x22, /* 00100010 */
    0x88, /* 10001000 */
    0x22, /* 00100010 */
@@ -1786,7 +1786,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x22, /* 00100010 */
    0x88, /* 10001000 */
 
-   /* 177 0xb1 '±' */
+   /* 177 0xb1 '' */
    0x55, /* 01010101 */
    0xaa, /* 10101010 */
    0x55, /* 01010101 */
@@ -1796,7 +1796,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x55, /* 01010101 */
    0xaa, /* 10101010 */
 
-   /* 178 0xb2 '²' */
+   /* 178 0xb2 '' */
    0x77, /* 01110111 */
    0xdd, /* 11011101 */
    0x77, /* 01110111 */
@@ -1806,7 +1806,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x77, /* 01110111 */
    0xdd, /* 11011101 */
 
-   /* 179 0xb3 '³' */
+   /* 179 0xb3 '' */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
@@ -1816,7 +1816,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x18, /* 00011000 */
 
-   /* 180 0xb4 '´' */
+   /* 180 0xb4 '' */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
@@ -1826,7 +1826,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x18, /* 00011000 */
 
-   /* 181 0xb5 'µ' */
+   /* 181 0xb5 '' */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
    0xf8, /* 11111000 */
@@ -1836,7 +1836,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x18, /* 00011000 */
 
-   /* 182 0xb6 '' */
+   /* 182 0xb6 '' */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
@@ -1846,7 +1846,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x36, /* 00110110 */
    0x36, /* 00110110 */
 
-   /* 183 0xb7 '·' */
+   /* 183 0xb7 '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
@@ -1856,7 +1856,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x36, /* 00110110 */
    0x36, /* 00110110 */
 
-   /* 184 0xb8 '¸' */
+   /* 184 0xb8 '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0xf8, /* 11111000 */
@@ -1866,7 +1866,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x18, /* 00011000 */
 
-   /* 185 0xb9 '¹' */
+   /* 185 0xb9 '' */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
    0xf6, /* 11110110 */
@@ -1876,7 +1876,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x36, /* 00110110 */
    0x36, /* 00110110 */
 
-   /* 186 0xba 'º' */
+   /* 186 0xba '' */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
@@ -1886,7 +1886,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x36, /* 00110110 */
    0x36, /* 00110110 */
 
-   /* 187 0xbb '»' */
+   /* 187 0xbb '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0xfe, /* 11111110 */
@@ -1896,7 +1896,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x36, /* 00110110 */
    0x36, /* 00110110 */
 
-   /* 188 0xbc '¼' */
+   /* 188 0xbc '' */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
    0xf6, /* 11110110 */
@@ -1906,7 +1906,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 189 0xbd '½' */
+   /* 189 0xbd '' */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
@@ -1916,7 +1916,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 190 0xbe '¾' */
+   /* 190 0xbe '' */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
    0xf8, /* 11111000 */
@@ -1926,7 +1926,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 191 0xbf '¿' */
+   /* 191 0xbf '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
@@ -1936,7 +1936,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x18, /* 00011000 */
 
-   /* 192 0xc0 'À' */
+   /* 192 0xc0 '' */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
@@ -1946,7 +1946,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 193 0xc1 'Á' */
+   /* 193 0xc1 '' */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
@@ -1956,7 +1956,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 194 0xc2 'Â' */
+   /* 194 0xc2 '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
@@ -1966,7 +1966,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x18, /* 00011000 */
 
-   /* 195 0xc3 'Ã' */
+   /* 195 0xc3 '' */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
@@ -1976,7 +1976,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x18, /* 00011000 */
 
-   /* 196 0xc4 'Ä' */
+   /* 196 0xc4 '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
@@ -1986,7 +1986,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 197 0xc5 'Å' */
+   /* 197 0xc5 '' */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
@@ -1996,7 +1996,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x18, /* 00011000 */
 
-   /* 198 0xc6 'Æ' */
+   /* 198 0xc6 '' */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
    0x1f, /* 00011111 */
@@ -2006,7 +2006,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x18, /* 00011000 */
 
-   /* 199 0xc7 'Ç' */
+   /* 199 0xc7 '' */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
@@ -2016,7 +2016,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x36, /* 00110110 */
    0x36, /* 00110110 */
 
-   /* 200 0xc8 'È' */
+   /* 200 0xc8 '' */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
    0x37, /* 00110111 */
@@ -2026,7 +2026,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 201 0xc9 'É' */
+   /* 201 0xc9 '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x3f, /* 00111111 */
@@ -2036,7 +2036,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x36, /* 00110110 */
    0x36, /* 00110110 */
 
-   /* 202 0xca 'Ê' */
+   /* 202 0xca '' */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
    0xf7, /* 11110111 */
@@ -2046,7 +2046,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 203 0xcb 'Ë' */
+   /* 203 0xcb '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0xff, /* 11111111 */
@@ -2056,7 +2056,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x36, /* 00110110 */
    0x36, /* 00110110 */
 
-   /* 204 0xcc 'Ì' */
+   /* 204 0xcc '' */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
    0x37, /* 00110111 */
@@ -2066,7 +2066,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x36, /* 00110110 */
    0x36, /* 00110110 */
 
-   /* 205 0xcd 'Í' */
+   /* 205 0xcd '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0xff, /* 11111111 */
@@ -2076,7 +2076,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 206 0xce 'Î' */
+   /* 206 0xce '' */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
    0xf7, /* 11110111 */
@@ -2086,7 +2086,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x36, /* 00110110 */
    0x36, /* 00110110 */
 
-   /* 207 0xcf 'Ï' */
+   /* 207 0xcf '' */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
    0xff, /* 11111111 */
@@ -2096,7 +2096,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 208 0xd0 'Ð' */
+   /* 208 0xd0 '' */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
@@ -2106,7 +2106,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 209 0xd1 'Ñ' */
+   /* 209 0xd1 '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0xff, /* 11111111 */
@@ -2116,7 +2116,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x18, /* 00011000 */
 
-   /* 210 0xd2 'Ò' */
+   /* 210 0xd2 '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
@@ -2126,7 +2126,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x36, /* 00110110 */
    0x36, /* 00110110 */
 
-   /* 211 0xd3 'Ó' */
+   /* 211 0xd3 '' */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
@@ -2136,7 +2136,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 212 0xd4 'Ô' */
+   /* 212 0xd4 '' */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
    0x1f, /* 00011111 */
@@ -2146,7 +2146,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 213 0xd5 'Õ' */
+   /* 213 0xd5 '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x1f, /* 00011111 */
@@ -2156,7 +2156,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x18, /* 00011000 */
 
-   /* 214 0xd6 'Ö' */
+   /* 214 0xd6 '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
@@ -2166,7 +2166,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x36, /* 00110110 */
    0x36, /* 00110110 */
 
-   /* 215 0xd7 '×' */
+   /* 215 0xd7 '' */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
@@ -2176,7 +2176,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x36, /* 00110110 */
    0x36, /* 00110110 */
 
-   /* 216 0xd8 'Ø' */
+   /* 216 0xd8 '' */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
    0xff, /* 11111111 */
@@ -2186,7 +2186,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x18, /* 00011000 */
 
-   /* 217 0xd9 'Ù' */
+   /* 217 0xd9 '' */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
@@ -2196,7 +2196,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 218 0xda 'Ú' */
+   /* 218 0xda '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
@@ -2206,7 +2206,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x18, /* 00011000 */
 
-   /* 219 0xdb 'Û' */
+   /* 219 0xdb '' */
    0xff, /* 11111111 */
    0xff, /* 11111111 */
    0xff, /* 11111111 */
@@ -2216,7 +2216,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xff, /* 11111111 */
    0xff, /* 11111111 */
 
-   /* 220 0xdc 'Ü' */
+   /* 220 0xdc '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
@@ -2226,7 +2226,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xff, /* 11111111 */
    0xff, /* 11111111 */
 
-   /* 221 0xdd 'Ý' */
+   /* 221 0xdd '' */
    0xf0, /* 11110000 */
    0xf0, /* 11110000 */
    0xf0, /* 11110000 */
@@ -2236,7 +2236,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xf0, /* 11110000 */
    0xf0, /* 11110000 */
 
-   /* 222 0xde 'Þ' */
+   /* 222 0xde '' */
    0x0f, /* 00001111 */
    0x0f, /* 00001111 */
    0x0f, /* 00001111 */
@@ -2246,7 +2246,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x0f, /* 00001111 */
    0x0f, /* 00001111 */
 
-   /* 223 0xdf 'ß' */
+   /* 223 0xdf '' */
    0xff, /* 11111111 */
    0xff, /* 11111111 */
    0xff, /* 11111111 */
@@ -2256,7 +2256,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 224 0xe0 'à' */
+   /* 224 0xe0 'α' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x76, /* 01110110 */
@@ -2266,7 +2266,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x76, /* 01110110 */
    0x00, /* 00000000 */
 
-   /* 225 0xe1 'á' */
+   /* 225 0xe1 'ß' */
    0x78, /* 01111000 */
    0xcc, /* 11001100 */
    0xcc, /* 11001100 */
@@ -2276,7 +2276,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xcc, /* 11001100 */
    0x00, /* 00000000 */
 
-   /* 226 0xe2 'â' */
+   /* 226 0xe2 'Γ' */
    0xfe, /* 11111110 */
    0xc6, /* 11000110 */
    0xc0, /* 11000000 */
@@ -2286,7 +2286,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xc0, /* 11000000 */
    0x00, /* 00000000 */
 
-   /* 227 0xe3 'ã' */
+   /* 227 0xe3 'π' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0xfe, /* 11111110 */
@@ -2296,7 +2296,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x6c, /* 01101100 */
    0x00, /* 00000000 */
 
-   /* 228 0xe4 'ä' */
+   /* 228 0xe4 'Σ' */
    0xfe, /* 11111110 */
    0xc6, /* 11000110 */
    0x60, /* 01100000 */
@@ -2306,7 +2306,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xfe, /* 11111110 */
    0x00, /* 00000000 */
 
-   /* 229 0xe5 'å' */
+   /* 229 0xe5 'σ' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x7e, /* 01111110 */
@@ -2316,7 +2316,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x70, /* 01110000 */
    0x00, /* 00000000 */
 
-   /* 230 0xe6 'æ' */
+   /* 230 0xe6 'µ' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x66, /* 01100110 */
@@ -2326,7 +2326,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x7c, /* 01111100 */
    0xc0, /* 11000000 */
 
-   /* 231 0xe7 'ç' */
+   /* 231 0xe7 'τ' */
    0x00, /* 00000000 */
    0x76, /* 01110110 */
    0xdc, /* 11011100 */
@@ -2336,7 +2336,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x00, /* 00000000 */
 
-   /* 232 0xe8 'è' */
+   /* 232 0xe8 'Φ' */
    0x7e, /* 01111110 */
    0x18, /* 00011000 */
    0x3c, /* 00111100 */
@@ -2346,7 +2346,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x7e, /* 01111110 */
 
-   /* 233 0xe9 'é' */
+   /* 233 0xe9 'Θ' */
    0x38, /* 00111000 */
    0x6c, /* 01101100 */
    0xc6, /* 11000110 */
@@ -2356,7 +2356,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x38, /* 00111000 */
    0x00, /* 00000000 */
 
-   /* 234 0xea 'ê' */
+   /* 234 0xea 'Ω' */
    0x38, /* 00111000 */
    0x6c, /* 01101100 */
    0xc6, /* 11000110 */
@@ -2366,7 +2366,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xee, /* 11101110 */
    0x00, /* 00000000 */
 
-   /* 235 0xeb 'ë' */
+   /* 235 0xeb 'δ' */
    0x0e, /* 00001110 */
    0x18, /* 00011000 */
    0x0c, /* 00001100 */
@@ -2376,7 +2376,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x3c, /* 00111100 */
    0x00, /* 00000000 */
 
-   /* 236 0xec 'ì' */
+   /* 236 0xec '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x7e, /* 01111110 */
@@ -2386,7 +2386,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 237 0xed 'í' */
+   /* 237 0xed 'φ' */
    0x06, /* 00000110 */
    0x0c, /* 00001100 */
    0x7e, /* 01111110 */
@@ -2396,7 +2396,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x60, /* 01100000 */
    0xc0, /* 11000000 */
 
-   /* 238 0xee 'î' */
+   /* 238 0xee 'ε' */
    0x1e, /* 00011110 */
    0x30, /* 00110000 */
    0x60, /* 01100000 */
@@ -2406,7 +2406,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x1e, /* 00011110 */
    0x00, /* 00000000 */
 
-   /* 239 0xef 'ï' */
+   /* 239 0xef '' */
    0x00, /* 00000000 */
    0x7c, /* 01111100 */
    0xc6, /* 11000110 */
@@ -2416,7 +2416,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xc6, /* 11000110 */
    0x00, /* 00000000 */
 
-   /* 240 0xf0 'ð' */
+   /* 240 0xf0 '' */
    0x00, /* 00000000 */
    0xfe, /* 11111110 */
    0x00, /* 00000000 */
@@ -2426,7 +2426,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 241 0xf1 'ñ' */
+   /* 241 0xf1 '±' */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
    0x7e, /* 01111110 */
@@ -2436,7 +2436,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x7e, /* 01111110 */
    0x00, /* 00000000 */
 
-   /* 242 0xf2 'ò' */
+   /* 242 0xf2 '' */
    0x30, /* 00110000 */
    0x18, /* 00011000 */
    0x0c, /* 00001100 */
@@ -2446,7 +2446,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x7e, /* 01111110 */
    0x00, /* 00000000 */
 
-   /* 243 0xf3 'ó' */
+   /* 243 0xf3 '' */
    0x0c, /* 00001100 */
    0x18, /* 00011000 */
    0x30, /* 00110000 */
@@ -2456,7 +2456,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x7e, /* 01111110 */
    0x00, /* 00000000 */
 
-   /* 244 0xf4 'ô' */
+   /* 244 0xf4 '' */
    0x0e, /* 00001110 */
    0x1b, /* 00011011 */
    0x1b, /* 00011011 */
@@ -2466,7 +2466,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x18, /* 00011000 */
    0x18, /* 00011000 */
 
-   /* 245 0xf5 'õ' */
+   /* 245 0xf5 '' */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
    0x18, /* 00011000 */
@@ -2476,7 +2476,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0xd8, /* 11011000 */
    0x70, /* 01110000 */
 
-   /* 246 0xf6 'ö' */
+   /* 246 0xf6 '÷' */
    0x00, /* 00000000 */
    0x18, /* 00011000 */
    0x00, /* 00000000 */
@@ -2486,7 +2486,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 247 0xf7 '÷' */
+   /* 247 0xf7 '' */
    0x00, /* 00000000 */
    0x76, /* 01110110 */
    0xdc, /* 11011100 */
@@ -2496,7 +2496,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 248 0xf8 'ø' */
+   /* 248 0xf8 '°' */
    0x38, /* 00111000 */
    0x6c, /* 01101100 */
    0x6c, /* 01101100 */
@@ -2506,7 +2506,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 249 0xf9 'ù' */
+   /* 249 0xf9 '·' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
@@ -2516,7 +2516,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 250 0xfa 'ú' */
+   /* 250 0xfa '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
@@ -2526,7 +2526,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 251 0xfb 'û' */
+   /* 251 0xfb '' */
    0x0f, /* 00001111 */
    0x0c, /* 00001100 */
    0x0c, /* 00001100 */
@@ -2536,7 +2536,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x3c, /* 00111100 */
    0x1c, /* 00011100 */
 
-   /* 252 0xfc 'ü' */
+   /* 252 0xfc '' */
    0x6c, /* 01101100 */
    0x36, /* 00110110 */
    0x36, /* 00110110 */
@@ -2546,7 +2546,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 253 0xfd 'ý' */
+   /* 253 0xfd '²' */
    0x78, /* 01111000 */
    0x0c, /* 00001100 */
    0x18, /* 00011000 */
@@ -2556,7 +2556,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 254 0xfe 'þ' */
+   /* 254 0xfe '' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x3c, /* 00111100 */
@@ -2566,7 +2566,7 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
    0x00, /* 00000000 */
    0x00, /* 00000000 */
 
-   /* 255 0xff 'ÿ' */
+   /* 255 0xff ' ' */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
    0x00, /* 00000000 */
diff --git a/lib/gen_crc64table.c b/lib/gen_crc64table.c
new file mode 100644 (file)
index 0000000..9011926
--- /dev/null
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Generate lookup table for the table-driven CRC64 calculation.
+ *
+ * gen_crc64table is executed in kernel build time and generates
+ * lib/crc64table.h. This header is included by lib/crc64.c for
+ * the table-driven CRC64 calculation.
+ *
+ * See lib/crc64.c for more information about which specification
+ * and polynomial arithmetic that gen_crc64table.c follows to
+ * generate the lookup table.
+ *
+ * Copyright 2018 SUSE Linux.
+ *   Author: Coly Li <colyli@suse.de>
+ */
+#include <inttypes.h>
+#include <stdio.h>
+
+#include <linux/swab.h>
+
+#define CRC64_ECMA182_POLY 0x42F0E1EBA9EA3693ULL
+
+static uint64_t crc64_table[256] = {0};
+
+static void generate_crc64_table(void)
+{
+       uint64_t i, j, c, crc;
+
+       for (i = 0; i < 256; i++) {
+               crc = 0;
+               c = i << 56;
+
+               for (j = 0; j < 8; j++) {
+                       if ((crc ^ c) & 0x8000000000000000ULL)
+                               crc = (crc << 1) ^ CRC64_ECMA182_POLY;
+                       else
+                               crc <<= 1;
+                       c <<= 1;
+               }
+
+               crc64_table[i] = crc;
+       }
+}
+
+static void print_crc64_table(void)
+{
+       int i;
+
+       printf("/* this file is generated - do not edit */\n\n");
+       printf("#include <linux/types.h>\n");
+       printf("#include <linux/cache.h>\n\n");
+       printf("static const u64 ____cacheline_aligned crc64table[256] = {\n");
+       for (i = 0; i < 256; i++) {
+               printf("\t0x%016" PRIx64 "ULL", crc64_table[i]);
+               if (i & 0x1)
+                       printf(",\n");
+               else
+                       printf(", ");
+       }
+       printf("};\n");
+}
+
+int main(int argc, char *argv[])
+{
+       generate_crc64_table();
+       print_crc64_table();
+       return 0;
+}
index ed9c169c12bdc966448d96b79de30f899e185a34..fab2fd5bc326bef8bdc9277485d9fe0d4ec50733 100644 (file)
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -317,18 +317,12 @@ EXPORT_SYMBOL(idr_replace);
  * bit per ID, and so is more space efficient than an IDR.  To use an IDA,
  * define it using DEFINE_IDA() (or embed a &struct ida in a data structure,
  * then initialise it using ida_init()).  To allocate a new ID, call
- * ida_simple_get().  To free an ID, call ida_simple_remove().
+ * ida_alloc(), ida_alloc_min(), ida_alloc_max() or ida_alloc_range().
+ * To free an ID, call ida_free().
  *
- * If you have more complex locking requirements, use a loop around
- * ida_pre_get() and ida_get_new() to allocate a new ID.  Then use
- * ida_remove() to free an ID.  You must make sure that ida_get_new() and
- * ida_remove() cannot be called at the same time as each other for the
- * same IDA.
- *
- * You can also use ida_get_new_above() if you need an ID to be allocated
- * above a particular number.  ida_destroy() can be used to dispose of an
- * IDA without needing to free the individual IDs in it.  You can use
- * ida_is_empty() to find out whether the IDA has any IDs currently allocated.
+ * ida_destroy() can be used to dispose of an IDA without needing to
+ * free the individual IDs in it.  You can use ida_is_empty() to find
+ * out whether the IDA has any IDs currently allocated.
  *
  * IDs are currently limited to the range [0-INT_MAX].  If this is an awkward
  * limitation, it should be quite straightforward to raise the maximum.
@@ -369,25 +363,7 @@ EXPORT_SYMBOL(idr_replace);
 
 #define IDA_MAX (0x80000000U / IDA_BITMAP_BITS - 1)
 
-/**
- * ida_get_new_above - allocate new ID above or equal to a start id
- * @ida: ida handle
- * @start: id to start search at
- * @id: pointer to the allocated handle
- *
- * Allocate new ID above or equal to @start.  It should be called
- * with any required locks to ensure that concurrent calls to
- * ida_get_new_above() / ida_get_new() / ida_remove() are not allowed.
- * Consider using ida_simple_get() if you do not have complex locking
- * requirements.
- *
- * If memory is required, it will return %-EAGAIN, you should unlock
- * and go back to the ida_pre_get() call.  If the ida is full, it will
- * return %-ENOSPC.  On success, it will return 0.
- *
- * @id returns a value in the range @start ... %0x7fffffff.
- */
-int ida_get_new_above(struct ida *ida, int start, int *id)
+static int ida_get_new_above(struct ida *ida, int start)
 {
        struct radix_tree_root *root = &ida->ida_rt;
        void __rcu **slot;
@@ -426,8 +402,8 @@ int ida_get_new_above(struct ida *ida, int start, int *id)
                        if (ebit < BITS_PER_LONG) {
                                tmp |= 1UL << ebit;
                                rcu_assign_pointer(*slot, (void *)tmp);
-                               *id = new + ebit - RADIX_TREE_EXCEPTIONAL_SHIFT;
-                               return 0;
+                               return new + ebit -
+                                       RADIX_TREE_EXCEPTIONAL_SHIFT;
                        }
                        bitmap = this_cpu_xchg(ida_bitmap, NULL);
                        if (!bitmap)
@@ -458,8 +434,7 @@ int ida_get_new_above(struct ida *ida, int start, int *id)
                                                RADIX_TREE_EXCEPTIONAL_ENTRY);
                                radix_tree_iter_replace(root, &iter, slot,
                                                bitmap);
-                               *id = new;
-                               return 0;
+                               return new;
                        }
                        bitmap = this_cpu_xchg(ida_bitmap, NULL);
                        if (!bitmap)
@@ -468,20 +443,11 @@ int ida_get_new_above(struct ida *ida, int start, int *id)
                        radix_tree_iter_replace(root, &iter, slot, bitmap);
                }
 
-               *id = new;
-               return 0;
+               return new;
        }
 }
-EXPORT_SYMBOL(ida_get_new_above);
 
-/**
- * ida_remove - Free the given ID
- * @ida: ida handle
- * @id: ID to free
- *
- * This function should not be called at the same time as ida_get_new_above().
- */
-void ida_remove(struct ida *ida, int id)
+static void ida_remove(struct ida *ida, int id)
 {
        unsigned long index = id / IDA_BITMAP_BITS;
        unsigned offset = id % IDA_BITMAP_BITS;
@@ -518,99 +484,90 @@ void ida_remove(struct ida *ida, int id)
        }
        return;
  err:
-       WARN(1, "ida_remove called for id=%d which is not allocated.\n", id);
+       WARN(1, "ida_free called for id=%d which is not allocated.\n", id);
 }
-EXPORT_SYMBOL(ida_remove);
 
 /**
- * ida_destroy - Free the contents of an ida
- * @ida: ida handle
+ * ida_destroy() - Free all IDs.
+ * @ida: IDA handle.
+ *
+ * Calling this function frees all IDs and releases all resources used
+ * by an IDA.  When this call returns, the IDA is empty and can be reused
+ * or freed.  If the IDA is already empty, there is no need to call this
+ * function.
  *
- * Calling this function releases all resources associated with an IDA.  When
- * this call returns, the IDA is empty and can be reused or freed.  The caller
- * should not allow ida_remove() or ida_get_new_above() to be called at the
- * same time.
+ * Context: Any context.
  */
 void ida_destroy(struct ida *ida)
 {
+       unsigned long flags;
        struct radix_tree_iter iter;
        void __rcu **slot;
 
+       xa_lock_irqsave(&ida->ida_rt, flags);
        radix_tree_for_each_slot(slot, &ida->ida_rt, &iter, 0) {
                struct ida_bitmap *bitmap = rcu_dereference_raw(*slot);
                if (!radix_tree_exception(bitmap))
                        kfree(bitmap);
                radix_tree_iter_delete(&ida->ida_rt, &iter, slot);
        }
+       xa_unlock_irqrestore(&ida->ida_rt, flags);
 }
 EXPORT_SYMBOL(ida_destroy);
 
 /**
- * ida_simple_get - get a new id.
- * @ida: the (initialized) ida.
- * @start: the minimum id (inclusive, < 0x8000000)
- * @end: the maximum id (exclusive, < 0x8000000 or 0)
- * @gfp_mask: memory allocation flags
- *
- * Allocates an id in the range start <= id < end, or returns -ENOSPC.
- * On memory allocation failure, returns -ENOMEM.
+ * ida_alloc_range() - Allocate an unused ID.
+ * @ida: IDA handle.
+ * @min: Lowest ID to allocate.
+ * @max: Highest ID to allocate.
+ * @gfp: Memory allocation flags.
  *
- * Compared to ida_get_new_above() this function does its own locking, and
- * should be used unless there are special requirements.
+ * Allocate an ID between @min and @max, inclusive.  The allocated ID will
+ * not exceed %INT_MAX, even if @max is larger.
  *
- * Use ida_simple_remove() to get rid of an id.
+ * Context: Any context.
+ * Return: The allocated ID, or %-ENOMEM if memory could not be allocated,
+ * or %-ENOSPC if there are no free IDs.
  */
-int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end,
-                  gfp_t gfp_mask)
+int ida_alloc_range(struct ida *ida, unsigned int min, unsigned int max,
+                       gfp_t gfp)
 {
-       int ret, id;
-       unsigned int max;
+       int id = 0;
        unsigned long flags;
 
-       BUG_ON((int)start < 0);
-       BUG_ON((int)end < 0);
+       if ((int)min < 0)
+               return -ENOSPC;
 
-       if (end == 0)
-               max = 0x80000000;
-       else {
-               BUG_ON(end < start);
-               max = end - 1;
-       }
+       if ((int)max < 0)
+               max = INT_MAX;
 
 again:
-       if (!ida_pre_get(ida, gfp_mask))
-               return -ENOMEM;
-
        xa_lock_irqsave(&ida->ida_rt, flags);
-       ret = ida_get_new_above(ida, start, &id);
-       if (!ret) {
-               if (id > max) {
-                       ida_remove(ida, id);
-                       ret = -ENOSPC;
-               } else {
-                       ret = id;
-               }
+       id = ida_get_new_above(ida, min);
+       if (id > (int)max) {
+               ida_remove(ida, id);
+               id = -ENOSPC;
        }
        xa_unlock_irqrestore(&ida->ida_rt, flags);
 
-       if (unlikely(ret == -EAGAIN))
+       if (unlikely(id == -EAGAIN)) {
+               if (!ida_pre_get(ida, gfp))
+                       return -ENOMEM;
                goto again;
+       }
 
-       return ret;
+       return id;
 }
-EXPORT_SYMBOL(ida_simple_get);
+EXPORT_SYMBOL(ida_alloc_range);
 
 /**
- * ida_simple_remove - remove an allocated id.
- * @ida: the (initialized) ida.
- * @id: the id returned by ida_simple_get.
- *
- * Use to release an id allocated with ida_simple_get().
+ * ida_free() - Release an allocated ID.
+ * @ida: IDA handle.
+ * @id: Previously allocated ID.
  *
- * Compared to ida_remove() this function does its own locking, and should be
- * used unless there are special requirements.
+ * Context: Any context.
  */
-void ida_simple_remove(struct ida *ida, unsigned int id)
+void ida_free(struct ida *ida, unsigned int id)
 {
        unsigned long flags;
 
@@ -619,4 +576,4 @@ void ida_simple_remove(struct ida *ida, unsigned int id)
        ida_remove(ida, id);
        xa_unlock_irqrestore(&ida->ida_rt, flags);
 }
-EXPORT_SYMBOL(ida_simple_remove);
+EXPORT_SYMBOL(ida_free);
index c72577e472f2f2929f825b0c105a237f54c42971..a66595ba5543e2a345da99b37313112e0dc1a4e6 100644 (file)
@@ -4,7 +4,6 @@
  */
 
 #include <linux/percpu_counter.h>
-#include <linux/notifier.h>
 #include <linux/mutex.h>
 #include <linux/init.h>
 #include <linux/cpu.h>
index a9e41aed6de4bfb063af9d16d41942a041a23fdd..bc03ecc4dfd2f69c8638cbff3270bc55793b7f6b 100644 (file)
@@ -120,7 +120,7 @@ bool is_sibling_entry(const struct radix_tree_node *parent, void *node)
 static inline unsigned long
 get_slot_offset(const struct radix_tree_node *parent, void __rcu **slot)
 {
-       return slot - parent->slots;
+       return parent ? slot - parent->slots : 0;
 }
 
 static unsigned int radix_tree_descend(const struct radix_tree_node *parent,
@@ -2106,14 +2106,6 @@ void idr_preload(gfp_t gfp_mask)
 }
 EXPORT_SYMBOL(idr_preload);
 
-/**
- * ida_pre_get - reserve resources for ida allocation
- * @ida: ida handle
- * @gfp: memory allocation flags
- *
- * This function should be called before calling ida_get_new_above().  If it
- * is unable to allocate memory, it will return %0.  On success, it returns %1.
- */
 int ida_pre_get(struct ida *ida, gfp_t gfp)
 {
        /*
@@ -2134,7 +2126,6 @@ int ida_pre_get(struct ida *ida, gfp_t gfp)
 
        return 1;
 }
-EXPORT_SYMBOL(ida_pre_get);
 
 void __rcu **idr_get_free(struct radix_tree_root *root,
                              struct radix_tree_iter *iter, gfp_t gfp,
index ae4223e0f5bcb68610511b2cb7ba2e12b7f7d086..30526afa8343124f06f0649592ee246dc4d88fbe 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/rhashtable.h>
 #include <linux/err.h>
 #include <linux/export.h>
-#include <linux/rhashtable.h>
 
 #define HASH_DEFAULT_SIZE      64UL
 #define HASH_MIN_SIZE          4U
@@ -174,17 +173,15 @@ static struct bucket_table *bucket_table_alloc(struct rhashtable *ht,
        int i;
 
        size = sizeof(*tbl) + nbuckets * sizeof(tbl->buckets[0]);
-       if (gfp != GFP_KERNEL)
-               tbl = kzalloc(size, gfp | __GFP_NOWARN | __GFP_NORETRY);
-       else
-               tbl = kvzalloc(size, gfp);
+       tbl = kvzalloc(size, gfp);
 
        size = nbuckets;
 
-       if (tbl == NULL && gfp != GFP_KERNEL) {
+       if (tbl == NULL && (gfp & ~__GFP_NOFAIL) != GFP_KERNEL) {
                tbl = nested_bucket_table_alloc(ht, nbuckets, gfp);
                nbuckets = 0;
        }
+
        if (tbl == NULL)
                return NULL;
 
@@ -450,7 +447,7 @@ static int rhashtable_insert_rehash(struct rhashtable *ht,
 
        err = -ENOMEM;
 
-       new_tbl = bucket_table_alloc(ht, size, GFP_ATOMIC);
+       new_tbl = bucket_table_alloc(ht, size, GFP_ATOMIC | __GFP_NOWARN);
        if (new_tbl == NULL)
                goto fail;
 
@@ -1060,9 +1057,16 @@ int rhashtable_init(struct rhashtable *ht,
                }
        }
 
+       /*
+        * This is api initialization and thus we need to guarantee the
+        * initial rhashtable allocation. Upon failure, retry with the
+        * smallest possible size with __GFP_NOFAIL semantics.
+        */
        tbl = bucket_table_alloc(ht, size, GFP_KERNEL);
-       if (tbl == NULL)
-               return -ENOMEM;
+       if (unlikely(tbl == NULL)) {
+               size = max_t(u16, ht->p.min_size, HASH_MIN_SIZE);
+               tbl = bucket_table_alloc(ht, size, GFP_KERNEL | __GFP_NOFAIL);
+       }
 
        atomic_set(&ht->nelems, 0);
 
index b9cdeecc19dc303f0167433457f41f5325684f6a..d5a06addeb27180a60577dbcd04ff2582cb391db 100644 (file)
@@ -15,7 +15,7 @@ struct foo {
        unsigned int bar;
 };
 
-struct foo *foo;
+static struct foo *foo;
 
 static int __init test_debug_virtual_init(void)
 {
index 3f415d8101f3209f16ba66143ee1b31b56d4b0b1..626f580b4ff7b0c52fd3aeb7cffdf19429c3f457 100644 (file)
@@ -18,7 +18,7 @@ static const unsigned char data_b[] = {
 
 static const unsigned char data_a[] = ".2.{....p..$}.4...1.....L...C...";
 
-static const char * const test_data_1_le[] __initconst = {
+static const char * const test_data_1[] __initconst = {
        "be", "32", "db", "7b", "0a", "18", "93", "b2",
        "70", "ba", "c4", "24", "7d", "83", "34", "9b",
        "a6", "9c", "31", "ad", "9c", "0f", "ac", "e9",
@@ -32,16 +32,33 @@ static const char * const test_data_2_le[] __initconst = {
        "d14c", "9919", "b143", "0caf",
 };
 
+static const char * const test_data_2_be[] __initconst = {
+       "be32", "db7b", "0a18", "93b2",
+       "70ba", "c424", "7d83", "349b",
+       "a69c", "31ad", "9c0f", "ace9",
+       "4cd1", "1999", "43b1", "af0c",
+};
+
 static const char * const test_data_4_le[] __initconst = {
        "7bdb32be", "b293180a", "24c4ba70", "9b34837d",
        "ad319ca6", "e9ac0f9c", "9919d14c", "0cafb143",
 };
 
+static const char * const test_data_4_be[] __initconst = {
+       "be32db7b", "0a1893b2", "70bac424", "7d83349b",
+       "a69c31ad", "9c0face9", "4cd11999", "43b1af0c",
+};
+
 static const char * const test_data_8_le[] __initconst = {
        "b293180a7bdb32be", "9b34837d24c4ba70",
        "e9ac0f9cad319ca6", "0cafb1439919d14c",
 };
 
+static const char * const test_data_8_be[] __initconst = {
+       "be32db7b0a1893b2", "70bac4247d83349b",
+       "a69c31ad9c0face9", "4cd1199943b1af0c",
+};
+
 #define FILL_CHAR      '#'
 
 static unsigned total_tests __initdata;
@@ -56,6 +73,7 @@ static void __init test_hexdump_prepare_test(size_t len, int rowsize,
        size_t l = len;
        int gs = groupsize, rs = rowsize;
        unsigned int i;
+       const bool is_be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN);
 
        if (rs != 16 && rs != 32)
                rs = 16;
@@ -67,13 +85,13 @@ static void __init test_hexdump_prepare_test(size_t len, int rowsize,
                gs = 1;
 
        if (gs == 8)
-               result = test_data_8_le;
+               result = is_be ? test_data_8_be : test_data_8_le;
        else if (gs == 4)
-               result = test_data_4_le;
+               result = is_be ? test_data_4_be : test_data_4_le;
        else if (gs == 2)
-               result = test_data_2_le;
+               result = is_be ? test_data_2_be : test_data_2_le;
        else
-               result = test_data_1_le;
+               result = test_data_1;
 
        /* hex dump */
        p = test;
diff --git a/lib/test_ida.c b/lib/test_ida.c
new file mode 100644 (file)
index 0000000..2d1637d
--- /dev/null
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * test_ida.c: Test the IDA API
+ * Copyright (c) 2016-2018 Microsoft Corporation
+ * Copyright (c) 2018 Oracle Corporation
+ * Author: Matthew Wilcox <willy@infradead.org>
+ */
+
+#include <linux/idr.h>
+#include <linux/module.h>
+
+static unsigned int tests_run;
+static unsigned int tests_passed;
+
+#ifdef __KERNEL__
+void ida_dump(struct ida *ida) { }
+#endif
+#define IDA_BUG_ON(ida, x) do {                                                \
+       tests_run++;                                                    \
+       if (x) {                                                        \
+               ida_dump(ida);                                          \
+               dump_stack();                                           \
+       } else {                                                        \
+               tests_passed++;                                         \
+       }                                                               \
+} while (0)
+
+/*
+ * Straightforward checks that allocating and freeing IDs work.
+ */
+static void ida_check_alloc(struct ida *ida)
+{
+       int i, id;
+
+       for (i = 0; i < 10000; i++)
+               IDA_BUG_ON(ida, ida_alloc(ida, GFP_KERNEL) != i);
+
+       ida_free(ida, 20);
+       ida_free(ida, 21);
+       for (i = 0; i < 3; i++) {
+               id = ida_alloc(ida, GFP_KERNEL);
+               IDA_BUG_ON(ida, id < 0);
+               if (i == 2)
+                       IDA_BUG_ON(ida, id != 10000);
+       }
+
+       for (i = 0; i < 5000; i++)
+               ida_free(ida, i);
+
+       IDA_BUG_ON(ida, ida_alloc_min(ida, 5000, GFP_KERNEL) != 10001);
+       ida_destroy(ida);
+
+       IDA_BUG_ON(ida, !ida_is_empty(ida));
+}
+
+/* Destroy an IDA with a single entry at @base */
+static void ida_check_destroy_1(struct ida *ida, unsigned int base)
+{
+       IDA_BUG_ON(ida, ida_alloc_min(ida, base, GFP_KERNEL) != base);
+       IDA_BUG_ON(ida, ida_is_empty(ida));
+       ida_destroy(ida);
+       IDA_BUG_ON(ida, !ida_is_empty(ida));
+}
+
+/* Check that ida_destroy and ida_is_empty work */
+static void ida_check_destroy(struct ida *ida)
+{
+       /* Destroy an already-empty IDA */
+       IDA_BUG_ON(ida, !ida_is_empty(ida));
+       ida_destroy(ida);
+       IDA_BUG_ON(ida, !ida_is_empty(ida));
+
+       ida_check_destroy_1(ida, 0);
+       ida_check_destroy_1(ida, 1);
+       ida_check_destroy_1(ida, 1023);
+       ida_check_destroy_1(ida, 1024);
+       ida_check_destroy_1(ida, 12345678);
+}
+
+/*
+ * Check what happens when we fill a leaf and then delete it.  This may
+ * discover mishandling of IDR_FREE.
+ */
+static void ida_check_leaf(struct ida *ida, unsigned int base)
+{
+       unsigned long i;
+
+       for (i = 0; i < IDA_BITMAP_BITS; i++) {
+               IDA_BUG_ON(ida, ida_alloc_min(ida, base, GFP_KERNEL) !=
+                               base + i);
+       }
+
+       ida_destroy(ida);
+       IDA_BUG_ON(ida, !ida_is_empty(ida));
+
+       IDA_BUG_ON(ida, ida_alloc(ida, GFP_KERNEL) != 0);
+       IDA_BUG_ON(ida, ida_is_empty(ida));
+       ida_free(ida, 0);
+       IDA_BUG_ON(ida, !ida_is_empty(ida));
+}
+
+/*
+ * Check allocations up to and slightly above the maximum allowed (2^31-1) ID.
+ * Allocating up to 2^31-1 should succeed, and then allocating the next one
+ * should fail.
+ */
+static void ida_check_max(struct ida *ida)
+{
+       unsigned long i, j;
+
+       for (j = 1; j < 65537; j *= 2) {
+               unsigned long base = (1UL << 31) - j;
+               for (i = 0; i < j; i++) {
+                       IDA_BUG_ON(ida, ida_alloc_min(ida, base, GFP_KERNEL) !=
+                                       base + i);
+               }
+               IDA_BUG_ON(ida, ida_alloc_min(ida, base, GFP_KERNEL) !=
+                               -ENOSPC);
+               ida_destroy(ida);
+               IDA_BUG_ON(ida, !ida_is_empty(ida));
+       }
+}
+
+/*
+ * Check handling of conversions between exceptional entries and full bitmaps.
+ */
+static void ida_check_conv(struct ida *ida)
+{
+       unsigned long i;
+
+       for (i = 0; i < IDA_BITMAP_BITS * 2; i += IDA_BITMAP_BITS) {
+               IDA_BUG_ON(ida, ida_alloc_min(ida, i + 1, GFP_KERNEL) != i + 1);
+               IDA_BUG_ON(ida, ida_alloc_min(ida, i + BITS_PER_LONG,
+                                       GFP_KERNEL) != i + BITS_PER_LONG);
+               ida_free(ida, i + 1);
+               ida_free(ida, i + BITS_PER_LONG);
+               IDA_BUG_ON(ida, !ida_is_empty(ida));
+       }
+
+       for (i = 0; i < IDA_BITMAP_BITS * 2; i++)
+               IDA_BUG_ON(ida, ida_alloc(ida, GFP_KERNEL) != i);
+       for (i = IDA_BITMAP_BITS * 2; i > 0; i--)
+               ida_free(ida, i - 1);
+       IDA_BUG_ON(ida, !ida_is_empty(ida));
+
+       for (i = 0; i < IDA_BITMAP_BITS + BITS_PER_LONG - 4; i++)
+               IDA_BUG_ON(ida, ida_alloc(ida, GFP_KERNEL) != i);
+       for (i = IDA_BITMAP_BITS + BITS_PER_LONG - 4; i > 0; i--)
+               ida_free(ida, i - 1);
+       IDA_BUG_ON(ida, !ida_is_empty(ida));
+}
+
+static int ida_checks(void)
+{
+       DEFINE_IDA(ida);
+
+       IDA_BUG_ON(&ida, !ida_is_empty(&ida));
+       ida_check_alloc(&ida);
+       ida_check_destroy(&ida);
+       ida_check_leaf(&ida, 0);
+       ida_check_leaf(&ida, 1024);
+       ida_check_leaf(&ida, 1024 * 64);
+       ida_check_max(&ida);
+       ida_check_conv(&ida);
+
+       printk("IDA: %u of %u tests passed\n", tests_passed, tests_run);
+       return (tests_run != tests_passed) ? 0 : -EINVAL;
+}
+
+static void ida_exit(void)
+{
+}
+
+module_init(ida_checks);
+module_exit(ida_exit);
+MODULE_AUTHOR("Matthew Wilcox <willy@infradead.org>");
+MODULE_LICENSE("GPL");
index e5e606ee5f715e846a19ea9186391c47a2efddc0..9a7b8b049d04fb42ca02783eabf5e70ef9fe5495 100644 (file)
@@ -46,7 +46,8 @@ config PAGE_POISONING
          Fill the pages with poison patterns after free_pages() and verify
          the patterns before alloc_pages. The filling of the memory helps
          reduce the risk of information leaks from freed data. This does
-         have a potential performance impact.
+         have a potential performance impact if enabled with the
+         "page_poison=1" kernel boot option.
 
          Note that "poison" here is not the same thing as the "HWPoison"
          for CONFIG_MEMORY_FAILURE. This is software poisoning only.
@@ -65,7 +66,7 @@ config PAGE_POISONING_NO_SANITY
           say N.
 
 config PAGE_POISONING_ZERO
-       bool "Use zero for poisoning instead of random data"
+       bool "Use zero for poisoning instead of debugging value"
        depends on PAGE_POISONING
        ---help---
           Instead of using the existing poison value, fill the pages with
@@ -75,7 +76,6 @@ config PAGE_POISONING_ZERO
           allocation.
 
           If unsure, say N
-       bool
 
 config DEBUG_PAGE_REF
        bool "Enable tracepoint to track down page reference manipulation"
index 2e5d3df0853d928021cba0e30c70ff682afeaf68..8a8bb8796c6c43cb711c0f618c488df188853623 100644 (file)
@@ -438,10 +438,10 @@ retry:
        if (new_congested) {
                /* !found and storage for new one already allocated, insert */
                congested = new_congested;
-               new_congested = NULL;
                rb_link_node(&congested->rb_node, parent, node);
                rb_insert_color(&congested->rb_node, &bdi->cgwb_congested_tree);
-               goto found;
+               spin_unlock_irqrestore(&cgwb_lock, flags);
+               return congested;
        }
 
        spin_unlock_irqrestore(&cgwb_lock, flags);
@@ -451,13 +451,13 @@ retry:
        if (!new_congested)
                return NULL;
 
-       atomic_set(&new_congested->refcnt, 0);
+       refcount_set(&new_congested->refcnt, 1);
        new_congested->__bdi = bdi;
        new_congested->blkcg_id = blkcg_id;
        goto retry;
 
 found:
-       atomic_inc(&congested->refcnt);
+       refcount_inc(&congested->refcnt);
        spin_unlock_irqrestore(&cgwb_lock, flags);
        kfree(new_congested);
        return congested;
@@ -473,11 +473,8 @@ void wb_congested_put(struct bdi_writeback_congested *congested)
 {
        unsigned long flags;
 
-       local_irq_save(flags);
-       if (!atomic_dec_and_lock(&congested->refcnt, &cgwb_lock)) {
-               local_irq_restore(flags);
+       if (!refcount_dec_and_lock_irqsave(&congested->refcnt, &cgwb_lock, &flags))
                return;
-       }
 
        /* bdi might already have been destroyed leaving @congested unlinked */
        if (congested->__bdi) {
@@ -494,6 +491,7 @@ static void cgwb_release_workfn(struct work_struct *work)
 {
        struct bdi_writeback *wb = container_of(work, struct bdi_writeback,
                                                release_work);
+       struct blkcg *blkcg = css_to_blkcg(wb->blkcg_css);
 
        mutex_lock(&wb->bdi->cgwb_release_mutex);
        wb_shutdown(wb);
@@ -502,6 +500,9 @@ static void cgwb_release_workfn(struct work_struct *work)
        css_put(wb->blkcg_css);
        mutex_unlock(&wb->bdi->cgwb_release_mutex);
 
+       /* triggers blkg destruction if cgwb_refcnt becomes zero */
+       blkcg_cgwb_put(blkcg);
+
        fprop_local_destroy_percpu(&wb->memcg_completions);
        percpu_ref_exit(&wb->refcnt);
        wb_exit(wb);
@@ -600,6 +601,7 @@ static int cgwb_create(struct backing_dev_info *bdi,
                        list_add_tail_rcu(&wb->bdi_node, &bdi->wb_list);
                        list_add(&wb->memcg_node, memcg_cgwb_list);
                        list_add(&wb->blkcg_node, blkcg_cgwb_list);
+                       blkcg_cgwb_get(blkcg);
                        css_get(memcg_css);
                        css_get(blkcg_css);
                }
@@ -804,7 +806,7 @@ static int cgwb_bdi_init(struct backing_dev_info *bdi)
        if (!bdi->wb_congested)
                return -ENOMEM;
 
-       atomic_set(&bdi->wb_congested->refcnt, 1);
+       refcount_set(&bdi->wb_congested->refcnt, 1);
 
        err = wb_init(&bdi->wb, bdi, 1, GFP_KERNEL);
        if (err) {
index fc5f98069f4ea5b2906cf45e8997327c99a5b7ce..1abc8b4afff65093459c43b46ebd84023fb5b66e 100644 (file)
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -497,7 +497,7 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma,
                unsigned long address, unsigned int *flags, int *nonblocking)
 {
        unsigned int fault_flags = 0;
-       int ret;
+       vm_fault_t ret;
 
        /* mlock all present pages, but do not fault in new pages */
        if ((*flags & (FOLL_POPULATE | FOLL_MLOCK)) == FOLL_MLOCK)
@@ -818,7 +818,7 @@ int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm,
                     bool *unlocked)
 {
        struct vm_area_struct *vma;
-       int ret, major = 0;
+       vm_fault_t ret, major = 0;
 
        if (unlocked)
                fault_flags |= FAULT_FLAG_ALLOW_RETRY;
index 76e7a058b32fc2c4dfb675d262dde082dced208d..c968e49f7a0c527258a85b8c0259467e3b2924de 100644 (file)
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -177,16 +177,19 @@ static void hmm_release(struct mmu_notifier *mn, struct mm_struct *mm)
        up_write(&hmm->mirrors_sem);
 }
 
-static void hmm_invalidate_range_start(struct mmu_notifier *mn,
+static int hmm_invalidate_range_start(struct mmu_notifier *mn,
                                       struct mm_struct *mm,
                                       unsigned long start,
-                                      unsigned long end)
+                                      unsigned long end,
+                                      bool blockable)
 {
        struct hmm *hmm = mm->hmm;
 
        VM_BUG_ON(!hmm);
 
        atomic_inc(&hmm->sequence);
+
+       return 0;
 }
 
 static void hmm_invalidate_range_end(struct mmu_notifier *mn,
@@ -965,6 +968,8 @@ static void hmm_devmem_free(struct page *page, void *data)
 {
        struct hmm_devmem *devmem = data;
 
+       page->mapping = NULL;
+
        devmem->ops->free(devmem, page);
 }
 
index 78427af91de96980a8450ef2c8dbeccbb59078d0..533f9b00147d267644bcbf98da717329fb07c38f 100644 (file)
@@ -541,14 +541,14 @@ unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr,
 }
 EXPORT_SYMBOL_GPL(thp_get_unmapped_area);
 
-static int __do_huge_pmd_anonymous_page(struct vm_fault *vmf, struct page *page,
-               gfp_t gfp)
+static vm_fault_t __do_huge_pmd_anonymous_page(struct vm_fault *vmf,
+                       struct page *page, gfp_t gfp)
 {
        struct vm_area_struct *vma = vmf->vma;
        struct mem_cgroup *memcg;
        pgtable_t pgtable;
        unsigned long haddr = vmf->address & HPAGE_PMD_MASK;
-       int ret = 0;
+       vm_fault_t ret = 0;
 
        VM_BUG_ON_PAGE(!PageCompound(page), page);
 
@@ -584,15 +584,15 @@ static int __do_huge_pmd_anonymous_page(struct vm_fault *vmf, struct page *page,
 
                /* Deliver the page fault to userland */
                if (userfaultfd_missing(vma)) {
-                       int ret;
+                       vm_fault_t ret2;
 
                        spin_unlock(vmf->ptl);
                        mem_cgroup_cancel_charge(page, memcg, true);
                        put_page(page);
                        pte_free(vma->vm_mm, pgtable);
-                       ret = handle_userfault(vmf, VM_UFFD_MISSING);
-                       VM_BUG_ON(ret & VM_FAULT_FALLBACK);
-                       return ret;
+                       ret2 = handle_userfault(vmf, VM_UFFD_MISSING);
+                       VM_BUG_ON(ret2 & VM_FAULT_FALLBACK);
+                       return ret2;
                }
 
                entry = mk_huge_pmd(page, vma->vm_page_prot);
@@ -663,7 +663,7 @@ static bool set_huge_zero_page(pgtable_t pgtable, struct mm_struct *mm,
        return true;
 }
 
-int do_huge_pmd_anonymous_page(struct vm_fault *vmf)
+vm_fault_t do_huge_pmd_anonymous_page(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
        gfp_t gfp;
@@ -682,7 +682,7 @@ int do_huge_pmd_anonymous_page(struct vm_fault *vmf)
                pgtable_t pgtable;
                struct page *zero_page;
                bool set;
-               int ret;
+               vm_fault_t ret;
                pgtable = pte_alloc_one(vma->vm_mm, haddr);
                if (unlikely(!pgtable))
                        return VM_FAULT_OOM;
@@ -752,7 +752,7 @@ static void insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr,
        spin_unlock(ptl);
 }
 
-int vmf_insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr,
+vm_fault_t vmf_insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr,
                        pmd_t *pmd, pfn_t pfn, bool write)
 {
        pgprot_t pgprot = vma->vm_page_prot;
@@ -812,7 +812,7 @@ static void insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr,
        spin_unlock(ptl);
 }
 
-int vmf_insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr,
+vm_fault_t vmf_insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr,
                        pud_t *pud, pfn_t pfn, bool write)
 {
        pgprot_t pgprot = vma->vm_page_prot;
@@ -821,11 +821,11 @@ int vmf_insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr,
         * but we need to be consistent with PTEs and architectures that
         * can't support a 'special' bit.
         */
-       BUG_ON(!(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)));
+       BUG_ON(!(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) &&
+                       !pfn_t_devmap(pfn));
        BUG_ON((vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) ==
                                                (VM_PFNMAP|VM_MIXEDMAP));
        BUG_ON((vma->vm_flags & VM_PFNMAP) && is_cow_mapping(vma->vm_flags));
-       BUG_ON(!pfn_t_devmap(pfn));
 
        if (addr < vma->vm_start || addr >= vma->vm_end)
                return VM_FAULT_SIGBUS;
@@ -1118,15 +1118,16 @@ unlock:
        spin_unlock(vmf->ptl);
 }
 
-static int do_huge_pmd_wp_page_fallback(struct vm_fault *vmf, pmd_t orig_pmd,
-               struct page *page)
+static vm_fault_t do_huge_pmd_wp_page_fallback(struct vm_fault *vmf,
+                       pmd_t orig_pmd, struct page *page)
 {
        struct vm_area_struct *vma = vmf->vma;
        unsigned long haddr = vmf->address & HPAGE_PMD_MASK;
        struct mem_cgroup *memcg;
        pgtable_t pgtable;
        pmd_t _pmd;
-       int ret = 0, i;
+       int i;
+       vm_fault_t ret = 0;
        struct page **pages;
        unsigned long mmun_start;       /* For mmu_notifiers */
        unsigned long mmun_end;         /* For mmu_notifiers */
@@ -1236,7 +1237,7 @@ out_free_pages:
        goto out;
 }
 
-int do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd)
+vm_fault_t do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd)
 {
        struct vm_area_struct *vma = vmf->vma;
        struct page *page = NULL, *new_page;
@@ -1245,7 +1246,7 @@ int do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd)
        unsigned long mmun_start;       /* For mmu_notifiers */
        unsigned long mmun_end;         /* For mmu_notifiers */
        gfp_t huge_gfp;                 /* for allocation and charge */
-       int ret = 0;
+       vm_fault_t ret = 0;
 
        vmf->ptl = pmd_lockptr(vma->vm_mm, vmf->pmd);
        VM_BUG_ON_VMA(!vma->anon_vma, vma);
@@ -1457,7 +1458,7 @@ out:
 }
 
 /* NUMA hinting page fault entry point for trans huge pmds */
-int do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t pmd)
+vm_fault_t do_huge_pmd_numa_page(struct vm_fault *vmf, pmd_t pmd)
 {
        struct vm_area_struct *vma = vmf->vma;
        struct anon_vma *anon_vma = NULL;
index 47566bb0b4b12fb126d01e4dc464737829363454..3c21775f196b2f38a25ed05687791a4c79a3d3d4 100644 (file)
@@ -1479,22 +1479,20 @@ static int free_pool_huge_page(struct hstate *h, nodemask_t *nodes_allowed,
 /*
  * Dissolve a given free hugepage into free buddy pages. This function does
  * nothing for in-use (including surplus) hugepages. Returns -EBUSY if the
- * number of free hugepages would be reduced below the number of reserved
- * hugepages.
+ * dissolution fails because a give page is not a free hugepage, or because
+ * free hugepages are fully reserved.
  */
 int dissolve_free_huge_page(struct page *page)
 {
-       int rc = 0;
+       int rc = -EBUSY;
 
        spin_lock(&hugetlb_lock);
        if (PageHuge(page) && !page_count(page)) {
                struct page *head = compound_head(page);
                struct hstate *h = page_hstate(head);
                int nid = page_to_nid(head);
-               if (h->free_huge_pages - h->resv_huge_pages == 0) {
-                       rc = -EBUSY;
+               if (h->free_huge_pages - h->resv_huge_pages == 0)
                        goto out;
-               }
                /*
                 * Move PageHWPoison flag from head page to the raw error page,
                 * which makes any subpages rather than the error page reusable.
@@ -1508,6 +1506,7 @@ int dissolve_free_huge_page(struct page *page)
                h->free_huge_pages_node[nid]--;
                h->max_huge_pages--;
                update_and_free_page(h, head);
+               rc = 0;
        }
 out:
        spin_unlock(&hugetlb_lock);
@@ -3502,14 +3501,15 @@ static void unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma,
  * cannot race with other handlers or page migration.
  * Keep the pte_same checks anyway to make transition from the mutex easier.
  */
-static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
+static vm_fault_t hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
                       unsigned long address, pte_t *ptep,
                       struct page *pagecache_page, spinlock_t *ptl)
 {
        pte_t pte;
        struct hstate *h = hstate_vma(vma);
        struct page *old_page, *new_page;
-       int ret = 0, outside_reserve = 0;
+       int outside_reserve = 0;
+       vm_fault_t ret = 0;
        unsigned long mmun_start;       /* For mmu_notifiers */
        unsigned long mmun_end;         /* For mmu_notifiers */
        unsigned long haddr = address & huge_page_mask(h);
@@ -3573,8 +3573,7 @@ retry_avoidcopy:
                        return 0;
                }
 
-               ret = (PTR_ERR(new_page) == -ENOMEM) ?
-                       VM_FAULT_OOM : VM_FAULT_SIGBUS;
+               ret = vmf_error(PTR_ERR(new_page));
                goto out_release_old;
        }
 
@@ -3677,12 +3676,13 @@ int huge_add_to_page_cache(struct page *page, struct address_space *mapping,
        return 0;
 }
 
-static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
-                          struct address_space *mapping, pgoff_t idx,
-                          unsigned long address, pte_t *ptep, unsigned int flags)
+static vm_fault_t hugetlb_no_page(struct mm_struct *mm,
+                       struct vm_area_struct *vma,
+                       struct address_space *mapping, pgoff_t idx,
+                       unsigned long address, pte_t *ptep, unsigned int flags)
 {
        struct hstate *h = hstate_vma(vma);
-       int ret = VM_FAULT_SIGBUS;
+       vm_fault_t ret = VM_FAULT_SIGBUS;
        int anon_rmap = 0;
        unsigned long size;
        struct page *page;
@@ -3745,11 +3745,7 @@ retry:
 
                page = alloc_huge_page(vma, haddr, 0);
                if (IS_ERR(page)) {
-                       ret = PTR_ERR(page);
-                       if (ret == -ENOMEM)
-                               ret = VM_FAULT_OOM;
-                       else
-                               ret = VM_FAULT_SIGBUS;
+                       ret = vmf_error(PTR_ERR(page));
                        goto out;
                }
                clear_huge_page(page, address, pages_per_huge_page(h));
@@ -3873,12 +3869,12 @@ u32 hugetlb_fault_mutex_hash(struct hstate *h, struct mm_struct *mm,
 }
 #endif
 
-int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+vm_fault_t hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
                        unsigned long address, unsigned int flags)
 {
        pte_t *ptep, entry;
        spinlock_t *ptl;
-       int ret;
+       vm_fault_t ret;
        u32 hash;
        pgoff_t idx;
        struct page *page = NULL;
@@ -4208,7 +4204,7 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
                if (absent || is_swap_pte(huge_ptep_get(pte)) ||
                    ((flags & FOLL_WRITE) &&
                      !huge_pte_write(huge_ptep_get(pte)))) {
-                       int ret;
+                       vm_fault_t ret;
                        unsigned int fault_flags = 0;
 
                        if (pte)
index 9e3654d70289895e67f6aff18734c165ed1d0e58..87256ae1bef86f58ea2b241f1bff5b171e06d920 100644 (file)
@@ -38,7 +38,7 @@
 
 void page_writeback_init(void);
 
-int do_swap_page(struct vm_fault *vmf);
+vm_fault_t do_swap_page(struct vm_fault *vmf);
 
 void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
                unsigned long floor, unsigned long ceiling);
@@ -389,18 +389,6 @@ static inline struct page *mem_map_next(struct page *iter,
        return iter + 1;
 }
 
-/*
- * FLATMEM and DISCONTIGMEM configurations use alloc_bootmem_node,
- * so all functions starting at paging_init should be marked __init
- * in those cases. SPARSEMEM, however, allows for memory hotplug,
- * and alloc_bootmem_node is not used.
- */
-#ifdef CONFIG_SPARSEMEM
-#define __paginginit __meminit
-#else
-#define __paginginit __init
-#endif
-
 /* Memory initialisation debug and verification */
 enum mminit_level {
        MMINIT_WARNING,
index 961cbe9062a5c3c8b51d9ded20b3bc0481efe4dd..a31d740e6cd1a7e95631b8bee3ee29915c697214 100644 (file)
@@ -880,7 +880,8 @@ static bool __collapse_huge_page_swapin(struct mm_struct *mm,
                                        unsigned long address, pmd_t *pmd,
                                        int referenced)
 {
-       int swapped_in = 0, ret = 0;
+       int swapped_in = 0;
+       vm_fault_t ret = 0;
        struct vm_fault vmf = {
                .vma = vma,
                .address = address,
index 9a085d525bbce1bd4aabb4599236d2874c964850..17dd883198aeab0dccebe762a6b432dad2f14c9d 100644 (file)
@@ -2097,6 +2097,11 @@ static int __init kmemleak_late_init(void)
 
        kmemleak_initialized = 1;
 
+       dentry = debugfs_create_file("kmemleak", 0644, NULL, NULL,
+                                    &kmemleak_fops);
+       if (!dentry)
+               pr_warn("Failed to create the debugfs kmemleak file\n");
+
        if (kmemleak_error) {
                /*
                 * Some error occurred and kmemleak was disabled. There is a
@@ -2108,10 +2113,6 @@ static int __init kmemleak_late_init(void)
                return -ENOMEM;
        }
 
-       dentry = debugfs_create_file("kmemleak", 0644, NULL, NULL,
-                                    &kmemleak_fops);
-       if (!dentry)
-               pr_warn("Failed to create the debugfs kmemleak file\n");
        mutex_lock(&scan_mutex);
        start_scan_thread();
        mutex_unlock(&scan_mutex);
index 2621be57bd957caabd5df559d41f2c40e284a26d..5b0894b45ee57257f34bde6072ae63a26c1714e6 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -652,9 +652,9 @@ static void remove_node_from_stable_tree(struct stable_node *stable_node)
         * list_head to stay clear from the rb_parent_color union
         * (aligned and different than any node) and also different
         * from &migrate_nodes. This will verify that future list.h changes
-        * don't break STABLE_NODE_DUP_HEAD.
+        * don't break STABLE_NODE_DUP_HEAD. Only recent gcc can handle it.
         */
-#if GCC_VERSION >= 40903 /* only recent gcc can handle it */
+#if defined(GCC_VERSION) && GCC_VERSION >= 40903
        BUILD_BUG_ON(STABLE_NODE_DUP_HEAD <= &migrate_nodes);
        BUILD_BUG_ON(STABLE_NODE_DUP_HEAD >= &migrate_nodes + 1);
 #endif
@@ -703,7 +703,7 @@ again:
         * We cannot do anything with the page while its refcount is 0.
         * Usually 0 means free, or tail of a higher-order page: in which
         * case this node is no longer referenced, and should be freed;
-        * however, it might mean that the page is under page_freeze_refs().
+        * however, it might mean that the page is under page_ref_freeze().
         * The __remove_mapping() case is easy, again the node is now stale;
         * but if page is swapcache in migrate_page_move_mapping(), it might
         * still be our page, in which case it's essential to keep the node.
@@ -714,7 +714,7 @@ again:
                 * work here too.  We have chosen the !PageSwapCache test to
                 * optimize the common case, when the page is or is about to
                 * be freed: PageSwapCache is cleared (under spin_lock_irq)
-                * in the freeze_refs section of __remove_mapping(); but Anon
+                * in the ref_freeze section of __remove_mapping(); but Anon
                 * page->mapping reset to NULL later, in free_pages_prepare().
                 */
                if (!PageSwapCache(page))
index 4d3c922ea1a1cb7558e1b69a3e32000833442489..972a9eaa898b6ad889a4647ed207ad82bd5d0f4b 100644 (file)
@@ -631,11 +631,13 @@ static int madvise_inject_error(int behavior,
 
 
        for (; start < end; start += PAGE_SIZE << order) {
+               unsigned long pfn;
                int ret;
 
                ret = get_user_pages_fast(start, 1, 0, &page);
                if (ret != 1)
                        return ret;
+               pfn = page_to_pfn(page);
 
                /*
                 * When soft offlining hugepages, after migrating the page
@@ -651,17 +653,25 @@ static int madvise_inject_error(int behavior,
 
                if (behavior == MADV_SOFT_OFFLINE) {
                        pr_info("Soft offlining pfn %#lx at process virtual address %#lx\n",
-                                               page_to_pfn(page), start);
+                                       pfn, start);
 
                        ret = soft_offline_page(page, MF_COUNT_INCREASED);
                        if (ret)
                                return ret;
                        continue;
                }
+
                pr_info("Injecting memory failure for pfn %#lx at process virtual address %#lx\n",
-                                               page_to_pfn(page), start);
+                               pfn, start);
 
-               ret = memory_failure(page_to_pfn(page), MF_COUNT_INCREASED);
+               /*
+                * Drop the page reference taken by get_user_pages_fast(). In
+                * the absence of MF_COUNT_INCREASED the memory_failure()
+                * routine is responsible for pinning the page to prevent it
+                * from being released back to the page allocator.
+                */
+               put_page(page);
+               ret = memory_failure(pfn, 0);
                if (ret)
                        return ret;
        }
index 6a921890739f7e1c0acad44d5916c5f43487a2a1..e79cb59552d9b0076a2c9cbfec3af9ebfa5c06e2 100644 (file)
@@ -1701,8 +1701,6 @@ static enum oom_status mem_cgroup_oom(struct mem_cgroup *memcg, gfp_t mask, int
        if (mem_cgroup_out_of_memory(memcg, mask, order))
                return OOM_SUCCESS;
 
-       WARN(1,"Memory cgroup charge failed because of no reclaimable memory! "
-               "This looks like a misconfiguration or a kernel bug.");
        return OOM_FAILED;
 }
 
@@ -1776,6 +1774,62 @@ cleanup:
        return true;
 }
 
+/**
+ * mem_cgroup_get_oom_group - get a memory cgroup to clean up after OOM
+ * @victim: task to be killed by the OOM killer
+ * @oom_domain: memcg in case of memcg OOM, NULL in case of system-wide OOM
+ *
+ * Returns a pointer to a memory cgroup, which has to be cleaned up
+ * by killing all belonging OOM-killable tasks.
+ *
+ * Caller has to call mem_cgroup_put() on the returned non-NULL memcg.
+ */
+struct mem_cgroup *mem_cgroup_get_oom_group(struct task_struct *victim,
+                                           struct mem_cgroup *oom_domain)
+{
+       struct mem_cgroup *oom_group = NULL;
+       struct mem_cgroup *memcg;
+
+       if (!cgroup_subsys_on_dfl(memory_cgrp_subsys))
+               return NULL;
+
+       if (!oom_domain)
+               oom_domain = root_mem_cgroup;
+
+       rcu_read_lock();
+
+       memcg = mem_cgroup_from_task(victim);
+       if (memcg == root_mem_cgroup)
+               goto out;
+
+       /*
+        * Traverse the memory cgroup hierarchy from the victim task's
+        * cgroup up to the OOMing cgroup (or root) to find the
+        * highest-level memory cgroup with oom.group set.
+        */
+       for (; memcg; memcg = parent_mem_cgroup(memcg)) {
+               if (memcg->oom_group)
+                       oom_group = memcg;
+
+               if (memcg == oom_domain)
+                       break;
+       }
+
+       if (oom_group)
+               css_get(&oom_group->css);
+out:
+       rcu_read_unlock();
+
+       return oom_group;
+}
+
+void mem_cgroup_print_oom_group(struct mem_cgroup *memcg)
+{
+       pr_info("Tasks in ");
+       pr_cont_cgroup_path(memcg->css.cgroup);
+       pr_cont(" are going to be killed due to memory.oom.group set\n");
+}
+
 /**
  * lock_page_memcg - lock a page->mem_cgroup binding
  * @page: the page
@@ -2899,29 +2953,34 @@ static int mem_cgroup_hierarchy_write(struct cgroup_subsys_state *css,
        return retval;
 }
 
-static void tree_stat(struct mem_cgroup *memcg, unsigned long *stat)
-{
-       struct mem_cgroup *iter;
-       int i;
-
-       memset(stat, 0, sizeof(*stat) * MEMCG_NR_STAT);
-
-       for_each_mem_cgroup_tree(iter, memcg) {
-               for (i = 0; i < MEMCG_NR_STAT; i++)
-                       stat[i] += memcg_page_state(iter, i);
-       }
-}
+struct accumulated_stats {
+       unsigned long stat[MEMCG_NR_STAT];
+       unsigned long events[NR_VM_EVENT_ITEMS];
+       unsigned long lru_pages[NR_LRU_LISTS];
+       const unsigned int *stats_array;
+       const unsigned int *events_array;
+       int stats_size;
+       int events_size;
+};
 
-static void tree_events(struct mem_cgroup *memcg, unsigned long *events)
+static void accumulate_memcg_tree(struct mem_cgroup *memcg,
+                                 struct accumulated_stats *acc)
 {
-       struct mem_cgroup *iter;
+       struct mem_cgroup *mi;
        int i;
 
-       memset(events, 0, sizeof(*events) * NR_VM_EVENT_ITEMS);
+       for_each_mem_cgroup_tree(mi, memcg) {
+               for (i = 0; i < acc->stats_size; i++)
+                       acc->stat[i] += memcg_page_state(mi,
+                               acc->stats_array ? acc->stats_array[i] : i);
 
-       for_each_mem_cgroup_tree(iter, memcg) {
-               for (i = 0; i < NR_VM_EVENT_ITEMS; i++)
-                       events[i] += memcg_sum_events(iter, i);
+               for (i = 0; i < acc->events_size; i++)
+                       acc->events[i] += memcg_sum_events(mi,
+                               acc->events_array ? acc->events_array[i] : i);
+
+               for (i = 0; i < NR_LRU_LISTS; i++)
+                       acc->lru_pages[i] +=
+                               mem_cgroup_nr_lru_pages(mi, BIT(i));
        }
 }
 
@@ -3332,6 +3391,7 @@ static int memcg_stat_show(struct seq_file *m, void *v)
        unsigned long memory, memsw;
        struct mem_cgroup *mi;
        unsigned int i;
+       struct accumulated_stats acc;
 
        BUILD_BUG_ON(ARRAY_SIZE(memcg1_stat_names) != ARRAY_SIZE(memcg1_stats));
        BUILD_BUG_ON(ARRAY_SIZE(mem_cgroup_lru_names) != NR_LRU_LISTS);
@@ -3364,32 +3424,27 @@ static int memcg_stat_show(struct seq_file *m, void *v)
                seq_printf(m, "hierarchical_memsw_limit %llu\n",
                           (u64)memsw * PAGE_SIZE);
 
-       for (i = 0; i < ARRAY_SIZE(memcg1_stats); i++) {
-               unsigned long long val = 0;
+       memset(&acc, 0, sizeof(acc));
+       acc.stats_size = ARRAY_SIZE(memcg1_stats);
+       acc.stats_array = memcg1_stats;
+       acc.events_size = ARRAY_SIZE(memcg1_events);
+       acc.events_array = memcg1_events;
+       accumulate_memcg_tree(memcg, &acc);
 
+       for (i = 0; i < ARRAY_SIZE(memcg1_stats); i++) {
                if (memcg1_stats[i] == MEMCG_SWAP && !do_memsw_account())
                        continue;
-               for_each_mem_cgroup_tree(mi, memcg)
-                       val += memcg_page_state(mi, memcg1_stats[i]) *
-                       PAGE_SIZE;
-               seq_printf(m, "total_%s %llu\n", memcg1_stat_names[i], val);
+               seq_printf(m, "total_%s %llu\n", memcg1_stat_names[i],
+                          (u64)acc.stat[i] * PAGE_SIZE);
        }
 
-       for (i = 0; i < ARRAY_SIZE(memcg1_events); i++) {
-               unsigned long long val = 0;
-
-               for_each_mem_cgroup_tree(mi, memcg)
-                       val += memcg_sum_events(mi, memcg1_events[i]);
-               seq_printf(m, "total_%s %llu\n", memcg1_event_names[i], val);
-       }
-
-       for (i = 0; i < NR_LRU_LISTS; i++) {
-               unsigned long long val = 0;
+       for (i = 0; i < ARRAY_SIZE(memcg1_events); i++)
+               seq_printf(m, "total_%s %llu\n", memcg1_event_names[i],
+                          (u64)acc.events[i]);
 
-               for_each_mem_cgroup_tree(mi, memcg)
-                       val += mem_cgroup_nr_lru_pages(mi, BIT(i)) * PAGE_SIZE;
-               seq_printf(m, "total_%s %llu\n", mem_cgroup_lru_names[i], val);
-       }
+       for (i = 0; i < NR_LRU_LISTS; i++)
+               seq_printf(m, "total_%s %llu\n", mem_cgroup_lru_names[i],
+                          (u64)acc.lru_pages[i] * PAGE_SIZE);
 
 #ifdef CONFIG_DEBUG_VM
        {
@@ -5486,8 +5541,7 @@ static int memory_events_show(struct seq_file *m, void *v)
 static int memory_stat_show(struct seq_file *m, void *v)
 {
        struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
-       unsigned long stat[MEMCG_NR_STAT];
-       unsigned long events[NR_VM_EVENT_ITEMS];
+       struct accumulated_stats acc;
        int i;
 
        /*
@@ -5501,70 +5555,97 @@ static int memory_stat_show(struct seq_file *m, void *v)
         * Current memory state:
         */
 
-       tree_stat(memcg, stat);
-       tree_events(memcg, events);
+       memset(&acc, 0, sizeof(acc));
+       acc.stats_size = MEMCG_NR_STAT;
+       acc.events_size = NR_VM_EVENT_ITEMS;
+       accumulate_memcg_tree(memcg, &acc);
 
        seq_printf(m, "anon %llu\n",
-                  (u64)stat[MEMCG_RSS] * PAGE_SIZE);
+                  (u64)acc.stat[MEMCG_RSS] * PAGE_SIZE);
        seq_printf(m, "file %llu\n",
-                  (u64)stat[MEMCG_CACHE] * PAGE_SIZE);
+                  (u64)acc.stat[MEMCG_CACHE] * PAGE_SIZE);
        seq_printf(m, "kernel_stack %llu\n",
-                  (u64)stat[MEMCG_KERNEL_STACK_KB] * 1024);
+                  (u64)acc.stat[MEMCG_KERNEL_STACK_KB] * 1024);
        seq_printf(m, "slab %llu\n",
-                  (u64)(stat[NR_SLAB_RECLAIMABLE] +
-                        stat[NR_SLAB_UNRECLAIMABLE]) * PAGE_SIZE);
+                  (u64)(acc.stat[NR_SLAB_RECLAIMABLE] +
+                        acc.stat[NR_SLAB_UNRECLAIMABLE]) * PAGE_SIZE);
        seq_printf(m, "sock %llu\n",
-                  (u64)stat[MEMCG_SOCK] * PAGE_SIZE);
+                  (u64)acc.stat[MEMCG_SOCK] * PAGE_SIZE);
 
        seq_printf(m, "shmem %llu\n",
-                  (u64)stat[NR_SHMEM] * PAGE_SIZE);
+                  (u64)acc.stat[NR_SHMEM] * PAGE_SIZE);
        seq_printf(m, "file_mapped %llu\n",
-                  (u64)stat[NR_FILE_MAPPED] * PAGE_SIZE);
+                  (u64)acc.stat[NR_FILE_MAPPED] * PAGE_SIZE);
        seq_printf(m, "file_dirty %llu\n",
-                  (u64)stat[NR_FILE_DIRTY] * PAGE_SIZE);
+                  (u64)acc.stat[NR_FILE_DIRTY] * PAGE_SIZE);
        seq_printf(m, "file_writeback %llu\n",
-                  (u64)stat[NR_WRITEBACK] * PAGE_SIZE);
-
-       for (i = 0; i < NR_LRU_LISTS; i++) {
-               struct mem_cgroup *mi;
-               unsigned long val = 0;
+                  (u64)acc.stat[NR_WRITEBACK] * PAGE_SIZE);
 
-               for_each_mem_cgroup_tree(mi, memcg)
-                       val += mem_cgroup_nr_lru_pages(mi, BIT(i));
-               seq_printf(m, "%s %llu\n",
-                          mem_cgroup_lru_names[i], (u64)val * PAGE_SIZE);
-       }
+       for (i = 0; i < NR_LRU_LISTS; i++)
+               seq_printf(m, "%s %llu\n", mem_cgroup_lru_names[i],
+                          (u64)acc.lru_pages[i] * PAGE_SIZE);
 
        seq_printf(m, "slab_reclaimable %llu\n",
-                  (u64)stat[NR_SLAB_RECLAIMABLE] * PAGE_SIZE);
+                  (u64)acc.stat[NR_SLAB_RECLAIMABLE] * PAGE_SIZE);
        seq_printf(m, "slab_unreclaimable %llu\n",
-                  (u64)stat[NR_SLAB_UNRECLAIMABLE] * PAGE_SIZE);
+                  (u64)acc.stat[NR_SLAB_UNRECLAIMABLE] * PAGE_SIZE);
 
        /* Accumulated memory events */
 
-       seq_printf(m, "pgfault %lu\n", events[PGFAULT]);
-       seq_printf(m, "pgmajfault %lu\n", events[PGMAJFAULT]);
+       seq_printf(m, "pgfault %lu\n", acc.events[PGFAULT]);
+       seq_printf(m, "pgmajfault %lu\n", acc.events[PGMAJFAULT]);
 
-       seq_printf(m, "pgrefill %lu\n", events[PGREFILL]);
-       seq_printf(m, "pgscan %lu\n", events[PGSCAN_KSWAPD] +
-                  events[PGSCAN_DIRECT]);
-       seq_printf(m, "pgsteal %lu\n", events[PGSTEAL_KSWAPD] +
-                  events[PGSTEAL_DIRECT]);
-       seq_printf(m, "pgactivate %lu\n", events[PGACTIVATE]);
-       seq_printf(m, "pgdeactivate %lu\n", events[PGDEACTIVATE]);
-       seq_printf(m, "pglazyfree %lu\n", events[PGLAZYFREE]);
-       seq_printf(m, "pglazyfreed %lu\n", events[PGLAZYFREED]);
+       seq_printf(m, "pgrefill %lu\n", acc.events[PGREFILL]);
+       seq_printf(m, "pgscan %lu\n", acc.events[PGSCAN_KSWAPD] +
+                  acc.events[PGSCAN_DIRECT]);
+       seq_printf(m, "pgsteal %lu\n", acc.events[PGSTEAL_KSWAPD] +
+                  acc.events[PGSTEAL_DIRECT]);
+       seq_printf(m, "pgactivate %lu\n", acc.events[PGACTIVATE]);
+       seq_printf(m, "pgdeactivate %lu\n", acc.events[PGDEACTIVATE]);
+       seq_printf(m, "pglazyfree %lu\n", acc.events[PGLAZYFREE]);
+       seq_printf(m, "pglazyfreed %lu\n", acc.events[PGLAZYFREED]);
 
        seq_printf(m, "workingset_refault %lu\n",
-                  stat[WORKINGSET_REFAULT]);
+                  acc.stat[WORKINGSET_REFAULT]);
        seq_printf(m, "workingset_activate %lu\n",
-                  stat[WORKINGSET_ACTIVATE]);
+                  acc.stat[WORKINGSET_ACTIVATE]);
        seq_printf(m, "workingset_nodereclaim %lu\n",
-                  stat[WORKINGSET_NODERECLAIM]);
+                  acc.stat[WORKINGSET_NODERECLAIM]);
+
+       return 0;
+}
+
+static int memory_oom_group_show(struct seq_file *m, void *v)
+{
+       struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
+
+       seq_printf(m, "%d\n", memcg->oom_group);
 
        return 0;
 }
 
+static ssize_t memory_oom_group_write(struct kernfs_open_file *of,
+                                     char *buf, size_t nbytes, loff_t off)
+{
+       struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of));
+       int ret, oom_group;
+
+       buf = strstrip(buf);
+       if (!buf)
+               return -EINVAL;
+
+       ret = kstrtoint(buf, 0, &oom_group);
+       if (ret)
+               return ret;
+
+       if (oom_group != 0 && oom_group != 1)
+               return -EINVAL;
+
+       memcg->oom_group = oom_group;
+
+       return nbytes;
+}
+
 static struct cftype memory_files[] = {
        {
                .name = "current",
@@ -5606,6 +5687,12 @@ static struct cftype memory_files[] = {
                .flags = CFTYPE_NOT_ON_ROOT,
                .seq_show = memory_stat_show,
        },
+       {
+               .name = "oom.group",
+               .flags = CFTYPE_NOT_ON_ROOT | CFTYPE_NS_DELEGATABLE,
+               .seq_show = memory_oom_group_show,
+               .write = memory_oom_group_write,
+       },
        { }     /* terminate */
 };
 
index 9d142b9b86dcd970d46a2b8124f065bd5eb29391..0cd3de3550f0830f507d286b0499789d7961171e 100644 (file)
 #include <linux/hugetlb.h>
 #include <linux/memory_hotplug.h>
 #include <linux/mm_inline.h>
+#include <linux/memremap.h>
 #include <linux/kfifo.h>
 #include <linux/ratelimit.h>
+#include <linux/page-isolation.h>
 #include "internal.h"
 #include "ras/ras_event.h"
 
@@ -173,23 +175,52 @@ int hwpoison_filter(struct page *p)
 
 EXPORT_SYMBOL_GPL(hwpoison_filter);
 
+/*
+ * Kill all processes that have a poisoned page mapped and then isolate
+ * the page.
+ *
+ * General strategy:
+ * Find all processes having the page mapped and kill them.
+ * But we keep a page reference around so that the page is not
+ * actually freed yet.
+ * Then stash the page away
+ *
+ * There's no convenient way to get back to mapped processes
+ * from the VMAs. So do a brute-force search over all
+ * running processes.
+ *
+ * Remember that machine checks are not common (or rather
+ * if they are common you have other problems), so this shouldn't
+ * be a performance issue.
+ *
+ * Also there are some races possible while we get from the
+ * error detection to actually handle it.
+ */
+
+struct to_kill {
+       struct list_head nd;
+       struct task_struct *tsk;
+       unsigned long addr;
+       short size_shift;
+       char addr_valid;
+};
+
 /*
  * Send all the processes who have the page mapped a signal.
  * ``action optional'' if they are not immediately affected by the error
  * ``action required'' if error happened in current execution context
  */
-static int kill_proc(struct task_struct *t, unsigned long addr,
-                       unsigned long pfn, struct page *page, int flags)
+static int kill_proc(struct to_kill *tk, unsigned long pfn, int flags)
 {
-       short addr_lsb;
+       struct task_struct *t = tk->tsk;
+       short addr_lsb = tk->size_shift;
        int ret;
 
        pr_err("Memory failure: %#lx: Killing %s:%d due to hardware memory corruption\n",
                pfn, t->comm, t->pid);
-       addr_lsb = compound_order(compound_head(page)) + PAGE_SHIFT;
 
        if ((flags & MF_ACTION_REQUIRED) && t->mm == current->mm) {
-               ret = force_sig_mceerr(BUS_MCEERR_AR, (void __user *)addr,
+               ret = force_sig_mceerr(BUS_MCEERR_AR, (void __user *)tk->addr,
                                       addr_lsb, current);
        } else {
                /*
@@ -198,7 +229,7 @@ static int kill_proc(struct task_struct *t, unsigned long addr,
                 * This could cause a loop when the user sets SIGBUS
                 * to SIG_IGN, but hopefully no one will do that?
                 */
-               ret = send_sig_mceerr(BUS_MCEERR_AO, (void __user *)addr,
+               ret = send_sig_mceerr(BUS_MCEERR_AO, (void __user *)tk->addr,
                                      addr_lsb, t);  /* synchronous? */
        }
        if (ret < 0)
@@ -234,34 +265,39 @@ void shake_page(struct page *p, int access)
 }
 EXPORT_SYMBOL_GPL(shake_page);
 
-/*
- * Kill all processes that have a poisoned page mapped and then isolate
- * the page.
- *
- * General strategy:
- * Find all processes having the page mapped and kill them.
- * But we keep a page reference around so that the page is not
- * actually freed yet.
- * Then stash the page away
- *
- * There's no convenient way to get back to mapped processes
- * from the VMAs. So do a brute-force search over all
- * running processes.
- *
- * Remember that machine checks are not common (or rather
- * if they are common you have other problems), so this shouldn't
- * be a performance issue.
- *
- * Also there are some races possible while we get from the
- * error detection to actually handle it.
- */
-
-struct to_kill {
-       struct list_head nd;
-       struct task_struct *tsk;
-       unsigned long addr;
-       char addr_valid;
-};
+static unsigned long dev_pagemap_mapping_shift(struct page *page,
+               struct vm_area_struct *vma)
+{
+       unsigned long address = vma_address(page, vma);
+       pgd_t *pgd;
+       p4d_t *p4d;
+       pud_t *pud;
+       pmd_t *pmd;
+       pte_t *pte;
+
+       pgd = pgd_offset(vma->vm_mm, address);
+       if (!pgd_present(*pgd))
+               return 0;
+       p4d = p4d_offset(pgd, address);
+       if (!p4d_present(*p4d))
+               return 0;
+       pud = pud_offset(p4d, address);
+       if (!pud_present(*pud))
+               return 0;
+       if (pud_devmap(*pud))
+               return PUD_SHIFT;
+       pmd = pmd_offset(pud, address);
+       if (!pmd_present(*pmd))
+               return 0;
+       if (pmd_devmap(*pmd))
+               return PMD_SHIFT;
+       pte = pte_offset_map(pmd, address);
+       if (!pte_present(*pte))
+               return 0;
+       if (pte_devmap(*pte))
+               return PAGE_SHIFT;
+       return 0;
+}
 
 /*
  * Failure handling: if we can't find or can't kill a process there's
@@ -292,6 +328,10 @@ static void add_to_kill(struct task_struct *tsk, struct page *p,
        }
        tk->addr = page_address_in_vma(p, vma);
        tk->addr_valid = 1;
+       if (is_zone_device_page(p))
+               tk->size_shift = dev_pagemap_mapping_shift(p, vma);
+       else
+               tk->size_shift = compound_order(compound_head(p)) + PAGE_SHIFT;
 
        /*
         * In theory we don't have to kill when the page was
@@ -299,7 +339,7 @@ static void add_to_kill(struct task_struct *tsk, struct page *p,
         * likely very rare kill anyways just out of paranoia, but use
         * a SIGKILL because the error is not contained anymore.
         */
-       if (tk->addr == -EFAULT) {
+       if (tk->addr == -EFAULT || tk->size_shift == 0) {
                pr_info("Memory failure: Unable to find user space address %lx in %s\n",
                        page_to_pfn(p), tsk->comm);
                tk->addr_valid = 0;
@@ -317,9 +357,8 @@ static void add_to_kill(struct task_struct *tsk, struct page *p,
  * Also when FAIL is set do a force kill because something went
  * wrong earlier.
  */
-static void kill_procs(struct list_head *to_kill, int forcekill,
-                         bool fail, struct page *page, unsigned long pfn,
-                         int flags)
+static void kill_procs(struct list_head *to_kill, int forcekill, bool fail,
+               unsigned long pfn, int flags)
 {
        struct to_kill *tk, *next;
 
@@ -342,8 +381,7 @@ static void kill_procs(struct list_head *to_kill, int forcekill,
                         * check for that, but we need to tell the
                         * process anyways.
                         */
-                       else if (kill_proc(tk->tsk, tk->addr,
-                                             pfn, page, flags) < 0)
+                       else if (kill_proc(tk, pfn, flags) < 0)
                                pr_err("Memory failure: %#lx: Cannot send advisory machine check signal to %s:%d\n",
                                       pfn, tk->tsk->comm, tk->tsk->pid);
                }
@@ -515,6 +553,7 @@ static const char * const action_page_types[] = {
        [MF_MSG_TRUNCATED_LRU]          = "already truncated LRU page",
        [MF_MSG_BUDDY]                  = "free buddy page",
        [MF_MSG_BUDDY_2ND]              = "free buddy page (2nd try)",
+       [MF_MSG_DAX]                    = "dax page",
        [MF_MSG_UNKNOWN]                = "unknown page",
 };
 
@@ -1012,7 +1051,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
         * any accesses to the poisoned memory.
         */
        forcekill = PageDirty(hpage) || (flags & MF_MUST_KILL);
-       kill_procs(&tokill, forcekill, !unmap_success, p, pfn, flags);
+       kill_procs(&tokill, forcekill, !unmap_success, pfn, flags);
 
        return unmap_success;
 }
@@ -1112,6 +1151,83 @@ out:
        return res;
 }
 
+static int memory_failure_dev_pagemap(unsigned long pfn, int flags,
+               struct dev_pagemap *pgmap)
+{
+       struct page *page = pfn_to_page(pfn);
+       const bool unmap_success = true;
+       unsigned long size = 0;
+       struct to_kill *tk;
+       LIST_HEAD(tokill);
+       int rc = -EBUSY;
+       loff_t start;
+
+       /*
+        * Prevent the inode from being freed while we are interrogating
+        * the address_space, typically this would be handled by
+        * lock_page(), but dax pages do not use the page lock. This
+        * also prevents changes to the mapping of this pfn until
+        * poison signaling is complete.
+        */
+       if (!dax_lock_mapping_entry(page))
+               goto out;
+
+       if (hwpoison_filter(page)) {
+               rc = 0;
+               goto unlock;
+       }
+
+       switch (pgmap->type) {
+       case MEMORY_DEVICE_PRIVATE:
+       case MEMORY_DEVICE_PUBLIC:
+               /*
+                * TODO: Handle HMM pages which may need coordination
+                * with device-side memory.
+                */
+               goto unlock;
+       default:
+               break;
+       }
+
+       /*
+        * Use this flag as an indication that the dax page has been
+        * remapped UC to prevent speculative consumption of poison.
+        */
+       SetPageHWPoison(page);
+
+       /*
+        * Unlike System-RAM there is no possibility to swap in a
+        * different physical page at a given virtual address, so all
+        * userspace consumption of ZONE_DEVICE memory necessitates
+        * SIGBUS (i.e. MF_MUST_KILL)
+        */
+       flags |= MF_ACTION_REQUIRED | MF_MUST_KILL;
+       collect_procs(page, &tokill, flags & MF_ACTION_REQUIRED);
+
+       list_for_each_entry(tk, &tokill, nd)
+               if (tk->size_shift)
+                       size = max(size, 1UL << tk->size_shift);
+       if (size) {
+               /*
+                * Unmap the largest mapping to avoid breaking up
+                * device-dax mappings which are constant size. The
+                * actual size of the mapping being torn down is
+                * communicated in siginfo, see kill_proc()
+                */
+               start = (page->index << PAGE_SHIFT) & ~(size - 1);
+               unmap_mapping_range(page->mapping, start, start + size, 0);
+       }
+       kill_procs(&tokill, flags & MF_MUST_KILL, !unmap_success, pfn, flags);
+       rc = 0;
+unlock:
+       dax_unlock_mapping_entry(page);
+out:
+       /* drop pgmap ref acquired in caller */
+       put_dev_pagemap(pgmap);
+       action_result(pfn, MF_MSG_DAX, rc ? MF_FAILED : MF_RECOVERED);
+       return rc;
+}
+
 /**
  * memory_failure - Handle memory failure of a page.
  * @pfn: Page Number of the corrupted page
@@ -1134,6 +1250,7 @@ int memory_failure(unsigned long pfn, int flags)
        struct page *p;
        struct page *hpage;
        struct page *orig_head;
+       struct dev_pagemap *pgmap;
        int res;
        unsigned long page_flags;
 
@@ -1146,6 +1263,10 @@ int memory_failure(unsigned long pfn, int flags)
                return -ENXIO;
        }
 
+       pgmap = get_dev_pagemap(pfn, NULL);
+       if (pgmap)
+               return memory_failure_dev_pagemap(pfn, flags, pgmap);
+
        p = pfn_to_page(pfn);
        if (PageHuge(p))
                return memory_failure_hugetlb(pfn, flags);
@@ -1167,7 +1288,7 @@ int memory_failure(unsigned long pfn, int flags)
         *    R/W the page; let's pray that the page has been
         *    used and will be freed some time later.
         * In fact it's dangerous to directly bump up page count from 0,
-        * that may make page_freeze_refs()/page_unfreeze_refs() mismatch.
+        * that may make page_ref_freeze()/page_ref_unfreeze() mismatch.
         */
        if (!(flags & MF_COUNT_INCREASED) && !get_hwpoison_page(p)) {
                if (is_free_buddy_page(p)) {
@@ -1598,8 +1719,18 @@ static int soft_offline_huge_page(struct page *page, int flags)
                if (ret > 0)
                        ret = -EIO;
        } else {
-               if (PageHuge(page))
-                       dissolve_free_huge_page(page);
+               /*
+                * We set PG_hwpoison only when the migration source hugepage
+                * was successfully dissolved, because otherwise hwpoisoned
+                * hugepage remains on free hugepage list, then userspace will
+                * find it as SIGBUS by allocation failure. That's not expected
+                * in soft-offlining.
+                */
+               ret = dissolve_free_huge_page(page);
+               if (!ret) {
+                       if (set_hwpoison_free_buddy_page(page))
+                               num_poisoned_pages_inc();
+               }
        }
        return ret;
 }
@@ -1687,6 +1818,7 @@ static int __soft_offline_page(struct page *page, int flags)
 static int soft_offline_in_use_page(struct page *page, int flags)
 {
        int ret;
+       int mt;
        struct page *hpage = compound_head(page);
 
        if (!PageHuge(page) && PageTransHuge(hpage)) {
@@ -1705,23 +1837,37 @@ static int soft_offline_in_use_page(struct page *page, int flags)
                put_hwpoison_page(hpage);
        }
 
+       /*
+        * Setting MIGRATE_ISOLATE here ensures that the page will be linked
+        * to free list immediately (not via pcplist) when released after
+        * successful page migration. Otherwise we can't guarantee that the
+        * page is really free after put_page() returns, so
+        * set_hwpoison_free_buddy_page() highly likely fails.
+        */
+       mt = get_pageblock_migratetype(page);
+       set_pageblock_migratetype(page, MIGRATE_ISOLATE);
        if (PageHuge(page))
                ret = soft_offline_huge_page(page, flags);
        else
                ret = __soft_offline_page(page, flags);
-
+       set_pageblock_migratetype(page, mt);
        return ret;
 }
 
-static void soft_offline_free_page(struct page *page)
+static int soft_offline_free_page(struct page *page)
 {
+       int rc = 0;
        struct page *head = compound_head(page);
 
-       if (!TestSetPageHWPoison(head)) {
-               num_poisoned_pages_inc();
-               if (PageHuge(head))
-                       dissolve_free_huge_page(page);
+       if (PageHuge(head))
+               rc = dissolve_free_huge_page(page);
+       if (!rc) {
+               if (set_hwpoison_free_buddy_page(page))
+                       num_poisoned_pages_inc();
+               else
+                       rc = -EBUSY;
        }
+       return rc;
 }
 
 /**
@@ -1751,6 +1897,14 @@ int soft_offline_page(struct page *page, int flags)
        int ret;
        unsigned long pfn = page_to_pfn(page);
 
+       if (is_zone_device_page(page)) {
+               pr_debug_ratelimited("soft_offline: %#lx page is device page\n",
+                               pfn);
+               if (flags & MF_COUNT_INCREASED)
+                       put_page(page);
+               return -EIO;
+       }
+
        if (PageHWPoison(page)) {
                pr_info("soft offline: %#lx page already poisoned\n", pfn);
                if (flags & MF_COUNT_INCREASED)
@@ -1765,7 +1919,7 @@ int soft_offline_page(struct page *page, int flags)
        if (ret > 0)
                ret = soft_offline_in_use_page(page, flags);
        else if (ret == 0)
-               soft_offline_free_page(page);
+               ret = soft_offline_free_page(page);
 
        return ret;
 }
index 19f47d7b9b86795ed8b116cffceedd1bb625675d..c467102a5cbc5de5ab2ea4dff740f2611c1124a4 100644 (file)
@@ -238,23 +238,13 @@ void arch_tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
        __tlb_reset_range(tlb);
 }
 
-static void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb)
+static void tlb_flush_mmu_free(struct mmu_gather *tlb)
 {
-       if (!tlb->end)
-               return;
+       struct mmu_gather_batch *batch;
 
-       tlb_flush(tlb);
-       mmu_notifier_invalidate_range(tlb->mm, tlb->start, tlb->end);
 #ifdef CONFIG_HAVE_RCU_TABLE_FREE
        tlb_table_flush(tlb);
 #endif
-       __tlb_reset_range(tlb);
-}
-
-static void tlb_flush_mmu_free(struct mmu_gather *tlb)
-{
-       struct mmu_gather_batch *batch;
-
        for (batch = &tlb->local; batch && batch->nr; batch = batch->next) {
                free_pages_and_swap_cache(batch->pages, batch->nr);
                batch->nr = 0;
@@ -326,20 +316,31 @@ bool __tlb_remove_page_size(struct mmu_gather *tlb, struct page *page, int page_
 
 #ifdef CONFIG_HAVE_RCU_TABLE_FREE
 
-static void tlb_remove_table_smp_sync(void *arg)
+/*
+ * See the comment near struct mmu_table_batch.
+ */
+
+/*
+ * If we want tlb_remove_table() to imply TLB invalidates.
+ */
+static inline void tlb_table_invalidate(struct mmu_gather *tlb)
 {
-       struct mm_struct __maybe_unused *mm = arg;
+#ifdef CONFIG_HAVE_RCU_TABLE_INVALIDATE
        /*
-        * On most architectures this does nothing. Simply delivering the
-        * interrupt is enough to prevent races with software page table
-        * walking like that done in get_user_pages_fast.
-        *
-        * See the comment near struct mmu_table_batch.
+        * Invalidate page-table caches used by hardware walkers. Then we still
+        * need to RCU-sched wait while freeing the pages because software
+        * walkers can still be in-flight.
         */
-       tlb_flush_remove_tables_local(mm);
+       tlb_flush_mmu_tlbonly(tlb);
+#endif
 }
 
-static void tlb_remove_table_one(void *table, struct mmu_gather *tlb)
+static void tlb_remove_table_smp_sync(void *arg)
+{
+       /* Simply deliver the interrupt */
+}
+
+static void tlb_remove_table_one(void *table)
 {
        /*
         * This isn't an RCU grace period and hence the page-tables cannot be
@@ -348,7 +349,7 @@ static void tlb_remove_table_one(void *table, struct mmu_gather *tlb)
         * It is however sufficient for software page-table walkers that rely on
         * IRQ disabling. See the comment near struct mmu_table_batch.
         */
-       smp_call_function(tlb_remove_table_smp_sync, tlb->mm, 1);
+       smp_call_function(tlb_remove_table_smp_sync, NULL, 1);
        __tlb_remove_table(table);
 }
 
@@ -369,9 +370,8 @@ void tlb_table_flush(struct mmu_gather *tlb)
 {
        struct mmu_table_batch **batch = &tlb->batch;
 
-       tlb_flush_remove_tables(tlb->mm);
-
        if (*batch) {
+               tlb_table_invalidate(tlb);
                call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu);
                *batch = NULL;
        }
@@ -381,23 +381,16 @@ void tlb_remove_table(struct mmu_gather *tlb, void *table)
 {
        struct mmu_table_batch **batch = &tlb->batch;
 
-       /*
-        * When there's less then two users of this mm there cannot be a
-        * concurrent page-table walk.
-        */
-       if (atomic_read(&tlb->mm->mm_users) < 2) {
-               __tlb_remove_table(table);
-               return;
-       }
-
        if (*batch == NULL) {
                *batch = (struct mmu_table_batch *)__get_free_page(GFP_NOWAIT | __GFP_NOWARN);
                if (*batch == NULL) {
-                       tlb_remove_table_one(table, tlb);
+                       tlb_table_invalidate(tlb);
+                       tlb_remove_table_one(table);
                        return;
                }
                (*batch)->nr = 0;
        }
+
        (*batch)->tables[(*batch)->nr++] = table;
        if ((*batch)->nr == MAX_TABLE_BATCH)
                tlb_table_flush(tlb);
@@ -1029,7 +1022,7 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
         * If it's a COW mapping, write protect it both
         * in the parent and the child
         */
-       if (is_cow_mapping(vm_flags)) {
+       if (is_cow_mapping(vm_flags) && pte_write(pte)) {
                ptep_set_wrprotect(src_mm, addr, src_pte);
                pte = pte_wrprotect(pte);
        }
@@ -2384,9 +2377,9 @@ static gfp_t __get_fault_gfp_mask(struct vm_area_struct *vma)
  *
  * We do this without the lock held, so that it can sleep if it needs to.
  */
-static int do_page_mkwrite(struct vm_fault *vmf)
+static vm_fault_t do_page_mkwrite(struct vm_fault *vmf)
 {
-       int ret;
+       vm_fault_t ret;
        struct page *page = vmf->page;
        unsigned int old_flags = vmf->flags;
 
@@ -2490,7 +2483,7 @@ static inline void wp_page_reuse(struct vm_fault *vmf)
  *   held to the old page, as well as updating the rmap.
  * - In any case, unlock the PTL and drop the reference we took to the old page.
  */
-static int wp_page_copy(struct vm_fault *vmf)
+static vm_fault_t wp_page_copy(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
        struct mm_struct *mm = vma->vm_mm;
@@ -2638,7 +2631,7 @@ oom:
  * The function expects the page to be locked or other protection against
  * concurrent faults / writeback (such as DAX radix tree locks).
  */
-int finish_mkwrite_fault(struct vm_fault *vmf)
+vm_fault_t finish_mkwrite_fault(struct vm_fault *vmf)
 {
        WARN_ON_ONCE(!(vmf->vma->vm_flags & VM_SHARED));
        vmf->pte = pte_offset_map_lock(vmf->vma->vm_mm, vmf->pmd, vmf->address,
@@ -2659,12 +2652,12 @@ int finish_mkwrite_fault(struct vm_fault *vmf)
  * Handle write page faults for VM_MIXEDMAP or VM_PFNMAP for a VM_SHARED
  * mapping
  */
-static int wp_pfn_shared(struct vm_fault *vmf)
+static vm_fault_t wp_pfn_shared(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
 
        if (vma->vm_ops && vma->vm_ops->pfn_mkwrite) {
-               int ret;
+               vm_fault_t ret;
 
                pte_unmap_unlock(vmf->pte, vmf->ptl);
                vmf->flags |= FAULT_FLAG_MKWRITE;
@@ -2677,7 +2670,7 @@ static int wp_pfn_shared(struct vm_fault *vmf)
        return VM_FAULT_WRITE;
 }
 
-static int wp_page_shared(struct vm_fault *vmf)
+static vm_fault_t wp_page_shared(struct vm_fault *vmf)
        __releases(vmf->ptl)
 {
        struct vm_area_struct *vma = vmf->vma;
@@ -2685,7 +2678,7 @@ static int wp_page_shared(struct vm_fault *vmf)
        get_page(vmf->page);
 
        if (vma->vm_ops && vma->vm_ops->page_mkwrite) {
-               int tmp;
+               vm_fault_t tmp;
 
                pte_unmap_unlock(vmf->pte, vmf->ptl);
                tmp = do_page_mkwrite(vmf);
@@ -2728,7 +2721,7 @@ static int wp_page_shared(struct vm_fault *vmf)
  * but allow concurrent faults), with pte both mapped and locked.
  * We return with mmap_sem still held, but pte unmapped and unlocked.
  */
-static int do_wp_page(struct vm_fault *vmf)
+static vm_fault_t do_wp_page(struct vm_fault *vmf)
        __releases(vmf->ptl)
 {
        struct vm_area_struct *vma = vmf->vma;
@@ -2904,7 +2897,7 @@ EXPORT_SYMBOL(unmap_mapping_range);
  * We return with the mmap_sem locked or unlocked in the same cases
  * as does filemap_fault().
  */
-int do_swap_page(struct vm_fault *vmf)
+vm_fault_t do_swap_page(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
        struct page *page = NULL, *swapcache;
@@ -2913,7 +2906,7 @@ int do_swap_page(struct vm_fault *vmf)
        pte_t pte;
        int locked;
        int exclusive = 0;
-       int ret = 0;
+       vm_fault_t ret = 0;
 
        if (!pte_unmap_same(vma->vm_mm, vmf->pmd, vmf->pte, vmf->orig_pte))
                goto out;
@@ -3124,12 +3117,12 @@ out_release:
  * but allow concurrent faults), and pte mapped but not yet locked.
  * We return with mmap_sem still held, but pte unmapped and unlocked.
  */
-static int do_anonymous_page(struct vm_fault *vmf)
+static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
        struct mem_cgroup *memcg;
        struct page *page;
-       int ret = 0;
+       vm_fault_t ret = 0;
        pte_t entry;
 
        /* File mapping without ->vm_ops ? */
@@ -3239,10 +3232,10 @@ oom:
  * released depending on flags and vma->vm_ops->fault() return value.
  * See filemap_fault() and __lock_page_retry().
  */
-static int __do_fault(struct vm_fault *vmf)
+static vm_fault_t __do_fault(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
-       int ret;
+       vm_fault_t ret;
 
        ret = vma->vm_ops->fault(vmf);
        if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY |
@@ -3276,7 +3269,7 @@ static int pmd_devmap_trans_unstable(pmd_t *pmd)
        return pmd_devmap(*pmd) || pmd_trans_unstable(pmd);
 }
 
-static int pte_alloc_one_map(struct vm_fault *vmf)
+static vm_fault_t pte_alloc_one_map(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
 
@@ -3352,13 +3345,14 @@ static void deposit_prealloc_pte(struct vm_fault *vmf)
        vmf->prealloc_pte = NULL;
 }
 
-static int do_set_pmd(struct vm_fault *vmf, struct page *page)
+static vm_fault_t do_set_pmd(struct vm_fault *vmf, struct page *page)
 {
        struct vm_area_struct *vma = vmf->vma;
        bool write = vmf->flags & FAULT_FLAG_WRITE;
        unsigned long haddr = vmf->address & HPAGE_PMD_MASK;
        pmd_t entry;
-       int i, ret;
+       int i;
+       vm_fault_t ret;
 
        if (!transhuge_vma_suitable(vma, haddr))
                return VM_FAULT_FALLBACK;
@@ -3408,7 +3402,7 @@ out:
        return ret;
 }
 #else
-static int do_set_pmd(struct vm_fault *vmf, struct page *page)
+static vm_fault_t do_set_pmd(struct vm_fault *vmf, struct page *page)
 {
        BUILD_BUG();
        return 0;
@@ -3429,13 +3423,13 @@ static int do_set_pmd(struct vm_fault *vmf, struct page *page)
  * Target users are page handler itself and implementations of
  * vm_ops->map_pages.
  */
-int alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg,
+vm_fault_t alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg,
                struct page *page)
 {
        struct vm_area_struct *vma = vmf->vma;
        bool write = vmf->flags & FAULT_FLAG_WRITE;
        pte_t entry;
-       int ret;
+       vm_fault_t ret;
 
        if (pmd_none(*vmf->pmd) && PageTransCompound(page) &&
                        IS_ENABLED(CONFIG_TRANSPARENT_HUGE_PAGECACHE)) {
@@ -3494,10 +3488,10 @@ int alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg,
  * The function expects the page to be locked and on success it consumes a
  * reference of a page being mapped (for the PTE which maps it).
  */
-int finish_fault(struct vm_fault *vmf)
+vm_fault_t finish_fault(struct vm_fault *vmf)
 {
        struct page *page;
-       int ret = 0;
+       vm_fault_t ret = 0;
 
        /* Did we COW the page? */
        if ((vmf->flags & FAULT_FLAG_WRITE) &&
@@ -3583,12 +3577,13 @@ late_initcall(fault_around_debugfs);
  * (and therefore to page order).  This way it's easier to guarantee
  * that we don't cross page table boundaries.
  */
-static int do_fault_around(struct vm_fault *vmf)
+static vm_fault_t do_fault_around(struct vm_fault *vmf)
 {
        unsigned long address = vmf->address, nr_pages, mask;
        pgoff_t start_pgoff = vmf->pgoff;
        pgoff_t end_pgoff;
-       int off, ret = 0;
+       int off;
+       vm_fault_t ret = 0;
 
        nr_pages = READ_ONCE(fault_around_bytes) >> PAGE_SHIFT;
        mask = ~(nr_pages * PAGE_SIZE - 1) & PAGE_MASK;
@@ -3638,10 +3633,10 @@ out:
        return ret;
 }
 
-static int do_read_fault(struct vm_fault *vmf)
+static vm_fault_t do_read_fault(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
-       int ret = 0;
+       vm_fault_t ret = 0;
 
        /*
         * Let's call ->map_pages() first and use ->fault() as fallback
@@ -3665,10 +3660,10 @@ static int do_read_fault(struct vm_fault *vmf)
        return ret;
 }
 
-static int do_cow_fault(struct vm_fault *vmf)
+static vm_fault_t do_cow_fault(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
-       int ret;
+       vm_fault_t ret;
 
        if (unlikely(anon_vma_prepare(vma)))
                return VM_FAULT_OOM;
@@ -3704,10 +3699,10 @@ uncharge_out:
        return ret;
 }
 
-static int do_shared_fault(struct vm_fault *vmf)
+static vm_fault_t do_shared_fault(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
-       int ret, tmp;
+       vm_fault_t ret, tmp;
 
        ret = __do_fault(vmf);
        if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY)))
@@ -3745,10 +3740,10 @@ static int do_shared_fault(struct vm_fault *vmf)
  * The mmap_sem may have been released depending on flags and our
  * return value.  See filemap_fault() and __lock_page_or_retry().
  */
-static int do_fault(struct vm_fault *vmf)
+static vm_fault_t do_fault(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
-       int ret;
+       vm_fault_t ret;
 
        /* The VMA was not fully populated on mmap() or missing VM_DONTEXPAND */
        if (!vma->vm_ops->fault)
@@ -3783,7 +3778,7 @@ static int numa_migrate_prep(struct page *page, struct vm_area_struct *vma,
        return mpol_misplaced(page, vma, addr);
 }
 
-static int do_numa_page(struct vm_fault *vmf)
+static vm_fault_t do_numa_page(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
        struct page *page = NULL;
@@ -3873,7 +3868,7 @@ out:
        return 0;
 }
 
-static inline int create_huge_pmd(struct vm_fault *vmf)
+static inline vm_fault_t create_huge_pmd(struct vm_fault *vmf)
 {
        if (vma_is_anonymous(vmf->vma))
                return do_huge_pmd_anonymous_page(vmf);
@@ -3883,7 +3878,7 @@ static inline int create_huge_pmd(struct vm_fault *vmf)
 }
 
 /* `inline' is required to avoid gcc 4.1.2 build error */
-static inline int wp_huge_pmd(struct vm_fault *vmf, pmd_t orig_pmd)
+static inline vm_fault_t wp_huge_pmd(struct vm_fault *vmf, pmd_t orig_pmd)
 {
        if (vma_is_anonymous(vmf->vma))
                return do_huge_pmd_wp_page(vmf, orig_pmd);
@@ -3902,7 +3897,7 @@ static inline bool vma_is_accessible(struct vm_area_struct *vma)
        return vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE);
 }
 
-static int create_huge_pud(struct vm_fault *vmf)
+static vm_fault_t create_huge_pud(struct vm_fault *vmf)
 {
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
        /* No support for anonymous transparent PUD pages yet */
@@ -3914,7 +3909,7 @@ static int create_huge_pud(struct vm_fault *vmf)
        return VM_FAULT_FALLBACK;
 }
 
-static int wp_huge_pud(struct vm_fault *vmf, pud_t orig_pud)
+static vm_fault_t wp_huge_pud(struct vm_fault *vmf, pud_t orig_pud)
 {
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
        /* No support for anonymous transparent PUD pages yet */
@@ -3941,7 +3936,7 @@ static int wp_huge_pud(struct vm_fault *vmf, pud_t orig_pud)
  * The mmap_sem may have been released depending on flags and our return value.
  * See filemap_fault() and __lock_page_or_retry().
  */
-static int handle_pte_fault(struct vm_fault *vmf)
+static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
 {
        pte_t entry;
 
@@ -4029,8 +4024,8 @@ unlock:
  * The mmap_sem may have been released depending on flags and our
  * return value.  See filemap_fault() and __lock_page_or_retry().
  */
-static int __handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
-               unsigned int flags)
+static vm_fault_t __handle_mm_fault(struct vm_area_struct *vma,
+               unsigned long address, unsigned int flags)
 {
        struct vm_fault vmf = {
                .vma = vma,
@@ -4043,7 +4038,7 @@ static int __handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
        struct mm_struct *mm = vma->vm_mm;
        pgd_t *pgd;
        p4d_t *p4d;
-       int ret;
+       vm_fault_t ret;
 
        pgd = pgd_offset(mm, address);
        p4d = p4d_alloc(mm, pgd, address);
@@ -4118,10 +4113,10 @@ static int __handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
  * The mmap_sem may have been released depending on flags and our
  * return value.  See filemap_fault() and __lock_page_or_retry().
  */
-int handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
+vm_fault_t handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
                unsigned int flags)
 {
-       int ret;
+       vm_fault_t ret;
 
        __set_current_state(TASK_RUNNING);
 
index 4eb6e824a80c800bddefbfb9b1a41eabf70916aa..38d94b703e9d4932279b5657a2c889dfaaf1b749 100644 (file)
@@ -982,8 +982,6 @@ static void reset_node_present_pages(pg_data_t *pgdat)
 static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start)
 {
        struct pglist_data *pgdat;
-       unsigned long zones_size[MAX_NR_ZONES] = {0};
-       unsigned long zholes_size[MAX_NR_ZONES] = {0};
        unsigned long start_pfn = PFN_DOWN(start);
 
        pgdat = NODE_DATA(nid);
@@ -1006,8 +1004,11 @@ static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start)
 
        /* we can use NODE_DATA(nid) from here */
 
+       pgdat->node_id = nid;
+       pgdat->node_start_pfn = start_pfn;
+
        /* init node's zones as empty zones, we don't have any present pages.*/
-       free_area_init_node(nid, zones_size, start_pfn, zholes_size);
+       free_area_init_core_hotplug(nid);
        pgdat->per_cpu_nodestats = alloc_percpu(struct per_cpu_nodestat);
 
        /*
@@ -1016,19 +1017,12 @@ static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start)
         */
        build_all_zonelists(pgdat);
 
-       /*
-        * zone->managed_pages is set to an approximate value in
-        * free_area_init_core(), which will cause
-        * /sys/device/system/node/nodeX/meminfo has wrong data.
-        * So reset it to 0 before any memory is onlined.
-        */
-       reset_node_managed_pages(pgdat);
-
        /*
         * When memory is hot-added, all the memory is in offline state. So
         * clear all zones' present_pages because they will be updated in
         * online_pages() and offline_pages().
         */
+       reset_node_managed_pages(pgdat);
        reset_node_present_pages(pgdat);
 
        return pgdat;
@@ -1339,7 +1333,8 @@ static unsigned long scan_movable_pages(unsigned long start, unsigned long end)
                        if (__PageMovable(page))
                                return pfn;
                        if (PageHuge(page)) {
-                               if (page_huge_active(page))
+                               if (hugepage_migration_supported(page_hstate(page)) &&
+                                   page_huge_active(page))
                                        return pfn;
                                else
                                        pfn = round_up(pfn + 1,
index 01f1a14facc461c4ca5490adc4060d50887aa053..da858f794eb694a934afb58da49f749343ed8c08 100644 (file)
@@ -1784,7 +1784,7 @@ unsigned int mempolicy_slab_node(void)
                zonelist = &NODE_DATA(node)->node_zonelists[ZONELIST_FALLBACK];
                z = first_zones_zonelist(zonelist, highest_zoneidx,
                                                        &policy->v.nodes);
-               return z->zone ? z->zone->node : node;
+               return z->zone ? zone_to_nid(z->zone) : node;
        }
 
        default:
@@ -2326,7 +2326,7 @@ int mpol_misplaced(struct page *page, struct vm_area_struct *vma, unsigned long
                                node_zonelist(numa_node_id(), GFP_HIGHUSER),
                                gfp_zone(GFP_HIGHUSER),
                                &pol->v.nodes);
-               polnid = z->zone->node;
+               polnid = zone_to_nid(z->zone);
                break;
 
        default:
@@ -2504,7 +2504,6 @@ void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol)
                        goto put_new;
 
                /* Create pseudo-vma that contains just the policy */
-               memset(&pvma, 0, sizeof(struct vm_area_struct));
                vma_init(&pvma, NULL);
                pvma.vm_end = TASK_SIZE;        /* policy covers entire file */
                mpol_set_shared_policy(sp, &pvma, new); /* adds ref */
index 44f5fa98c1e77f34ce3f56b715e3e38e9755af54..0ef8cc8d1602246a670d4e443ba7624bd2c99df0 100644 (file)
@@ -213,6 +213,7 @@ EXPORT_SYMBOL(mempool_init_node);
 
 /**
  * mempool_init - initialize a memory pool
+ * @pool:      pointer to the memory pool that should be initialized
  * @min_nr:    the minimum number of elements guaranteed to be
  *             allocated for this pool.
  * @alloc_fn:  user-defined element-allocation function.
index 4a83268e23c2ee656dbdd1df4a56badc068a5122..d6a2e89b086a43d77f155f6b525fc15326d9c035 100644 (file)
@@ -1131,7 +1131,8 @@ out:
  * gcc 4.7 and 4.8 on arm get an ICEs when inlining unmap_and_move().  Work
  * around it.
  */
-#if (GCC_VERSION >= 40700 && GCC_VERSION < 40900) && defined(CONFIG_ARM)
+#if defined(CONFIG_ARM) && \
+       defined(GCC_VERSION) && GCC_VERSION < 40900 && GCC_VERSION >= 40700
 #define ICE_noinline noinline
 #else
 #define ICE_noinline
@@ -1211,7 +1212,7 @@ out:
                         * intentionally. Although it's rather weird,
                         * it's how HWPoison flag works at the moment.
                         */
-                       if (!test_set_page_hwpoison(page))
+                       if (set_hwpoison_free_buddy_page(page))
                                num_poisoned_pages_inc();
                }
        } else {
@@ -1330,8 +1331,6 @@ put_anon:
 out:
        if (rc != -EAGAIN)
                putback_active_hugepage(hpage);
-       if (reason == MR_MEMORY_FAILURE && !test_set_page_hwpoison(hpage))
-               num_poisoned_pages_inc();
 
        /*
         * If migration was not successful and there's a freeing callback, use
index 5b72266b4b03362ebb792ccbbfbf9b84e30c1702..6838a530789b414bcda3a2fca71747d067760118 100644 (file)
@@ -53,13 +53,8 @@ void __init mminit_verify_zonelist(void)
                                zone->name);
 
                        /* Iterate the zonelist */
-                       for_each_zone_zonelist(zone, z, zonelist, zoneid) {
-#ifdef CONFIG_NUMA
-                               pr_cont("%d:%s ", zone->node, zone->name);
-#else
-                               pr_cont("0:%s ", zone->name);
-#endif /* CONFIG_NUMA */
-                       }
+                       for_each_zone_zonelist(zone, z, zonelist, zoneid)
+                               pr_cont("%d:%s ", zone_to_nid(zone), zone->name);
                        pr_cont("\n");
                }
        }
index 8d6449e74431155edcb21308743bd52d449bd8f2..5f2b2b184c604b203f38142d8e638db87487f5f4 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -3063,9 +3063,7 @@ void exit_mmap(struct mm_struct *mm)
                 * which clears VM_LOCKED, otherwise the oom reaper cannot
                 * reliably test it.
                 */
-               mutex_lock(&oom_lock);
-               __oom_reap_task_mm(mm);
-               mutex_unlock(&oom_lock);
+               (void)__oom_reap_task_mm(mm);
 
                set_bit(MMF_OOM_SKIP, &mm->flags);
                down_write(&mm->mmap_sem);
index eff6b88a993f2491b8fb96a2ad553196448966da..82bb1a939c0e496affc2849c1e1af795fe3d5d96 100644 (file)
@@ -174,18 +174,29 @@ void __mmu_notifier_change_pte(struct mm_struct *mm, unsigned long address,
        srcu_read_unlock(&srcu, id);
 }
 
-void __mmu_notifier_invalidate_range_start(struct mm_struct *mm,
-                                 unsigned long start, unsigned long end)
+int __mmu_notifier_invalidate_range_start(struct mm_struct *mm,
+                                 unsigned long start, unsigned long end,
+                                 bool blockable)
 {
        struct mmu_notifier *mn;
+       int ret = 0;
        int id;
 
        id = srcu_read_lock(&srcu);
        hlist_for_each_entry_rcu(mn, &mm->mmu_notifier_mm->list, hlist) {
-               if (mn->ops->invalidate_range_start)
-                       mn->ops->invalidate_range_start(mn, mm, start, end);
+               if (mn->ops->invalidate_range_start) {
+                       int _ret = mn->ops->invalidate_range_start(mn, mm, start, end, blockable);
+                       if (_ret) {
+                               pr_info("%pS callback failed with %d in %sblockable context.\n",
+                                               mn->ops->invalidate_range_start, _ret,
+                                               !blockable ? "non-" : "");
+                               ret = _ret;
+                       }
+               }
        }
        srcu_read_unlock(&srcu, id);
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(__mmu_notifier_invalidate_range_start);
 
index 412f43453a68ff5260ec46c6211c9249cf9d9cc6..f10aa5360616ea3247b6e508ed28ace237d70ad9 100644 (file)
@@ -400,7 +400,8 @@ static void dump_tasks(struct mem_cgroup *memcg, const nodemask_t *nodemask)
        struct task_struct *p;
        struct task_struct *task;
 
-       pr_info("[ pid ]   uid  tgid total_vm      rss pgtables_bytes swapents oom_score_adj name\n");
+       pr_info("Tasks state (memory values in pages):\n");
+       pr_info("[  pid  ]   uid  tgid total_vm      rss pgtables_bytes swapents oom_score_adj name\n");
        rcu_read_lock();
        for_each_process(p) {
                if (oom_unkillable_task(p, memcg, nodemask))
@@ -416,7 +417,7 @@ static void dump_tasks(struct mem_cgroup *memcg, const nodemask_t *nodemask)
                        continue;
                }
 
-               pr_info("[%5d] %5d %5d %8lu %8lu %8ld %8lu         %5hd %s\n",
+               pr_info("[%7d] %5d %5d %8lu %8lu %8ld %8lu         %5hd %s\n",
                        task->pid, from_kuid(&init_user_ns, task_uid(task)),
                        task->tgid, task->mm->total_vm, get_mm_rss(task->mm),
                        mm_pgtables_bytes(task->mm),
@@ -487,9 +488,10 @@ static DECLARE_WAIT_QUEUE_HEAD(oom_reaper_wait);
 static struct task_struct *oom_reaper_list;
 static DEFINE_SPINLOCK(oom_reaper_lock);
 
-void __oom_reap_task_mm(struct mm_struct *mm)
+bool __oom_reap_task_mm(struct mm_struct *mm)
 {
        struct vm_area_struct *vma;
+       bool ret = true;
 
        /*
         * Tell all users of get_user/copy_from_user etc... that the content
@@ -519,50 +521,33 @@ void __oom_reap_task_mm(struct mm_struct *mm)
                        struct mmu_gather tlb;
 
                        tlb_gather_mmu(&tlb, mm, start, end);
-                       mmu_notifier_invalidate_range_start(mm, start, end);
+                       if (mmu_notifier_invalidate_range_start_nonblock(mm, start, end)) {
+                               tlb_finish_mmu(&tlb, start, end);
+                               ret = false;
+                               continue;
+                       }
                        unmap_page_range(&tlb, vma, start, end, NULL);
                        mmu_notifier_invalidate_range_end(mm, start, end);
                        tlb_finish_mmu(&tlb, start, end);
                }
        }
+
+       return ret;
 }
 
+/*
+ * Reaps the address space of the give task.
+ *
+ * Returns true on success and false if none or part of the address space
+ * has been reclaimed and the caller should retry later.
+ */
 static bool oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm)
 {
        bool ret = true;
 
-       /*
-        * We have to make sure to not race with the victim exit path
-        * and cause premature new oom victim selection:
-        * oom_reap_task_mm             exit_mm
-        *   mmget_not_zero
-        *                                mmput
-        *                                  atomic_dec_and_test
-        *                                exit_oom_victim
-        *                              [...]
-        *                              out_of_memory
-        *                                select_bad_process
-        *                                  # no TIF_MEMDIE task selects new victim
-        *  unmap_page_range # frees some memory
-        */
-       mutex_lock(&oom_lock);
-
        if (!down_read_trylock(&mm->mmap_sem)) {
-               ret = false;
                trace_skip_task_reaping(tsk->pid);
-               goto unlock_oom;
-       }
-
-       /*
-        * If the mm has invalidate_{start,end}() notifiers that could block,
-        * sleep to give the oom victim some more time.
-        * TODO: we really want to get rid of this ugly hack and make sure that
-        * notifiers cannot block for unbounded amount of time
-        */
-       if (mm_has_blockable_invalidate_notifiers(mm)) {
-               up_read(&mm->mmap_sem);
-               schedule_timeout_idle(HZ);
-               goto unlock_oom;
+               return false;
        }
 
        /*
@@ -572,25 +557,27 @@ static bool oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm)
         * down_write();up_write() cycle in exit_mmap().
         */
        if (test_bit(MMF_OOM_SKIP, &mm->flags)) {
-               up_read(&mm->mmap_sem);
                trace_skip_task_reaping(tsk->pid);
-               goto unlock_oom;
+               goto out_unlock;
        }
 
        trace_start_task_reaping(tsk->pid);
 
-       __oom_reap_task_mm(mm);
+       /* failed to reap part of the address space. Try again later */
+       ret = __oom_reap_task_mm(mm);
+       if (!ret)
+               goto out_finish;
 
        pr_info("oom_reaper: reaped process %d (%s), now anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n",
                        task_pid_nr(tsk), tsk->comm,
                        K(get_mm_counter(mm, MM_ANONPAGES)),
                        K(get_mm_counter(mm, MM_FILEPAGES)),
                        K(get_mm_counter(mm, MM_SHMEMPAGES)));
+out_finish:
+       trace_finish_task_reaping(tsk->pid);
+out_unlock:
        up_read(&mm->mmap_sem);
 
-       trace_finish_task_reaping(tsk->pid);
-unlock_oom:
-       mutex_unlock(&oom_lock);
        return ret;
 }
 
@@ -843,68 +830,12 @@ static bool task_will_free_mem(struct task_struct *task)
        return ret;
 }
 
-static void oom_kill_process(struct oom_control *oc, const char *message)
+static void __oom_kill_process(struct task_struct *victim)
 {
-       struct task_struct *p = oc->chosen;
-       unsigned int points = oc->chosen_points;
-       struct task_struct *victim = p;
-       struct task_struct *child;
-       struct task_struct *t;
+       struct task_struct *p;
        struct mm_struct *mm;
-       unsigned int victim_points = 0;
-       static DEFINE_RATELIMIT_STATE(oom_rs, DEFAULT_RATELIMIT_INTERVAL,
-                                             DEFAULT_RATELIMIT_BURST);
        bool can_oom_reap = true;
 
-       /*
-        * If the task is already exiting, don't alarm the sysadmin or kill
-        * its children or threads, just give it access to memory reserves
-        * so it can die quickly
-        */
-       task_lock(p);
-       if (task_will_free_mem(p)) {
-               mark_oom_victim(p);
-               wake_oom_reaper(p);
-               task_unlock(p);
-               put_task_struct(p);
-               return;
-       }
-       task_unlock(p);
-
-       if (__ratelimit(&oom_rs))
-               dump_header(oc, p);
-
-       pr_err("%s: Kill process %d (%s) score %u or sacrifice child\n",
-               message, task_pid_nr(p), p->comm, points);
-
-       /*
-        * If any of p's children has a different mm and is eligible for kill,
-        * the one with the highest oom_badness() score is sacrificed for its
-        * parent.  This attempts to lose the minimal amount of work done while
-        * still freeing memory.
-        */
-       read_lock(&tasklist_lock);
-       for_each_thread(p, t) {
-               list_for_each_entry(child, &t->children, sibling) {
-                       unsigned int child_points;
-
-                       if (process_shares_mm(child, p->mm))
-                               continue;
-                       /*
-                        * oom_badness() returns 0 if the thread is unkillable
-                        */
-                       child_points = oom_badness(child,
-                               oc->memcg, oc->nodemask, oc->totalpages);
-                       if (child_points > victim_points) {
-                               put_task_struct(victim);
-                               victim = child;
-                               victim_points = child_points;
-                               get_task_struct(victim);
-                       }
-               }
-       }
-       read_unlock(&tasklist_lock);
-
        p = find_lock_task_mm(victim);
        if (!p) {
                put_task_struct(victim);
@@ -928,7 +859,7 @@ static void oom_kill_process(struct oom_control *oc, const char *message)
         * in order to prevent the OOM victim from depleting the memory
         * reserves from the user space under its control.
         */
-       do_send_sig_info(SIGKILL, SEND_SIG_FORCED, victim, true);
+       do_send_sig_info(SIGKILL, SEND_SIG_FORCED, victim, PIDTYPE_TGID);
        mark_oom_victim(victim);
        pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n",
                task_pid_nr(victim), victim->comm, K(victim->mm->total_vm),
@@ -966,7 +897,7 @@ static void oom_kill_process(struct oom_control *oc, const char *message)
                 */
                if (unlikely(p->flags & PF_KTHREAD))
                        continue;
-               do_send_sig_info(SIGKILL, SEND_SIG_FORCED, p, true);
+               do_send_sig_info(SIGKILL, SEND_SIG_FORCED, p, PIDTYPE_TGID);
        }
        rcu_read_unlock();
 
@@ -978,6 +909,99 @@ static void oom_kill_process(struct oom_control *oc, const char *message)
 }
 #undef K
 
+/*
+ * Kill provided task unless it's secured by setting
+ * oom_score_adj to OOM_SCORE_ADJ_MIN.
+ */
+static int oom_kill_memcg_member(struct task_struct *task, void *unused)
+{
+       if (task->signal->oom_score_adj != OOM_SCORE_ADJ_MIN) {
+               get_task_struct(task);
+               __oom_kill_process(task);
+       }
+       return 0;
+}
+
+static void oom_kill_process(struct oom_control *oc, const char *message)
+{
+       struct task_struct *p = oc->chosen;
+       unsigned int points = oc->chosen_points;
+       struct task_struct *victim = p;
+       struct task_struct *child;
+       struct task_struct *t;
+       struct mem_cgroup *oom_group;
+       unsigned int victim_points = 0;
+       static DEFINE_RATELIMIT_STATE(oom_rs, DEFAULT_RATELIMIT_INTERVAL,
+                                             DEFAULT_RATELIMIT_BURST);
+
+       /*
+        * If the task is already exiting, don't alarm the sysadmin or kill
+        * its children or threads, just give it access to memory reserves
+        * so it can die quickly
+        */
+       task_lock(p);
+       if (task_will_free_mem(p)) {
+               mark_oom_victim(p);
+               wake_oom_reaper(p);
+               task_unlock(p);
+               put_task_struct(p);
+               return;
+       }
+       task_unlock(p);
+
+       if (__ratelimit(&oom_rs))
+               dump_header(oc, p);
+
+       pr_err("%s: Kill process %d (%s) score %u or sacrifice child\n",
+               message, task_pid_nr(p), p->comm, points);
+
+       /*
+        * If any of p's children has a different mm and is eligible for kill,
+        * the one with the highest oom_badness() score is sacrificed for its
+        * parent.  This attempts to lose the minimal amount of work done while
+        * still freeing memory.
+        */
+       read_lock(&tasklist_lock);
+       for_each_thread(p, t) {
+               list_for_each_entry(child, &t->children, sibling) {
+                       unsigned int child_points;
+
+                       if (process_shares_mm(child, p->mm))
+                               continue;
+                       /*
+                        * oom_badness() returns 0 if the thread is unkillable
+                        */
+                       child_points = oom_badness(child,
+                               oc->memcg, oc->nodemask, oc->totalpages);
+                       if (child_points > victim_points) {
+                               put_task_struct(victim);
+                               victim = child;
+                               victim_points = child_points;
+                               get_task_struct(victim);
+                       }
+               }
+       }
+       read_unlock(&tasklist_lock);
+
+       /*
+        * Do we need to kill the entire memory cgroup?
+        * Or even one of the ancestor memory cgroups?
+        * Check this out before killing the victim task.
+        */
+       oom_group = mem_cgroup_get_oom_group(victim, oc->memcg);
+
+       __oom_kill_process(victim);
+
+       /*
+        * If necessary, kill all tasks in the selected memory cgroup.
+        */
+       if (oom_group) {
+               mem_cgroup_print_oom_group(oom_group);
+               mem_cgroup_scan_tasks(oom_group, oom_kill_memcg_member, NULL);
+               mem_cgroup_put(oom_group);
+       }
+}
+
 /*
  * Determines whether the kernel must panic because of the panic_on_oom sysctl.
  */
@@ -1080,10 +1104,17 @@ bool out_of_memory(struct oom_control *oc)
        }
 
        select_bad_process(oc);
-       /* Found nothing?!?! Either we hang forever, or we panic. */
-       if (!oc->chosen && !is_sysrq_oom(oc) && !is_memcg_oom(oc)) {
+       /* Found nothing?!?! */
+       if (!oc->chosen) {
                dump_header(oc, NULL);
-               panic("Out of memory and no killable processes...\n");
+               pr_warn("Out of memory and no killable processes...\n");
+               /*
+                * If we got here due to an actual allocation at the
+                * system level, we cannot survive this and will enter
+                * an endless loop in the allocator. Bail out now.
+                */
+               if (!is_sysrq_oom(oc) && !is_memcg_oom(oc))
+                       panic("System is deadlocked on memory\n");
        }
        if (oc->chosen && oc->chosen != (void *)-1UL)
                oom_kill_process(oc, !is_memcg_oom(oc) ? "Out of memory" :
index 6551d3b0dc30a5e5a951f24f27a5586cbe920237..84ae9bf5858ac9dcf7e1155e514a9b9062e0f10d 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/mpage.h>
 #include <linux/rmap.h>
 #include <linux/percpu.h>
-#include <linux/notifier.h>
 #include <linux/smp.h>
 #include <linux/sysctl.h>
 #include <linux/cpu.h>
index 15ea511fb41c56bc16ae9b48e3b49d4b5e937717..89d2a2ab3fe68c3ae46104074c519c7500dd86cb 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/slab.h>
 #include <linux/ratelimit.h>
 #include <linux/oom.h>
-#include <linux/notifier.h>
 #include <linux/topology.h>
 #include <linux/sysctl.h>
 #include <linux/cpu.h>
@@ -2909,10 +2908,10 @@ static inline void zone_statistics(struct zone *preferred_zone, struct zone *z)
        if (!static_branch_likely(&vm_numa_stat_key))
                return;
 
-       if (z->node != numa_node_id())
+       if (zone_to_nid(z) != numa_node_id())
                local_stat = NUMA_OTHER;
 
-       if (z->node == preferred_zone->node)
+       if (zone_to_nid(z) == zone_to_nid(preferred_zone))
                __inc_numa_state(z, NUMA_HIT);
        else {
                __inc_numa_state(z, NUMA_MISS);
@@ -5278,7 +5277,7 @@ int local_memory_node(int node)
        z = first_zones_zonelist(node_zonelist(node, GFP_KERNEL),
                                   gfp_zone(GFP_KERNEL),
                                   NULL);
-       return z->zone->node;
+       return zone_to_nid(z->zone);
 }
 #endif
 
@@ -6120,7 +6119,7 @@ static unsigned long __init usemap_size(unsigned long zone_start_pfn, unsigned l
        return usemapsize / 8;
 }
 
-static void __init setup_usemap(struct pglist_data *pgdat,
+static void __ref setup_usemap(struct pglist_data *pgdat,
                                struct zone *zone,
                                unsigned long zone_start_pfn,
                                unsigned long zonesize)
@@ -6140,7 +6139,7 @@ static inline void setup_usemap(struct pglist_data *pgdat, struct zone *zone,
 #ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
 
 /* Initialise the number of pages represented by NR_PAGEBLOCK_BITS */
-void __paginginit set_pageblock_order(void)
+void __init set_pageblock_order(void)
 {
        unsigned int order;
 
@@ -6168,14 +6167,14 @@ void __paginginit set_pageblock_order(void)
  * include/linux/pageblock-flags.h for the values of pageblock_order based on
  * the kernel config
  */
-void __paginginit set_pageblock_order(void)
+void __init set_pageblock_order(void)
 {
 }
 
 #endif /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
 
-static unsigned long __paginginit calc_memmap_size(unsigned long spanned_pages,
-                                                  unsigned long present_pages)
+static unsigned long __init calc_memmap_size(unsigned long spanned_pages,
+                                               unsigned long present_pages)
 {
        unsigned long pages = spanned_pages;
 
@@ -6194,39 +6193,99 @@ static unsigned long __paginginit calc_memmap_size(unsigned long spanned_pages,
        return PAGE_ALIGN(pages * sizeof(struct page)) >> PAGE_SHIFT;
 }
 
-/*
- * Set up the zone data structures:
- *   - mark all pages reserved
- *   - mark all memory queues empty
- *   - clear the memory bitmaps
- *
- * NOTE: pgdat should get zeroed by caller.
- */
-static void __paginginit free_area_init_core(struct pglist_data *pgdat)
-{
-       enum zone_type j;
-       int nid = pgdat->node_id;
-
-       pgdat_resize_init(pgdat);
 #ifdef CONFIG_NUMA_BALANCING
+static void pgdat_init_numabalancing(struct pglist_data *pgdat)
+{
        spin_lock_init(&pgdat->numabalancing_migrate_lock);
        pgdat->numabalancing_migrate_nr_pages = 0;
        pgdat->numabalancing_migrate_next_window = jiffies;
+}
+#else
+static void pgdat_init_numabalancing(struct pglist_data *pgdat) {}
 #endif
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static void pgdat_init_split_queue(struct pglist_data *pgdat)
+{
        spin_lock_init(&pgdat->split_queue_lock);
        INIT_LIST_HEAD(&pgdat->split_queue);
        pgdat->split_queue_len = 0;
+}
+#else
+static void pgdat_init_split_queue(struct pglist_data *pgdat) {}
 #endif
-       init_waitqueue_head(&pgdat->kswapd_wait);
-       init_waitqueue_head(&pgdat->pfmemalloc_wait);
+
 #ifdef CONFIG_COMPACTION
+static void pgdat_init_kcompactd(struct pglist_data *pgdat)
+{
        init_waitqueue_head(&pgdat->kcompactd_wait);
+}
+#else
+static void pgdat_init_kcompactd(struct pglist_data *pgdat) {}
 #endif
+
+static void __meminit pgdat_init_internals(struct pglist_data *pgdat)
+{
+       pgdat_resize_init(pgdat);
+
+       pgdat_init_numabalancing(pgdat);
+       pgdat_init_split_queue(pgdat);
+       pgdat_init_kcompactd(pgdat);
+
+       init_waitqueue_head(&pgdat->kswapd_wait);
+       init_waitqueue_head(&pgdat->pfmemalloc_wait);
+
        pgdat_page_ext_init(pgdat);
        spin_lock_init(&pgdat->lru_lock);
        lruvec_init(node_lruvec(pgdat));
+}
+
+static void __meminit zone_init_internals(struct zone *zone, enum zone_type idx, int nid,
+                                                       unsigned long remaining_pages)
+{
+       zone->managed_pages = remaining_pages;
+       zone_set_nid(zone, nid);
+       zone->name = zone_names[idx];
+       zone->zone_pgdat = NODE_DATA(nid);
+       spin_lock_init(&zone->lock);
+       zone_seqlock_init(zone);
+       zone_pcp_init(zone);
+}
+
+/*
+ * Set up the zone data structures
+ * - init pgdat internals
+ * - init all zones belonging to this node
+ *
+ * NOTE: this function is only called during memory hotplug
+ */
+#ifdef CONFIG_MEMORY_HOTPLUG
+void __ref free_area_init_core_hotplug(int nid)
+{
+       enum zone_type z;
+       pg_data_t *pgdat = NODE_DATA(nid);
+
+       pgdat_init_internals(pgdat);
+       for (z = 0; z < MAX_NR_ZONES; z++)
+               zone_init_internals(&pgdat->node_zones[z], z, nid, 0);
+}
+#endif
+
+/*
+ * Set up the zone data structures:
+ *   - mark all pages reserved
+ *   - mark all memory queues empty
+ *   - clear the memory bitmaps
+ *
+ * NOTE: pgdat should get zeroed by caller.
+ * NOTE: this function is only called during early init.
+ */
+static void __init free_area_init_core(struct pglist_data *pgdat)
+{
+       enum zone_type j;
+       int nid = pgdat->node_id;
 
+       pgdat_init_internals(pgdat);
        pgdat->per_cpu_nodestats = &boot_nodestats;
 
        for (j = 0; j < MAX_NR_ZONES; j++) {
@@ -6274,15 +6333,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat)
                 * when the bootmem allocator frees pages into the buddy system.
                 * And all highmem pages will be managed by the buddy system.
                 */
-               zone->managed_pages = freesize;
-#ifdef CONFIG_NUMA
-               zone->node = nid;
-#endif
-               zone->name = zone_names[j];
-               zone->zone_pgdat = pgdat;
-               spin_lock_init(&zone->lock);
-               zone_seqlock_init(zone);
-               zone_pcp_init(zone);
+               zone_init_internals(zone, j, nid, freesize);
 
                if (!size)
                        continue;
@@ -6342,8 +6393,24 @@ static void __ref alloc_node_mem_map(struct pglist_data *pgdat)
 static void __ref alloc_node_mem_map(struct pglist_data *pgdat) { }
 #endif /* CONFIG_FLAT_NODE_MEM_MAP */
 
-void __paginginit free_area_init_node(int nid, unsigned long *zones_size,
-               unsigned long node_start_pfn, unsigned long *zholes_size)
+#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
+static inline void pgdat_set_deferred_range(pg_data_t *pgdat)
+{
+       /*
+        * We start only with one section of pages, more pages are added as
+        * needed until the rest of deferred pages are initialized.
+        */
+       pgdat->static_init_pgcnt = min_t(unsigned long, PAGES_PER_SECTION,
+                                               pgdat->node_spanned_pages);
+       pgdat->first_deferred_pfn = ULONG_MAX;
+}
+#else
+static inline void pgdat_set_deferred_range(pg_data_t *pgdat) {}
+#endif
+
+void __init free_area_init_node(int nid, unsigned long *zones_size,
+                                  unsigned long node_start_pfn,
+                                  unsigned long *zholes_size)
 {
        pg_data_t *pgdat = NODE_DATA(nid);
        unsigned long start_pfn = 0;
@@ -6367,16 +6434,8 @@ void __paginginit free_area_init_node(int nid, unsigned long *zones_size,
                                  zones_size, zholes_size);
 
        alloc_node_mem_map(pgdat);
+       pgdat_set_deferred_range(pgdat);
 
-#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
-       /*
-        * We start only with one section of pages, more pages are added as
-        * needed until the rest of deferred pages are initialized.
-        */
-       pgdat->static_init_pgcnt = min_t(unsigned long, PAGES_PER_SECTION,
-                                        pgdat->node_spanned_pages);
-       pgdat->first_deferred_pfn = ULONG_MAX;
-#endif
        free_area_init_core(pgdat);
 }
 
@@ -6388,7 +6447,7 @@ void __paginginit free_area_init_node(int nid, unsigned long *zones_size,
  * may be accessed (for example page_to_pfn() on some configuration accesses
  * flags). We must explicitly zero those struct pages.
  */
-void __paginginit zero_resv_unavail(void)
+void __init zero_resv_unavail(void)
 {
        phys_addr_t start, end;
        unsigned long pfn;
@@ -7649,6 +7708,10 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
                 * handle each tail page individually in migration.
                 */
                if (PageHuge(page)) {
+
+                       if (!hugepage_migration_supported(page_hstate(page)))
+                               goto unmovable;
+
                        iter = round_up(iter + 1, 1<<compound_order(page)) - 1;
                        continue;
                }
@@ -8036,3 +8099,33 @@ bool is_free_buddy_page(struct page *page)
 
        return order < MAX_ORDER;
 }
+
+#ifdef CONFIG_MEMORY_FAILURE
+/*
+ * Set PG_hwpoison flag if a given page is confirmed to be a free page.  This
+ * test is performed under the zone lock to prevent a race against page
+ * allocation.
+ */
+bool set_hwpoison_free_buddy_page(struct page *page)
+{
+       struct zone *zone = page_zone(page);
+       unsigned long pfn = page_to_pfn(page);
+       unsigned long flags;
+       unsigned int order;
+       bool hwpoisoned = false;
+
+       spin_lock_irqsave(&zone->lock, flags);
+       for (order = 0; order < MAX_ORDER; order++) {
+               struct page *page_head = page - (pfn & ((1 << order) - 1));
+
+               if (PageBuddy(page_head) && page_order(page_head) >= order) {
+                       if (!TestSetPageHWPoison(page))
+                               hwpoisoned = true;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&zone->lock, flags);
+
+       return hwpoisoned;
+}
+#endif
index 0b6480979ac78147d4a3fe33d8aded2d5e9a1a75..a749d4d96e3ec72baa7da9c325230855243e0bfa 100644 (file)
@@ -169,6 +169,14 @@ static LIST_HEAD(pcpu_map_extend_chunks);
  */
 int pcpu_nr_empty_pop_pages;
 
+/*
+ * The number of populated pages in use by the allocator, protected by
+ * pcpu_lock.  This number is kept per a unit per chunk (i.e. when a page gets
+ * allocated/deallocated, it is allocated/deallocated in all units of a chunk
+ * and increments/decrements this count by 1).
+ */
+static unsigned long pcpu_nr_populated;
+
 /*
  * Balance work is used to populate or destroy chunks asynchronously.  We
  * try to keep the number of populated free pages between
@@ -1232,6 +1240,7 @@ static void pcpu_chunk_populated(struct pcpu_chunk *chunk, int page_start,
 
        bitmap_set(chunk->populated, page_start, nr);
        chunk->nr_populated += nr;
+       pcpu_nr_populated += nr;
 
        if (!for_alloc) {
                chunk->nr_empty_pop_pages += nr;
@@ -1260,6 +1269,7 @@ static void pcpu_chunk_depopulated(struct pcpu_chunk *chunk,
        chunk->nr_populated -= nr;
        chunk->nr_empty_pop_pages -= nr;
        pcpu_nr_empty_pop_pages -= nr;
+       pcpu_nr_populated -= nr;
 }
 
 /*
@@ -2176,6 +2186,9 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
        pcpu_nr_empty_pop_pages = pcpu_first_chunk->nr_empty_pop_pages;
        pcpu_chunk_relocate(pcpu_first_chunk, -1);
 
+       /* include all regions of the first chunk */
+       pcpu_nr_populated += PFN_DOWN(size_sum);
+
        pcpu_stats_chunk_alloc();
        trace_percpu_create_chunk(base_addr);
 
@@ -2745,6 +2758,22 @@ void __init setup_per_cpu_areas(void)
 
 #endif /* CONFIG_SMP */
 
+/*
+ * pcpu_nr_pages - calculate total number of populated backing pages
+ *
+ * This reflects the number of pages populated to back chunks.  Metadata is
+ * excluded in the number exposed in meminfo as the number of backing pages
+ * scales with the number of cpus and can quickly outweigh the memory used for
+ * metadata.  It also keeps this calculation nice and simple.
+ *
+ * RETURNS:
+ * Total number of populated backing pages in use by the allocator.
+ */
+unsigned long pcpu_nr_pages(void)
+{
+       return pcpu_nr_populated * pcpu_nr_units;
+}
+
 /*
  * Percpu allocator is initialized early during boot when neither slab or
  * workqueue is available.  Plug async management until everything is up
index c48c79018a7c0c7bad72ac3fda1584280267b210..0376c124b043be4d9be9f9fc233c3e03092ce428 100644 (file)
@@ -124,7 +124,7 @@ static int shmem_replace_page(struct page **pagep, gfp_t gfp,
 static int shmem_getpage_gfp(struct inode *inode, pgoff_t index,
                struct page **pagep, enum sgp_type sgp,
                gfp_t gfp, struct vm_area_struct *vma,
-               struct vm_fault *vmf, int *fault_type);
+               struct vm_fault *vmf, vm_fault_t *fault_type);
 
 int shmem_getpage(struct inode *inode, pgoff_t index,
                struct page **pagep, enum sgp_type sgp)
@@ -1421,7 +1421,6 @@ static void shmem_pseudo_vma_init(struct vm_area_struct *vma,
                struct shmem_inode_info *info, pgoff_t index)
 {
        /* Create a pseudo vma that just contains the policy */
-       memset(vma, 0, sizeof(*vma));
        vma_init(vma, NULL);
        /* Bias interleave by inode number to distribute better across nodes */
        vma->vm_pgoff = index + info->vfs_inode.i_ino;
@@ -1621,7 +1620,8 @@ static int shmem_replace_page(struct page **pagep, gfp_t gfp,
  */
 static int shmem_getpage_gfp(struct inode *inode, pgoff_t index,
        struct page **pagep, enum sgp_type sgp, gfp_t gfp,
-       struct vm_area_struct *vma, struct vm_fault *vmf, int *fault_type)
+       struct vm_area_struct *vma, struct vm_fault *vmf,
+                       vm_fault_t *fault_type)
 {
        struct address_space *mapping = inode->i_mapping;
        struct shmem_inode_info *info = SHMEM_I(inode);
index ce2b9e5cea771cb9f06e9bc6bb65151fd7281a95..8da34a8af53d58754ff4a394f26f6f252cbafbe0 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -19,7 +19,6 @@
 #include <linux/slab.h>
 #include "slab.h"
 #include <linux/proc_fs.h>
-#include <linux/notifier.h>
 #include <linux/seq_file.h>
 #include <linux/kasan.h>
 #include <linux/cpu.h>
index 008ccb22fee6c3057fffa1fd3f0713767614cbfb..63a7b4563a57ee3367b8963b1219323a4d3b28c9 100644 (file)
@@ -269,8 +269,8 @@ static int refill_swap_slots_cache(struct swap_slots_cache *cache)
 
        cache->cur = 0;
        if (swap_slot_cache_active)
-               cache->nr = get_swap_pages(SWAP_SLOTS_CACHE_SIZE, false,
-                                          cache->slots);
+               cache->nr = get_swap_pages(SWAP_SLOTS_CACHE_SIZE,
+                                          cache->slots, 1);
 
        return cache->nr;
 }
@@ -316,7 +316,7 @@ swp_entry_t get_swap_page(struct page *page)
 
        if (PageTransHuge(page)) {
                if (IS_ENABLED(CONFIG_THP_SWAP))
-                       get_swap_pages(1, true, &entry);
+                       get_swap_pages(1, &entry, HPAGE_PMD_NR);
                goto out;
        }
 
@@ -350,7 +350,7 @@ repeat:
                        goto out;
        }
 
-       get_swap_pages(1, false, &entry);
+       get_swap_pages(1, &entry, 1);
 out:
        if (mem_cgroup_try_charge_swap(page, entry)) {
                put_swap_page(page, entry);
index 8837b22c848d069262653318a69a542b6ddf34dd..d954b71c4f9c2e842e142713e1a921addb6a4c9d 100644 (file)
@@ -204,8 +204,16 @@ static void discard_swap_cluster(struct swap_info_struct *si,
 
 #ifdef CONFIG_THP_SWAP
 #define SWAPFILE_CLUSTER       HPAGE_PMD_NR
+
+#define swap_entry_size(size)  (size)
 #else
 #define SWAPFILE_CLUSTER       256
+
+/*
+ * Define swap_entry_size() as constant to let compiler to optimize
+ * out some code if !CONFIG_THP_SWAP
+ */
+#define swap_entry_size(size)  1
 #endif
 #define LATENCY_LIMIT          256
 
@@ -269,7 +277,9 @@ static inline void cluster_set_null(struct swap_cluster_info *info)
 
 static inline bool cluster_is_huge(struct swap_cluster_info *info)
 {
-       return info->flags & CLUSTER_FLAG_HUGE;
+       if (IS_ENABLED(CONFIG_THP_SWAP))
+               return info->flags & CLUSTER_FLAG_HUGE;
+       return false;
 }
 
 static inline void cluster_clear_huge(struct swap_cluster_info *info)
@@ -296,13 +306,18 @@ static inline void unlock_cluster(struct swap_cluster_info *ci)
                spin_unlock(&ci->lock);
 }
 
+/*
+ * Determine the locking method in use for this device.  Return
+ * swap_cluster_info if SSD-style cluster-based locking is in place.
+ */
 static inline struct swap_cluster_info *lock_cluster_or_swap_info(
-       struct swap_info_struct *si,
-       unsigned long offset)
+               struct swap_info_struct *si, unsigned long offset)
 {
        struct swap_cluster_info *ci;
 
+       /* Try to use fine-grained SSD-style locking if available: */
        ci = lock_cluster(si, offset);
+       /* Otherwise, fall back to traditional, coarse locking: */
        if (!ci)
                spin_lock(&si->lock);
 
@@ -863,7 +878,6 @@ no_page:
        return n_ret;
 }
 
-#ifdef CONFIG_THP_SWAP
 static int swap_alloc_cluster(struct swap_info_struct *si, swp_entry_t *slot)
 {
        unsigned long idx;
@@ -871,6 +885,15 @@ static int swap_alloc_cluster(struct swap_info_struct *si, swp_entry_t *slot)
        unsigned long offset, i;
        unsigned char *map;
 
+       /*
+        * Should not even be attempting cluster allocations when huge
+        * page swap is disabled.  Warn and fail the allocation.
+        */
+       if (!IS_ENABLED(CONFIG_THP_SWAP)) {
+               VM_WARN_ON_ONCE(1);
+               return 0;
+       }
+
        if (cluster_list_empty(&si->free_clusters))
                return 0;
 
@@ -901,13 +924,6 @@ static void swap_free_cluster(struct swap_info_struct *si, unsigned long idx)
        unlock_cluster(ci);
        swap_range_free(si, offset, SWAPFILE_CLUSTER);
 }
-#else
-static int swap_alloc_cluster(struct swap_info_struct *si, swp_entry_t *slot)
-{
-       VM_WARN_ON_ONCE(1);
-       return 0;
-}
-#endif /* CONFIG_THP_SWAP */
 
 static unsigned long scan_swap_map(struct swap_info_struct *si,
                                   unsigned char usage)
@@ -924,18 +940,18 @@ static unsigned long scan_swap_map(struct swap_info_struct *si,
 
 }
 
-int get_swap_pages(int n_goal, bool cluster, swp_entry_t swp_entries[])
+int get_swap_pages(int n_goal, swp_entry_t swp_entries[], int entry_size)
 {
-       unsigned long nr_pages = cluster ? SWAPFILE_CLUSTER : 1;
+       unsigned long size = swap_entry_size(entry_size);
        struct swap_info_struct *si, *next;
        long avail_pgs;
        int n_ret = 0;
        int node;
 
        /* Only single cluster request supported */
-       WARN_ON_ONCE(n_goal > 1 && cluster);
+       WARN_ON_ONCE(n_goal > 1 && size == SWAPFILE_CLUSTER);
 
-       avail_pgs = atomic_long_read(&nr_swap_pages) / nr_pages;
+       avail_pgs = atomic_long_read(&nr_swap_pages) / size;
        if (avail_pgs <= 0)
                goto noswap;
 
@@ -945,7 +961,7 @@ int get_swap_pages(int n_goal, bool cluster, swp_entry_t swp_entries[])
        if (n_goal > avail_pgs)
                n_goal = avail_pgs;
 
-       atomic_long_sub(n_goal * nr_pages, &nr_swap_pages);
+       atomic_long_sub(n_goal * size, &nr_swap_pages);
 
        spin_lock(&swap_avail_lock);
 
@@ -972,14 +988,14 @@ start_over:
                        spin_unlock(&si->lock);
                        goto nextsi;
                }
-               if (cluster) {
+               if (size == SWAPFILE_CLUSTER) {
                        if (!(si->flags & SWP_FILE))
                                n_ret = swap_alloc_cluster(si, swp_entries);
                } else
                        n_ret = scan_swap_map_slots(si, SWAP_HAS_CACHE,
                                                    n_goal, swp_entries);
                spin_unlock(&si->lock);
-               if (n_ret || cluster)
+               if (n_ret || size == SWAPFILE_CLUSTER)
                        goto check_out;
                pr_debug("scan_swap_map of si %d failed to find offset\n",
                        si->type);
@@ -1005,7 +1021,7 @@ nextsi:
 
 check_out:
        if (n_ret < n_goal)
-               atomic_long_add((long)(n_goal - n_ret) * nr_pages,
+               atomic_long_add((long)(n_goal - n_ret) * size,
                                &nr_swap_pages);
 noswap:
        return n_ret;
@@ -1107,16 +1123,13 @@ static struct swap_info_struct *swap_info_get_cont(swp_entry_t entry,
        return p;
 }
 
-static unsigned char __swap_entry_free(struct swap_info_struct *p,
-                                      swp_entry_t entry, unsigned char usage)
+static unsigned char __swap_entry_free_locked(struct swap_info_struct *p,
+                                             unsigned long offset,
+                                             unsigned char usage)
 {
-       struct swap_cluster_info *ci;
-       unsigned long offset = swp_offset(entry);
        unsigned char count;
        unsigned char has_cache;
 
-       ci = lock_cluster_or_swap_info(p, offset);
-
        count = p->swap_map[offset];
 
        has_cache = count & SWAP_HAS_CACHE;
@@ -1144,6 +1157,17 @@ static unsigned char __swap_entry_free(struct swap_info_struct *p,
        usage = count | has_cache;
        p->swap_map[offset] = usage ? : SWAP_HAS_CACHE;
 
+       return usage;
+}
+
+static unsigned char __swap_entry_free(struct swap_info_struct *p,
+                                      swp_entry_t entry, unsigned char usage)
+{
+       struct swap_cluster_info *ci;
+       unsigned long offset = swp_offset(entry);
+
+       ci = lock_cluster_or_swap_info(p, offset);
+       usage = __swap_entry_free_locked(p, offset, usage);
        unlock_cluster_or_swap_info(p, ci);
 
        return usage;
@@ -1184,19 +1208,7 @@ void swap_free(swp_entry_t entry)
 /*
  * Called after dropping swapcache to decrease refcnt to swap entries.
  */
-static void swapcache_free(swp_entry_t entry)
-{
-       struct swap_info_struct *p;
-
-       p = _swap_info_get(entry);
-       if (p) {
-               if (!__swap_entry_free(p, entry, SWAP_HAS_CACHE))
-                       free_swap_slot(entry);
-       }
-}
-
-#ifdef CONFIG_THP_SWAP
-static void swapcache_free_cluster(swp_entry_t entry)
+void put_swap_page(struct page *page, swp_entry_t entry)
 {
        unsigned long offset = swp_offset(entry);
        unsigned long idx = offset / SWAPFILE_CLUSTER;
@@ -1205,42 +1217,48 @@ static void swapcache_free_cluster(swp_entry_t entry)
        unsigned char *map;
        unsigned int i, free_entries = 0;
        unsigned char val;
+       int size = swap_entry_size(hpage_nr_pages(page));
 
        si = _swap_info_get(entry);
        if (!si)
                return;
 
-       ci = lock_cluster(si, offset);
-       VM_BUG_ON(!cluster_is_huge(ci));
-       map = si->swap_map + offset;
-       for (i = 0; i < SWAPFILE_CLUSTER; i++) {
-               val = map[i];
-               VM_BUG_ON(!(val & SWAP_HAS_CACHE));
-               if (val == SWAP_HAS_CACHE)
-                       free_entries++;
-       }
-       if (!free_entries) {
-               for (i = 0; i < SWAPFILE_CLUSTER; i++)
-                       map[i] &= ~SWAP_HAS_CACHE;
+       ci = lock_cluster_or_swap_info(si, offset);
+       if (size == SWAPFILE_CLUSTER) {
+               VM_BUG_ON(!cluster_is_huge(ci));
+               map = si->swap_map + offset;
+               for (i = 0; i < SWAPFILE_CLUSTER; i++) {
+                       val = map[i];
+                       VM_BUG_ON(!(val & SWAP_HAS_CACHE));
+                       if (val == SWAP_HAS_CACHE)
+                               free_entries++;
+               }
+               cluster_clear_huge(ci);
+               if (free_entries == SWAPFILE_CLUSTER) {
+                       unlock_cluster_or_swap_info(si, ci);
+                       spin_lock(&si->lock);
+                       ci = lock_cluster(si, offset);
+                       memset(map, 0, SWAPFILE_CLUSTER);
+                       unlock_cluster(ci);
+                       mem_cgroup_uncharge_swap(entry, SWAPFILE_CLUSTER);
+                       swap_free_cluster(si, idx);
+                       spin_unlock(&si->lock);
+                       return;
+               }
        }
-       cluster_clear_huge(ci);
-       unlock_cluster(ci);
-       if (free_entries == SWAPFILE_CLUSTER) {
-               spin_lock(&si->lock);
-               ci = lock_cluster(si, offset);
-               memset(map, 0, SWAPFILE_CLUSTER);
-               unlock_cluster(ci);
-               mem_cgroup_uncharge_swap(entry, SWAPFILE_CLUSTER);
-               swap_free_cluster(si, idx);
-               spin_unlock(&si->lock);
-       } else if (free_entries) {
-               for (i = 0; i < SWAPFILE_CLUSTER; i++, entry.val++) {
-                       if (!__swap_entry_free(si, entry, SWAP_HAS_CACHE))
-                               free_swap_slot(entry);
+       for (i = 0; i < size; i++, entry.val++) {
+               if (!__swap_entry_free_locked(si, offset + i, SWAP_HAS_CACHE)) {
+                       unlock_cluster_or_swap_info(si, ci);
+                       free_swap_slot(entry);
+                       if (i == size - 1)
+                               return;
+                       lock_cluster_or_swap_info(si, offset);
                }
        }
+       unlock_cluster_or_swap_info(si, ci);
 }
 
+#ifdef CONFIG_THP_SWAP
 int split_swap_cluster(swp_entry_t entry)
 {
        struct swap_info_struct *si;
@@ -1255,19 +1273,7 @@ int split_swap_cluster(swp_entry_t entry)
        unlock_cluster(ci);
        return 0;
 }
-#else
-static inline void swapcache_free_cluster(swp_entry_t entry)
-{
-}
-#endif /* CONFIG_THP_SWAP */
-
-void put_swap_page(struct page *page, swp_entry_t entry)
-{
-       if (!PageTransHuge(page))
-               swapcache_free(entry);
-       else
-               swapcache_free_cluster(entry);
-}
+#endif
 
 static int swp_entry_cmp(const void *ent1, const void *ent2)
 {
@@ -1409,7 +1415,6 @@ out:
        return count;
 }
 
-#ifdef CONFIG_THP_SWAP
 static bool swap_page_trans_huge_swapped(struct swap_info_struct *si,
                                         swp_entry_t entry)
 {
@@ -1422,12 +1427,12 @@ static bool swap_page_trans_huge_swapped(struct swap_info_struct *si,
 
        ci = lock_cluster_or_swap_info(si, offset);
        if (!ci || !cluster_is_huge(ci)) {
-               if (map[roffset] != SWAP_HAS_CACHE)
+               if (swap_count(map[roffset]))
                        ret = true;
                goto unlock_out;
        }
        for (i = 0; i < SWAPFILE_CLUSTER; i++) {
-               if (map[offset + i] != SWAP_HAS_CACHE) {
+               if (swap_count(map[offset + i])) {
                        ret = true;
                        break;
                }
@@ -1442,7 +1447,7 @@ static bool page_swapped(struct page *page)
        swp_entry_t entry;
        struct swap_info_struct *si;
 
-       if (likely(!PageTransCompound(page)))
+       if (!IS_ENABLED(CONFIG_THP_SWAP) || likely(!PageTransCompound(page)))
                return page_swapcount(page) != 0;
 
        page = compound_head(page);
@@ -1466,10 +1471,8 @@ static int page_trans_huge_map_swapcount(struct page *page, int *total_mapcount,
        /* hugetlbfs shouldn't call it */
        VM_BUG_ON_PAGE(PageHuge(page), page);
 
-       if (likely(!PageTransCompound(page))) {
-               mapcount = atomic_read(&page->_mapcount) + 1;
-               if (total_mapcount)
-                       *total_mapcount = mapcount;
+       if (!IS_ENABLED(CONFIG_THP_SWAP) || likely(!PageTransCompound(page))) {
+               mapcount = page_trans_huge_mapcount(page, total_mapcount);
                if (PageSwapCache(page))
                        swapcount = page_swapcount(page);
                if (total_swapcount)
@@ -1516,26 +1519,6 @@ static int page_trans_huge_map_swapcount(struct page *page, int *total_mapcount,
 
        return map_swapcount;
 }
-#else
-#define swap_page_trans_huge_swapped(si, entry)        swap_swapcount(si, entry)
-#define page_swapped(page)                     (page_swapcount(page) != 0)
-
-static int page_trans_huge_map_swapcount(struct page *page, int *total_mapcount,
-                                        int *total_swapcount)
-{
-       int mapcount, swapcount = 0;
-
-       /* hugetlbfs shouldn't call it */
-       VM_BUG_ON_PAGE(PageHuge(page), page);
-
-       mapcount = page_trans_huge_mapcount(page, total_mapcount);
-       if (PageSwapCache(page))
-               swapcount = page_swapcount(page);
-       if (total_swapcount)
-               *total_swapcount = swapcount;
-       return mapcount + swapcount;
-}
-#endif
 
 /*
  * We can write to an anon page without COW if there are no other references
index 3351659200e658f6f9e71ab52a854531c974910d..9e3ebd2ef65f8925b0a1f894567c0e3d98665b34 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -196,7 +196,7 @@ void *vmemdup_user(const void __user *src, size_t len)
 }
 EXPORT_SYMBOL(vmemdup_user);
 
-/*
+/**
  * strndup_user - duplicate an existing string from user space
  * @s: The string to duplicate
  * @n: Maximum number of bytes to copy, including the trailing NUL.
@@ -434,6 +434,16 @@ void *kvmalloc_node(size_t size, gfp_t flags, int node)
 }
 EXPORT_SYMBOL(kvmalloc_node);
 
+/**
+ * kvfree() - Free memory.
+ * @addr: Pointer to allocated memory.
+ *
+ * kvfree frees memory allocated by any of vmalloc(), kmalloc() or kvmalloc().
+ * It is slightly more efficient to use kfree() or vfree() if you are certain
+ * that you know which one to use.
+ *
+ * Context: Any context except NMI.
+ */
 void kvfree(const void *addr)
 {
        if (is_vmalloc_addr(addr))
index 4375b1e9bd56142b0f0d0b94fbe63d4c067ed7f4..7e7d25504651d5b666f1706ff9a0743b3c62079f 100644 (file)
@@ -408,7 +408,8 @@ void register_shrinker_prepared(struct shrinker *shrinker)
        down_write(&shrinker_rwsem);
        list_add_tail(&shrinker->list, &shrinker_list);
 #ifdef CONFIG_MEMCG_KMEM
-       idr_replace(&shrinker_idr, shrinker, shrinker->id);
+       if (shrinker->flags & SHRINKER_MEMCG_AWARE)
+               idr_replace(&shrinker_idr, shrinker, shrinker->id);
 #endif
        up_write(&shrinker_rwsem);
 }
@@ -902,7 +903,7 @@ static int __remove_mapping(struct address_space *mapping, struct page *page,
                refcount = 2;
        if (!page_ref_freeze(page, refcount))
                goto cannot_free;
-       /* note: atomic_cmpxchg in page_freeze_refs provides the smp_rmb */
+       /* note: atomic_cmpxchg in page_ref_freeze provides the smp_rmb */
        if (unlikely(PageDirty(page))) {
                page_ref_unfreeze(page, refcount);
                goto cannot_free;
index f8cceb99e732726cabd7678d30ca8236fbe5a2eb..cd2d5b9301a111aed82e6fc57a3ee0dab7d2e04c 100644 (file)
@@ -41,4 +41,3 @@ config CEPH_LIB_USE_DNS_RESOLVER
          Documentation/networking/dns_resolver.txt
 
          If unsure, say N.
-
index 12bf49772d24b93c90c49ebb87e8770f41bb3918..db09defe27d0ac9434a093fb9ca76eb8e84da94d 100644 (file)
@@ -15,4 +15,3 @@ libceph-y := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \
        auth_x.o \
        ceph_fs.o ceph_strings.o ceph_hash.o \
        pagevec.o snapshot.o string_table.o
-
index dbde2b3c3c15d5ef8cb94d9d8d2af8c262ee9a3b..fbeee068ea149e591b039706a4e26c7fa93c589e 100644 (file)
@@ -315,6 +315,22 @@ int ceph_auth_update_authorizer(struct ceph_auth_client *ac,
 }
 EXPORT_SYMBOL(ceph_auth_update_authorizer);
 
+int ceph_auth_add_authorizer_challenge(struct ceph_auth_client *ac,
+                                      struct ceph_authorizer *a,
+                                      void *challenge_buf,
+                                      int challenge_buf_len)
+{
+       int ret = 0;
+
+       mutex_lock(&ac->mutex);
+       if (ac->ops && ac->ops->add_authorizer_challenge)
+               ret = ac->ops->add_authorizer_challenge(ac, a, challenge_buf,
+                                                       challenge_buf_len);
+       mutex_unlock(&ac->mutex);
+       return ret;
+}
+EXPORT_SYMBOL(ceph_auth_add_authorizer_challenge);
+
 int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
                                      struct ceph_authorizer *a)
 {
index 41d2a0c7223640cce174698882d26bd666c6cfa6..edb7042479ed493fd60b794095671858da34138c 100644 (file)
@@ -142,4 +142,3 @@ int ceph_auth_none_init(struct ceph_auth_client *ac)
        ac->ops = &ceph_auth_none_ops;
        return 0;
 }
-
index 860ed9875791aa079ec6ee9cc3a4abc5703b4949..4158f064302e9fb7fd3e31015d15954ab2454e72 100644 (file)
@@ -26,4 +26,3 @@ struct ceph_auth_none_info {
 int ceph_auth_none_init(struct ceph_auth_client *ac);
 
 #endif
-
index 2f4a1baf5f5287065e4c8bc91779c0d6b868f081..b52732337ca6491b7510fc51f664c0785856037d 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/ceph/decode.h>
 #include <linux/ceph/auth.h>
+#include <linux/ceph/ceph_features.h>
 #include <linux/ceph/libceph.h>
 #include <linux/ceph/messenger.h>
 
@@ -70,25 +71,40 @@ static int ceph_x_encrypt(struct ceph_crypto_key *secret, void *buf,
        return sizeof(u32) + ciphertext_len;
 }
 
+static int __ceph_x_decrypt(struct ceph_crypto_key *secret, void *p,
+                           int ciphertext_len)
+{
+       struct ceph_x_encrypt_header *hdr = p;
+       int plaintext_len;
+       int ret;
+
+       ret = ceph_crypt(secret, false, p, ciphertext_len, ciphertext_len,
+                        &plaintext_len);
+       if (ret)
+               return ret;
+
+       if (le64_to_cpu(hdr->magic) != CEPHX_ENC_MAGIC) {
+               pr_err("%s bad magic\n", __func__);
+               return -EINVAL;
+       }
+
+       return plaintext_len - sizeof(*hdr);
+}
+
 static int ceph_x_decrypt(struct ceph_crypto_key *secret, void **p, void *end)
 {
-       struct ceph_x_encrypt_header *hdr = *p + sizeof(u32);
-       int ciphertext_len, plaintext_len;
+       int ciphertext_len;
        int ret;
 
        ceph_decode_32_safe(p, end, ciphertext_len, e_inval);
        ceph_decode_need(p, end, ciphertext_len, e_inval);
 
-       ret = ceph_crypt(secret, false, *p, end - *p, ciphertext_len,
-                        &plaintext_len);
-       if (ret)
+       ret = __ceph_x_decrypt(secret, *p, ciphertext_len);
+       if (ret < 0)
                return ret;
 
-       if (hdr->struct_v != 1 || le64_to_cpu(hdr->magic) != CEPHX_ENC_MAGIC)
-               return -EPERM;
-
        *p += ciphertext_len;
-       return plaintext_len - sizeof(struct ceph_x_encrypt_header);
+       return ret;
 
 e_inval:
        return -EINVAL;
@@ -149,12 +165,12 @@ static int process_one_ticket(struct ceph_auth_client *ac,
        void *dp, *dend;
        int dlen;
        char is_enc;
-       struct timespec validity;
+       struct timespec64 validity;
        void *tp, *tpend;
        void **ptp;
        struct ceph_crypto_key new_session_key = { 0 };
        struct ceph_buffer *new_ticket_blob;
-       unsigned long new_expires, new_renew_after;
+       time64_t new_expires, new_renew_after;
        u64 new_secret_id;
        int ret;
 
@@ -189,11 +205,11 @@ static int process_one_ticket(struct ceph_auth_client *ac,
        if (ret)
                goto out;
 
-       ceph_decode_timespec(&validity, dp);
+       ceph_decode_timespec64(&validity, dp);
        dp += sizeof(struct ceph_timespec);
-       new_expires = get_seconds() + validity.tv_sec;
+       new_expires = ktime_get_real_seconds() + validity.tv_sec;
        new_renew_after = new_expires - (validity.tv_sec / 4);
-       dout(" expires=%lu renew_after=%lu\n", new_expires,
+       dout(" expires=%llu renew_after=%llu\n", new_expires,
             new_renew_after);
 
        /* ticket blob for service */
@@ -275,6 +291,51 @@ bad:
        return -EINVAL;
 }
 
+/*
+ * Encode and encrypt the second part (ceph_x_authorize_b) of the
+ * authorizer.  The first part (ceph_x_authorize_a) should already be
+ * encoded.
+ */
+static int encrypt_authorizer(struct ceph_x_authorizer *au,
+                             u64 *server_challenge)
+{
+       struct ceph_x_authorize_a *msg_a;
+       struct ceph_x_authorize_b *msg_b;
+       void *p, *end;
+       int ret;
+
+       msg_a = au->buf->vec.iov_base;
+       WARN_ON(msg_a->ticket_blob.secret_id != cpu_to_le64(au->secret_id));
+       p = (void *)(msg_a + 1) + le32_to_cpu(msg_a->ticket_blob.blob_len);
+       end = au->buf->vec.iov_base + au->buf->vec.iov_len;
+
+       msg_b = p + ceph_x_encrypt_offset();
+       msg_b->struct_v = 2;
+       msg_b->nonce = cpu_to_le64(au->nonce);
+       if (server_challenge) {
+               msg_b->have_challenge = 1;
+               msg_b->server_challenge_plus_one =
+                   cpu_to_le64(*server_challenge + 1);
+       } else {
+               msg_b->have_challenge = 0;
+               msg_b->server_challenge_plus_one = 0;
+       }
+
+       ret = ceph_x_encrypt(&au->session_key, p, end - p, sizeof(*msg_b));
+       if (ret < 0)
+               return ret;
+
+       p += ret;
+       if (server_challenge) {
+               WARN_ON(p != end);
+       } else {
+               WARN_ON(p > end);
+               au->buf->vec.iov_len = p - au->buf->vec.iov_base;
+       }
+
+       return 0;
+}
+
 static void ceph_x_authorizer_cleanup(struct ceph_x_authorizer *au)
 {
        ceph_crypto_key_destroy(&au->session_key);
@@ -291,7 +352,6 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
        int maxlen;
        struct ceph_x_authorize_a *msg_a;
        struct ceph_x_authorize_b *msg_b;
-       void *p, *end;
        int ret;
        int ticket_blob_len =
                (th->ticket_blob ? th->ticket_blob->vec.iov_len : 0);
@@ -335,21 +395,13 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
        dout(" th %p secret_id %lld %lld\n", th, th->secret_id,
             le64_to_cpu(msg_a->ticket_blob.secret_id));
 
-       p = msg_a + 1;
-       p += ticket_blob_len;
-       end = au->buf->vec.iov_base + au->buf->vec.iov_len;
-
-       msg_b = p + ceph_x_encrypt_offset();
-       msg_b->struct_v = 1;
        get_random_bytes(&au->nonce, sizeof(au->nonce));
-       msg_b->nonce = cpu_to_le64(au->nonce);
-       ret = ceph_x_encrypt(&au->session_key, p, end - p, sizeof(*msg_b));
-       if (ret < 0)
+       ret = encrypt_authorizer(au, NULL);
+       if (ret) {
+               pr_err("failed to encrypt authorizer: %d", ret);
                goto out_au;
+       }
 
-       p += ret;
-       WARN_ON(p > end);
-       au->buf->vec.iov_len = p - au->buf->vec.iov_base;
        dout(" built authorizer nonce %llx len %d\n", au->nonce,
             (int)au->buf->vec.iov_len);
        return 0;
@@ -385,13 +437,13 @@ static bool need_key(struct ceph_x_ticket_handler *th)
        if (!th->have_key)
                return true;
 
-       return get_seconds() >= th->renew_after;
+       return ktime_get_real_seconds() >= th->renew_after;
 }
 
 static bool have_key(struct ceph_x_ticket_handler *th)
 {
        if (th->have_key) {
-               if (get_seconds() >= th->expires)
+               if (ktime_get_real_seconds() >= th->expires)
                        th->have_key = false;
        }
 
@@ -626,6 +678,54 @@ static int ceph_x_update_authorizer(
        return 0;
 }
 
+static int decrypt_authorize_challenge(struct ceph_x_authorizer *au,
+                                      void *challenge_buf,
+                                      int challenge_buf_len,
+                                      u64 *server_challenge)
+{
+       struct ceph_x_authorize_challenge *ch =
+           challenge_buf + sizeof(struct ceph_x_encrypt_header);
+       int ret;
+
+       /* no leading len */
+       ret = __ceph_x_decrypt(&au->session_key, challenge_buf,
+                              challenge_buf_len);
+       if (ret < 0)
+               return ret;
+       if (ret < sizeof(*ch)) {
+               pr_err("bad size %d for ceph_x_authorize_challenge\n", ret);
+               return -EINVAL;
+       }
+
+       *server_challenge = le64_to_cpu(ch->server_challenge);
+       return 0;
+}
+
+static int ceph_x_add_authorizer_challenge(struct ceph_auth_client *ac,
+                                          struct ceph_authorizer *a,
+                                          void *challenge_buf,
+                                          int challenge_buf_len)
+{
+       struct ceph_x_authorizer *au = (void *)a;
+       u64 server_challenge;
+       int ret;
+
+       ret = decrypt_authorize_challenge(au, challenge_buf, challenge_buf_len,
+                                         &server_challenge);
+       if (ret) {
+               pr_err("failed to decrypt authorize challenge: %d", ret);
+               return ret;
+       }
+
+       ret = encrypt_authorizer(au, &server_challenge);
+       if (ret) {
+               pr_err("failed to encrypt authorizer w/ challenge: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
 static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac,
                                          struct ceph_authorizer *a)
 {
@@ -637,8 +737,10 @@ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac,
        ret = ceph_x_decrypt(&au->session_key, &p, p + CEPHX_AU_ENC_BUF_LEN);
        if (ret < 0)
                return ret;
-       if (ret != sizeof(*reply))
-               return -EPERM;
+       if (ret < sizeof(*reply)) {
+               pr_err("bad size %d for ceph_x_authorize_reply\n", ret);
+               return -EINVAL;
+       }
 
        if (au->nonce + 1 != le64_to_cpu(reply->nonce_plus_one))
                ret = -EPERM;
@@ -704,26 +806,64 @@ static int calc_signature(struct ceph_x_authorizer *au, struct ceph_msg *msg,
                          __le64 *psig)
 {
        void *enc_buf = au->enc_buf;
-       struct {
-               __le32 len;
-               __le32 header_crc;
-               __le32 front_crc;
-               __le32 middle_crc;
-               __le32 data_crc;
-       } __packed *sigblock = enc_buf + ceph_x_encrypt_offset();
        int ret;
 
-       sigblock->len = cpu_to_le32(4*sizeof(u32));
-       sigblock->header_crc = msg->hdr.crc;
-       sigblock->front_crc = msg->footer.front_crc;
-       sigblock->middle_crc = msg->footer.middle_crc;
-       sigblock->data_crc =  msg->footer.data_crc;
-       ret = ceph_x_encrypt(&au->session_key, enc_buf, CEPHX_AU_ENC_BUF_LEN,
-                            sizeof(*sigblock));
-       if (ret < 0)
-               return ret;
+       if (!CEPH_HAVE_FEATURE(msg->con->peer_features, CEPHX_V2)) {
+               struct {
+                       __le32 len;
+                       __le32 header_crc;
+                       __le32 front_crc;
+                       __le32 middle_crc;
+                       __le32 data_crc;
+               } __packed *sigblock = enc_buf + ceph_x_encrypt_offset();
+
+               sigblock->len = cpu_to_le32(4*sizeof(u32));
+               sigblock->header_crc = msg->hdr.crc;
+               sigblock->front_crc = msg->footer.front_crc;
+               sigblock->middle_crc = msg->footer.middle_crc;
+               sigblock->data_crc =  msg->footer.data_crc;
+
+               ret = ceph_x_encrypt(&au->session_key, enc_buf,
+                                    CEPHX_AU_ENC_BUF_LEN, sizeof(*sigblock));
+               if (ret < 0)
+                       return ret;
+
+               *psig = *(__le64 *)(enc_buf + sizeof(u32));
+       } else {
+               struct {
+                       __le32 header_crc;
+                       __le32 front_crc;
+                       __le32 front_len;
+                       __le32 middle_crc;
+                       __le32 middle_len;
+                       __le32 data_crc;
+                       __le32 data_len;
+                       __le32 seq_lower_word;
+               } __packed *sigblock = enc_buf;
+               struct {
+                       __le64 a, b, c, d;
+               } __packed *penc = enc_buf;
+               int ciphertext_len;
+
+               sigblock->header_crc = msg->hdr.crc;
+               sigblock->front_crc = msg->footer.front_crc;
+               sigblock->front_len = msg->hdr.front_len;
+               sigblock->middle_crc = msg->footer.middle_crc;
+               sigblock->middle_len = msg->hdr.middle_len;
+               sigblock->data_crc =  msg->footer.data_crc;
+               sigblock->data_len = msg->hdr.data_len;
+               sigblock->seq_lower_word = *(__le32 *)&msg->hdr.seq;
+
+               /* no leading len, no ceph_x_encrypt_header */
+               ret = ceph_crypt(&au->session_key, true, enc_buf,
+                                CEPHX_AU_ENC_BUF_LEN, sizeof(*sigblock),
+                                &ciphertext_len);
+               if (ret)
+                       return ret;
+
+               *psig = penc->a ^ penc->b ^ penc->c ^ penc->d;
+       }
 
-       *psig = *(__le64 *)(enc_buf + sizeof(u32));
        return 0;
 }
 
@@ -778,6 +918,7 @@ static const struct ceph_auth_client_ops ceph_x_ops = {
        .handle_reply = ceph_x_handle_reply,
        .create_authorizer = ceph_x_create_authorizer,
        .update_authorizer = ceph_x_update_authorizer,
+       .add_authorizer_challenge = ceph_x_add_authorizer_challenge,
        .verify_authorizer_reply = ceph_x_verify_authorizer_reply,
        .invalidate_authorizer = ceph_x_invalidate_authorizer,
        .reset =  ceph_x_reset,
@@ -823,5 +964,3 @@ out_nomem:
 out:
        return ret;
 }
-
-
index 454cb54568aff249856309200bf6ca43054cd679..c03735f96df930894a8a7bf68a426548cbbcbc93 100644 (file)
@@ -22,7 +22,7 @@ struct ceph_x_ticket_handler {
        u64 secret_id;
        struct ceph_buffer *ticket_blob;
 
-       unsigned long renew_after, expires;
+       time64_t renew_after, expires;
 };
 
 #define CEPHX_AU_ENC_BUF_LEN   128  /* big enough for encrypted blob */
@@ -52,4 +52,3 @@ struct ceph_x_info {
 int ceph_x_init(struct ceph_auth_client *ac);
 
 #endif
-
index 32c13d763b9a4291bc5bbee195542d8e5163f9bf..24b0b74564d0c9b93d612825744209e55a926b2a 100644 (file)
@@ -70,6 +70,13 @@ struct ceph_x_authorize_a {
 struct ceph_x_authorize_b {
        __u8 struct_v;
        __le64 nonce;
+       __u8 have_challenge;
+       __le64 server_challenge_plus_one;
+} __attribute__ ((packed));
+
+struct ceph_x_authorize_challenge {
+       __u8 struct_v;
+       __le64 server_challenge;
 } __attribute__ ((packed));
 
 struct ceph_x_authorize_reply {
index 584fdbef2088cf7eaa6ad8fea103dc6aa42b6ce9..87afb9ec4c68962b73f96263c60f907e36eb2152 100644 (file)
@@ -304,7 +304,7 @@ static int get_secret(struct ceph_crypto_key *dst, const char *name) {
        struct ceph_crypto_key *ckey;
 
        ukey = request_key(&key_type_ceph, name, NULL);
-       if (!ukey || IS_ERR(ukey)) {
+       if (IS_ERR(ukey)) {
                /* request_key errors don't map nicely to mount(2)
                   errors; don't even try, but still printk */
                key_err = PTR_ERR(ukey);
@@ -379,7 +379,7 @@ ceph_parse_options(char *options, const char *dev_name,
 
        /* parse mount options */
        while ((c = strsep(&options, ",")) != NULL) {
-               int token, intval, ret;
+               int token, intval;
                if (!*c)
                        continue;
                err = -EINVAL;
@@ -394,11 +394,10 @@ ceph_parse_options(char *options, const char *dev_name,
                        continue;
                }
                if (token < Opt_last_int) {
-                       ret = match_int(&argstr[0], &intval);
-                       if (ret < 0) {
-                               pr_err("bad mount option arg (not int) "
-                                      "at '%s'\n", c);
-                               continue;
+                       err = match_int(&argstr[0], &intval);
+                       if (err < 0) {
+                               pr_err("bad option arg (not int) at '%s'\n", c);
+                               goto out;
                        }
                        dout("got int token %d val %d\n", token, intval);
                } else if (token > Opt_last_int && token < Opt_last_string) {
index 8d2032b2f2250e174b0bf02cedc4bea28ff47959..2105a6eaa66cdaa038e43363341d3dff2896d1a9 100644 (file)
@@ -32,7 +32,7 @@ int ceph_cls_lock(struct ceph_osd_client *osdc,
        int desc_len = strlen(desc);
        void *p, *end;
        struct page *lock_op_page;
-       struct timespec mtime;
+       struct timespec64 mtime;
        int ret;
 
        lock_op_buf_size = name_len + sizeof(__le32) +
@@ -63,7 +63,7 @@ int ceph_cls_lock(struct ceph_osd_client *osdc,
        ceph_encode_string(&p, end, desc, desc_len);
        /* only support infinite duration */
        memset(&mtime, 0, sizeof(mtime));
-       ceph_encode_timespec(p, &mtime);
+       ceph_encode_timespec64(p, &mtime);
        p += sizeof(struct ceph_timespec);
        ceph_encode_8(&p, flags);
 
index 417df675c71b0a2e53a25b0f7e9195c6f3c7804e..3f323ed9df52fe2acf37919827c5cc79f9382a05 100644 (file)
@@ -514,7 +514,7 @@ static int crush_choose_firstn(const struct crush_map *map,
                                                in, work->work[-1-in->id],
                                                x, r,
                                                (choose_args ?
-                                                &choose_args[-1-in->id] : 0),
+                                                &choose_args[-1-in->id] : NULL),
                                                outpos);
                                if (item >= map->max_devices) {
                                        dprintk("   bad item %d\n", item);
@@ -725,7 +725,7 @@ static void crush_choose_indep(const struct crush_map *map,
                                        in, work->work[-1-in->id],
                                        x, r,
                                        (choose_args ?
-                                        &choose_args[-1-in->id] : 0),
+                                        &choose_args[-1-in->id] : NULL),
                                        outpos);
                                if (item >= map->max_devices) {
                                        dprintk("   bad item %d\n", item);
index c6413c3607712de1d20e2b6010433434395020be..0a187196aeede6375b817a102890f024b552bc3f 100644 (file)
@@ -1417,11 +1417,11 @@ static void prepare_write_keepalive(struct ceph_connection *con)
        dout("prepare_write_keepalive %p\n", con);
        con_out_kvec_reset(con);
        if (con->peer_features & CEPH_FEATURE_MSGR_KEEPALIVE2) {
-               struct timespec now;
+               struct timespec64 now;
 
-               ktime_get_real_ts(&now);
+               ktime_get_real_ts64(&now);
                con_out_kvec_add(con, sizeof(tag_keepalive2), &tag_keepalive2);
-               ceph_encode_timespec(&con->out_temp_keepalive2, &now);
+               ceph_encode_timespec64(&con->out_temp_keepalive2, &now);
                con_out_kvec_add(con, sizeof(con->out_temp_keepalive2),
                                 &con->out_temp_keepalive2);
        } else {
@@ -1434,24 +1434,26 @@ static void prepare_write_keepalive(struct ceph_connection *con)
  * Connection negotiation.
  */
 
-static struct ceph_auth_handshake *get_connect_authorizer(struct ceph_connection *con,
-                                               int *auth_proto)
+static int get_connect_authorizer(struct ceph_connection *con)
 {
        struct ceph_auth_handshake *auth;
+       int auth_proto;
 
        if (!con->ops->get_authorizer) {
+               con->auth = NULL;
                con->out_connect.authorizer_protocol = CEPH_AUTH_UNKNOWN;
                con->out_connect.authorizer_len = 0;
-               return NULL;
+               return 0;
        }
 
-       auth = con->ops->get_authorizer(con, auth_proto, con->auth_retry);
+       auth = con->ops->get_authorizer(con, &auth_proto, con->auth_retry);
        if (IS_ERR(auth))
-               return auth;
+               return PTR_ERR(auth);
 
-       con->auth_reply_buf = auth->authorizer_reply_buf;
-       con->auth_reply_buf_len = auth->authorizer_reply_buf_len;
-       return auth;
+       con->auth = auth;
+       con->out_connect.authorizer_protocol = cpu_to_le32(auth_proto);
+       con->out_connect.authorizer_len = cpu_to_le32(auth->authorizer_buf_len);
+       return 0;
 }
 
 /*
@@ -1467,12 +1469,22 @@ static void prepare_write_banner(struct ceph_connection *con)
        con_flag_set(con, CON_FLAG_WRITE_PENDING);
 }
 
+static void __prepare_write_connect(struct ceph_connection *con)
+{
+       con_out_kvec_add(con, sizeof(con->out_connect), &con->out_connect);
+       if (con->auth)
+               con_out_kvec_add(con, con->auth->authorizer_buf_len,
+                                con->auth->authorizer_buf);
+
+       con->out_more = 0;
+       con_flag_set(con, CON_FLAG_WRITE_PENDING);
+}
+
 static int prepare_write_connect(struct ceph_connection *con)
 {
        unsigned int global_seq = get_global_seq(con->msgr, 0);
        int proto;
-       int auth_proto;
-       struct ceph_auth_handshake *auth;
+       int ret;
 
        switch (con->peer_name.type) {
        case CEPH_ENTITY_TYPE_MON:
@@ -1499,24 +1511,11 @@ static int prepare_write_connect(struct ceph_connection *con)
        con->out_connect.protocol_version = cpu_to_le32(proto);
        con->out_connect.flags = 0;
 
-       auth_proto = CEPH_AUTH_UNKNOWN;
-       auth = get_connect_authorizer(con, &auth_proto);
-       if (IS_ERR(auth))
-               return PTR_ERR(auth);
-
-       con->out_connect.authorizer_protocol = cpu_to_le32(auth_proto);
-       con->out_connect.authorizer_len = auth ?
-               cpu_to_le32(auth->authorizer_buf_len) : 0;
-
-       con_out_kvec_add(con, sizeof (con->out_connect),
-                                       &con->out_connect);
-       if (auth && auth->authorizer_buf_len)
-               con_out_kvec_add(con, auth->authorizer_buf_len,
-                                       auth->authorizer_buf);
-
-       con->out_more = 0;
-       con_flag_set(con, CON_FLAG_WRITE_PENDING);
+       ret = get_connect_authorizer(con);
+       if (ret)
+               return ret;
 
+       __prepare_write_connect(con);
        return 0;
 }
 
@@ -1781,11 +1780,21 @@ static int read_partial_connect(struct ceph_connection *con)
        if (ret <= 0)
                goto out;
 
-       size = le32_to_cpu(con->in_reply.authorizer_len);
-       end += size;
-       ret = read_partial(con, end, size, con->auth_reply_buf);
-       if (ret <= 0)
-               goto out;
+       if (con->auth) {
+               size = le32_to_cpu(con->in_reply.authorizer_len);
+               if (size > con->auth->authorizer_reply_buf_len) {
+                       pr_err("authorizer reply too big: %d > %zu\n", size,
+                              con->auth->authorizer_reply_buf_len);
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               end += size;
+               ret = read_partial(con, end, size,
+                                  con->auth->authorizer_reply_buf);
+               if (ret <= 0)
+                       goto out;
+       }
 
        dout("read_partial_connect %p tag %d, con_seq = %u, g_seq = %u\n",
             con, (int)con->in_reply.tag,
@@ -1793,7 +1802,6 @@ static int read_partial_connect(struct ceph_connection *con)
             le32_to_cpu(con->in_reply.global_seq));
 out:
        return ret;
-
 }
 
 /*
@@ -2076,12 +2084,27 @@ static int process_connect(struct ceph_connection *con)
 
        dout("process_connect on %p tag %d\n", con, (int)con->in_tag);
 
-       if (con->auth_reply_buf) {
+       if (con->auth) {
                /*
                 * Any connection that defines ->get_authorizer()
-                * should also define ->verify_authorizer_reply().
+                * should also define ->add_authorizer_challenge() and
+                * ->verify_authorizer_reply().
+                *
                 * See get_connect_authorizer().
                 */
+               if (con->in_reply.tag == CEPH_MSGR_TAG_CHALLENGE_AUTHORIZER) {
+                       ret = con->ops->add_authorizer_challenge(
+                                   con, con->auth->authorizer_reply_buf,
+                                   le32_to_cpu(con->in_reply.authorizer_len));
+                       if (ret < 0)
+                               return ret;
+
+                       con_out_kvec_reset(con);
+                       __prepare_write_connect(con);
+                       prepare_read_connect(con);
+                       return 0;
+               }
+
                ret = con->ops->verify_authorizer_reply(con);
                if (ret < 0) {
                        con->error_msg = "bad authorize reply";
@@ -2555,7 +2578,7 @@ static int read_keepalive_ack(struct ceph_connection *con)
        int ret = read_partial(con, size, size, &ceph_ts);
        if (ret <= 0)
                return ret;
-       ceph_decode_timespec(&con->last_keepalive_ack, &ceph_ts);
+       ceph_decode_timespec64(&con->last_keepalive_ack, &ceph_ts);
        prepare_read_tag(con);
        return 1;
 }
@@ -3223,12 +3246,12 @@ bool ceph_con_keepalive_expired(struct ceph_connection *con,
 {
        if (interval > 0 &&
            (con->peer_features & CEPH_FEATURE_MSGR_KEEPALIVE2)) {
-               struct timespec now;
-               struct timespec ts;
-               ktime_get_real_ts(&now);
-               jiffies_to_timespec(interval, &ts);
-               ts = timespec_add(con->last_keepalive_ack, ts);
-               return timespec_compare(&now, &ts) >= 0;
+               struct timespec64 now;
+               struct timespec64 ts;
+               ktime_get_real_ts64(&now);
+               jiffies_to_timespec64(interval, &ts);
+               ts = timespec64_add(con->last_keepalive_ack, ts);
+               return timespec64_compare(&now, &ts) >= 0;
        }
        return false;
 }
index d7a7a2330ef780cebf3b2b7b99b8b094130b6386..18deb3d889c4ae94a10417457fa0275a77568b48 100644 (file)
@@ -1249,7 +1249,7 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
                if (monc->client->extra_mon_dispatch &&
                    monc->client->extra_mon_dispatch(monc->client, msg) == 0)
                        break;
-                       
+
                pr_err("received unknown message type %d %s\n", type,
                       ceph_msg_type_name(type));
        }
index a00c74f1154e3a16902c3c788de921c601efe12b..60934bd8796c53c5ec96477e1c29fb9e8234e804 100644 (file)
@@ -1978,7 +1978,7 @@ static void encode_request_partial(struct ceph_osd_request *req,
        p += sizeof(struct ceph_blkin_trace_info);
 
        ceph_encode_32(&p, 0); /* client_inc, always 0 */
-       ceph_encode_timespec(p, &req->r_mtime);
+       ceph_encode_timespec64(p, &req->r_mtime);
        p += sizeof(struct ceph_timespec);
 
        encode_oloc(&p, end, &req->r_t.target_oloc);
@@ -4512,7 +4512,7 @@ ceph_osdc_watch(struct ceph_osd_client *osdc,
        ceph_oid_copy(&lreq->t.base_oid, oid);
        ceph_oloc_copy(&lreq->t.base_oloc, oloc);
        lreq->t.flags = CEPH_OSD_FLAG_WRITE;
-       ktime_get_real_ts(&lreq->mtime);
+       ktime_get_real_ts64(&lreq->mtime);
 
        lreq->reg_req = alloc_linger_request(lreq);
        if (!lreq->reg_req) {
@@ -4570,7 +4570,7 @@ int ceph_osdc_unwatch(struct ceph_osd_client *osdc,
        ceph_oid_copy(&req->r_base_oid, &lreq->t.base_oid);
        ceph_oloc_copy(&req->r_base_oloc, &lreq->t.base_oloc);
        req->r_flags = CEPH_OSD_FLAG_WRITE;
-       ktime_get_real_ts(&req->r_mtime);
+       ktime_get_real_ts64(&req->r_mtime);
        osd_req_op_watch_init(req, 0, lreq->linger_id,
                              CEPH_OSD_WATCH_OP_UNWATCH);
 
@@ -4591,7 +4591,7 @@ EXPORT_SYMBOL(ceph_osdc_unwatch);
 
 static int osd_req_op_notify_ack_init(struct ceph_osd_request *req, int which,
                                      u64 notify_id, u64 cookie, void *payload,
-                                     size_t payload_len)
+                                     u32 payload_len)
 {
        struct ceph_osd_req_op *op;
        struct ceph_pagelist *pl;
@@ -4628,7 +4628,7 @@ int ceph_osdc_notify_ack(struct ceph_osd_client *osdc,
                         u64 notify_id,
                         u64 cookie,
                         void *payload,
-                        size_t payload_len)
+                        u32 payload_len)
 {
        struct ceph_osd_request *req;
        int ret;
@@ -4661,7 +4661,7 @@ EXPORT_SYMBOL(ceph_osdc_notify_ack);
 
 static int osd_req_op_notify_init(struct ceph_osd_request *req, int which,
                                  u64 cookie, u32 prot_ver, u32 timeout,
-                                 void *payload, size_t payload_len)
+                                 void *payload, u32 payload_len)
 {
        struct ceph_osd_req_op *op;
        struct ceph_pagelist *pl;
@@ -4701,7 +4701,7 @@ int ceph_osdc_notify(struct ceph_osd_client *osdc,
                     struct ceph_object_id *oid,
                     struct ceph_object_locator *oloc,
                     void *payload,
-                    size_t payload_len,
+                    u32 payload_len,
                     u32 timeout,
                     struct page ***preply_pages,
                     size_t *preply_len)
@@ -5136,7 +5136,7 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
                         struct ceph_snap_context *snapc,
                         u64 off, u64 len,
                         u32 truncate_seq, u64 truncate_size,
-                        struct timespec *mtime,
+                        struct timespec64 *mtime,
                         struct page **pages, int num_pages)
 {
        struct ceph_osd_request *req;
@@ -5393,6 +5393,16 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con,
        return auth;
 }
 
+static int add_authorizer_challenge(struct ceph_connection *con,
+                                   void *challenge_buf, int challenge_buf_len)
+{
+       struct ceph_osd *o = con->private;
+       struct ceph_osd_client *osdc = o->o_osdc;
+       struct ceph_auth_client *ac = osdc->client->monc.auth;
+
+       return ceph_auth_add_authorizer_challenge(ac, o->o_auth.authorizer,
+                                           challenge_buf, challenge_buf_len);
+}
 
 static int verify_authorizer_reply(struct ceph_connection *con)
 {
@@ -5442,6 +5452,7 @@ static const struct ceph_connection_operations osd_con_ops = {
        .put = put_osd_con,
        .dispatch = dispatch,
        .get_authorizer = get_authorizer,
+       .add_authorizer_challenge = add_authorizer_challenge,
        .verify_authorizer_reply = verify_authorizer_reply,
        .invalidate_authorizer = invalidate_authorizer,
        .alloc_msg = alloc_msg,
index e560d3975f41cb89827017b1e920e43648d5b453..d3736f5bffec695aa94ea6dfb05be8319a3d195f 100644 (file)
@@ -197,4 +197,3 @@ void ceph_zero_page_vector_range(int off, int len, struct page **pages)
        }
 }
 EXPORT_SYMBOL(ceph_zero_page_vector_range);
-
index 325fc5088370b5b0f06daaaf990c5cee86dfecce..82114e1111e6558d5b8ecc2207aac679e21698c6 100644 (file)
@@ -93,7 +93,6 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
-#include <linux/notifier.h>
 #include <linux/skbuff.h>
 #include <linux/bpf.h>
 #include <linux/bpf_trace.h>
index c25eb36f13204e0df620e6d9eb76783fe67ad243..aecdeba052d3f0ff3d4f0a33ec36891f9738052c 100644 (file)
@@ -2282,14 +2282,21 @@ static const struct bpf_func_proto bpf_msg_cork_bytes_proto = {
        .arg2_type      = ARG_ANYTHING,
 };
 
+#define sk_msg_iter_var(var)                   \
+       do {                                    \
+               var++;                          \
+               if (var == MAX_SKB_FRAGS)       \
+                       var = 0;                \
+       } while (0)
+
 BPF_CALL_4(bpf_msg_pull_data,
           struct sk_msg_buff *, msg, u32, start, u32, end, u64, flags)
 {
-       unsigned int len = 0, offset = 0, copy = 0;
+       unsigned int len = 0, offset = 0, copy = 0, poffset = 0;
+       int bytes = end - start, bytes_sg_total;
        struct scatterlist *sg = msg->sg_data;
        int first_sg, last_sg, i, shift;
        unsigned char *p, *to, *from;
-       int bytes = end - start;
        struct page *page;
 
        if (unlikely(flags || end <= start))
@@ -2299,21 +2306,22 @@ BPF_CALL_4(bpf_msg_pull_data,
        i = msg->sg_start;
        do {
                len = sg[i].length;
-               offset += len;
                if (start < offset + len)
                        break;
-               i++;
-               if (i == MAX_SKB_FRAGS)
-                       i = 0;
+               offset += len;
+               sk_msg_iter_var(i);
        } while (i != msg->sg_end);
 
        if (unlikely(start >= offset + len))
                return -EINVAL;
 
-       if (!msg->sg_copy[i] && bytes <= len)
-               goto out;
-
        first_sg = i;
+       /* The start may point into the sg element so we need to also
+        * account for the headroom.
+        */
+       bytes_sg_total = start - offset + bytes;
+       if (!msg->sg_copy[i] && bytes_sg_total <= len)
+               goto out;
 
        /* At this point we need to linearize multiple scatterlist
         * elements or a single shared page. Either way we need to
@@ -2327,37 +2335,32 @@ BPF_CALL_4(bpf_msg_pull_data,
         */
        do {
                copy += sg[i].length;
-               i++;
-               if (i == MAX_SKB_FRAGS)
-                       i = 0;
-               if (bytes < copy)
+               sk_msg_iter_var(i);
+               if (bytes_sg_total <= copy)
                        break;
        } while (i != msg->sg_end);
        last_sg = i;
 
-       if (unlikely(copy < end - start))
+       if (unlikely(bytes_sg_total > copy))
                return -EINVAL;
 
        page = alloc_pages(__GFP_NOWARN | GFP_ATOMIC, get_order(copy));
        if (unlikely(!page))
                return -ENOMEM;
        p = page_address(page);
-       offset = 0;
 
        i = first_sg;
        do {
                from = sg_virt(&sg[i]);
                len = sg[i].length;
-               to = p + offset;
+               to = p + poffset;
 
                memcpy(to, from, len);
-               offset += len;
+               poffset += len;
                sg[i].length = 0;
                put_page(sg_page(&sg[i]));
 
-               i++;
-               if (i == MAX_SKB_FRAGS)
-                       i = 0;
+               sk_msg_iter_var(i);
        } while (i != last_sg);
 
        sg[first_sg].length = copy;
@@ -2367,11 +2370,15 @@ BPF_CALL_4(bpf_msg_pull_data,
         * had a single entry though we can just replace it and
         * be done. Otherwise walk the ring and shift the entries.
         */
-       shift = last_sg - first_sg - 1;
+       WARN_ON_ONCE(last_sg == first_sg);
+       shift = last_sg > first_sg ?
+               last_sg - first_sg - 1 :
+               MAX_SKB_FRAGS - first_sg + last_sg - 1;
        if (!shift)
                goto out;
 
-       i = first_sg + 1;
+       i = first_sg;
+       sk_msg_iter_var(i);
        do {
                int move_from;
 
@@ -2388,15 +2395,13 @@ BPF_CALL_4(bpf_msg_pull_data,
                sg[move_from].page_link = 0;
                sg[move_from].offset = 0;
 
-               i++;
-               if (i == MAX_SKB_FRAGS)
-                       i = 0;
+               sk_msg_iter_var(i);
        } while (1);
        msg->sg_end -= shift;
        if (msg->sg_end < 0)
                msg->sg_end += MAX_SKB_FRAGS;
 out:
-       msg->data = sg_virt(&sg[i]) + start - offset;
+       msg->data = sg_virt(&sg[first_sg]) + start - offset;
        msg->data_end = msg->data + bytes;
 
        return 0;
@@ -7281,7 +7286,7 @@ static u32 sk_reuseport_convert_ctx_access(enum bpf_access_type type,
                break;
 
        case offsetof(struct sk_reuseport_md, ip_protocol):
-               BUILD_BUG_ON(hweight_long(SK_FL_PROTO_MASK) != BITS_PER_BYTE);
+               BUILD_BUG_ON(HWEIGHT32(SK_FL_PROTO_MASK) != BITS_PER_BYTE);
                SK_REUSEPORT_LOAD_SK_FIELD_SIZE_OFF(__sk_flags_offset,
                                                    BPF_W, 0);
                *insn++ = BPF_ALU32_IMM(BPF_AND, si->dst_reg, SK_FL_PROTO_MASK);
index 738871af5efaa246b55c1803259e98f67a60ae54..670c84b1bfc23bbb9dde13b4df21a503350d390e 100644 (file)
@@ -1001,22 +1001,18 @@ static int register_pernet_operations(struct list_head *list,
        int error;
 
        if (ops->id) {
-again:
-               error = ida_get_new_above(&net_generic_ids, MIN_PERNET_OPS_ID, ops->id);
-               if (error < 0) {
-                       if (error == -EAGAIN) {
-                               ida_pre_get(&net_generic_ids, GFP_KERNEL);
-                               goto again;
-                       }
+               error = ida_alloc_min(&net_generic_ids, MIN_PERNET_OPS_ID,
+                               GFP_KERNEL);
+               if (error < 0)
                        return error;
-               }
+               *ops->id = error;
                max_gen_ptrs = max(max_gen_ptrs, *ops->id + 1);
        }
        error = __register_pernet_operations(list, ops);
        if (error) {
                rcu_barrier();
                if (ops->id)
-                       ida_remove(&net_generic_ids, *ops->id);
+                       ida_free(&net_generic_ids, *ops->id);
        }
 
        return error;
@@ -1027,7 +1023,7 @@ static void unregister_pernet_operations(struct pernet_operations *ops)
        __unregister_pernet_operations(ops);
        rcu_barrier();
        if (ops->id)
-               ida_remove(&net_generic_ids, *ops->id);
+               ida_free(&net_generic_ids, *ops->id);
 }
 
 /**
index 24431e578310cb1602c05ea26a24069d49309c74..60c928894a7868e5f1bcec39f5204eba9e0fe82f 100644 (file)
@@ -324,6 +324,10 @@ void rtnl_unregister_all(int protocol)
 
        rtnl_lock();
        tab = rtnl_msg_handlers[protocol];
+       if (!tab) {
+               rtnl_unlock();
+               return;
+       }
        RCU_INIT_POINTER(rtnl_msg_handlers[protocol], NULL);
        for (msgindex = 0; msgindex < RTM_NR_MSGTYPES; msgindex++) {
                link = tab[msgindex];
index e63c554e0623e54971ed90af69ff0d0c35ecebad..9f3209ff7ffde754230720ca9117111fdbd7c3bc 100644 (file)
 #include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 #include <linux/of_net.h>
-#include <linux/of_gpio.h>
 #include <linux/netdevice.h>
 #include <linux/sysfs.h>
 #include <linux/phy_fixed.h>
 #include <linux/ptp_classify.h>
-#include <linux/gpio/consumer.h>
 #include <linux/etherdevice.h>
 
 #include "dsa_priv.h"
index 962c4fd338ba57e4344eeb62a648de59a5460c36..1c45c1d6d241dbcca8542c51eb0f25b903131756 100644 (file)
@@ -767,7 +767,6 @@ static int dsa_slave_add_cls_matchall(struct net_device *dev,
        const struct tc_action *a;
        struct dsa_port *to_dp;
        int err = -EOPNOTSUPP;
-       LIST_HEAD(actions);
 
        if (!ds->ops->port_mirror_add)
                return err;
@@ -775,8 +774,7 @@ static int dsa_slave_add_cls_matchall(struct net_device *dev,
        if (!tcf_exts_has_one_action(cls->exts))
                return err;
 
-       tcf_exts_to_list(cls->exts, &actions);
-       a = list_first_entry(&actions, struct tc_action, list);
+       a = tcf_exts_first_action(cls->exts);
 
        if (is_tcf_mirred_egress_mirror(a) && protocol == htons(ETH_P_ALL)) {
                struct dsa_mall_mirror_tc_entry *mirror;
index cf75f8944b05eb302c11cd8e2e0e9f762ab7e35c..4da39446da2d89b529973eb33902577a0e6cbb54 100644 (file)
@@ -820,10 +820,9 @@ static void igmp_timer_expire(struct timer_list *t)
        spin_lock(&im->lock);
        im->tm_running = 0;
 
-       if (im->unsolicit_count) {
-               im->unsolicit_count--;
+       if (im->unsolicit_count && --im->unsolicit_count)
                igmp_start_timer(im, unsolicited_report_interval(in_dev));
-       }
+
        im->reporter = 1;
        spin_unlock(&im->lock);
 
@@ -1308,6 +1307,8 @@ static void igmp_group_added(struct ip_mc_list *im)
 
        if (in_dev->dead)
                return;
+
+       im->unsolicit_count = net->ipv4.sysctl_igmp_qrv;
        if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev)) {
                spin_lock_bh(&im->lock);
                igmp_start_timer(im, IGMP_INITIAL_REPORT_DELAY);
@@ -1391,9 +1392,6 @@ static void __ip_mc_inc_group(struct in_device *in_dev, __be32 addr,
                              unsigned int mode)
 {
        struct ip_mc_list *im;
-#ifdef CONFIG_IP_MULTICAST
-       struct net *net = dev_net(in_dev->dev);
-#endif
 
        ASSERT_RTNL();
 
@@ -1420,7 +1418,6 @@ static void __ip_mc_inc_group(struct in_device *in_dev, __be32 addr,
        spin_lock_init(&im->lock);
 #ifdef CONFIG_IP_MULTICAST
        timer_setup(&im->timer, igmp_timer_expire, 0);
-       im->unsolicit_count = net->ipv4.sysctl_igmp_qrv;
 #endif
 
        im->next_rcu = in_dev->mc_list;
index 51a5d06085ac44777c622a58476d7700d7bc0a97..ae714aecc31c030cdce19fc5b2e92eb6ca214a16 100644 (file)
@@ -1508,11 +1508,14 @@ nla_put_failure:
 
 static void erspan_setup(struct net_device *dev)
 {
+       struct ip_tunnel *t = netdev_priv(dev);
+
        ether_setup(dev);
        dev->netdev_ops = &erspan_netdev_ops;
        dev->priv_flags &= ~IFF_TX_SKB_SHARING;
        dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
        ip_tunnel_setup(dev, erspan_net_id);
+       t->erspan_ver = 1;
 }
 
 static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
index 13d34427ca3dd5bee810395ba4a1ab9759863182..02ff2dde96094cf33b662a20994424a7adea509e 100644 (file)
@@ -95,11 +95,10 @@ struct bbr {
        u32     mode:3,              /* current bbr_mode in state machine */
                prev_ca_state:3,     /* CA state on previous ACK */
                packet_conservation:1,  /* use packet conservation? */
-               restore_cwnd:1,      /* decided to revert cwnd to old value */
                round_start:1,       /* start of packet-timed tx->ack round? */
                idle_restart:1,      /* restarting after idle? */
                probe_rtt_round_done:1,  /* a BBR_PROBE_RTT round at 4 pkts? */
-               unused:12,
+               unused:13,
                lt_is_sampling:1,    /* taking long-term ("LT") samples now? */
                lt_rtt_cnt:7,        /* round trips in long-term interval */
                lt_use_bw:1;         /* use lt_bw as our bw estimate? */
@@ -175,6 +174,8 @@ static const u32 bbr_lt_bw_diff = 4000 / 8;
 /* If we estimate we're policed, use lt_bw for this many round trips: */
 static const u32 bbr_lt_bw_max_rtts = 48;
 
+static void bbr_check_probe_rtt_done(struct sock *sk);
+
 /* Do we estimate that STARTUP filled the pipe? */
 static bool bbr_full_bw_reached(const struct sock *sk)
 {
@@ -309,6 +310,8 @@ static void bbr_cwnd_event(struct sock *sk, enum tcp_ca_event event)
                 */
                if (bbr->mode == BBR_PROBE_BW)
                        bbr_set_pacing_rate(sk, bbr_bw(sk), BBR_UNIT);
+               else if (bbr->mode == BBR_PROBE_RTT)
+                       bbr_check_probe_rtt_done(sk);
        }
 }
 
@@ -396,17 +399,11 @@ static bool bbr_set_cwnd_to_recover_or_restore(
                cwnd = tcp_packets_in_flight(tp) + acked;
        } else if (prev_state >= TCP_CA_Recovery && state < TCP_CA_Recovery) {
                /* Exiting loss recovery; restore cwnd saved before recovery. */
-               bbr->restore_cwnd = 1;
+               cwnd = max(cwnd, bbr->prior_cwnd);
                bbr->packet_conservation = 0;
        }
        bbr->prev_ca_state = state;
 
-       if (bbr->restore_cwnd) {
-               /* Restore cwnd after exiting loss recovery or PROBE_RTT. */
-               cwnd = max(cwnd, bbr->prior_cwnd);
-               bbr->restore_cwnd = 0;
-       }
-
        if (bbr->packet_conservation) {
                *new_cwnd = max(cwnd, tcp_packets_in_flight(tp) + acked);
                return true;    /* yes, using packet conservation */
@@ -423,10 +420,10 @@ static void bbr_set_cwnd(struct sock *sk, const struct rate_sample *rs,
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct bbr *bbr = inet_csk_ca(sk);
-       u32 cwnd = 0, target_cwnd = 0;
+       u32 cwnd = tp->snd_cwnd, target_cwnd = 0;
 
        if (!acked)
-               return;
+               goto done;  /* no packet fully ACKed; just apply caps */
 
        if (bbr_set_cwnd_to_recover_or_restore(sk, rs, acked, &cwnd))
                goto done;
@@ -748,6 +745,20 @@ static void bbr_check_drain(struct sock *sk, const struct rate_sample *rs)
                bbr_reset_probe_bw_mode(sk);  /* we estimate queue is drained */
 }
 
+static void bbr_check_probe_rtt_done(struct sock *sk)
+{
+       struct tcp_sock *tp = tcp_sk(sk);
+       struct bbr *bbr = inet_csk_ca(sk);
+
+       if (!(bbr->probe_rtt_done_stamp &&
+             after(tcp_jiffies32, bbr->probe_rtt_done_stamp)))
+               return;
+
+       bbr->min_rtt_stamp = tcp_jiffies32;  /* wait a while until PROBE_RTT */
+       tp->snd_cwnd = max(tp->snd_cwnd, bbr->prior_cwnd);
+       bbr_reset_mode(sk);
+}
+
 /* The goal of PROBE_RTT mode is to have BBR flows cooperatively and
  * periodically drain the bottleneck queue, to converge to measure the true
  * min_rtt (unloaded propagation delay). This allows the flows to keep queues
@@ -806,12 +817,8 @@ static void bbr_update_min_rtt(struct sock *sk, const struct rate_sample *rs)
                } else if (bbr->probe_rtt_done_stamp) {
                        if (bbr->round_start)
                                bbr->probe_rtt_round_done = 1;
-                       if (bbr->probe_rtt_round_done &&
-                           after(tcp_jiffies32, bbr->probe_rtt_done_stamp)) {
-                               bbr->min_rtt_stamp = tcp_jiffies32;
-                               bbr->restore_cwnd = 1;  /* snap to prior_cwnd */
-                               bbr_reset_mode(sk);
-                       }
+                       if (bbr->probe_rtt_round_done)
+                               bbr_check_probe_rtt_done(sk);
                }
        }
        /* Restart after idle ends only once we process a new S/ACK for data */
@@ -862,7 +869,6 @@ static void bbr_init(struct sock *sk)
        bbr->has_seen_rtt = 0;
        bbr_init_pacing_rate_from_rtt(sk);
 
-       bbr->restore_cwnd = 0;
        bbr->round_start = 0;
        bbr->idle_restart = 0;
        bbr->full_bw_reached = 0;
index 9e041fa5c545367961f03fa8a9124aebbc1b6c69..44c09eddbb781c03da2417aaa925e360de01a6e9 100644 (file)
@@ -2517,6 +2517,12 @@ static int __net_init tcp_sk_init(struct net *net)
                if (res)
                        goto fail;
                sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
+
+               /* Please enforce IP_DF and IPID==0 for RST and
+                * ACK sent in SYN-RECV and TIME-WAIT state.
+                */
+               inet_sk(sk)->pmtudisc = IP_PMTUDISC_DO;
+
                *per_cpu_ptr(net->ipv4.tcp_sk, cpu) = sk;
        }
 
index 75ef332a7caf44de619acf030977eba01565c70a..12affb7864d981a6494059232c4965aaee756803 100644 (file)
@@ -184,8 +184,9 @@ kill:
                                inet_twsk_deschedule_put(tw);
                                return TCP_TW_SUCCESS;
                        }
+               } else {
+                       inet_twsk_reschedule(tw, TCP_TIMEWAIT_LEN);
                }
-               inet_twsk_reschedule(tw, TCP_TIMEWAIT_LEN);
 
                if (tmp_opt.saw_tstamp) {
                        tcptw->tw_ts_recent       = tmp_opt.rcv_tsval;
index 2fac4ad748672cd62de6653d3fdedebe743c6ad0..d51a8c0b3372d09ad1c78b76f94b4ebaf7ca3f61 100644 (file)
@@ -2398,7 +2398,7 @@ static void addrconf_add_mroute(struct net_device *dev)
 
        ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0);
 
-       ip6_route_add(&cfg, GFP_ATOMIC, NULL);
+       ip6_route_add(&cfg, GFP_KERNEL, NULL);
 }
 
 static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
@@ -3062,7 +3062,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
        if (addr.s6_addr32[3]) {
                add_addr(idev, &addr, plen, scope);
                addrconf_prefix_route(&addr, plen, 0, idev->dev, 0, pflags,
-                                     GFP_ATOMIC);
+                                     GFP_KERNEL);
                return;
        }
 
@@ -3087,7 +3087,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
 
                                add_addr(idev, &addr, plen, flag);
                                addrconf_prefix_route(&addr, plen, 0, idev->dev,
-                                                     0, pflags, GFP_ATOMIC);
+                                                     0, pflags, GFP_KERNEL);
                        }
                }
        }
index 673bba31eb1807eb04ee0d0c072333000bde4305..9a4261e502727005b3ea5e26795afd747533ee9e 100644 (file)
@@ -938,14 +938,14 @@ static int __init inet6_init(void)
 
        err = proto_register(&pingv6_prot, 1);
        if (err)
-               goto out_unregister_ping_proto;
+               goto out_unregister_raw_proto;
 
        /* We MUST register RAW sockets before we create the ICMP6,
         * IGMP6, or NDISC control sockets.
         */
        err = rawv6_init();
        if (err)
-               goto out_unregister_raw_proto;
+               goto out_unregister_ping_proto;
 
        /* Register the family here so that the init calls below will
         * be able to create sockets. (?? is this dangerous ??)
@@ -1113,11 +1113,11 @@ netfilter_fail:
 igmp_fail:
        ndisc_cleanup();
 ndisc_fail:
-       ip6_mr_cleanup();
+       icmpv6_cleanup();
 icmp_fail:
-       unregister_pernet_subsys(&inet6_net_ops);
+       ip6_mr_cleanup();
 ipmr_fail:
-       icmpv6_cleanup();
+       unregister_pernet_subsys(&inet6_net_ops);
 register_pernet_fail:
        sock_unregister(PF_INET6);
        rtnl_unregister_all(PF_INET6);
index d212738e9d100d4e3270f9188466da6b8a3d186c..5516f55e214bd85ff7a07cf8c24648db327902c2 100644 (file)
@@ -198,6 +198,8 @@ void fib6_info_destroy_rcu(struct rcu_head *head)
                }
        }
 
+       lwtstate_put(f6i->fib6_nh.nh_lwtstate);
+
        if (f6i->fib6_nh.nh_dev)
                dev_put(f6i->fib6_nh.nh_dev);
 
@@ -987,7 +989,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
                                        fib6_clean_expires(iter);
                                else
                                        fib6_set_expires(iter, rt->expires);
-                               fib6_metric_set(iter, RTAX_MTU, rt->fib6_pmtu);
+
+                               if (rt->fib6_pmtu)
+                                       fib6_metric_set(iter, RTAX_MTU,
+                                                       rt->fib6_pmtu);
                                return -EEXIST;
                        }
                        /* If we have the same destination and the same metric,
index 18a3794b0f52e1dd7b8bf5179bcdcfdbd882f158..e493b041d4ac9900d44972a22ebdc898def323fe 100644 (file)
@@ -1778,6 +1778,7 @@ static void ip6gre_netlink_parms(struct nlattr *data[],
        if (data[IFLA_GRE_COLLECT_METADATA])
                parms->collect_md = true;
 
+       parms->erspan_ver = 1;
        if (data[IFLA_GRE_ERSPAN_VER])
                parms->erspan_ver = nla_get_u8(data[IFLA_GRE_ERSPAN_VER]);
 
index 5df2a58d945cc2d37fc1a30c7b850d928dcd2ccf..419960b0ba16370ec9c47bee16aad15d9819f349 100644 (file)
@@ -1188,7 +1188,15 @@ route_lookup:
                init_tel_txopt(&opt, encap_limit);
                ipv6_push_frag_opts(skb, &opt.ops, &proto);
        }
-       hop_limit = hop_limit ? : ip6_dst_hoplimit(dst);
+
+       if (hop_limit == 0) {
+               if (skb->protocol == htons(ETH_P_IP))
+                       hop_limit = ip_hdr(skb)->ttl;
+               else if (skb->protocol == htons(ETH_P_IPV6))
+                       hop_limit = ipv6_hdr(skb)->hop_limit;
+               else
+                       hop_limit = ip6_dst_hoplimit(dst);
+       }
 
        /* Calculate max headroom for all the headers and adjust
         * needed_headroom if necessary.
index 38dec9da90d338b4704a8acd4586536b467f75b9..eeaf7455d51e52f12b62ffd0c1c82e2ee09e4fc1 100644 (file)
@@ -481,7 +481,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
        }
 
        mtu = dst_mtu(dst);
-       if (!skb->ignore_df && skb->len > mtu) {
+       if (skb->len > mtu) {
                skb_dst_update_pmtu(skb, mtu);
 
                if (skb->protocol == htons(ETH_P_IPV6)) {
@@ -1094,7 +1094,8 @@ static void __net_exit vti6_destroy_tunnels(struct vti6_net *ip6n,
        }
 
        t = rtnl_dereference(ip6n->tnls_wc[0]);
-       unregister_netdevice_queue(t->dev, list);
+       if (t)
+               unregister_netdevice_queue(t->dev, list);
 }
 
 static int __net_init vti6_init_net(struct net *net)
index 7208c16302f61adc15636f6a332ff0c02325cfcf..18e00ce1719a3d16f5099ea2271d89916929074f 100644 (file)
@@ -956,7 +956,7 @@ static void ip6_rt_init_dst(struct rt6_info *rt, struct fib6_info *ort)
        rt->dst.error = 0;
        rt->dst.output = ip6_output;
 
-       if (ort->fib6_type == RTN_LOCAL) {
+       if (ort->fib6_type == RTN_LOCAL || ort->fib6_type == RTN_ANYCAST) {
                rt->dst.input = ip6_input;
        } else if (ipv6_addr_type(&ort->fib6_dst.addr) & IPV6_ADDR_MULTICAST) {
                rt->dst.input = ip6_mc_input;
@@ -996,7 +996,6 @@ static void ip6_rt_copy_init(struct rt6_info *rt, struct fib6_info *ort)
        rt->rt6i_src = ort->fib6_src;
 #endif
        rt->rt6i_prefsrc = ort->fib6_prefsrc;
-       rt->dst.lwtstate = lwtstate_get(ort->fib6_nh.nh_lwtstate);
 }
 
 static struct fib6_node* fib6_backtrack(struct fib6_node *fn,
index 6449a1c2283bf236728f36dc627de7e91c886cda..f0f5fedb8caacd164d6575ebcca9e27b19cfd516 100644 (file)
@@ -947,8 +947,8 @@ static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata,
        if (len < IEEE80211_DEAUTH_FRAME_LEN)
                return;
 
-       ibss_dbg(sdata, "RX DeAuth SA=%pM DA=%pM BSSID=%pM (reason: %d)\n",
-                mgmt->sa, mgmt->da, mgmt->bssid, reason);
+       ibss_dbg(sdata, "RX DeAuth SA=%pM DA=%pM\n", mgmt->sa, mgmt->da);
+       ibss_dbg(sdata, "\tBSSID=%pM (reason: %d)\n", mgmt->bssid, reason);
        sta_info_destroy_addr(sdata, mgmt->sa);
 }
 
@@ -966,9 +966,9 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
        auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
        auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
 
-       ibss_dbg(sdata,
-                "RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n",
-                mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction);
+       ibss_dbg(sdata, "RX Auth SA=%pM DA=%pM\n", mgmt->sa, mgmt->da);
+       ibss_dbg(sdata, "\tBSSID=%pM (auth_transaction=%d)\n",
+                mgmt->bssid, auth_transaction);
 
        if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
                return;
@@ -1175,10 +1175,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                rx_timestamp = drv_get_tsf(local, sdata);
        }
 
-       ibss_dbg(sdata,
-                "RX beacon SA=%pM BSSID=%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n",
+       ibss_dbg(sdata, "RX beacon SA=%pM BSSID=%pM TSF=0x%llx\n",
                 mgmt->sa, mgmt->bssid,
-                (unsigned long long)rx_timestamp,
+                (unsigned long long)rx_timestamp);
+       ibss_dbg(sdata, "\tBCN=0x%llx diff=%lld @%lu\n",
                 (unsigned long long)beacon_timestamp,
                 (unsigned long long)(rx_timestamp - beacon_timestamp),
                 jiffies);
@@ -1537,9 +1537,9 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
 
        tx_last_beacon = drv_tx_last_beacon(local);
 
-       ibss_dbg(sdata,
-                "RX ProbeReq SA=%pM DA=%pM BSSID=%pM (tx_last_beacon=%d)\n",
-                mgmt->sa, mgmt->da, mgmt->bssid, tx_last_beacon);
+       ibss_dbg(sdata, "RX ProbeReq SA=%pM DA=%pM\n", mgmt->sa, mgmt->da);
+       ibss_dbg(sdata, "\tBSSID=%pM (tx_last_beacon=%d)\n",
+                mgmt->bssid, tx_last_beacon);
 
        if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da))
                return;
index 4fb2709cb52796c752f052a746bd5c420d6caf08..513627896204938485ef01f0f2d76606d4418af4 100644 (file)
@@ -256,8 +256,27 @@ static void ieee80211_restart_work(struct work_struct *work)
 
        flush_work(&local->radar_detected_work);
        rtnl_lock();
-       list_for_each_entry(sdata, &local->interfaces, list)
+       list_for_each_entry(sdata, &local->interfaces, list) {
+               /*
+                * XXX: there may be more work for other vif types and even
+                * for station mode: a good thing would be to run most of
+                * the iface type's dependent _stop (ieee80211_mg_stop,
+                * ieee80211_ibss_stop) etc...
+                * For now, fix only the specific bug that was seen: race
+                * between csa_connection_drop_work and us.
+                */
+               if (sdata->vif.type == NL80211_IFTYPE_STATION) {
+                       /*
+                        * This worker is scheduled from the iface worker that
+                        * runs on mac80211's workqueue, so we can't be
+                        * scheduling this worker after the cancel right here.
+                        * The exception is ieee80211_chswitch_done.
+                        * Then we can have a race...
+                        */
+                       cancel_work_sync(&sdata->u.mgd.csa_connection_drop_work);
+               }
                flush_delayed_work(&sdata->dec_tailroom_needed_wk);
+       }
        ieee80211_scan_cancel(local);
 
        /* make sure any new ROC will consider local->in_reconfig */
@@ -471,10 +490,7 @@ static const struct ieee80211_vht_cap mac80211_vht_capa_mod_mask = {
                cpu_to_le32(IEEE80211_VHT_CAP_RXLDPC |
                            IEEE80211_VHT_CAP_SHORT_GI_80 |
                            IEEE80211_VHT_CAP_SHORT_GI_160 |
-                           IEEE80211_VHT_CAP_RXSTBC_1 |
-                           IEEE80211_VHT_CAP_RXSTBC_2 |
-                           IEEE80211_VHT_CAP_RXSTBC_3 |
-                           IEEE80211_VHT_CAP_RXSTBC_4 |
+                           IEEE80211_VHT_CAP_RXSTBC_MASK |
                            IEEE80211_VHT_CAP_TXSTBC |
                            IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
                            IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
@@ -1208,6 +1224,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
 #if IS_ENABLED(CONFIG_IPV6)
        unregister_inet6addr_notifier(&local->ifa6_notifier);
 #endif
+       ieee80211_txq_teardown_flows(local);
 
        rtnl_lock();
 
@@ -1236,7 +1253,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
        skb_queue_purge(&local->skb_queue);
        skb_queue_purge(&local->skb_queue_unreliable);
        skb_queue_purge(&local->skb_queue_tdls_chsw);
-       ieee80211_txq_teardown_flows(local);
 
        destroy_workqueue(local->workqueue);
        wiphy_unregister(local->hw.wiphy);
index 35ad3983ae4b6b26fb13f6718b692c9b9b0d6e98..daf9db3c8f24f389df84d95ae973c969d65622f1 100644 (file)
@@ -572,6 +572,10 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
                forward = false;
                reply = true;
                target_metric = 0;
+
+               if (SN_GT(target_sn, ifmsh->sn))
+                       ifmsh->sn = target_sn;
+
                if (time_after(jiffies, ifmsh->last_sn_update +
                                        net_traversal_jiffies(sdata)) ||
                    time_before(jiffies, ifmsh->last_sn_update)) {
index 7fb9957359a3c1be557e577ba5b76cc4c1177105..3dbecae4be73cb1aae05752807b717a329b80980 100644 (file)
@@ -1073,6 +1073,10 @@ static void ieee80211_chswitch_work(struct work_struct *work)
         */
 
        if (sdata->reserved_chanctx) {
+               struct ieee80211_supported_band *sband = NULL;
+               struct sta_info *mgd_sta = NULL;
+               enum ieee80211_sta_rx_bandwidth bw = IEEE80211_STA_RX_BW_20;
+
                /*
                 * with multi-vif csa driver may call ieee80211_csa_finish()
                 * many times while waiting for other interfaces to use their
@@ -1081,6 +1085,48 @@ static void ieee80211_chswitch_work(struct work_struct *work)
                if (sdata->reserved_ready)
                        goto out;
 
+               if (sdata->vif.bss_conf.chandef.width !=
+                   sdata->csa_chandef.width) {
+                       /*
+                        * For managed interface, we need to also update the AP
+                        * station bandwidth and align the rate scale algorithm
+                        * on the bandwidth change. Here we only consider the
+                        * bandwidth of the new channel definition (as channel
+                        * switch flow does not have the full HT/VHT/HE
+                        * information), assuming that if additional changes are
+                        * required they would be done as part of the processing
+                        * of the next beacon from the AP.
+                        */
+                       switch (sdata->csa_chandef.width) {
+                       case NL80211_CHAN_WIDTH_20_NOHT:
+                       case NL80211_CHAN_WIDTH_20:
+                       default:
+                               bw = IEEE80211_STA_RX_BW_20;
+                               break;
+                       case NL80211_CHAN_WIDTH_40:
+                               bw = IEEE80211_STA_RX_BW_40;
+                               break;
+                       case NL80211_CHAN_WIDTH_80:
+                               bw = IEEE80211_STA_RX_BW_80;
+                               break;
+                       case NL80211_CHAN_WIDTH_80P80:
+                       case NL80211_CHAN_WIDTH_160:
+                               bw = IEEE80211_STA_RX_BW_160;
+                               break;
+                       }
+
+                       mgd_sta = sta_info_get(sdata, ifmgd->bssid);
+                       sband =
+                               local->hw.wiphy->bands[sdata->csa_chandef.chan->band];
+               }
+
+               if (sdata->vif.bss_conf.chandef.width >
+                   sdata->csa_chandef.width) {
+                       mgd_sta->sta.bandwidth = bw;
+                       rate_control_rate_update(local, sband, mgd_sta,
+                                                IEEE80211_RC_BW_CHANGED);
+               }
+
                ret = ieee80211_vif_use_reserved_context(sdata);
                if (ret) {
                        sdata_info(sdata,
@@ -1091,6 +1137,13 @@ static void ieee80211_chswitch_work(struct work_struct *work)
                        goto out;
                }
 
+               if (sdata->vif.bss_conf.chandef.width <
+                   sdata->csa_chandef.width) {
+                       mgd_sta->sta.bandwidth = bw;
+                       rate_control_rate_update(local, sband, mgd_sta,
+                                                IEEE80211_RC_BW_CHANGED);
+               }
+
                goto out;
        }
 
@@ -1312,6 +1365,16 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
                                         cbss->beacon_interval));
        return;
  drop_connection:
+       /*
+        * This is just so that the disconnect flow will know that
+        * we were trying to switch channel and failed. In case the
+        * mode is 1 (we are not allowed to Tx), we will know not to
+        * send a deauthentication frame. Those two fields will be
+        * reset when the disconnection worker runs.
+        */
+       sdata->vif.csa_active = true;
+       sdata->csa_block_tx = csa_ie.mode;
+
        ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work);
        mutex_unlock(&local->chanctx_mtx);
        mutex_unlock(&local->mtx);
@@ -2522,6 +2585,7 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
+       bool tx;
 
        sdata_lock(sdata);
        if (!ifmgd->associated) {
@@ -2529,6 +2593,8 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
                return;
        }
 
+       tx = !sdata->csa_block_tx;
+
        /* AP is probably out of range (or not reachable for another reason) so
         * remove the bss struct for that AP.
         */
@@ -2536,7 +2602,7 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
 
        ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
                               WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
-                              true, frame_buf);
+                              tx, frame_buf);
        mutex_lock(&local->mtx);
        sdata->vif.csa_active = false;
        ifmgd->csa_waiting_bcn = false;
@@ -2547,7 +2613,7 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
        }
        mutex_unlock(&local->mtx);
 
-       ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
+       ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), tx,
                                    WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
 
        sdata_unlock(sdata);
index 64742f2765c4846c36d3f9304314059023215d0a..96611d5dfadb0ce37effd4adcce80454bb69f285 100644 (file)
@@ -1728,6 +1728,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
         */
        if (!ieee80211_hw_check(&sta->local->hw, AP_LINK_PS) &&
            !ieee80211_has_morefrags(hdr->frame_control) &&
+           !is_multicast_ether_addr(hdr->addr1) &&
            (ieee80211_is_mgmt(hdr->frame_control) ||
             ieee80211_is_data(hdr->frame_control)) &&
            !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
index cd332e3e1134bed3efb89838ac245b0402e7a604..f353d9db54bc1f049e14b20713af88bde1da3c62 100644 (file)
@@ -3078,27 +3078,18 @@ void ieee80211_clear_fast_xmit(struct sta_info *sta)
 }
 
 static bool ieee80211_amsdu_realloc_pad(struct ieee80211_local *local,
-                                       struct sk_buff *skb, int headroom,
-                                       int *subframe_len)
+                                       struct sk_buff *skb, int headroom)
 {
-       int amsdu_len = *subframe_len + sizeof(struct ethhdr);
-       int padding = (4 - amsdu_len) & 3;
-
-       if (skb_headroom(skb) < headroom || skb_tailroom(skb) < padding) {
+       if (skb_headroom(skb) < headroom) {
                I802_DEBUG_INC(local->tx_expand_skb_head);
 
-               if (pskb_expand_head(skb, headroom, padding, GFP_ATOMIC)) {
+               if (pskb_expand_head(skb, headroom, 0, GFP_ATOMIC)) {
                        wiphy_debug(local->hw.wiphy,
                                    "failed to reallocate TX buffer\n");
                        return false;
                }
        }
 
-       if (padding) {
-               *subframe_len += padding;
-               skb_put_zero(skb, padding);
-       }
-
        return true;
 }
 
@@ -3122,8 +3113,7 @@ static bool ieee80211_amsdu_prepare_head(struct ieee80211_sub_if_data *sdata,
        if (info->control.flags & IEEE80211_TX_CTRL_AMSDU)
                return true;
 
-       if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(*amsdu_hdr),
-                                        &subframe_len))
+       if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(*amsdu_hdr)))
                return false;
 
        data = skb_push(skb, sizeof(*amsdu_hdr));
@@ -3189,7 +3179,8 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
        void *data;
        bool ret = false;
        unsigned int orig_len;
-       int n = 1, nfrags;
+       int n = 2, nfrags, pad = 0;
+       u16 hdrlen;
 
        if (!ieee80211_hw_check(&local->hw, TX_AMSDU))
                return false;
@@ -3222,9 +3213,6 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
        if (skb->len + head->len > max_amsdu_len)
                goto out;
 
-       if (!ieee80211_amsdu_prepare_head(sdata, fast_tx, head))
-               goto out;
-
        nfrags = 1 + skb_shinfo(skb)->nr_frags;
        nfrags += 1 + skb_shinfo(head)->nr_frags;
        frag_tail = &skb_shinfo(head)->frag_list;
@@ -3240,10 +3228,24 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
        if (max_frags && nfrags > max_frags)
                goto out;
 
-       if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(rfc1042_header) + 2,
-                                        &subframe_len))
+       if (!ieee80211_amsdu_prepare_head(sdata, fast_tx, head))
                goto out;
 
+       /*
+        * Pad out the previous subframe to a multiple of 4 by adding the
+        * padding to the next one, that's being added. Note that head->len
+        * is the length of the full A-MSDU, but that works since each time
+        * we add a new subframe we pad out the previous one to a multiple
+        * of 4 and thus it no longer matters in the next round.
+        */
+       hdrlen = fast_tx->hdr_len - sizeof(rfc1042_header);
+       if ((head->len - hdrlen) & 3)
+               pad = 4 - ((head->len - hdrlen) & 3);
+
+       if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(rfc1042_header) +
+                                                    2 + pad))
+               goto out_recalc;
+
        ret = true;
        data = skb_push(skb, ETH_ALEN + 2);
        memmove(data, data + ETH_ALEN + 2, 2 * ETH_ALEN);
@@ -3253,15 +3255,19 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
        memcpy(data, &len, 2);
        memcpy(data + 2, rfc1042_header, sizeof(rfc1042_header));
 
+       memset(skb_push(skb, pad), 0, pad);
+
        head->len += skb->len;
        head->data_len += skb->len;
        *frag_tail = skb;
 
-       flow->backlog += head->len - orig_len;
-       tin->backlog_bytes += head->len - orig_len;
-
-       fq_recalc_backlog(fq, tin, flow);
+out_recalc:
+       if (head->len != orig_len) {
+               flow->backlog += head->len - orig_len;
+               tin->backlog_bytes += head->len - orig_len;
 
+               fq_recalc_backlog(fq, tin, flow);
+       }
 out:
        spin_unlock_bh(&fq->lock);
 
index 88efda7c9f8a78737538a355b1b499104ab55aea..716cd6442d86c85b6507ba1aaa8e28e56f58e65b 100644 (file)
@@ -1135,7 +1135,7 @@ void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,
 {
        struct ieee80211_chanctx_conf *chanctx_conf;
        const struct ieee80211_reg_rule *rrule;
-       struct ieee80211_wmm_ac *wmm_ac;
+       const struct ieee80211_wmm_ac *wmm_ac;
        u16 center_freq = 0;
 
        if (sdata->vif.type != NL80211_IFTYPE_AP &&
@@ -1154,20 +1154,19 @@ void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,
 
        rrule = freq_reg_info(sdata->wdev.wiphy, MHZ_TO_KHZ(center_freq));
 
-       if (IS_ERR_OR_NULL(rrule) || !rrule->wmm_rule) {
+       if (IS_ERR_OR_NULL(rrule) || !rrule->has_wmm) {
                rcu_read_unlock();
                return;
        }
 
        if (sdata->vif.type == NL80211_IFTYPE_AP)
-               wmm_ac = &rrule->wmm_rule->ap[ac];
+               wmm_ac = &rrule->wmm_rule.ap[ac];
        else
-               wmm_ac = &rrule->wmm_rule->client[ac];
+               wmm_ac = &rrule->wmm_rule.client[ac];
        qparam->cw_min = max_t(u16, qparam->cw_min, wmm_ac->cw_min);
        qparam->cw_max = max_t(u16, qparam->cw_max, wmm_ac->cw_max);
        qparam->aifs = max_t(u8, qparam->aifs, wmm_ac->aifsn);
-       qparam->txop = !qparam->txop ? wmm_ac->cot / 32 :
-               min_t(u16, qparam->txop, wmm_ac->cot / 32);
+       qparam->txop = min_t(u16, qparam->txop, wmm_ac->cot / 32);
        rcu_read_unlock();
 }
 
index 82e6edf9c5d9c8454d17c53a2e0c461ff399a881..45f33d6dedf771c7d9f4a21496201ad3198aba8b 100644 (file)
@@ -100,7 +100,7 @@ static int ncsi_write_package_info(struct sk_buff *skb,
        bool found;
        int rc;
 
-       if (id > ndp->package_num) {
+       if (id > ndp->package_num - 1) {
                netdev_info(ndp->ndev.dev, "NCSI: No package with id %u\n", id);
                return -ENODEV;
        }
@@ -240,7 +240,7 @@ static int ncsi_pkg_info_all_nl(struct sk_buff *skb,
                return 0; /* done */
 
        hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
-                         &ncsi_genl_family, 0,  NCSI_CMD_PKG_INFO);
+                         &ncsi_genl_family, NLM_F_MULTI,  NCSI_CMD_PKG_INFO);
        if (!hdr) {
                rc = -EMSGSIZE;
                goto err;
index 05dc1b77e466f4d556037b8bb6464c151ccb89a6..cad48d07c818a81930ac15916b5b1430bcac9df9 100644 (file)
@@ -296,10 +296,10 @@ config IP_VS_MH_TAB_INDEX
          stored in a hash table. This table is assigned by a preference
          list of the positions to each destination until all slots in
          the table are filled. The index determines the prime for size of
-         the table as 251, 509, 1021, 2039, 4093, 8191, 16381, 32749,
-         65521 or 131071. When using weights to allow destinations to
-         receive more connections, the table is assigned an amount
-         proportional to the weights specified. The table needs to be large
+         the table as 251, 509, 1021, 2039, 4093, 8191, 16381, 32749,
+         65521 or 131071. When using weights to allow destinations to
+         receive more connections, the table is assigned an amount
+         proportional to the weights specified. The table needs to be large
          enough to effectively fit all the destinations multiplied by their
          respective weights.
 
index 0f795b186eb3d71216282694cb9e233853cb00ed..94d9d349ebb0832d43db4e203be296162c41dda0 100644 (file)
@@ -5,10 +5,10 @@
  *
  */
 
-/* The mh algorithm is to assign a preference list of all the lookup
+/* The mh algorithm is to assign a preference list of all the lookup
  * table positions to each destination and populate the table with
  * the most-preferred position of destinations. Then it is to select
- * destination with the hash key of source IP address through looking
+ * destination with the hash key of source IP address through looking
  * up a the lookup table.
  *
  * The algorithm is detailed in:
index 5610061e7f2e00b935ce44dd9cf82d10eb77a7bf..75c92a87e7b2481141161c8945f5e7eef8e0abf8 100644 (file)
@@ -4137,36 +4137,52 @@ static const struct vm_operations_struct packet_mmap_ops = {
        .close  =       packet_mm_close,
 };
 
-static void free_pg_vec(struct pgv *pg_vec, unsigned int len)
+static void free_pg_vec(struct pgv *pg_vec, unsigned int order,
+                       unsigned int len)
 {
        int i;
 
        for (i = 0; i < len; i++) {
                if (likely(pg_vec[i].buffer)) {
-                       kvfree(pg_vec[i].buffer);
+                       if (is_vmalloc_addr(pg_vec[i].buffer))
+                               vfree(pg_vec[i].buffer);
+                       else
+                               free_pages((unsigned long)pg_vec[i].buffer,
+                                          order);
                        pg_vec[i].buffer = NULL;
                }
        }
        kfree(pg_vec);
 }
 
-static char *alloc_one_pg_vec_page(unsigned long size)
+static char *alloc_one_pg_vec_page(unsigned long order)
 {
        char *buffer;
+       gfp_t gfp_flags = GFP_KERNEL | __GFP_COMP |
+                         __GFP_ZERO | __GFP_NOWARN | __GFP_NORETRY;
 
-       buffer = kvzalloc(size, GFP_KERNEL);
+       buffer = (char *) __get_free_pages(gfp_flags, order);
        if (buffer)
                return buffer;
 
-       buffer = kvzalloc(size, GFP_KERNEL | __GFP_RETRY_MAYFAIL);
+       /* __get_free_pages failed, fall back to vmalloc */
+       buffer = vzalloc(array_size((1 << order), PAGE_SIZE));
+       if (buffer)
+               return buffer;
 
-       return buffer;
+       /* vmalloc failed, lets dig into swap here */
+       gfp_flags &= ~__GFP_NORETRY;
+       buffer = (char *) __get_free_pages(gfp_flags, order);
+       if (buffer)
+               return buffer;
+
+       /* complete and utter failure */
+       return NULL;
 }
 
-static struct pgv *alloc_pg_vec(struct tpacket_req *req)
+static struct pgv *alloc_pg_vec(struct tpacket_req *req, int order)
 {
        unsigned int block_nr = req->tp_block_nr;
-       unsigned long size = req->tp_block_size;
        struct pgv *pg_vec;
        int i;
 
@@ -4175,7 +4191,7 @@ static struct pgv *alloc_pg_vec(struct tpacket_req *req)
                goto out;
 
        for (i = 0; i < block_nr; i++) {
-               pg_vec[i].buffer = alloc_one_pg_vec_page(size);
+               pg_vec[i].buffer = alloc_one_pg_vec_page(order);
                if (unlikely(!pg_vec[i].buffer))
                        goto out_free_pgvec;
        }
@@ -4184,7 +4200,7 @@ out:
        return pg_vec;
 
 out_free_pgvec:
-       free_pg_vec(pg_vec, block_nr);
+       free_pg_vec(pg_vec, order, block_nr);
        pg_vec = NULL;
        goto out;
 }
@@ -4194,9 +4210,9 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
 {
        struct pgv *pg_vec = NULL;
        struct packet_sock *po = pkt_sk(sk);
+       int was_running, order = 0;
        struct packet_ring_buffer *rb;
        struct sk_buff_head *rb_queue;
-       int was_running;
        __be16 num;
        int err = -EINVAL;
        /* Added to avoid minimal code churn */
@@ -4258,7 +4274,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
                        goto out;
 
                err = -ENOMEM;
-               pg_vec = alloc_pg_vec(req);
+               order = get_order(req->tp_block_size);
+               pg_vec = alloc_pg_vec(req, order);
                if (unlikely(!pg_vec))
                        goto out;
                switch (po->tp_version) {
@@ -4312,6 +4329,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
                rb->frame_size = req->tp_frame_size;
                spin_unlock_bh(&rb_queue->lock);
 
+               swap(rb->pg_vec_order, order);
                swap(rb->pg_vec_len, req->tp_block_nr);
 
                rb->pg_vec_pages = req->tp_block_size/PAGE_SIZE;
@@ -4337,7 +4355,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
        }
 
        if (pg_vec)
-               free_pg_vec(pg_vec, req->tp_block_nr);
+               free_pg_vec(pg_vec, order, req->tp_block_nr);
 out:
        return err;
 }
index 8f50036f62f05c76632dea82491d6a60dba39f0f..3bb7c5fb3bff2fd5d91c3d973d006d0cdde29a0b 100644 (file)
@@ -64,6 +64,7 @@ struct packet_ring_buffer {
        unsigned int            frame_size;
        unsigned int            frame_max;
 
+       unsigned int            pg_vec_order;
        unsigned int            pg_vec_pages;
        unsigned int            pg_vec_len;
 
index 01b3bd6a3708dece9e1e064c58e21c9d61ad8138..b9092111bc459d1b309c84a713005e7df66b02cf 100644 (file)
@@ -1,6 +1,6 @@
 
 config RDS
-       tristate "The RDS Protocol"
+       tristate "The Reliable Datagram Sockets Protocol"
        depends on INET
        ---help---
          The RDS (Reliable Datagram Sockets) protocol provides reliable,
index c1d97640c0be7bf6307806e2e6b112111756b7a1..eba75c1ba359446ca7e39e5aaa88287129531055 100644 (file)
@@ -341,15 +341,10 @@ static int rds6_ib_conn_info_visitor(struct rds_connection *conn,
 
        if (rds_conn_state(conn) == RDS_CONN_UP) {
                struct rds_ib_device *rds_ibdev;
-               struct rdma_dev_addr *dev_addr;
 
                ic = conn->c_transport_data;
-               dev_addr = &ic->i_cm_id->route.addr.dev_addr;
-               rdma_addr_get_sgid(dev_addr,
-                                  (union ib_gid *)&iinfo6->src_gid);
-               rdma_addr_get_dgid(dev_addr,
-                                  (union ib_gid *)&iinfo6->dst_gid);
-
+               rdma_read_gids(ic->i_cm_id, (union ib_gid *)&iinfo6->src_gid,
+                              (union ib_gid *)&iinfo6->dst_gid);
                rds_ibdev = ic->rds_ibdev;
                iinfo6->max_send_wr = ic->i_send_ring.w_nr;
                iinfo6->max_recv_wr = ic->i_recv_ring.w_nr;
index 2c7b7c352d3e8cf77c7aed4d29b61d481249827f..b9bbcf3d6c63976912433109d5c450830fb779f4 100644 (file)
@@ -37,7 +37,6 @@
 #include <net/tcp.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
-#include <net/tcp.h>
 #include <net/addrconf.h>
 
 #include "rds.h"
index 00192a996be0eab95be229f801ada687cca0f71a..0f846585225431c6ae903bd8308884729c99bb3c 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/mod_devicetable.h>
 #include <linux/rfkill.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
index 229d63c99be23b2329caa84b6912c8f770ccca64..e12f8ef7baa438997da79c86eedec3efde1babcd 100644 (file)
@@ -300,21 +300,17 @@ int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
 }
 EXPORT_SYMBOL(tcf_generic_walker);
 
-static bool __tcf_idr_check(struct tc_action_net *tn, u32 index,
-                           struct tc_action **a, int bind)
+int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index)
 {
        struct tcf_idrinfo *idrinfo = tn->idrinfo;
        struct tc_action *p;
 
        spin_lock(&idrinfo->lock);
        p = idr_find(&idrinfo->action_idr, index);
-       if (IS_ERR(p)) {
+       if (IS_ERR(p))
                p = NULL;
-       } else if (p) {
+       else if (p)
                refcount_inc(&p->tcfa_refcnt);
-               if (bind)
-                       atomic_inc(&p->tcfa_bindcnt);
-       }
        spin_unlock(&idrinfo->lock);
 
        if (p) {
@@ -323,23 +319,10 @@ static bool __tcf_idr_check(struct tc_action_net *tn, u32 index,
        }
        return false;
 }
-
-int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index)
-{
-       return __tcf_idr_check(tn, index, a, 0);
-}
 EXPORT_SYMBOL(tcf_idr_search);
 
-bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a,
-                  int bind)
+static int tcf_idr_delete_index(struct tcf_idrinfo *idrinfo, u32 index)
 {
-       return __tcf_idr_check(tn, index, a, bind);
-}
-EXPORT_SYMBOL(tcf_idr_check);
-
-int tcf_idr_delete_index(struct tc_action_net *tn, u32 index)
-{
-       struct tcf_idrinfo *idrinfo = tn->idrinfo;
        struct tc_action *p;
        int ret = 0;
 
@@ -370,7 +353,6 @@ int tcf_idr_delete_index(struct tc_action_net *tn, u32 index)
        spin_unlock(&idrinfo->lock);
        return ret;
 }
-EXPORT_SYMBOL(tcf_idr_delete_index);
 
 int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
                   struct tc_action **a, const struct tc_action_ops *ops,
@@ -409,7 +391,6 @@ int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
 
        p->idrinfo = idrinfo;
        p->ops = ops;
-       INIT_LIST_HEAD(&p->list);
        *a = p;
        return 0;
 err3:
@@ -681,19 +662,30 @@ int tcf_action_destroy(struct tc_action *actions[], int bind)
        return ret;
 }
 
+static int tcf_action_destroy_1(struct tc_action *a, int bind)
+{
+       struct tc_action *actions[] = { a, NULL };
+
+       return tcf_action_destroy(actions, bind);
+}
+
 static int tcf_action_put(struct tc_action *p)
 {
        return __tcf_action_put(p, false);
 }
 
+/* Put all actions in this array, skip those NULL's. */
 static void tcf_action_put_many(struct tc_action *actions[])
 {
        int i;
 
-       for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
+       for (i = 0; i < TCA_ACT_MAX_PRIO; i++) {
                struct tc_action *a = actions[i];
-               const struct tc_action_ops *ops = a->ops;
+               const struct tc_action_ops *ops;
 
+               if (!a)
+                       continue;
+               ops = a->ops;
                if (tcf_action_put(a))
                        module_put(ops->owner);
        }
@@ -896,17 +888,16 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
        if (TC_ACT_EXT_CMP(a->tcfa_action, TC_ACT_GOTO_CHAIN)) {
                err = tcf_action_goto_chain_init(a, tp);
                if (err) {
-                       struct tc_action *actions[] = { a, NULL };
-
-                       tcf_action_destroy(actions, bind);
+                       tcf_action_destroy_1(a, bind);
                        NL_SET_ERR_MSG(extack, "Failed to init TC action chain");
                        return ERR_PTR(err);
                }
        }
 
        if (!tcf_action_valid(a->tcfa_action)) {
-               NL_SET_ERR_MSG(extack, "invalid action value, using TC_ACT_UNSPEC instead");
-               a->tcfa_action = TC_ACT_UNSPEC;
+               tcf_action_destroy_1(a, bind);
+               NL_SET_ERR_MSG(extack, "Invalid control action value");
+               return ERR_PTR(-EINVAL);
        }
 
        return a;
@@ -1175,41 +1166,38 @@ err_out:
        return err;
 }
 
-static int tcf_action_delete(struct net *net, struct tc_action *actions[],
-                            int *acts_deleted, struct netlink_ext_ack *extack)
+static int tcf_action_delete(struct net *net, struct tc_action *actions[])
 {
-       u32 act_index;
-       int ret, i;
+       int i;
 
        for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) {
                struct tc_action *a = actions[i];
                const struct tc_action_ops *ops = a->ops;
-
                /* Actions can be deleted concurrently so we must save their
                 * type and id to search again after reference is released.
                 */
-               act_index = a->tcfa_index;
+               struct tcf_idrinfo *idrinfo = a->idrinfo;
+               u32 act_index = a->tcfa_index;
 
+               actions[i] = NULL;
                if (tcf_action_put(a)) {
                        /* last reference, action was deleted concurrently */
                        module_put(ops->owner);
                } else  {
+                       int ret;
+
                        /* now do the delete */
-                       ret = ops->delete(net, act_index);
-                       if (ret < 0) {
-                               *acts_deleted = i + 1;
+                       ret = tcf_idr_delete_index(idrinfo, act_index);
+                       if (ret < 0)
                                return ret;
-                       }
                }
        }
-       *acts_deleted = i;
        return 0;
 }
 
 static int
 tcf_del_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
-              int *acts_deleted, u32 portid, size_t attr_size,
-              struct netlink_ext_ack *extack)
+              u32 portid, size_t attr_size, struct netlink_ext_ack *extack)
 {
        int ret;
        struct sk_buff *skb;
@@ -1227,7 +1215,7 @@ tcf_del_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
        }
 
        /* now do the delete */
-       ret = tcf_action_delete(net, actions, acts_deleted, extack);
+       ret = tcf_action_delete(net, actions);
        if (ret < 0) {
                NL_SET_ERR_MSG(extack, "Failed to delete TC action");
                kfree_skb(skb);
@@ -1249,8 +1237,7 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
        struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
        struct tc_action *act;
        size_t attr_size = 0;
-       struct tc_action *actions[TCA_ACT_MAX_PRIO + 1] = {};
-       int acts_deleted = 0;
+       struct tc_action *actions[TCA_ACT_MAX_PRIO] = {};
 
        ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, extack);
        if (ret < 0)
@@ -1280,14 +1267,13 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
        if (event == RTM_GETACTION)
                ret = tcf_get_notify(net, portid, n, actions, event, extack);
        else { /* delete */
-               ret = tcf_del_notify(net, n, actions, &acts_deleted, portid,
-                                    attr_size, extack);
+               ret = tcf_del_notify(net, n, actions, portid, attr_size, extack);
                if (ret)
                        goto err;
-               return ret;
+               return 0;
        }
 err:
-       tcf_action_put_many(&actions[acts_deleted]);
+       tcf_action_put_many(actions);
        return ret;
 }
 
index d30b23e424364300f5440da022abb2129b9cf5f8..0c68bc9cf0b4df540a223e14dfa8ff569f96a40c 100644 (file)
@@ -395,13 +395,6 @@ static int tcf_bpf_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_bpf_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, bpf_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_bpf_ops __read_mostly = {
        .kind           =       "bpf",
        .type           =       TCA_ACT_BPF,
@@ -412,7 +405,6 @@ static struct tc_action_ops act_bpf_ops __read_mostly = {
        .init           =       tcf_bpf_init,
        .walk           =       tcf_bpf_walker,
        .lookup         =       tcf_bpf_search,
-       .delete         =       tcf_bpf_delete,
        .size           =       sizeof(struct tcf_bpf),
 };
 
index 54c0bf54f2acf71cd63ff17ef0cb74898bc0d478..6f0f273f1139f83ef1a45f017c37d200c36fcae1 100644 (file)
@@ -198,13 +198,6 @@ static int tcf_connmark_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_connmark_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, connmark_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_connmark_ops = {
        .kind           =       "connmark",
        .type           =       TCA_ACT_CONNMARK,
@@ -214,7 +207,6 @@ static struct tc_action_ops act_connmark_ops = {
        .init           =       tcf_connmark_init,
        .walk           =       tcf_connmark_walker,
        .lookup         =       tcf_connmark_search,
-       .delete         =       tcf_connmark_delete,
        .size           =       sizeof(struct tcf_connmark_info),
 };
 
index e698d3fe2080d1051d70c6ab92ff111bcd42d36d..b8a67ae3105ad10f645bfcb65a503dafcbe5cbb2 100644 (file)
@@ -659,13 +659,6 @@ static size_t tcf_csum_get_fill_size(const struct tc_action *act)
        return nla_total_size(sizeof(struct tc_csum));
 }
 
-static int tcf_csum_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, csum_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_csum_ops = {
        .kind           = "csum",
        .type           = TCA_ACT_CSUM,
@@ -677,7 +670,6 @@ static struct tc_action_ops act_csum_ops = {
        .walk           = tcf_csum_walker,
        .lookup         = tcf_csum_search,
        .get_fill_size  = tcf_csum_get_fill_size,
-       .delete         = tcf_csum_delete,
        .size           = sizeof(struct tcf_csum),
 };
 
index 6a3f25a8ffb30b8998fc2a7c37aaccc2c29c466d..cd1d9bd32ef9af4c5789e0331b6d1c1b7e6820f3 100644 (file)
@@ -243,13 +243,6 @@ static size_t tcf_gact_get_fill_size(const struct tc_action *act)
        return sz;
 }
 
-static int tcf_gact_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, gact_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_gact_ops = {
        .kind           =       "gact",
        .type           =       TCA_ACT_GACT,
@@ -261,7 +254,6 @@ static struct tc_action_ops act_gact_ops = {
        .walk           =       tcf_gact_walker,
        .lookup         =       tcf_gact_search,
        .get_fill_size  =       tcf_gact_get_fill_size,
-       .delete         =       tcf_gact_delete,
        .size           =       sizeof(struct tcf_gact),
 };
 
index d1081bdf1bdb5565660e41130e541800392e3889..06a3d48018782e5d35981fdcfc3208a5f11ad276 100644 (file)
@@ -167,16 +167,16 @@ static struct tcf_meta_ops *find_ife_oplist(u16 metaid)
 {
        struct tcf_meta_ops *o;
 
-       read_lock_bh(&ife_mod_lock);
+       read_lock(&ife_mod_lock);
        list_for_each_entry(o, &ifeoplist, list) {
                if (o->metaid == metaid) {
                        if (!try_module_get(o->owner))
                                o = NULL;
-                       read_unlock_bh(&ife_mod_lock);
+                       read_unlock(&ife_mod_lock);
                        return o;
                }
        }
-       read_unlock_bh(&ife_mod_lock);
+       read_unlock(&ife_mod_lock);
 
        return NULL;
 }
@@ -190,12 +190,12 @@ int register_ife_op(struct tcf_meta_ops *mops)
            !mops->get || !mops->alloc)
                return -EINVAL;
 
-       write_lock_bh(&ife_mod_lock);
+       write_lock(&ife_mod_lock);
 
        list_for_each_entry(m, &ifeoplist, list) {
                if (m->metaid == mops->metaid ||
                    (strcmp(mops->name, m->name) == 0)) {
-                       write_unlock_bh(&ife_mod_lock);
+                       write_unlock(&ife_mod_lock);
                        return -EEXIST;
                }
        }
@@ -204,7 +204,7 @@ int register_ife_op(struct tcf_meta_ops *mops)
                mops->release = ife_release_meta_gen;
 
        list_add_tail(&mops->list, &ifeoplist);
-       write_unlock_bh(&ife_mod_lock);
+       write_unlock(&ife_mod_lock);
        return 0;
 }
 EXPORT_SYMBOL_GPL(unregister_ife_op);
@@ -214,7 +214,7 @@ int unregister_ife_op(struct tcf_meta_ops *mops)
        struct tcf_meta_ops *m;
        int err = -ENOENT;
 
-       write_lock_bh(&ife_mod_lock);
+       write_lock(&ife_mod_lock);
        list_for_each_entry(m, &ifeoplist, list) {
                if (m->metaid == mops->metaid) {
                        list_del(&mops->list);
@@ -222,7 +222,7 @@ int unregister_ife_op(struct tcf_meta_ops *mops)
                        break;
                }
        }
-       write_unlock_bh(&ife_mod_lock);
+       write_unlock(&ife_mod_lock);
 
        return err;
 }
@@ -265,11 +265,8 @@ static const char *ife_meta_id2name(u32 metaid)
 #endif
 
 /* called when adding new meta information
- * under ife->tcf_lock for existing action
 */
-static int load_metaops_and_vet(struct tcf_ife_info *ife, u32 metaid,
-                               void *val, int len, bool exists,
-                               bool rtnl_held)
+static int load_metaops_and_vet(u32 metaid, void *val, int len, bool rtnl_held)
 {
        struct tcf_meta_ops *ops = find_ife_oplist(metaid);
        int ret = 0;
@@ -277,15 +274,11 @@ static int load_metaops_and_vet(struct tcf_ife_info *ife, u32 metaid,
        if (!ops) {
                ret = -ENOENT;
 #ifdef CONFIG_MODULES
-               if (exists)
-                       spin_unlock_bh(&ife->tcf_lock);
                if (rtnl_held)
                        rtnl_unlock();
                request_module("ife-meta-%s", ife_meta_id2name(metaid));
                if (rtnl_held)
                        rtnl_lock();
-               if (exists)
-                       spin_lock_bh(&ife->tcf_lock);
                ops = find_ife_oplist(metaid);
 #endif
        }
@@ -302,24 +295,17 @@ static int load_metaops_and_vet(struct tcf_ife_info *ife, u32 metaid,
 }
 
 /* called when adding new meta information
- * under ife->tcf_lock for existing action
 */
-static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval,
-                       int len, bool atomic)
+static int __add_metainfo(const struct tcf_meta_ops *ops,
+                         struct tcf_ife_info *ife, u32 metaid, void *metaval,
+                         int len, bool atomic, bool exists)
 {
        struct tcf_meta_info *mi = NULL;
-       struct tcf_meta_ops *ops = find_ife_oplist(metaid);
        int ret = 0;
 
-       if (!ops)
-               return -ENOENT;
-
        mi = kzalloc(sizeof(*mi), atomic ? GFP_ATOMIC : GFP_KERNEL);
-       if (!mi) {
-               /*put back what find_ife_oplist took */
-               module_put(ops->owner);
+       if (!mi)
                return -ENOMEM;
-       }
 
        mi->metaid = metaid;
        mi->ops = ops;
@@ -327,29 +313,61 @@ static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval,
                ret = ops->alloc(mi, metaval, atomic ? GFP_ATOMIC : GFP_KERNEL);
                if (ret != 0) {
                        kfree(mi);
-                       module_put(ops->owner);
                        return ret;
                }
        }
 
+       if (exists)
+               spin_lock_bh(&ife->tcf_lock);
        list_add_tail(&mi->metalist, &ife->metalist);
+       if (exists)
+               spin_unlock_bh(&ife->tcf_lock);
+
+       return ret;
+}
+
+static int add_metainfo_and_get_ops(const struct tcf_meta_ops *ops,
+                                   struct tcf_ife_info *ife, u32 metaid,
+                                   bool exists)
+{
+       int ret;
+
+       if (!try_module_get(ops->owner))
+               return -ENOENT;
+       ret = __add_metainfo(ops, ife, metaid, NULL, 0, true, exists);
+       if (ret)
+               module_put(ops->owner);
+       return ret;
+}
+
+static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval,
+                       int len, bool exists)
+{
+       const struct tcf_meta_ops *ops = find_ife_oplist(metaid);
+       int ret;
 
+       if (!ops)
+               return -ENOENT;
+       ret = __add_metainfo(ops, ife, metaid, metaval, len, false, exists);
+       if (ret)
+               /*put back what find_ife_oplist took */
+               module_put(ops->owner);
        return ret;
 }
 
-static int use_all_metadata(struct tcf_ife_info *ife)
+static int use_all_metadata(struct tcf_ife_info *ife, bool exists)
 {
        struct tcf_meta_ops *o;
        int rc = 0;
        int installed = 0;
 
-       read_lock_bh(&ife_mod_lock);
+       read_lock(&ife_mod_lock);
        list_for_each_entry(o, &ifeoplist, list) {
-               rc = add_metainfo(ife, o->metaid, NULL, 0, true);
+               rc = add_metainfo_and_get_ops(o, ife, o->metaid, exists);
                if (rc == 0)
                        installed += 1;
        }
-       read_unlock_bh(&ife_mod_lock);
+       read_unlock(&ife_mod_lock);
 
        if (installed)
                return 0;
@@ -396,7 +414,6 @@ static void _tcf_ife_cleanup(struct tc_action *a)
        struct tcf_meta_info *e, *n;
 
        list_for_each_entry_safe(e, n, &ife->metalist, metalist) {
-               module_put(e->ops->owner);
                list_del(&e->metalist);
                if (e->metaval) {
                        if (e->ops->release)
@@ -404,6 +421,7 @@ static void _tcf_ife_cleanup(struct tc_action *a)
                        else
                                kfree(e->metaval);
                }
+               module_put(e->ops->owner);
                kfree(e);
        }
 }
@@ -422,7 +440,6 @@ static void tcf_ife_cleanup(struct tc_action *a)
                kfree_rcu(p, rcu);
 }
 
-/* under ife->tcf_lock for existing action */
 static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb,
                             bool exists, bool rtnl_held)
 {
@@ -436,8 +453,7 @@ static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb,
                        val = nla_data(tb[i]);
                        len = nla_len(tb[i]);
 
-                       rc = load_metaops_and_vet(ife, i, val, len, exists,
-                                                 rtnl_held);
+                       rc = load_metaops_and_vet(i, val, len, rtnl_held);
                        if (rc != 0)
                                return rc;
 
@@ -540,8 +556,6 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
                p->eth_type = ife_type;
        }
 
-       if (exists)
-               spin_lock_bh(&ife->tcf_lock);
 
        if (ret == ACT_P_CREATED)
                INIT_LIST_HEAD(&ife->metalist);
@@ -551,10 +565,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
                                       NULL, NULL);
                if (err) {
 metadata_parse_err:
-                       if (exists)
-                               spin_unlock_bh(&ife->tcf_lock);
                        tcf_idr_release(*a, bind);
-
                        kfree(p);
                        return err;
                }
@@ -569,17 +580,16 @@ metadata_parse_err:
                 * as we can. You better have at least one else we are
                 * going to bail out
                 */
-               err = use_all_metadata(ife);
+               err = use_all_metadata(ife, exists);
                if (err) {
-                       if (exists)
-                               spin_unlock_bh(&ife->tcf_lock);
                        tcf_idr_release(*a, bind);
-
                        kfree(p);
                        return err;
                }
        }
 
+       if (exists)
+               spin_lock_bh(&ife->tcf_lock);
        ife->tcf_action = parm->action;
        /* protected by tcf_lock when modifying existing action */
        rcu_swap_protected(ife->params, p, 1);
@@ -853,13 +863,6 @@ static int tcf_ife_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_ife_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, ife_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_ife_ops = {
        .kind = "ife",
        .type = TCA_ACT_IFE,
@@ -870,7 +873,6 @@ static struct tc_action_ops act_ife_ops = {
        .init = tcf_ife_init,
        .walk = tcf_ife_walker,
        .lookup = tcf_ife_search,
-       .delete = tcf_ife_delete,
        .size = sizeof(struct tcf_ife_info),
 };
 
index 51f235bbeb5bccb4267fd70eeec8399494c9f246..23273b5303fd9dcc68cf09ee6f701defe50580b5 100644 (file)
@@ -337,13 +337,6 @@ static int tcf_ipt_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_ipt_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, ipt_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_ipt_ops = {
        .kind           =       "ipt",
        .type           =       TCA_ACT_IPT,
@@ -354,7 +347,6 @@ static struct tc_action_ops act_ipt_ops = {
        .init           =       tcf_ipt_init,
        .walk           =       tcf_ipt_walker,
        .lookup         =       tcf_ipt_search,
-       .delete         =       tcf_ipt_delete,
        .size           =       sizeof(struct tcf_ipt),
 };
 
@@ -395,13 +387,6 @@ static int tcf_xt_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_xt_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, xt_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_xt_ops = {
        .kind           =       "xt",
        .type           =       TCA_ACT_XT,
@@ -412,7 +397,6 @@ static struct tc_action_ops act_xt_ops = {
        .init           =       tcf_xt_init,
        .walk           =       tcf_xt_walker,
        .lookup         =       tcf_xt_search,
-       .delete         =       tcf_xt_delete,
        .size           =       sizeof(struct tcf_ipt),
 };
 
index 38fd20f10f6796eaba1402ee572d7712837f1a2c..8bf66d0a6800006e070eacc77519257410696097 100644 (file)
@@ -395,13 +395,6 @@ static void tcf_mirred_put_dev(struct net_device *dev)
        dev_put(dev);
 }
 
-static int tcf_mirred_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, mirred_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_mirred_ops = {
        .kind           =       "mirred",
        .type           =       TCA_ACT_MIRRED,
@@ -416,7 +409,6 @@ static struct tc_action_ops act_mirred_ops = {
        .size           =       sizeof(struct tcf_mirred),
        .get_dev        =       tcf_mirred_get_dev,
        .put_dev        =       tcf_mirred_put_dev,
-       .delete         =       tcf_mirred_delete,
 };
 
 static __net_init int mirred_init_net(struct net *net)
index 822e903bfc25f008d9754d1340a5b4352f4fe59e..4313aa102440e9b55fb0ba200406801217d65284 100644 (file)
@@ -300,13 +300,6 @@ static int tcf_nat_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_nat_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, nat_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_nat_ops = {
        .kind           =       "nat",
        .type           =       TCA_ACT_NAT,
@@ -316,7 +309,6 @@ static struct tc_action_ops act_nat_ops = {
        .init           =       tcf_nat_init,
        .walk           =       tcf_nat_walker,
        .lookup         =       tcf_nat_search,
-       .delete         =       tcf_nat_delete,
        .size           =       sizeof(struct tcf_nat),
 };
 
index 8a7a7cb94e8308e8b4d240f957b64080b269f485..ad99a99f11f6de4ad452b501aa8b23a01f156790 100644 (file)
@@ -109,16 +109,18 @@ static int tcf_pedit_key_ex_dump(struct sk_buff *skb,
 {
        struct nlattr *keys_start = nla_nest_start(skb, TCA_PEDIT_KEYS_EX);
 
+       if (!keys_start)
+               goto nla_failure;
        for (; n > 0; n--) {
                struct nlattr *key_start;
 
                key_start = nla_nest_start(skb, TCA_PEDIT_KEY_EX);
+               if (!key_start)
+                       goto nla_failure;
 
                if (nla_put_u16(skb, TCA_PEDIT_KEY_EX_HTYPE, keys_ex->htype) ||
-                   nla_put_u16(skb, TCA_PEDIT_KEY_EX_CMD, keys_ex->cmd)) {
-                       nlmsg_trim(skb, keys_start);
-                       return -EINVAL;
-               }
+                   nla_put_u16(skb, TCA_PEDIT_KEY_EX_CMD, keys_ex->cmd))
+                       goto nla_failure;
 
                nla_nest_end(skb, key_start);
 
@@ -128,6 +130,9 @@ static int tcf_pedit_key_ex_dump(struct sk_buff *skb,
        nla_nest_end(skb, keys_start);
 
        return 0;
+nla_failure:
+       nla_nest_cancel(skb, keys_start);
+       return -EINVAL;
 }
 
 static int tcf_pedit_init(struct net *net, struct nlattr *nla,
@@ -418,7 +423,10 @@ static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,
        opt->bindcnt = atomic_read(&p->tcf_bindcnt) - bind;
 
        if (p->tcfp_keys_ex) {
-               tcf_pedit_key_ex_dump(skb, p->tcfp_keys_ex, p->tcfp_nkeys);
+               if (tcf_pedit_key_ex_dump(skb,
+                                         p->tcfp_keys_ex,
+                                         p->tcfp_nkeys))
+                       goto nla_put_failure;
 
                if (nla_put(skb, TCA_PEDIT_PARMS_EX, s, opt))
                        goto nla_put_failure;
@@ -460,13 +468,6 @@ static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_pedit_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, pedit_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_pedit_ops = {
        .kind           =       "pedit",
        .type           =       TCA_ACT_PEDIT,
@@ -477,7 +478,6 @@ static struct tc_action_ops act_pedit_ops = {
        .init           =       tcf_pedit_init,
        .walk           =       tcf_pedit_walker,
        .lookup         =       tcf_pedit_search,
-       .delete         =       tcf_pedit_delete,
        .size           =       sizeof(struct tcf_pedit),
 };
 
index 06f0742db593166370cfb69f1ef8a687e29007be..5d8bfa878477e8e738be55d2c9b818423c3c8ccc 100644 (file)
@@ -320,13 +320,6 @@ static int tcf_police_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_police_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, police_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 MODULE_AUTHOR("Alexey Kuznetsov");
 MODULE_DESCRIPTION("Policing actions");
 MODULE_LICENSE("GPL");
@@ -340,7 +333,6 @@ static struct tc_action_ops act_police_ops = {
        .init           =       tcf_police_init,
        .walk           =       tcf_police_walker,
        .lookup         =       tcf_police_search,
-       .delete         =       tcf_police_delete,
        .size           =       sizeof(struct tcf_police),
 };
 
index 207b4132d1b066a394467ace6cf454dbce53a33f..44e9c00657bc1e8572d78e8a9ca1c6a142eb9c76 100644 (file)
@@ -232,13 +232,6 @@ static int tcf_sample_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_sample_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, sample_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_sample_ops = {
        .kind     = "sample",
        .type     = TCA_ACT_SAMPLE,
@@ -249,7 +242,6 @@ static struct tc_action_ops act_sample_ops = {
        .cleanup  = tcf_sample_cleanup,
        .walk     = tcf_sample_walker,
        .lookup   = tcf_sample_search,
-       .delete   = tcf_sample_delete,
        .size     = sizeof(struct tcf_sample),
 };
 
index e616523ba3c15f9126146240d440d96849ac4ded..52400d49f81f233a572de8cdffff9c94099e614a 100644 (file)
@@ -196,13 +196,6 @@ static int tcf_simp_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_simp_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, simp_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_simp_ops = {
        .kind           =       "simple",
        .type           =       TCA_ACT_SIMP,
@@ -213,7 +206,6 @@ static struct tc_action_ops act_simp_ops = {
        .init           =       tcf_simp_init,
        .walk           =       tcf_simp_walker,
        .lookup         =       tcf_simp_search,
-       .delete         =       tcf_simp_delete,
        .size           =       sizeof(struct tcf_defact),
 };
 
index 926d7bc4a89d9db85078677f1bdb9d6c57a767fc..73e44ce2a8837d9151b77de1e1bf619872af217c 100644 (file)
@@ -299,13 +299,6 @@ static int tcf_skbedit_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_skbedit_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, skbedit_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_skbedit_ops = {
        .kind           =       "skbedit",
        .type           =       TCA_ACT_SKBEDIT,
@@ -316,7 +309,6 @@ static struct tc_action_ops act_skbedit_ops = {
        .cleanup        =       tcf_skbedit_cleanup,
        .walk           =       tcf_skbedit_walker,
        .lookup         =       tcf_skbedit_search,
-       .delete         =       tcf_skbedit_delete,
        .size           =       sizeof(struct tcf_skbedit),
 };
 
index d6a1af0c41712cf6e61bcdaefc06959e616efa21..588077fafd6cc58473b1d0de85b1aa3103b3bf69 100644 (file)
@@ -259,13 +259,6 @@ static int tcf_skbmod_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_skbmod_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, skbmod_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_skbmod_ops = {
        .kind           =       "skbmod",
        .type           =       TCA_ACT_SKBMOD,
@@ -276,7 +269,6 @@ static struct tc_action_ops act_skbmod_ops = {
        .cleanup        =       tcf_skbmod_cleanup,
        .walk           =       tcf_skbmod_walker,
        .lookup         =       tcf_skbmod_search,
-       .delete         =       tcf_skbmod_delete,
        .size           =       sizeof(struct tcf_skbmod),
 };
 
index 8f09cf08d8fe1242cdbbc1951124e0f19ace18ae..420759153d5f4442eebab5a375714f7f89df7ea9 100644 (file)
@@ -548,13 +548,6 @@ static int tunnel_key_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tunnel_key_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_tunnel_key_ops = {
        .kind           =       "tunnel_key",
        .type           =       TCA_ACT_TUNNEL_KEY,
@@ -565,7 +558,6 @@ static struct tc_action_ops act_tunnel_key_ops = {
        .cleanup        =       tunnel_key_release,
        .walk           =       tunnel_key_walker,
        .lookup         =       tunnel_key_search,
-       .delete         =       tunnel_key_delete,
        .size           =       sizeof(struct tcf_tunnel_key),
 };
 
index 209e70ad2c09a0b0e9567f24b33108f7b5e1f1e4..033d273afe50236a090fd4caddd0a8328ce82157 100644 (file)
@@ -296,13 +296,6 @@ static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index,
        return tcf_idr_search(tn, a, index);
 }
 
-static int tcf_vlan_delete(struct net *net, u32 index)
-{
-       struct tc_action_net *tn = net_generic(net, vlan_net_id);
-
-       return tcf_idr_delete_index(tn, index);
-}
-
 static struct tc_action_ops act_vlan_ops = {
        .kind           =       "vlan",
        .type           =       TCA_ACT_VLAN,
@@ -313,7 +306,6 @@ static struct tc_action_ops act_vlan_ops = {
        .cleanup        =       tcf_vlan_cleanup,
        .walk           =       tcf_vlan_walker,
        .lookup         =       tcf_vlan_search,
-       .delete         =       tcf_vlan_delete,
        .size           =       sizeof(struct tcf_vlan),
 };
 
index 31bd1439cf6059fbcb3e99525e4a964154ef7907..1a67af8a6e8ce93bc9821804567d738b4d4547e5 100644 (file)
@@ -1252,7 +1252,7 @@ replay:
        }
        chain = tcf_chain_get(block, chain_index, true);
        if (!chain) {
-               NL_SET_ERR_MSG(extack, "Cannot find specified filter chain");
+               NL_SET_ERR_MSG(extack, "Cannot create specified filter chain");
                err = -ENOMEM;
                goto errout;
        }
@@ -1399,7 +1399,7 @@ static int tc_del_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
                        goto errout;
                }
                NL_SET_ERR_MSG(extack, "Cannot find specified filter chain");
-               err = -EINVAL;
+               err = -ENOENT;
                goto errout;
        }
 
index d5d2a6dc39216b0ca28bd11094f0b64fda5c5964..f218ccf1e2d9a651ad07c2a6276742b97d3b2102 100644 (file)
@@ -914,6 +914,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
        struct nlattr *opt = tca[TCA_OPTIONS];
        struct nlattr *tb[TCA_U32_MAX + 1];
        u32 htid, flags = 0;
+       size_t sel_size;
        int err;
 #ifdef CONFIG_CLS_U32_PERF
        size_t size;
@@ -1076,8 +1077,13 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
        }
 
        s = nla_data(tb[TCA_U32_SEL]);
+       sel_size = struct_size(s, keys, s->nkeys);
+       if (nla_len(tb[TCA_U32_SEL]) < sel_size) {
+               err = -EINVAL;
+               goto erridr;
+       }
 
-       n = kzalloc(sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key), GFP_KERNEL);
+       n = kzalloc(offsetof(typeof(*n), sel) + sel_size, GFP_KERNEL);
        if (n == NULL) {
                err = -ENOBUFS;
                goto erridr;
@@ -1092,7 +1098,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
        }
 #endif
 
-       memcpy(&n->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key));
+       memcpy(&n->sel, s, sel_size);
        RCU_INIT_POINTER(n->ht_up, ht);
        n->handle = handle;
        n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0;
index 35fc7252187c1f54fbcbceb827d7270381b2da5b..c07c30b916d5e4d7b7fef5586f92df366194da85 100644 (file)
@@ -64,7 +64,6 @@
 #include <linux/vmalloc.h>
 #include <linux/reciprocal_div.h>
 #include <net/netlink.h>
-#include <linux/version.h>
 #include <linux/if_vlan.h>
 #include <net/pkt_sched.h>
 #include <net/pkt_cls.h>
@@ -621,15 +620,20 @@ static bool cake_ddst(int flow_mode)
 }
 
 static u32 cake_hash(struct cake_tin_data *q, const struct sk_buff *skb,
-                    int flow_mode)
+                    int flow_mode, u16 flow_override, u16 host_override)
 {
-       u32 flow_hash = 0, srchost_hash, dsthost_hash;
+       u32 flow_hash = 0, srchost_hash = 0, dsthost_hash = 0;
        u16 reduced_hash, srchost_idx, dsthost_idx;
        struct flow_keys keys, host_keys;
 
        if (unlikely(flow_mode == CAKE_FLOW_NONE))
                return 0;
 
+       /* If both overrides are set we can skip packet dissection entirely */
+       if ((flow_override || !(flow_mode & CAKE_FLOW_FLOWS)) &&
+           (host_override || !(flow_mode & CAKE_FLOW_HOSTS)))
+               goto skip_hash;
+
        skb_flow_dissect_flow_keys(skb, &keys,
                                   FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
 
@@ -676,6 +680,14 @@ static u32 cake_hash(struct cake_tin_data *q, const struct sk_buff *skb,
        if (flow_mode & CAKE_FLOW_FLOWS)
                flow_hash = flow_hash_from_keys(&keys);
 
+skip_hash:
+       if (flow_override)
+               flow_hash = flow_override - 1;
+       if (host_override) {
+               dsthost_hash = host_override - 1;
+               srchost_hash = host_override - 1;
+       }
+
        if (!(flow_mode & CAKE_FLOW_FLOWS)) {
                if (flow_mode & CAKE_FLOW_SRC_IP)
                        flow_hash ^= srchost_hash;
@@ -1571,7 +1583,7 @@ static u32 cake_classify(struct Qdisc *sch, struct cake_tin_data **t,
        struct cake_sched_data *q = qdisc_priv(sch);
        struct tcf_proto *filter;
        struct tcf_result res;
-       u32 flow = 0;
+       u16 flow = 0, host = 0;
        int result;
 
        filter = rcu_dereference_bh(q->filter_list);
@@ -1595,10 +1607,12 @@ static u32 cake_classify(struct Qdisc *sch, struct cake_tin_data **t,
 #endif
                if (TC_H_MIN(res.classid) <= CAKE_QUEUES)
                        flow = TC_H_MIN(res.classid);
+               if (TC_H_MAJ(res.classid) <= (CAKE_QUEUES << 16))
+                       host = TC_H_MAJ(res.classid) >> 16;
        }
 hash:
        *t = cake_select_tin(sch, skb);
-       return flow ?: cake_hash(*t, skb, flow_mode) + 1;
+       return cake_hash(*t, skb, flow_mode, flow, host) + 1;
 }
 
 static void cake_reconfigure(struct Qdisc *sch);
index ef5c9a82d4e896b506271cb229b07ee570c917f3..a644292f9fafd6cff9219c7fe6b64bfcc7bc898b 100644 (file)
@@ -215,7 +215,6 @@ static const struct seq_operations sctp_eps_ops = {
 struct sctp_ht_iter {
        struct seq_net_private p;
        struct rhashtable_iter hti;
-       int start_fail;
 };
 
 static void *sctp_transport_seq_start(struct seq_file *seq, loff_t *pos)
@@ -224,7 +223,6 @@ static void *sctp_transport_seq_start(struct seq_file *seq, loff_t *pos)
 
        sctp_transport_walk_start(&iter->hti);
 
-       iter->start_fail = 0;
        return sctp_transport_get_idx(seq_file_net(seq), &iter->hti, *pos);
 }
 
@@ -232,8 +230,6 @@ static void sctp_transport_seq_stop(struct seq_file *seq, void *v)
 {
        struct sctp_ht_iter *iter = seq->private;
 
-       if (iter->start_fail)
-               return;
        sctp_transport_walk_stop(&iter->hti);
 }
 
@@ -264,8 +260,6 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
        }
 
        transport = (struct sctp_transport *)v;
-       if (!sctp_transport_hold(transport))
-               return 0;
        assoc = transport->asoc;
        epb = &assoc->base;
        sk = epb->sk;
@@ -322,8 +316,6 @@ static int sctp_remaddr_seq_show(struct seq_file *seq, void *v)
        }
 
        transport = (struct sctp_transport *)v;
-       if (!sctp_transport_hold(transport))
-               return 0;
        assoc = transport->asoc;
 
        list_for_each_entry_rcu(tsp, &assoc->peer.transport_addr_list,
index e96b15a66abaa481b64db1ebd34f75d59d724c3d..f73e9d38d5ba734d7ee3347e4015fd30d355bbfa 100644 (file)
@@ -2658,20 +2658,23 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
        }
 
        if (params->spp_flags & SPP_IPV6_FLOWLABEL) {
-               if (trans && trans->ipaddr.sa.sa_family == AF_INET6) {
-                       trans->flowlabel = params->spp_ipv6_flowlabel &
-                                          SCTP_FLOWLABEL_VAL_MASK;
-                       trans->flowlabel |= SCTP_FLOWLABEL_SET_MASK;
-               } else if (asoc) {
-                       list_for_each_entry(trans,
-                                           &asoc->peer.transport_addr_list,
-                                           transports) {
-                               if (trans->ipaddr.sa.sa_family != AF_INET6)
-                                       continue;
+               if (trans) {
+                       if (trans->ipaddr.sa.sa_family == AF_INET6) {
                                trans->flowlabel = params->spp_ipv6_flowlabel &
                                                   SCTP_FLOWLABEL_VAL_MASK;
                                trans->flowlabel |= SCTP_FLOWLABEL_SET_MASK;
                        }
+               } else if (asoc) {
+                       struct sctp_transport *t;
+
+                       list_for_each_entry(t, &asoc->peer.transport_addr_list,
+                                           transports) {
+                               if (t->ipaddr.sa.sa_family != AF_INET6)
+                                       continue;
+                               t->flowlabel = params->spp_ipv6_flowlabel &
+                                              SCTP_FLOWLABEL_VAL_MASK;
+                               t->flowlabel |= SCTP_FLOWLABEL_SET_MASK;
+                       }
                        asoc->flowlabel = params->spp_ipv6_flowlabel &
                                          SCTP_FLOWLABEL_VAL_MASK;
                        asoc->flowlabel |= SCTP_FLOWLABEL_SET_MASK;
@@ -2687,12 +2690,13 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
                        trans->dscp = params->spp_dscp & SCTP_DSCP_VAL_MASK;
                        trans->dscp |= SCTP_DSCP_SET_MASK;
                } else if (asoc) {
-                       list_for_each_entry(trans,
-                                           &asoc->peer.transport_addr_list,
+                       struct sctp_transport *t;
+
+                       list_for_each_entry(t, &asoc->peer.transport_addr_list,
                                            transports) {
-                               trans->dscp = params->spp_dscp &
-                                             SCTP_DSCP_VAL_MASK;
-                               trans->dscp |= SCTP_DSCP_SET_MASK;
+                               t->dscp = params->spp_dscp &
+                                         SCTP_DSCP_VAL_MASK;
+                               t->dscp |= SCTP_DSCP_SET_MASK;
                        }
                        asoc->dscp = params->spp_dscp & SCTP_DSCP_VAL_MASK;
                        asoc->dscp |= SCTP_DSCP_SET_MASK;
@@ -5005,9 +5009,14 @@ struct sctp_transport *sctp_transport_get_next(struct net *net,
                        break;
                }
 
+               if (!sctp_transport_hold(t))
+                       continue;
+
                if (net_eq(sock_net(t->asoc->base.sk), net) &&
                    t->asoc->peer.primary_path == t)
                        break;
+
+               sctp_transport_put(t);
        }
 
        return t;
@@ -5017,13 +5026,18 @@ struct sctp_transport *sctp_transport_get_idx(struct net *net,
                                              struct rhashtable_iter *iter,
                                              int pos)
 {
-       void *obj = SEQ_START_TOKEN;
+       struct sctp_transport *t;
 
-       while (pos && (obj = sctp_transport_get_next(net, iter)) &&
-              !IS_ERR(obj))
-               pos--;
+       if (!pos)
+               return SEQ_START_TOKEN;
 
-       return obj;
+       while ((t = sctp_transport_get_next(net, iter)) && !IS_ERR(t)) {
+               if (!--pos)
+                       break;
+               sctp_transport_put(t);
+       }
+
+       return t;
 }
 
 int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *),
@@ -5082,8 +5096,6 @@ again:
 
        tsp = sctp_transport_get_idx(net, &hti, *pos + 1);
        for (; !IS_ERR_OR_NULL(tsp); tsp = sctp_transport_get_next(net, &hti)) {
-               if (!sctp_transport_hold(tsp))
-                       continue;
                ret = cb(tsp, p);
                if (ret)
                        break;
index 9bb5274a244e83e577617cb1ce71dc9c44d4d980..e519ef29c0ffcb74baf25753a58048504fedd813 100644 (file)
@@ -145,17 +145,21 @@ out:
 
 static int smc_ib_fill_mac(struct smc_ib_device *smcibdev, u8 ibport)
 {
-       struct ib_gid_attr gattr;
-       union ib_gid gid;
-       int rc;
+       const struct ib_gid_attr *attr;
+       int rc = 0;
 
-       rc = ib_query_gid(smcibdev->ibdev, ibport, 0, &gid, &gattr);
-       if (rc || !gattr.ndev)
+       attr = rdma_get_gid_attr(smcibdev->ibdev, ibport, 0);
+       if (IS_ERR(attr))
                return -ENODEV;
 
-       memcpy(smcibdev->mac[ibport - 1], gattr.ndev->dev_addr, ETH_ALEN);
-       dev_put(gattr.ndev);
-       return 0;
+       if (attr->ndev)
+               memcpy(smcibdev->mac[ibport - 1], attr->ndev->dev_addr,
+                      ETH_ALEN);
+       else
+               rc = -ENODEV;
+
+       rdma_put_gid_attr(attr);
+       return rc;
 }
 
 /* Create an identifier unique for this instance of SMC-R.
@@ -180,29 +184,27 @@ bool smc_ib_port_active(struct smc_ib_device *smcibdev, u8 ibport)
 int smc_ib_determine_gid(struct smc_ib_device *smcibdev, u8 ibport,
                         unsigned short vlan_id, u8 gid[], u8 *sgid_index)
 {
-       struct ib_gid_attr gattr;
-       union ib_gid _gid;
+       const struct ib_gid_attr *attr;
        int i;
 
        for (i = 0; i < smcibdev->pattr[ibport - 1].gid_tbl_len; i++) {
-               memset(&_gid, 0, SMC_GID_SIZE);
-               memset(&gattr, 0, sizeof(gattr));
-               if (ib_query_gid(smcibdev->ibdev, ibport, i, &_gid, &gattr))
+               attr = rdma_get_gid_attr(smcibdev->ibdev, ibport, i);
+               if (IS_ERR(attr))
                        continue;
-               if (!gattr.ndev)
-                       continue;
-               if (((!vlan_id && !is_vlan_dev(gattr.ndev)) ||
-                    (vlan_id && is_vlan_dev(gattr.ndev) &&
-                     vlan_dev_vlan_id(gattr.ndev) == vlan_id)) &&
-                   gattr.gid_type == IB_GID_TYPE_IB) {
+
+               if (attr->ndev &&
+                   ((!vlan_id && !is_vlan_dev(attr->ndev)) ||
+                    (vlan_id && is_vlan_dev(attr->ndev) &&
+                     vlan_dev_vlan_id(attr->ndev) == vlan_id)) &&
+                   attr->gid_type == IB_GID_TYPE_ROCE) {
                        if (gid)
-                               memcpy(gid, &_gid, SMC_GID_SIZE);
+                               memcpy(gid, &attr->gid, SMC_GID_SIZE);
                        if (sgid_index)
-                               *sgid_index = i;
-                       dev_put(gattr.ndev);
+                               *sgid_index = attr->index;
+                       rdma_put_gid_attr(attr);
                        return 0;
                }
-               dev_put(gattr.ndev);
+               rdma_put_gid_attr(attr);
        }
        return -ENODEV;
 }
index d2623b9f23d66c20243d57d69d91e5da6a3cf4c0..305ecea9217071208147ed84755c745b6299606e 100644 (file)
@@ -50,7 +50,7 @@ static int param_set_hashtbl_sz(const char *val, const struct kernel_param *kp)
        if (!val)
                goto out_inval;
        ret = kstrtoul(val, 0, &num);
-       if (ret == -EINVAL)
+       if (ret)
                goto out_inval;
        nbits = fls(num - 1);
        if (nbits > MAX_HASHTABLE_BITS || nbits < 2)
@@ -253,7 +253,7 @@ rpcauth_list_flavors(rpc_authflavor_t *array, int size)
 EXPORT_SYMBOL_GPL(rpcauth_list_flavors);
 
 struct rpc_auth *
-rpcauth_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
+rpcauth_create(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
 {
        struct rpc_auth         *auth;
        const struct rpc_authops *ops;
index 0fc397fae42bc3ae017c2260b746c32d0d0c952e..21c0aa0a0d1d4fde901aed91a51fc65481f72b7b 100644 (file)
@@ -284,7 +284,12 @@ err:
        return p;
 }
 
-#define UPCALL_BUF_LEN 128
+/* XXX: Need some documentation about why UPCALL_BUF_LEN is so small.
+ *     Is user space expecting no more than UPCALL_BUF_LEN bytes?
+ *     Note that there are now _two_ NI_MAXHOST sized data items
+ *     being passed in this string.
+ */
+#define UPCALL_BUF_LEN 256
 
 struct gss_upcall_msg {
        refcount_t count;
@@ -456,18 +461,44 @@ static int gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
        buflen -= len;
        p += len;
        gss_msg->msg.len = len;
+
+       /*
+        * target= is a full service principal that names the remote
+        * identity that we are authenticating to.
+        */
        if (target_name) {
                len = scnprintf(p, buflen, "target=%s ", target_name);
                buflen -= len;
                p += len;
                gss_msg->msg.len += len;
        }
-       if (service_name != NULL) {
-               len = scnprintf(p, buflen, "service=%s ", service_name);
+
+       /*
+        * gssd uses service= and srchost= to select a matching key from
+        * the system's keytab to use as the source principal.
+        *
+        * service= is the service name part of the source principal,
+        * or "*" (meaning choose any).
+        *
+        * srchost= is the hostname part of the source principal. When
+        * not provided, gssd uses the local hostname.
+        */
+       if (service_name) {
+               char *c = strchr(service_name, '@');
+
+               if (!c)
+                       len = scnprintf(p, buflen, "service=%s ",
+                                       service_name);
+               else
+                       len = scnprintf(p, buflen,
+                                       "service=%.*s srchost=%s ",
+                                       (int)(c - service_name),
+                                       service_name, c + 1);
                buflen -= len;
                p += len;
                gss_msg->msg.len += len;
        }
+
        if (mech->gm_upcall_enctypes) {
                len = scnprintf(p, buflen, "enctypes=%s ",
                                mech->gm_upcall_enctypes);
@@ -985,7 +1016,7 @@ static void gss_pipe_free(struct gss_pipe *p)
  * parameters based on the input flavor (which must be a pseudoflavor)
  */
 static struct gss_auth *
-gss_create_new(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
+gss_create_new(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
 {
        rpc_authflavor_t flavor = args->pseudoflavor;
        struct gss_auth *gss_auth;
@@ -1132,7 +1163,7 @@ gss_destroy(struct rpc_auth *auth)
  * (which is guaranteed to last as long as any of its descendants).
  */
 static struct gss_auth *
-gss_auth_find_or_add_hashed(struct rpc_auth_create_args *args,
+gss_auth_find_or_add_hashed(const struct rpc_auth_create_args *args,
                struct rpc_clnt *clnt,
                struct gss_auth *new)
 {
@@ -1169,7 +1200,8 @@ out:
 }
 
 static struct gss_auth *
-gss_create_hashed(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
+gss_create_hashed(const struct rpc_auth_create_args *args,
+                 struct rpc_clnt *clnt)
 {
        struct gss_auth *gss_auth;
        struct gss_auth *new;
@@ -1188,7 +1220,7 @@ out:
 }
 
 static struct rpc_auth *
-gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
+gss_create(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
 {
        struct gss_auth *gss_auth;
        struct rpc_xprt_switch *xps = rcu_access_pointer(clnt->cl_xpi.xpi_xpswitch);
@@ -1571,7 +1603,7 @@ static int gss_cred_is_negative_entry(struct rpc_cred *cred)
        if (test_bit(RPCAUTH_CRED_NEGATIVE, &cred->cr_flags)) {
                unsigned long now = jiffies;
                unsigned long begin, expire;
-               struct gss_cred *gss_cred; 
+               struct gss_cred *gss_cred;
 
                gss_cred = container_of(cred, struct gss_cred, gc_base);
                begin = gss_cred->gc_upcall_timestamp;
index 254defe446a73ae371b2d6a04e6bb561fc2d727f..fe97f31065367e633659fee5fc57dc2a15948e07 100644 (file)
@@ -231,4 +231,3 @@ g_verify_token_header(struct xdr_netobj *mech, int *body_size,
 }
 
 EXPORT_SYMBOL_GPL(g_verify_token_header);
-
index 8654494b4d0a39c2ad970597fd7919640b948885..0220e1ca52806d76289f5c8b37558e111fbf35c9 100644 (file)
@@ -169,7 +169,7 @@ make_checksum_hmac_md5(struct krb5_ctx *kctx, char *header, int hdrlen,
        struct scatterlist              sg[1];
        int err = -1;
        u8 *checksumdata;
-       u8 rc4salt[4];
+       u8 *rc4salt;
        struct crypto_ahash *md5;
        struct crypto_ahash *hmac_md5;
        struct ahash_request *req;
@@ -183,14 +183,18 @@ make_checksum_hmac_md5(struct krb5_ctx *kctx, char *header, int hdrlen,
                return GSS_S_FAILURE;
        }
 
+       rc4salt = kmalloc_array(4, sizeof(*rc4salt), GFP_NOFS);
+       if (!rc4salt)
+               return GSS_S_FAILURE;
+
        if (arcfour_hmac_md5_usage_to_salt(usage, rc4salt)) {
                dprintk("%s: invalid usage value %u\n", __func__, usage);
-               return GSS_S_FAILURE;
+               goto out_free_rc4salt;
        }
 
        checksumdata = kmalloc(GSS_KRB5_MAX_CKSUM_LEN, GFP_NOFS);
        if (!checksumdata)
-               return GSS_S_FAILURE;
+               goto out_free_rc4salt;
 
        md5 = crypto_alloc_ahash("md5", 0, CRYPTO_ALG_ASYNC);
        if (IS_ERR(md5))
@@ -258,6 +262,8 @@ out_free_md5:
        crypto_free_ahash(md5);
 out_free_cksum:
        kfree(checksumdata);
+out_free_rc4salt:
+       kfree(rc4salt);
        return err ? GSS_S_FAILURE : 0;
 }
 
@@ -373,7 +379,6 @@ make_checksum_v2(struct krb5_ctx *kctx, char *header, int hdrlen,
        struct scatterlist sg[1];
        int err = -1;
        u8 *checksumdata;
-       unsigned int checksumlen;
 
        if (kctx->gk5e->keyed_cksum == 0) {
                dprintk("%s: expected keyed hash for %s\n",
@@ -393,7 +398,6 @@ make_checksum_v2(struct krb5_ctx *kctx, char *header, int hdrlen,
        tfm = crypto_alloc_ahash(kctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC);
        if (IS_ERR(tfm))
                goto out_free_cksum;
-       checksumlen = crypto_ahash_digestsize(tfm);
 
        req = ahash_request_alloc(tfm, GFP_NOFS);
        if (!req)
@@ -1077,4 +1081,3 @@ out_err:
        dprintk("%s: returning %d\n", __func__, err);
        return err;
 }
-
index 87013314602634711ad9dbd223823d896a373210..f7fe2d2b851fdca15412c8823e8ada2e6f5dd804 100644 (file)
@@ -324,4 +324,3 @@ u32 gss_krb5_aes_make_key(const struct gss_krb5_enctype *gk5e,
 err_out:
        return ret;
 }
-
index 94a2b3f082a85794ee0c8d64ae265f6d60427fab..eaad9bc7a0bdc956ef25e40121bb17449723f6d1 100644 (file)
@@ -229,4 +229,3 @@ gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text,
                return gss_get_mic_v2(ctx, text, token);
        }
 }
-
index b601a73cc9db6ee28086001b2140af9ef3b6cbae..ef2b25b86d2f43615bc83df2f81bc57e43e81ac4 100644 (file)
@@ -225,4 +225,3 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
                return gss_verify_mic_v2(ctx, message_buffer, read_token);
        }
 }
-
index a737c2da08373e33aabb42b994cf83a02182711a..39a2e672900bdde2fe8c362d026db49af4e3d3e5 100644 (file)
@@ -440,7 +440,6 @@ static u32
 gss_wrap_kerberos_v2(struct krb5_ctx *kctx, u32 offset,
                     struct xdr_buf *buf, struct page **pages)
 {
-       int             blocksize;
        u8              *ptr, *plainhdr;
        s32             now;
        u8              flags = 0x00;
@@ -473,7 +472,6 @@ gss_wrap_kerberos_v2(struct krb5_ctx *kctx, u32 offset,
        *ptr++ = 0xff;
        be16ptr = (__be16 *)ptr;
 
-       blocksize = crypto_skcipher_blocksize(kctx->acceptor_enc);
        *be16ptr++ = 0;
        /* "inner" token header always uses 0 for RRC */
        *be16ptr++ = 0;
@@ -623,4 +621,3 @@ gss_unwrap_kerberos(struct gss_ctx *gctx, int offset, struct xdr_buf *buf)
                return gss_unwrap_kerberos_v2(kctx, offset, buf);
        }
 }
-
index 1c7c49dbf8ba6a837658aef0a72dc0b0e58df128..73dcda060335fc1a52105b399a65f20bf12f4d6e 100644 (file)
@@ -234,6 +234,35 @@ static int gssp_alloc_receive_pages(struct gssx_arg_accept_sec_context *arg)
        return 0;
 }
 
+static char *gssp_stringify(struct xdr_netobj *netobj)
+{
+       return kstrndup(netobj->data, netobj->len, GFP_KERNEL);
+}
+
+static void gssp_hostbased_service(char **principal)
+{
+       char *c;
+
+       if (!*principal)
+               return;
+
+       /* terminate and remove realm part */
+       c = strchr(*principal, '@');
+       if (c) {
+               *c = '\0';
+
+               /* change service-hostname delimiter */
+               c = strchr(*principal, '/');
+               if (c)
+                       *c = '@';
+       }
+       if (!c) {
+               /* not a service principal */
+               kfree(*principal);
+               *principal = NULL;
+       }
+}
+
 /*
  * Public functions
  */
@@ -262,6 +291,7 @@ int gssp_accept_sec_context_upcall(struct net *net,
                 */
                .exported_context_token.len = GSSX_max_output_handle_sz,
                .mech.len = GSS_OID_MAX_LEN,
+               .targ_name.display_name.len = GSSX_max_princ_sz,
                .src_name.display_name.len = GSSX_max_princ_sz
        };
        struct gssx_res_accept_sec_context res = {
@@ -275,6 +305,7 @@ int gssp_accept_sec_context_upcall(struct net *net,
                .rpc_cred = NULL, /* FIXME ? */
        };
        struct xdr_netobj client_name = { 0 , NULL };
+       struct xdr_netobj target_name = { 0, NULL };
        int ret;
 
        if (data->in_handle.len != 0)
@@ -285,8 +316,6 @@ int gssp_accept_sec_context_upcall(struct net *net,
        if (ret)
                return ret;
 
-       /* use nfs/ for targ_name ? */
-
        ret = gssp_call(net, &msg);
 
        gssp_free_receive_pages(&arg);
@@ -304,6 +333,7 @@ int gssp_accept_sec_context_upcall(struct net *net,
                        kfree(rctxh.mech.data);
                }
                client_name = rctxh.src_name.display_name;
+               target_name = rctxh.targ_name.display_name;
        }
 
        if (res.options.count == 1) {
@@ -325,32 +355,22 @@ int gssp_accept_sec_context_upcall(struct net *net,
        }
 
        /* convert to GSS_NT_HOSTBASED_SERVICE form and set into creds */
-       if (data->found_creds && client_name.data != NULL) {
-               char *c;
-
-               data->creds.cr_raw_principal = kstrndup(client_name.data,
-                                               client_name.len, GFP_KERNEL);
-
-               data->creds.cr_principal = kstrndup(client_name.data,
-                                               client_name.len, GFP_KERNEL);
-               if (data->creds.cr_principal) {
-                       /* terminate and remove realm part */
-                       c = strchr(data->creds.cr_principal, '@');
-                       if (c) {
-                               *c = '\0';
-
-                               /* change service-hostname delimiter */
-                               c = strchr(data->creds.cr_principal, '/');
-                               if (c) *c = '@';
-                       }
-                       if (!c) {
-                               /* not a service principal */
-                               kfree(data->creds.cr_principal);
-                               data->creds.cr_principal = NULL;
-                       }
+       if (data->found_creds) {
+               if (client_name.data) {
+                       data->creds.cr_raw_principal =
+                                       gssp_stringify(&client_name);
+                       data->creds.cr_principal =
+                                       gssp_stringify(&client_name);
+                       gssp_hostbased_service(&data->creds.cr_principal);
+               }
+               if (target_name.data) {
+                       data->creds.cr_targ_princ =
+                                       gssp_stringify(&target_name);
+                       gssp_hostbased_service(&data->creds.cr_targ_princ);
                }
        }
        kfree(client_name.data);
+       kfree(target_name.data);
 
        return ret;
 }
index 5089dbb96d58f8f65c9a2cbaef85df32fdd52135..860f2a1bbb675d71f4de3bd70acd1284974ffe3a 100644 (file)
@@ -1389,7 +1389,7 @@ static void destroy_use_gss_proxy_proc_entry(struct net *net)
        struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
        if (sn->use_gssp_proc) {
-               remove_proc_entry("use-gss-proxy", sn->proc_net_rpc); 
+               remove_proc_entry("use-gss-proxy", sn->proc_net_rpc);
                clear_gssp_clnt(sn);
        }
 }
index 75d72e109a04d2c9c92e8310a7c2852c710b9924..4b48228ee8c74a6d313289d7425c0c3d5262b2e4 100644 (file)
@@ -19,7 +19,7 @@ static struct rpc_auth null_auth;
 static struct rpc_cred null_cred;
 
 static struct rpc_auth *
-nul_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
+nul_create(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
 {
        atomic_inc(&null_auth.au_count);
        return &null_auth;
index dafd6b870ba3946835b8aa00977e1aeeaa116b6a..185e56d4f9aee4da149dc73556ae0e35abed4424 100644 (file)
@@ -30,7 +30,7 @@ static struct rpc_auth                unix_auth;
 static const struct rpc_credops        unix_credops;
 
 static struct rpc_auth *
-unx_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
+unx_create(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
 {
        dprintk("RPC:       creating UNIX authenticator for client %p\n",
                        clnt);
index c2c68a15b59de07c9837599d959174b55ae353ba..3c15a99b97003d1441a532d18c9ffe4f3980b5b9 100644 (file)
@@ -362,4 +362,3 @@ void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied)
        wake_up(&bc_serv->sv_cb_waitq);
        spin_unlock(&bc_serv->sv_cb_lock);
 }
-
index d839c33ae7d9909c627727ca1e2da9ec432021eb..8ea2f5fadd967c03a2fa87baa5c8c40710d8fedc 100644 (file)
@@ -892,7 +892,7 @@ rpc_free_client(struct rpc_clnt *clnt)
 /*
  * Free an RPC client
  */
-static struct rpc_clnt * 
+static struct rpc_clnt *
 rpc_free_auth(struct rpc_clnt *clnt)
 {
        if (clnt->cl_auth == NULL)
@@ -965,10 +965,20 @@ out:
 }
 EXPORT_SYMBOL_GPL(rpc_bind_new_program);
 
+void rpc_task_release_transport(struct rpc_task *task)
+{
+       struct rpc_xprt *xprt = task->tk_xprt;
+
+       if (xprt) {
+               task->tk_xprt = NULL;
+               xprt_put(xprt);
+       }
+}
+EXPORT_SYMBOL_GPL(rpc_task_release_transport);
+
 void rpc_task_release_client(struct rpc_task *task)
 {
        struct rpc_clnt *clnt = task->tk_client;
-       struct rpc_xprt *xprt = task->tk_xprt;
 
        if (clnt != NULL) {
                /* Remove from client task list */
@@ -979,12 +989,14 @@ void rpc_task_release_client(struct rpc_task *task)
 
                rpc_release_client(clnt);
        }
+       rpc_task_release_transport(task);
+}
 
-       if (xprt != NULL) {
-               task->tk_xprt = NULL;
-
-               xprt_put(xprt);
-       }
+static
+void rpc_task_set_transport(struct rpc_task *task, struct rpc_clnt *clnt)
+{
+       if (!task->tk_xprt)
+               task->tk_xprt = xprt_iter_get_next(&clnt->cl_xpi);
 }
 
 static
@@ -992,8 +1004,7 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt)
 {
 
        if (clnt != NULL) {
-               if (task->tk_xprt == NULL)
-                       task->tk_xprt = xprt_iter_get_next(&clnt->cl_xpi);
+               rpc_task_set_transport(task, clnt);
                task->tk_client = clnt;
                atomic_inc(&clnt->cl_count);
                if (clnt->cl_softrtry)
@@ -1512,6 +1523,7 @@ call_start(struct rpc_task *task)
                clnt->cl_program->version[clnt->cl_vers]->counts[idx]++;
        clnt->cl_stats->rpccnt++;
        task->tk_action = call_reserve;
+       rpc_task_set_transport(task, clnt);
 }
 
 /*
index c526f8fb37c924a36712dd04385d1e0d4b0116e8..c7872bc138605b3450727ca2c737d1ba8d986564 100644 (file)
@@ -213,7 +213,7 @@ static void rpcb_set_local(struct net *net, struct rpc_clnt *clnt,
        sn->rpcb_local_clnt = clnt;
        sn->rpcb_local_clnt4 = clnt4;
        sn->rpcb_is_af_local = is_af_local ? 1 : 0;
-       smp_wmb(); 
+       smp_wmb();
        sn->rpcb_users = 1;
        dprintk("RPC:       created new rpcb local clients (rpcb_local_clnt: "
                "%p, rpcb_local_clnt4: %p) for net %x%s\n",
index f68aa46c9dd7125bee03506a9a3e4914939770ae..71166b393732c0632ca86ce0e590570cc2e14ae1 100644 (file)
@@ -208,13 +208,39 @@ static void _print_name(struct seq_file *seq, unsigned int op,
                seq_printf(seq, "\t%12u: ", op);
 }
 
-void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt)
+static void _add_rpc_iostats(struct rpc_iostats *a, struct rpc_iostats *b)
+{
+       a->om_ops += b->om_ops;
+       a->om_ntrans += b->om_ntrans;
+       a->om_timeouts += b->om_timeouts;
+       a->om_bytes_sent += b->om_bytes_sent;
+       a->om_bytes_recv += b->om_bytes_recv;
+       a->om_queue = ktime_add(a->om_queue, b->om_queue);
+       a->om_rtt = ktime_add(a->om_rtt, b->om_rtt);
+       a->om_execute = ktime_add(a->om_execute, b->om_execute);
+}
+
+static void _print_rpc_iostats(struct seq_file *seq, struct rpc_iostats *stats,
+                              int op, const struct rpc_procinfo *procs)
+{
+       _print_name(seq, op, procs);
+       seq_printf(seq, "%lu %lu %lu %Lu %Lu %Lu %Lu %Lu\n",
+                  stats->om_ops,
+                  stats->om_ntrans,
+                  stats->om_timeouts,
+                  stats->om_bytes_sent,
+                  stats->om_bytes_recv,
+                  ktime_to_ms(stats->om_queue),
+                  ktime_to_ms(stats->om_rtt),
+                  ktime_to_ms(stats->om_execute));
+}
+
+void rpc_clnt_show_stats(struct seq_file *seq, struct rpc_clnt *clnt)
 {
-       struct rpc_iostats *stats = clnt->cl_metrics;
        struct rpc_xprt *xprt;
        unsigned int op, maxproc = clnt->cl_maxproc;
 
-       if (!stats)
+       if (!clnt->cl_metrics)
                return;
 
        seq_printf(seq, "\tRPC iostats version: %s  ", RPC_IOSTATS_VERS);
@@ -229,20 +255,18 @@ void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt)
 
        seq_printf(seq, "\tper-op statistics\n");
        for (op = 0; op < maxproc; op++) {
-               struct rpc_iostats *metrics = &stats[op];
-               _print_name(seq, op, clnt->cl_procinfo);
-               seq_printf(seq, "%lu %lu %lu %Lu %Lu %Lu %Lu %Lu\n",
-                               metrics->om_ops,
-                               metrics->om_ntrans,
-                               metrics->om_timeouts,
-                               metrics->om_bytes_sent,
-                               metrics->om_bytes_recv,
-                               ktime_to_ms(metrics->om_queue),
-                               ktime_to_ms(metrics->om_rtt),
-                               ktime_to_ms(metrics->om_execute));
+               struct rpc_iostats stats = {};
+               struct rpc_clnt *next = clnt;
+               do {
+                       _add_rpc_iostats(&stats, &next->cl_metrics[op]);
+                       if (next == next->cl_parent)
+                               break;
+                       next = next->cl_parent;
+               } while (next);
+               _print_rpc_iostats(seq, &stats, op, clnt->cl_procinfo);
        }
 }
-EXPORT_SYMBOL_GPL(rpc_print_iostats);
+EXPORT_SYMBOL_GPL(rpc_clnt_show_stats);
 
 /*
  * Register/unregister RPC proc files
@@ -310,4 +334,3 @@ void rpc_proc_exit(struct net *net)
        dprintk("RPC:       unregistering /proc/net/rpc\n");
        remove_proc_entry("rpc", net->proc_net);
 }
-
index 09a0315ea77b3955115aa3db9abe891b518799c9..c9bacb3c930fa7feeb4fdb110cdfc8e3ee0c177a 100644 (file)
@@ -57,4 +57,3 @@ int svc_send_common(struct socket *sock, struct xdr_buf *xdr,
 int rpc_clients_notifier_register(void);
 void rpc_clients_notifier_unregister(void);
 #endif /* _NET_SUNRPC_SUNRPC_H */
-
index 30a4226baf03e1677a8b06d7a285d124d88a54ed..d13e05f1a9905f93abb187385eea478de38d4a93 100644 (file)
@@ -1537,16 +1537,16 @@ EXPORT_SYMBOL_GPL(svc_max_payload);
 /**
  * svc_fill_write_vector - Construct data argument for VFS write call
  * @rqstp: svc_rqst to operate on
+ * @pages: list of pages containing data payload
  * @first: buffer containing first section of write payload
  * @total: total number of bytes of write payload
  *
- * Returns the number of elements populated in the data argument array.
+ * Fills in rqstp::rq_vec, and returns the number of elements.
  */
-unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, struct kvec *first,
-                                  size_t total)
+unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, struct page **pages,
+                                  struct kvec *first, size_t total)
 {
        struct kvec *vec = rqstp->rq_vec;
-       struct page **pages;
        unsigned int i;
 
        /* Some types of transport can present the write payload
@@ -1560,14 +1560,11 @@ unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, struct kvec *first,
                ++i;
        }
 
-       WARN_ON_ONCE(rqstp->rq_arg.page_base != 0);
-       pages = rqstp->rq_arg.pages;
        while (total) {
                vec[i].iov_base = page_address(*pages);
                vec[i].iov_len = min_t(size_t, total, PAGE_SIZE);
                total -= vec[i].iov_len;
                ++i;
-
                ++pages;
        }
 
@@ -1580,65 +1577,48 @@ EXPORT_SYMBOL_GPL(svc_fill_write_vector);
  * svc_fill_symlink_pathname - Construct pathname argument for VFS symlink call
  * @rqstp: svc_rqst to operate on
  * @first: buffer containing first section of pathname
+ * @p: buffer containing remaining section of pathname
  * @total: total length of the pathname argument
  *
- * Returns pointer to a NUL-terminated string, or an ERR_PTR. The buffer is
- * released automatically when @rqstp is recycled.
+ * The VFS symlink API demands a NUL-terminated pathname in mapped memory.
+ * Returns pointer to a NUL-terminated string, or an ERR_PTR. Caller must free
+ * the returned string.
  */
 char *svc_fill_symlink_pathname(struct svc_rqst *rqstp, struct kvec *first,
-                               size_t total)
+                               void *p, size_t total)
 {
-       struct xdr_buf *arg = &rqstp->rq_arg;
-       struct page **pages;
-       char *result;
-
-       /* VFS API demands a NUL-terminated pathname. This function
-        * uses a page from @rqstp as the pathname buffer, to enable
-        * direct placement. Thus the total buffer size is PAGE_SIZE.
-        * Space in this buffer for NUL-termination requires that we
-        * cap the size of the returned symlink pathname just a
-        * little early.
-        */
-       if (total > PAGE_SIZE - 1)
-               return ERR_PTR(-ENAMETOOLONG);
+       size_t len, remaining;
+       char *result, *dst;
 
-       /* Some types of transport can present the pathname entirely
-        * in rq_arg.pages. If not, then copy the pathname into one
-        * page.
-        */
-       pages = arg->pages;
-       WARN_ON_ONCE(arg->page_base != 0);
-       if (first->iov_base == 0) {
-               result = page_address(*pages);
-               result[total] = '\0';
-       } else {
-               size_t len, remaining;
-               char *dst;
+       result = kmalloc(total + 1, GFP_KERNEL);
+       if (!result)
+               return ERR_PTR(-ESERVERFAULT);
 
-               result = page_address(*(rqstp->rq_next_page++));
-               dst = result;
-               remaining = total;
+       dst = result;
+       remaining = total;
 
-               len = min_t(size_t, total, first->iov_len);
+       len = min_t(size_t, total, first->iov_len);
+       if (len) {
                memcpy(dst, first->iov_base, len);
                dst += len;
                remaining -= len;
+       }
 
-               /* No more than one page left */
-               if (remaining) {
-                       len = min_t(size_t, remaining, PAGE_SIZE);
-                       memcpy(dst, page_address(*pages), len);
-                       dst += len;
-               }
-
-               *dst = '\0';
+       if (remaining) {
+               len = min_t(size_t, remaining, PAGE_SIZE);
+               memcpy(dst, p, len);
+               dst += len;
        }
 
-       /* Sanity check: we don't allow the pathname argument to
+       *dst = '\0';
+
+       /* Sanity check: Linux doesn't allow the pathname argument to
         * contain a NUL byte.
         */
-       if (strlen(result) != total)
+       if (strlen(result) != total) {
+               kfree(result);
                return ERR_PTR(-EINVAL);
+       }
        return result;
 }
 EXPORT_SYMBOL_GPL(svc_fill_symlink_pathname);
index 3fabf9f6a0f9d92eaccbc33a9600ca2d1370aa18..a8db2e3f89044460741fe41dcb6dcadfd7b2d669 100644 (file)
@@ -880,7 +880,7 @@ static void xprt_wait_on_pinned_rqst(struct rpc_rqst *req)
 __must_hold(&req->rq_xprt->recv_lock)
 {
        struct rpc_task *task = req->rq_task;
-       
+
        if (task && test_bit(RPC_TASK_MSG_RECV, &task->tk_runstate)) {
                spin_unlock(&req->rq_xprt->recv_lock);
                set_bit(RPC_TASK_MSG_RECV_WAIT, &task->tk_runstate);
index 357ba90c382d5d6e44efe28d7b7971dca0ffc211..134bef6a451ebc80fd6ccc6ba3610fdf5e7e5442 100644 (file)
@@ -94,7 +94,6 @@ static int read_reset_stat(struct ctl_table *table, int write,
                atomic_set(stat, 0);
        else {
                char str_buf[32];
-               char *data;
                int len = snprintf(str_buf, 32, "%d\n", atomic_read(stat));
                if (len >= 32)
                        return -EFAULT;
@@ -103,7 +102,6 @@ static int read_reset_stat(struct ctl_table *table, int write,
                        *lenp = 0;
                        return 0;
                }
-               data = &str_buf[*ppos];
                len -= *ppos;
                if (len > *lenp)
                        len = *lenp;
index 2ef75e885411765273c7e5c63f9b5b32d8e33f76..b24d5b8f2feeda5a2d5d66d755694475a6003cf7 100644 (file)
@@ -365,9 +365,6 @@ static void svc_rdma_build_arg_xdr(struct svc_rqst *rqstp,
        arg->page_base = 0;
        arg->buflen = ctxt->rc_byte_len;
        arg->len = ctxt->rc_byte_len;
-
-       rqstp->rq_respages = &rqstp->rq_pages[0];
-       rqstp->rq_next_page = rqstp->rq_respages + 1;
 }
 
 /* This accommodates the largest possible Write chunk,
@@ -729,6 +726,12 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
 
        svc_rdma_build_arg_xdr(rqstp, ctxt);
 
+       /* Prevent svc_xprt_release from releasing pages in rq_pages
+        * if we return 0 or an error.
+        */
+       rqstp->rq_respages = rqstp->rq_pages;
+       rqstp->rq_next_page = rqstp->rq_respages;
+
        p = (__be32 *)rqstp->rq_arg.head[0].iov_base;
        ret = svc_rdma_xdr_decode_req(&rqstp->rq_arg);
        if (ret < 0)
index 04cb3363172a1cfce1e750d4a2d55c4e104c1415..dc1951759a8eff65dd8b0f315af692e2e59a5def 100644 (file)
@@ -680,6 +680,7 @@ static int svc_rdma_build_read_chunk(struct svc_rqst *rqstp,
                                     struct svc_rdma_read_info *info,
                                     __be32 *p)
 {
+       unsigned int i;
        int ret;
 
        ret = -EINVAL;
@@ -702,6 +703,12 @@ static int svc_rdma_build_read_chunk(struct svc_rqst *rqstp,
                info->ri_chunklen += rs_length;
        }
 
+       /* Pages under I/O have been copied to head->rc_pages.
+        * Prevent their premature release by svc_xprt_release() .
+        */
+       for (i = 0; i < info->ri_readctxt->rc_page_count; i++)
+               rqstp->rq_pages[i] = NULL;
+
        return ret;
 }
 
@@ -817,7 +824,6 @@ int svc_rdma_recv_read_chunk(struct svcxprt_rdma *rdma, struct svc_rqst *rqstp,
                             struct svc_rdma_recv_ctxt *head, __be32 *p)
 {
        struct svc_rdma_read_info *info;
-       struct page **page;
        int ret;
 
        /* The request (with page list) is constructed in
@@ -844,27 +850,15 @@ int svc_rdma_recv_read_chunk(struct svcxprt_rdma *rdma, struct svc_rqst *rqstp,
                ret = svc_rdma_build_normal_read_chunk(rqstp, info, p);
        else
                ret = svc_rdma_build_pz_read_chunk(rqstp, info, p);
-
-       /* Mark the start of the pages that can be used for the reply */
-       if (info->ri_pageoff > 0)
-               info->ri_pageno++;
-       rqstp->rq_respages = &rqstp->rq_pages[info->ri_pageno];
-       rqstp->rq_next_page = rqstp->rq_respages + 1;
-
        if (ret < 0)
-               goto out;
+               goto out_err;
 
        ret = svc_rdma_post_chunk_ctxt(&info->ri_cc);
-
-out:
-       /* Read sink pages have been moved from rqstp->rq_pages to
-        * head->rc_arg.pages. Force svc_recv to refill those slots
-        * in rq_pages.
-        */
-       for (page = rqstp->rq_pages; page < rqstp->rq_respages; page++)
-               *page = NULL;
-
        if (ret < 0)
-               svc_rdma_read_info_free(info);
+               goto out_err;
+       return 0;
+
+out_err:
+       svc_rdma_read_info_free(info);
        return ret;
 }
index ffef0c508f1afe8db348953c81bd2d5d2d8d21fc..8602a5f1b5156049bc780919dd613c889824647a 100644 (file)
@@ -656,7 +656,9 @@ static void svc_rdma_save_io_pages(struct svc_rqst *rqstp,
                ctxt->sc_pages[i] = rqstp->rq_respages[i];
                rqstp->rq_respages[i] = NULL;
        }
-       rqstp->rq_next_page = rqstp->rq_respages + 1;
+
+       /* Prevent svc_xprt_release from releasing pages in rq_pages */
+       rqstp->rq_next_page = rqstp->rq_respages;
 }
 
 /* Prepare the portion of the RPC Reply that will be transmitted
index 547b2cdf14274f4267ad6ea8ddc605ff0da4a7b6..2848cafd4a17744d2fe9a515126611d9a891a189 100644 (file)
@@ -296,7 +296,6 @@ static int rdma_listen_handler(struct rdma_cm_id *cma_id,
                               struct rdma_cm_event *event)
 {
        struct sockaddr *sap = (struct sockaddr *)&cma_id->route.addr.src_addr;
-       int ret = 0;
 
        trace_svcrdma_cm_event(event, sap);
 
@@ -315,7 +314,7 @@ static int rdma_listen_handler(struct rdma_cm_id *cma_id,
                break;
        }
 
-       return ret;
+       return 0;
 }
 
 static int rdma_cma_handler(struct rdma_cm_id *cma_id,
index 5efeba08918b97a319005f5f1548733e929b843c..956a5ea47b58ee8a6009aa8b6315ce5887ec9110 100644 (file)
@@ -280,7 +280,6 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
                ++xprt->rx_xprt.connect_cookie;
                connstate = -ECONNABORTED;
 connected:
-               xprt->rx_buf.rb_credits = 1;
                ep->rep_connected = connstate;
                rpcrdma_conn_func(ep);
                wake_up_all(&ep->rep_connect_wait);
@@ -755,6 +754,7 @@ retry:
        }
 
        ep->rep_connected = 0;
+       rpcrdma_post_recvs(r_xprt, true);
 
        rc = rdma_connect(ia->ri_id, &ep->rep_remote_cma);
        if (rc) {
@@ -773,8 +773,6 @@ retry:
 
        dprintk("RPC:       %s: connected\n", __func__);
 
-       rpcrdma_post_recvs(r_xprt, true);
-
 out:
        if (rc)
                ep->rep_connected = rc;
@@ -1171,6 +1169,7 @@ rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
                list_add(&req->rl_list, &buf->rb_send_bufs);
        }
 
+       buf->rb_credits = 1;
        buf->rb_posted_receives = 0;
        INIT_LIST_HEAD(&buf->rb_recv_bufs);
 
index 9e1c5024aba97750f05946a98e38238b9aaa20e6..6b7539c0466e85b164512de3845f11dec404c16d 100644 (file)
@@ -3375,4 +3375,3 @@ module_param_named(tcp_max_slot_table_entries, xprt_max_tcp_slot_table_entries,
                   max_slot_table_size, 0644);
 module_param_named(udp_slot_table_entries, xprt_udp_slot_table_entries,
                   slot_table_size, 0644);
-
index 9ee6cfea56dd015851302f1702f9e068803d01dd..d8026543bf4ce53634cb2d6fc114e57cdb74b21f 100644 (file)
@@ -51,12 +51,12 @@ const char tipc_bclink_name[] = "broadcast-link";
  * struct tipc_bc_base - base structure for keeping broadcast send state
  * @link: broadcast send link structure
  * @inputq: data input queue; will only carry SOCK_WAKEUP messages
- * @dest: array keeping number of reachable destinations per bearer
+ * @dests: array keeping number of reachable destinations per bearer
  * @primary_bearer: a bearer having links to all broadcast destinations, if any
  * @bcast_support: indicates if primary bearer, if any, supports broadcast
  * @rcast_support: indicates if all peer nodes support replicast
  * @rc_ratio: dest count as percentage of cluster size where send method changes
- * @bc_threshold: calculated drom rc_ratio; if dests > threshold use broadcast
+ * @bc_threshold: calculated from rc_ratio; if dests > threshold use broadcast
  */
 struct tipc_bc_base {
        struct tipc_link *link;
index aaabb0b776dda6041defb902804e08388e39f9c5..73137f4aeb68f95677e34a3b2d5e823565024483 100644 (file)
@@ -84,7 +84,9 @@ static int tipc_sock_diag_handler_dump(struct sk_buff *skb,
 
        if (h->nlmsg_flags & NLM_F_DUMP) {
                struct netlink_dump_control c = {
+                       .start = tipc_dump_start,
                        .dump = tipc_diag_dump,
+                       .done = tipc_dump_done,
                };
                netlink_dump_start(net->diag_nlsk, skb, h, &c);
                return 0;
index 88f027b502f6f5ed955b03bd645321ea8e79eec3..66d5b2c5987ad6a2e05ca45f236ade58459ac0bf 100644 (file)
@@ -980,20 +980,17 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb)
 
 struct tipc_dest *tipc_dest_find(struct list_head *l, u32 node, u32 port)
 {
-       u64 value = (u64)node << 32 | port;
        struct tipc_dest *dst;
 
        list_for_each_entry(dst, l, list) {
-               if (dst->value != value)
-                       continue;
-               return dst;
+               if (dst->node == node && dst->port == port)
+                       return dst;
        }
        return NULL;
 }
 
 bool tipc_dest_push(struct list_head *l, u32 node, u32 port)
 {
-       u64 value = (u64)node << 32 | port;
        struct tipc_dest *dst;
 
        if (tipc_dest_find(l, node, port))
@@ -1002,7 +999,8 @@ bool tipc_dest_push(struct list_head *l, u32 node, u32 port)
        dst = kmalloc(sizeof(*dst), GFP_ATOMIC);
        if (unlikely(!dst))
                return false;
-       dst->value = value;
+       dst->node = node;
+       dst->port = port;
        list_add(&dst->list, l);
        return true;
 }
index 0febba41da86ed64df54f447e7eb9b63cbea30cf..892bd750b85fa48639b15af9bbeb6d437a7660a7 100644 (file)
@@ -133,13 +133,8 @@ void tipc_nametbl_stop(struct net *net);
 
 struct tipc_dest {
        struct list_head list;
-       union {
-               struct {
-                       u32 port;
-                       u32 node;
-               };
-               u64 value;
-       };
+       u32 port;
+       u32 node;
 };
 
 struct tipc_dest *tipc_dest_find(struct list_head *l, u32 node, u32 port);
index 6ff2254088f647d4f7410c3335ccdae2e68ec522..99ee419210baf4374d438b138ab922034950ba7e 100644 (file)
@@ -167,7 +167,9 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
        },
        {
                .cmd    = TIPC_NL_SOCK_GET,
+               .start = tipc_dump_start,
                .dumpit = tipc_nl_sk_dump,
+               .done   = tipc_dump_done,
                .policy = tipc_nl_policy,
        },
        {
index c1e93c9515bca5abaae647f18402a8bc25bfa2b4..ab7a2a7178f7167b2cac5c0f382a8bbda42bf4d5 100644 (file)
@@ -2672,6 +2672,8 @@ void tipc_sk_reinit(struct net *net)
 
                rhashtable_walk_stop(&iter);
        } while (tsk == ERR_PTR(-EAGAIN));
+
+       rhashtable_walk_exit(&iter);
 }
 
 static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid)
@@ -3227,45 +3229,69 @@ int tipc_nl_sk_walk(struct sk_buff *skb, struct netlink_callback *cb,
                                       struct netlink_callback *cb,
                                       struct tipc_sock *tsk))
 {
-       struct net *net = sock_net(skb->sk);
-       struct tipc_net *tn = tipc_net(net);
-       const struct bucket_table *tbl;
-       u32 prev_portid = cb->args[1];
-       u32 tbl_id = cb->args[0];
-       struct rhash_head *pos;
+       struct rhashtable_iter *iter = (void *)cb->args[0];
        struct tipc_sock *tsk;
        int err;
 
-       rcu_read_lock();
-       tbl = rht_dereference_rcu((&tn->sk_rht)->tbl, &tn->sk_rht);
-       for (; tbl_id < tbl->size; tbl_id++) {
-               rht_for_each_entry_rcu(tsk, pos, tbl, tbl_id, node) {
-                       spin_lock_bh(&tsk->sk.sk_lock.slock);
-                       if (prev_portid && prev_portid != tsk->portid) {
-                               spin_unlock_bh(&tsk->sk.sk_lock.slock);
+       rhashtable_walk_start(iter);
+       while ((tsk = rhashtable_walk_next(iter)) != NULL) {
+               if (IS_ERR(tsk)) {
+                       err = PTR_ERR(tsk);
+                       if (err == -EAGAIN) {
+                               err = 0;
                                continue;
                        }
+                       break;
+               }
 
-                       err = skb_handler(skb, cb, tsk);
-                       if (err) {
-                               prev_portid = tsk->portid;
-                               spin_unlock_bh(&tsk->sk.sk_lock.slock);
-                               goto out;
-                       }
-
-                       prev_portid = 0;
-                       spin_unlock_bh(&tsk->sk.sk_lock.slock);
+               sock_hold(&tsk->sk);
+               rhashtable_walk_stop(iter);
+               lock_sock(&tsk->sk);
+               err = skb_handler(skb, cb, tsk);
+               if (err) {
+                       release_sock(&tsk->sk);
+                       sock_put(&tsk->sk);
+                       goto out;
                }
+               release_sock(&tsk->sk);
+               rhashtable_walk_start(iter);
+               sock_put(&tsk->sk);
        }
+       rhashtable_walk_stop(iter);
 out:
-       rcu_read_unlock();
-       cb->args[0] = tbl_id;
-       cb->args[1] = prev_portid;
-
        return skb->len;
 }
 EXPORT_SYMBOL(tipc_nl_sk_walk);
 
+int tipc_dump_start(struct netlink_callback *cb)
+{
+       struct rhashtable_iter *iter = (void *)cb->args[0];
+       struct net *net = sock_net(cb->skb->sk);
+       struct tipc_net *tn = tipc_net(net);
+
+       if (!iter) {
+               iter = kmalloc(sizeof(*iter), GFP_KERNEL);
+               if (!iter)
+                       return -ENOMEM;
+
+               cb->args[0] = (long)iter;
+       }
+
+       rhashtable_walk_enter(&tn->sk_rht, iter);
+       return 0;
+}
+EXPORT_SYMBOL(tipc_dump_start);
+
+int tipc_dump_done(struct netlink_callback *cb)
+{
+       struct rhashtable_iter *hti = (void *)cb->args[0];
+
+       rhashtable_walk_exit(hti);
+       kfree(hti);
+       return 0;
+}
+EXPORT_SYMBOL(tipc_dump_done);
+
 int tipc_sk_fill_sock_diag(struct sk_buff *skb, struct netlink_callback *cb,
                           struct tipc_sock *tsk, u32 sk_filter_state,
                           u64 (*tipc_diag_gen_cookie)(struct sock *sk))
index aff9b2ae5a1f448d64d72927686d28146dfd5d7d..d43032e26532c406bea693b923fb25572a8ad567 100644 (file)
@@ -68,4 +68,6 @@ int tipc_nl_sk_walk(struct sk_buff *skb, struct netlink_callback *cb,
                    int (*skb_handler)(struct sk_buff *skb,
                                       struct netlink_callback *cb,
                                       struct tipc_sock *tsk));
+int tipc_dump_start(struct netlink_callback *cb);
+int tipc_dump_done(struct netlink_callback *cb);
 #endif
index c8e34ef22c30223d57ea8254d239331402040742..2627b5d812e9040b11396f34f8bc31fb5da3956a 100644 (file)
@@ -313,8 +313,8 @@ static void tipc_conn_send_work(struct work_struct *work)
        conn_put(con);
 }
 
-/* tipc_conn_queue_evt() - interrupt level call from a subscription instance
- * The queued work is launched into tipc_send_work()->tipc_send_to_sock()
+/* tipc_topsrv_queue_evt() - interrupt level call from a subscription instance
+ * The queued work is launched into tipc_conn_send_work()->tipc_conn_send_to_sock()
  */
 void tipc_topsrv_queue_evt(struct net *net, int conid,
                           u32 event, struct tipc_event *evt)
index 93c0c225ab340ae0f0de3c5c2e6b2a149579c19e..180b6640e5316bb89b502414c2b51c4db0269997 100644 (file)
@@ -213,9 +213,14 @@ static void tls_write_space(struct sock *sk)
 {
        struct tls_context *ctx = tls_get_ctx(sk);
 
-       /* We are already sending pages, ignore notification */
-       if (ctx->in_tcp_sendpages)
+       /* If in_tcp_sendpages call lower protocol write space handler
+        * to ensure we wake up any waiting operations there. For example
+        * if do_tcp_sendpages where to call sk_wait_event.
+        */
+       if (ctx->in_tcp_sendpages) {
+               ctx->sk_write_space(sk);
                return;
+       }
 
        if (!sk->sk_write_pending && tls_is_pending_closed_record(ctx)) {
                gfp_t sk_allocation = sk->sk_allocation;
index 5fb9b7dd98318b6e9d4842474361104855b42983..4b8ec659e797ff743267773e315c6220b90993d0 100644 (file)
@@ -669,13 +669,13 @@ static int nl80211_msg_put_wmm_rules(struct sk_buff *msg,
                        goto nla_put_failure;
 
                if (nla_put_u16(msg, NL80211_WMMR_CW_MIN,
-                               rule->wmm_rule->client[j].cw_min) ||
+                               rule->wmm_rule.client[j].cw_min) ||
                    nla_put_u16(msg, NL80211_WMMR_CW_MAX,
-                               rule->wmm_rule->client[j].cw_max) ||
+                               rule->wmm_rule.client[j].cw_max) ||
                    nla_put_u8(msg, NL80211_WMMR_AIFSN,
-                              rule->wmm_rule->client[j].aifsn) ||
-                   nla_put_u8(msg, NL80211_WMMR_TXOP,
-                              rule->wmm_rule->client[j].cot))
+                              rule->wmm_rule.client[j].aifsn) ||
+                   nla_put_u16(msg, NL80211_WMMR_TXOP,
+                               rule->wmm_rule.client[j].cot))
                        goto nla_put_failure;
 
                nla_nest_end(msg, nl_wmm_rule);
@@ -766,9 +766,9 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy,
 
        if (large) {
                const struct ieee80211_reg_rule *rule =
-                       freq_reg_info(wiphy, chan->center_freq);
+                       freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq));
 
-               if (!IS_ERR(rule) && rule->wmm_rule) {
+               if (!IS_ERR_OR_NULL(rule) && rule->has_wmm) {
                        if (nl80211_msg_put_wmm_rules(msg, rule))
                                goto nla_put_failure;
                }
@@ -12205,6 +12205,7 @@ static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
                return -EOPNOTSUPP;
 
        if (!info->attrs[NL80211_ATTR_MDID] ||
+           !info->attrs[NL80211_ATTR_IE] ||
            !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
                return -EINVAL;
 
index 4fc66a117b7d74f86a1589a7a02b88f02f203b7d..2f702adf2912105947560d07d79ff86119333bbf 100644 (file)
@@ -425,36 +425,23 @@ static const struct ieee80211_regdomain *
 reg_copy_regd(const struct ieee80211_regdomain *src_regd)
 {
        struct ieee80211_regdomain *regd;
-       int size_of_regd, size_of_wmms;
+       int size_of_regd;
        unsigned int i;
-       struct ieee80211_wmm_rule *d_wmm, *s_wmm;
 
        size_of_regd =
                sizeof(struct ieee80211_regdomain) +
                src_regd->n_reg_rules * sizeof(struct ieee80211_reg_rule);
-       size_of_wmms = src_regd->n_wmm_rules *
-               sizeof(struct ieee80211_wmm_rule);
 
-       regd = kzalloc(size_of_regd + size_of_wmms, GFP_KERNEL);
+       regd = kzalloc(size_of_regd, GFP_KERNEL);
        if (!regd)
                return ERR_PTR(-ENOMEM);
 
        memcpy(regd, src_regd, sizeof(struct ieee80211_regdomain));
 
-       d_wmm = (struct ieee80211_wmm_rule *)((u8 *)regd + size_of_regd);
-       s_wmm = (struct ieee80211_wmm_rule *)((u8 *)src_regd + size_of_regd);
-       memcpy(d_wmm, s_wmm, size_of_wmms);
-
-       for (i = 0; i < src_regd->n_reg_rules; i++) {
+       for (i = 0; i < src_regd->n_reg_rules; i++)
                memcpy(&regd->reg_rules[i], &src_regd->reg_rules[i],
                       sizeof(struct ieee80211_reg_rule));
-               if (!src_regd->reg_rules[i].wmm_rule)
-                       continue;
 
-               regd->reg_rules[i].wmm_rule = d_wmm +
-                       (src_regd->reg_rules[i].wmm_rule - s_wmm) /
-                       sizeof(struct ieee80211_wmm_rule);
-       }
        return regd;
 }
 
@@ -860,9 +847,10 @@ static bool valid_regdb(const u8 *data, unsigned int size)
        return true;
 }
 
-static void set_wmm_rule(struct ieee80211_wmm_rule *rule,
+static void set_wmm_rule(struct ieee80211_reg_rule *rrule,
                         struct fwdb_wmm_rule *wmm)
 {
+       struct ieee80211_wmm_rule *rule = &rrule->wmm_rule;
        unsigned int i;
 
        for (i = 0; i < IEEE80211_NUM_ACS; i++) {
@@ -876,11 +864,13 @@ static void set_wmm_rule(struct ieee80211_wmm_rule *rule,
                rule->ap[i].aifsn = wmm->ap[i].aifsn;
                rule->ap[i].cot = 1000 * be16_to_cpu(wmm->ap[i].cot);
        }
+
+       rrule->has_wmm = true;
 }
 
 static int __regdb_query_wmm(const struct fwdb_header *db,
                             const struct fwdb_country *country, int freq,
-                            u32 *dbptr, struct ieee80211_wmm_rule *rule)
+                            struct ieee80211_reg_rule *rule)
 {
        unsigned int ptr = be16_to_cpu(country->coll_ptr) << 2;
        struct fwdb_collection *coll = (void *)((u8 *)db + ptr);
@@ -901,8 +891,6 @@ static int __regdb_query_wmm(const struct fwdb_header *db,
                        wmm_ptr = be16_to_cpu(rrule->wmm_ptr) << 2;
                        wmm = (void *)((u8 *)db + wmm_ptr);
                        set_wmm_rule(rule, wmm);
-                       if (dbptr)
-                               *dbptr = wmm_ptr;
                        return 0;
                }
        }
@@ -910,8 +898,7 @@ static int __regdb_query_wmm(const struct fwdb_header *db,
        return -ENODATA;
 }
 
-int reg_query_regdb_wmm(char *alpha2, int freq, u32 *dbptr,
-                       struct ieee80211_wmm_rule *rule)
+int reg_query_regdb_wmm(char *alpha2, int freq, struct ieee80211_reg_rule *rule)
 {
        const struct fwdb_header *hdr = regdb;
        const struct fwdb_country *country;
@@ -925,8 +912,7 @@ int reg_query_regdb_wmm(char *alpha2, int freq, u32 *dbptr,
        country = &hdr->country[0];
        while (country->coll_ptr) {
                if (alpha2_equal(alpha2, country->alpha2))
-                       return __regdb_query_wmm(regdb, country, freq, dbptr,
-                                                rule);
+                       return __regdb_query_wmm(regdb, country, freq, rule);
 
                country++;
        }
@@ -935,32 +921,13 @@ int reg_query_regdb_wmm(char *alpha2, int freq, u32 *dbptr,
 }
 EXPORT_SYMBOL(reg_query_regdb_wmm);
 
-struct wmm_ptrs {
-       struct ieee80211_wmm_rule *rule;
-       u32 ptr;
-};
-
-static struct ieee80211_wmm_rule *find_wmm_ptr(struct wmm_ptrs *wmm_ptrs,
-                                              u32 wmm_ptr, int n_wmms)
-{
-       int i;
-
-       for (i = 0; i < n_wmms; i++) {
-               if (wmm_ptrs[i].ptr == wmm_ptr)
-                       return wmm_ptrs[i].rule;
-       }
-       return NULL;
-}
-
 static int regdb_query_country(const struct fwdb_header *db,
                               const struct fwdb_country *country)
 {
        unsigned int ptr = be16_to_cpu(country->coll_ptr) << 2;
        struct fwdb_collection *coll = (void *)((u8 *)db + ptr);
        struct ieee80211_regdomain *regdom;
-       struct ieee80211_regdomain *tmp_rd;
-       unsigned int size_of_regd, i, n_wmms = 0;
-       struct wmm_ptrs *wmm_ptrs;
+       unsigned int size_of_regd, i;
 
        size_of_regd = sizeof(struct ieee80211_regdomain) +
                coll->n_rules * sizeof(struct ieee80211_reg_rule);
@@ -969,12 +936,6 @@ static int regdb_query_country(const struct fwdb_header *db,
        if (!regdom)
                return -ENOMEM;
 
-       wmm_ptrs = kcalloc(coll->n_rules, sizeof(*wmm_ptrs), GFP_KERNEL);
-       if (!wmm_ptrs) {
-               kfree(regdom);
-               return -ENOMEM;
-       }
-
        regdom->n_reg_rules = coll->n_rules;
        regdom->alpha2[0] = country->alpha2[0];
        regdom->alpha2[1] = country->alpha2[1];
@@ -1013,37 +974,11 @@ static int regdb_query_country(const struct fwdb_header *db,
                                1000 * be16_to_cpu(rule->cac_timeout);
                if (rule->len >= offsetofend(struct fwdb_rule, wmm_ptr)) {
                        u32 wmm_ptr = be16_to_cpu(rule->wmm_ptr) << 2;
-                       struct ieee80211_wmm_rule *wmm_pos =
-                               find_wmm_ptr(wmm_ptrs, wmm_ptr, n_wmms);
-                       struct fwdb_wmm_rule *wmm;
-                       struct ieee80211_wmm_rule *wmm_rule;
-
-                       if (wmm_pos) {
-                               rrule->wmm_rule = wmm_pos;
-                               continue;
-                       }
-                       wmm = (void *)((u8 *)db + wmm_ptr);
-                       tmp_rd = krealloc(regdom, size_of_regd + (n_wmms + 1) *
-                                         sizeof(struct ieee80211_wmm_rule),
-                                         GFP_KERNEL);
-
-                       if (!tmp_rd) {
-                               kfree(regdom);
-                               kfree(wmm_ptrs);
-                               return -ENOMEM;
-                       }
-                       regdom = tmp_rd;
-
-                       wmm_rule = (struct ieee80211_wmm_rule *)
-                               ((u8 *)regdom + size_of_regd + n_wmms *
-                               sizeof(struct ieee80211_wmm_rule));
+                       struct fwdb_wmm_rule *wmm = (void *)((u8 *)db + wmm_ptr);
 
-                       set_wmm_rule(wmm_rule, wmm);
-                       wmm_ptrs[n_wmms].ptr = wmm_ptr;
-                       wmm_ptrs[n_wmms++].rule = wmm_rule;
+                       set_wmm_rule(rrule, wmm);
                }
        }
-       kfree(wmm_ptrs);
 
        return reg_schedule_apply(regdom);
 }
index e0825a019e9fb255adc2f4f749b08e241b2c2dde..959ed3acd2407c8c4beb4ce91b625315bf926109 100644 (file)
@@ -1456,7 +1456,7 @@ bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef,
                                          u8 *op_class)
 {
        u8 vht_opclass;
-       u16 freq = chandef->center_freq1;
+       u32 freq = chandef->center_freq1;
 
        if (freq >= 2412 && freq <= 2472) {
                if (chandef->width > NL80211_CHAN_WIDTH_40)
index 911ca6d3cb5a6cd7d056a04cf3df57d5833bafeb..bfe2dbea480ba8ef54e0cc24659aa15d267aea2a 100644 (file)
@@ -74,14 +74,14 @@ int xdp_umem_assign_dev(struct xdp_umem *umem, struct net_device *dev,
                return 0;
 
        if (!dev->netdev_ops->ndo_bpf || !dev->netdev_ops->ndo_xsk_async_xmit)
-               return force_zc ? -ENOTSUPP : 0; /* fail or fallback */
+               return force_zc ? -EOPNOTSUPP : 0; /* fail or fallback */
 
        bpf.command = XDP_QUERY_XSK_UMEM;
 
        rtnl_lock();
        err = xdp_umem_query(dev, queue_id);
        if (err) {
-               err = err < 0 ? -ENOTSUPP : -EBUSY;
+               err = err < 0 ? -EOPNOTSUPP : -EBUSY;
                goto err_rtnl_unlock;
        }
 
index 7c98f60e226677ca8c0c81a1c665d150a0906f2a..ce53639a864a14fa13d85710af4b875fd477217f 100644 (file)
@@ -153,18 +153,14 @@ cc-fullversion = $(shell $(CONFIG_SHELL) \
 # Usage:  EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1)
 cc-ifversion = $(shell [ $(cc-version) $(1) $(2) ] && echo $(3) || echo $(4))
 
-# cc-if-fullversion
-# Usage:  EXTRA_CFLAGS += $(call cc-if-fullversion, -lt, 040502, -O1)
-cc-if-fullversion = $(shell [ $(cc-fullversion) $(1) $(2) ] && echo $(3) || echo $(4))
-
 # cc-ldoption
 # Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both)
 cc-ldoption = $(call try-run,\
        $(CC) $(1) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2))
 
 # ld-option
-# Usage: LDFLAGS += $(call ld-option, -X, -Y)
-ld-option = $(call try-run, $(LD) $(LDFLAGS) $(1) -v,$(1),$(2),$(3))
+# Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y)
+ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3))
 
 # ar-option
 # Usage: KBUILD_ARFLAGS := $(call ar-option,D)
index 1adaac4e10d8f78ae571ba115729d51727db8fd1..5a2d1c9578a0ce19d764dcc8d84740234feb58c6 100644 (file)
@@ -190,7 +190,7 @@ cmd_modversions_c =                                                         \
                $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes))  \
                    > $(@D)/.tmp_$(@F:.o=.ver);                                 \
                                                                                \
-               $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F)                      \
+               $(LD) $(KBUILD_LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F)               \
                        -T $(@D)/.tmp_$(@F:.o=.ver);                            \
                rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver);                \
        else                                                                    \
@@ -199,11 +199,8 @@ cmd_modversions_c =                                                                \
 endif
 
 ifdef CONFIG_FTRACE_MCOUNT_RECORD
-# gcc 5 supports generating the mcount tables directly
-ifneq ($(call cc-option,-mrecord-mcount,y),y)
-KBUILD_CFLAGS += -mrecord-mcount
-else
-# else do it all manually
+ifndef CC_USING_RECORD_MCOUNT
+# compiler will not generate __mcount_loc use recordmcount or recordmcount.pl
 ifdef BUILD_C_RECORDMCOUNT
 ifeq ("$(origin RECORDMCOUNT_WARN)", "command line")
   RECORDMCOUNT_FLAGS = -w
@@ -223,7 +220,7 @@ sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH
        "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \
        "$(if $(CONFIG_64BIT),64,32)" \
        "$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CFLAGS)" \
-       "$(LD)" "$(NM)" "$(RM)" "$(MV)" \
+       "$(LD) $(KBUILD_LDFLAGS)" "$(NM)" "$(RM)" "$(MV)" \
        "$(if $(part-of-module),1,0)" "$(@)";
 recordmcount_source := $(srctree)/scripts/recordmcount.pl
 endif # BUILD_C_RECORDMCOUNT
@@ -232,7 +229,7 @@ cmd_record_mcount =                                         \
             "$(CC_FLAGS_FTRACE)" ]; then                       \
                $(sub_cmd_record_mcount)                        \
        fi;
-endif # -record-mcount
+endif # CC_USING_RECORD_MCOUNT
 endif # CONFIG_FTRACE_MCOUNT_RECORD
 
 ifdef CONFIG_STACK_VALIDATION
@@ -249,8 +246,6 @@ objtool_args += --no-fp
 endif
 ifdef CONFIG_GCOV_KERNEL
 objtool_args += --no-unreachable
-else
-objtool_args += $(call cc-ifversion, -lt, 0405, --no-unreachable)
 endif
 ifdef CONFIG_RETPOLINE
 ifneq ($(RETPOLINE_CFLAGS),)
@@ -397,7 +392,7 @@ cmd_modversions_S =                                                         \
                $(call cmd_gensymtypes_S,$(KBUILD_SYMTYPES),$(@:.o=.symtypes))  \
                    > $(@D)/.tmp_$(@F:.o=.ver);                                 \
                                                                                \
-               $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F)                      \
+               $(LD) $(KBUILD_LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F)               \
                        -T $(@D)/.tmp_$(@F:.o=.ver);                            \
                rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver);                \
        else                                                                    \
index df0fff2526194d37641b4bf34a865c2a3a867635..61e596650ed314c7d655fbabb3fce675f41bb4ed 100644 (file)
@@ -162,7 +162,7 @@ a_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
 cpp_flags      = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
                 $(__cpp_flags)
 
-ld_flags       = $(LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F))
+ld_flags       = $(KBUILD_LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F))
 
 DTC_INCLUDE    := $(srctree)/scripts/dtc/include-prefixes
 
index dd92dbbbaa687b73f31b922187c0da15f66266e0..7d4af0d0accb34a990098a80062d289168c8fe5e 100644 (file)
@@ -120,7 +120,7 @@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink)
 # Step 6), final link of the modules with optional arch pass after final link
 quiet_cmd_ld_ko_o = LD [M]  $@
       cmd_ld_ko_o =                                                     \
-       $(LD) -r $(LDFLAGS)                                             \
+       $(LD) -r $(KBUILD_LDFLAGS)                                      \
                  $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE)             \
                  -o $@ $(filter-out FORCE,$^) ;                         \
        $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
index 447857ffaf6be157841f8b0283d8ac67cb37dc5e..161b0224d6ae9ca927269664eaded3bcce41e91f 100755 (executable)
@@ -13,6 +13,7 @@ use POSIX;
 use File::Basename;
 use Cwd 'abs_path';
 use Term::ANSIColor qw(:constants);
+use Encode qw(decode encode);
 
 my $P = $0;
 my $D = dirname(abs_path($P));
@@ -240,11 +241,11 @@ $check_orig = $check;
 
 my $exit = 0;
 
+my $perl_version_ok = 1;
 if ($^V && $^V lt $minimum_perl_version) {
+       $perl_version_ok = 0;
        printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
-       if (!$ignore_perl_version) {
-               exit(1);
-       }
+       exit(1) if (!$ignore_perl_version);
 }
 
 #if no filenames are given, push '-' to read patch from stdin
@@ -346,9 +347,10 @@ our $Sparse        = qr{
                        __force|
                        __iomem|
                        __must_check|
-                       __init_refok|
                        __kprobes|
                        __ref|
+                       __refconst|
+                       __refdata|
                        __rcu|
                        __private
                }x;
@@ -378,6 +380,7 @@ our $Attribute      = qr{
                        __noclone|
                        __deprecated|
                        __read_mostly|
+                       __ro_after_init|
                        __kprobes|
                        $InitAttribute|
                        ____cacheline_aligned|
@@ -847,6 +850,17 @@ sub is_maintained_obsolete {
        return $status =~ /obsolete/i;
 }
 
+sub is_SPDX_License_valid {
+       my ($license) = @_;
+
+       return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$root/.git"));
+
+       my $root_path = abs_path($root);
+       my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`;
+       return 0 if ($status ne "");
+       return 1;
+}
+
 my $camelcase_seeded = 0;
 sub seed_camelcase_includes {
        return if ($camelcase_seeded);
@@ -1026,11 +1040,11 @@ if (!$quiet) {
        hash_show_words(\%use_type, "Used");
        hash_show_words(\%ignore_type, "Ignored");
 
-       if ($^V lt 5.10.0) {
+       if (!$perl_version_ok) {
                print << "EOM"
 
 NOTE: perl $^V is not modern enough to detect all possible issues.
-      An upgrade to at least perl v5.10.0 is suggested.
+      An upgrade to at least perl $minimum_perl_version is suggested.
 EOM
        }
        if ($exit) {
@@ -2235,10 +2249,14 @@ sub process {
 
        our $clean = 1;
        my $signoff = 0;
+       my $author = '';
+       my $authorsignoff = 0;
        my $is_patch = 0;
+       my $is_binding_patch = -1;
        my $in_header_lines = $file ? 0 : 1;
        my $in_commit_log = 0;          #Scanning lines before patch
        my $has_commit_log = 0;         #Encountered lines before patch
+       my $commit_log_lines = 0;       #Number of commit log lines
        my $commit_log_possible_stack_dump = 0;
        my $commit_log_long_line = 0;
        my $commit_log_has_diff = 0;
@@ -2485,6 +2503,19 @@ sub process {
                                $check = $check_orig;
                        }
                        $checklicenseline = 1;
+
+                       if ($realfile !~ /^MAINTAINERS/) {
+                               my $last_binding_patch = $is_binding_patch;
+
+                               $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
+
+                               if (($last_binding_patch != -1) &&
+                                   ($last_binding_patch ^ $is_binding_patch)) {
+                                       WARN("DT_SPLIT_BINDING_PATCH",
+                                            "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n");
+                               }
+                       }
+
                        next;
                }
 
@@ -2496,6 +2527,18 @@ sub process {
 
                $cnt_lines++ if ($realcnt != 0);
 
+# Verify the existence of a commit log if appropriate
+# 2 is used because a $signature is counted in $commit_log_lines
+               if ($in_commit_log) {
+                       if ($line !~ /^\s*$/) {
+                               $commit_log_lines++;    #could be a $signature
+                       }
+               } elsif ($has_commit_log && $commit_log_lines < 2) {
+                       WARN("COMMIT_MESSAGE",
+                            "Missing commit description - Add an appropriate one\n");
+                       $commit_log_lines = 2;  #warn only once
+               }
+
 # Check if the commit log has what seems like a diff which can confuse patch
                if ($in_commit_log && !$commit_log_has_diff &&
                    (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
@@ -2517,10 +2560,24 @@ sub process {
                        }
                }
 
+# Check the patch for a From:
+               if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
+                       $author = $1;
+                       $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
+                       $author =~ s/"//g;
+               }
+
 # Check the patch for a signoff:
                if ($line =~ /^\s*signed-off-by:/i) {
                        $signoff++;
                        $in_commit_log = 0;
+                       if ($author ne '') {
+                               my $l = $line;
+                               $l =~ s/"//g;
+                               if ($l =~ /^\s*signed-off-by:\s*\Q$author\E/i) {
+                                   $authorsignoff = 1;
+                               }
+                       }
                }
 
 # Check if MAINTAINERS is being updated.  If so, there's probably no need to
@@ -2960,8 +3017,14 @@ sub process {
 
                                if ($comment !~ /^$/ &&
                                    $rawline !~ /^\+\Q$comment\E SPDX-License-Identifier: /) {
-                                       WARN("SPDX_LICENSE_TAG",
-                                            "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
+                                        WARN("SPDX_LICENSE_TAG",
+                                             "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
+                               } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
+                                        my $spdx_license = $1;
+                                        if (!is_SPDX_License_valid($spdx_license)) {
+                                                 WARN("SPDX_LICENSE_TAG",
+                                                      "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
+                                        }
                                }
                        }
                }
@@ -3079,7 +3142,7 @@ sub process {
                }
 
 # check indentation starts on a tab stop
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
                        my $indent = length($1);
                        if ($indent % 8) {
@@ -3092,7 +3155,7 @@ sub process {
                }
 
 # check multi-line statement indentation matches previous line
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
                        $prevline =~ /^\+(\t*)(.*)$/;
                        my $oldindent = $1;
@@ -3249,7 +3312,7 @@ sub process {
                        # known declaration macros
                      $sline =~ /^\+\s+$declaration_macros/ ||
                        # start of struct or union or enum
-                     $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ ||
+                     $sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
                        # start or end of block or continuation of declaration
                      $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
                        # bitfield continuation
@@ -3781,6 +3844,26 @@ sub process {
                             "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
                }
 
+# check for unnecessary <signed> int declarations of short/long/long long
+               while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
+                       my $type = trim($1);
+                       next if ($type !~ /\bint\b/);
+                       next if ($type !~ /\b(?:short|long\s+long|long)\b/);
+                       my $new_type = $type;
+                       $new_type =~ s/\b\s*int\s*\b/ /;
+                       $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
+                       $new_type =~ s/^const\s+//;
+                       $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
+                       $new_type = "const $new_type" if ($type =~ /^const\b/);
+                       $new_type =~ s/\s+/ /g;
+                       $new_type = trim($new_type);
+                       if (WARN("UNNECESSARY_INT",
+                                "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
+                           $fix) {
+                               $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
+                       }
+               }
+
 # check for static const char * arrays.
                if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
                        WARN("STATIC_CONST_CHAR_ARRAY",
@@ -3967,7 +4050,7 @@ sub process {
 
 # function brace can't be on same line, except for #defines of do while,
 # or if closed on same line
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
                    $sline !~ /\#\s*define\b.*do\s*\{/ &&
                    $sline !~ /}/) {
@@ -4483,11 +4566,11 @@ sub process {
 
 #need space before brace following if, while, etc
                if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
-                   $line =~ /do\{/) {
+                   $line =~ /\b(?:else|do)\{/) {
                        if (ERROR("SPACING",
                                  "space required before the open brace '{'\n" . $herecurr) &&
                            $fix) {
-                               $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\)))\{/$1 {/;
+                               $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
                        }
                }
 
@@ -4578,7 +4661,7 @@ sub process {
 # check for unnecessary parentheses around comparisons in if uses
 # when !drivers/staging or command-line uses --strict
                if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
-                   $^V && $^V ge 5.10.0 && defined($stat) &&
+                   $perl_version_ok && defined($stat) &&
                    $stat =~ /(^.\s*if\s*($balanced_parens))/) {
                        my $if_stat = $1;
                        my $test = substr($2, 1, -1);
@@ -4615,7 +4698,7 @@ sub process {
 # return is not a function
                if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
                        my $spacing = $1;
-                       if ($^V && $^V ge 5.10.0 &&
+                       if ($perl_version_ok &&
                            $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
                                my $value = $1;
                                $value = deparenthesize($value);
@@ -4642,7 +4725,7 @@ sub process {
                }
 
 # if statements using unnecessary parentheses - ie: if ((foo == bar))
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    $line =~ /\bif\s*((?:\(\s*){2,})/) {
                        my $openparens = $1;
                        my $count = $openparens =~ tr@\(@\(@;
@@ -4659,7 +4742,7 @@ sub process {
 #      avoid cases like "foo + BAR < baz"
 #      only fix matches surrounded by parentheses to avoid incorrect
 #      conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
                        my $lead = $1;
                        my $const = $2;
@@ -4949,6 +5032,7 @@ sub process {
                        if (defined $define_args && $define_args ne "") {
                                $define_args = substr($define_args, 1, length($define_args) - 2);
                                $define_args =~ s/\s*//g;
+                               $define_args =~ s/\\\+?//g;
                                @def_args = split(",", $define_args);
                        }
 
@@ -5084,7 +5168,7 @@ sub process {
 # do {} while (0) macro tests:
 # single-statement macros do not need to be enclosed in do while (0) loop,
 # macro should not end with a semicolon
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    $realfile !~ m@/vmlinux.lds.h$@ &&
                    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
                        my $ln = $linenr;
@@ -5330,15 +5414,28 @@ sub process {
                }
 
 # concatenated string without spaces between elements
-               if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) {
-                       CHK("CONCATENATED_STRING",
-                           "Concatenated strings should use spaces between elements\n" . $herecurr);
+               if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) {
+                       if (CHK("CONCATENATED_STRING",
+                               "Concatenated strings should use spaces between elements\n" . $herecurr) &&
+                           $fix) {
+                               while ($line =~ /($String)/g) {
+                                       my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
+                                       $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
+                                       $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
+                               }
+                       }
                }
 
 # uncoalesced string fragments
                if ($line =~ /$String\s*"/) {
-                       WARN("STRING_FRAGMENTS",
-                            "Consecutive strings are generally better as a single string\n" . $herecurr);
+                       if (WARN("STRING_FRAGMENTS",
+                                "Consecutive strings are generally better as a single string\n" . $herecurr) &&
+                           $fix) {
+                               while ($line =~ /($String)(?=\s*")/g) {
+                                       my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
+                                       $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
+                               }
+                       }
                }
 
 # check for non-standard and hex prefixed decimal printf formats
@@ -5374,9 +5471,14 @@ sub process {
 
 # warn about #if 0
                if ($line =~ /^.\s*\#\s*if\s+0\b/) {
-                       CHK("REDUNDANT_CODE",
-                           "if this code is redundant consider removing it\n" .
-                               $herecurr);
+                       WARN("IF_0",
+                            "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
+               }
+
+# warn about #if 1
+               if ($line =~ /^.\s*\#\s*if\s+1\b/) {
+                       WARN("IF_1",
+                            "Consider removing the #if 1 and its #endif\n" . $herecurr);
                }
 
 # check for needless "if (<foo>) fn(<foo>)" uses
@@ -5447,7 +5549,7 @@ sub process {
                }
 
 # check for mask then right shift without a parentheses
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
                    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
                        WARN("MASK_THEN_SHIFT",
@@ -5455,7 +5557,7 @@ sub process {
                }
 
 # check for pointer comparisons to NULL
-               if ($^V && $^V ge 5.10.0) {
+               if ($perl_version_ok) {
                        while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
                                my $val = $1;
                                my $equal = "!";
@@ -5727,7 +5829,7 @@ sub process {
                }
 
 # Check for __attribute__ weak, or __weak declarations (may have link issues)
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
                    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
                     $line =~ /\b__weak\b/)) {
@@ -5809,7 +5911,7 @@ sub process {
                }
 
 # check for vsprintf extension %p<foo> misuses
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    defined $stat &&
                    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
                    $1 !~ /^_*volatile_*$/) {
@@ -5856,7 +5958,7 @@ sub process {
                }
 
 # Check for misused memsets
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    defined $stat &&
                    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
 
@@ -5874,7 +5976,7 @@ sub process {
                }
 
 # Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
-#              if ($^V && $^V ge 5.10.0 &&
+#              if ($perl_version_ok &&
 #                  defined $stat &&
 #                  $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
 #                      if (WARN("PREFER_ETHER_ADDR_COPY",
@@ -5885,7 +5987,7 @@ sub process {
 #              }
 
 # Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
-#              if ($^V && $^V ge 5.10.0 &&
+#              if ($perl_version_ok &&
 #                  defined $stat &&
 #                  $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
 #                      WARN("PREFER_ETHER_ADDR_EQUAL",
@@ -5894,7 +5996,7 @@ sub process {
 
 # check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
 # check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
-#              if ($^V && $^V ge 5.10.0 &&
+#              if ($perl_version_ok &&
 #                  defined $stat &&
 #                  $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
 #
@@ -5916,7 +6018,7 @@ sub process {
 #              }
 
 # typecasts on min/max could be min_t/max_t
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    defined $stat &&
                    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
                        if (defined $2 || defined $7) {
@@ -5940,7 +6042,7 @@ sub process {
                }
 
 # check usleep_range arguments
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    defined $stat &&
                    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
                        my $min = $1;
@@ -5956,7 +6058,7 @@ sub process {
                }
 
 # check for naked sscanf
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    defined $stat &&
                    $line =~ /\bsscanf\b/ &&
                    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
@@ -5970,7 +6072,7 @@ sub process {
                }
 
 # check for simple sscanf that should be kstrto<foo>
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    defined $stat &&
                    $line =~ /\bsscanf\b/) {
                        my $lc = $stat =~ tr@\n@@;
@@ -6042,7 +6144,7 @@ sub process {
                }
 
 # check for function definitions
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    defined $stat &&
                    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
                        $context_function = $1;
@@ -6082,14 +6184,14 @@ sub process {
 
 # alloc style
 # p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
                        CHK("ALLOC_SIZEOF_STRUCT",
                            "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
                }
 
 # check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    defined $stat &&
                    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
                        my $oldfunc = $3;
@@ -6118,8 +6220,9 @@ sub process {
                }
 
 # check for krealloc arg reuse
-               if ($^V && $^V ge 5.10.0 &&
-                   $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) {
+               if ($perl_version_ok &&
+                   $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
+                   $1 eq $3) {
                        WARN("KREALLOC_ARG_REUSE",
                             "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
                }
@@ -6187,7 +6290,7 @@ sub process {
                }
 
 # check for switch/default statements without a break;
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    defined $stat &&
                    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
                        my $cnt = statement_rawlines($stat);
@@ -6251,6 +6354,13 @@ sub process {
                             "Avoid using bool as bitfield.  Prefer bool bitfields as unsigned int or u<8|16|32>\n" . $herecurr);
                }
 
+# check for bool use in .h files
+               if ($realfile =~ /\.h$/ &&
+                   $sline =~ /^.\s+bool\s*$Ident\s*(?::\s*d+\s*)?;/) {
+                       CHK("BOOL_MEMBER",
+                           "Avoid using bool structure members because of possible alignment issues - see: https://lkml.org/lkml/2017/11/21/384\n" . $herecurr);
+               }
+
 # check for semaphores initialized locked
                if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
                        WARN("CONSIDER_COMPLETION",
@@ -6297,7 +6407,7 @@ sub process {
                }
 
 # likely/unlikely comparisons similar to "(likely(foo) > 0)"
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
                        WARN("LIKELY_MISUSE",
                             "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
@@ -6340,7 +6450,7 @@ sub process {
 # check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
 # and whether or not function naming is typical and if
 # DEVICE_ATTR permissions uses are unusual too
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    defined $stat &&
                    $stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) {
                        my $var = $1;
@@ -6400,7 +6510,7 @@ sub process {
 #   specific definition of not visible in sysfs.
 # o Ignore proc_create*(...) uses with a decimal 0 permission as that means
 #   use the default permissions
-               if ($^V && $^V ge 5.10.0 &&
+               if ($perl_version_ok &&
                    defined $stat &&
                    $line =~ /$mode_perms_search/) {
                        foreach my $entry (@mode_permission_funcs) {
@@ -6486,9 +6596,14 @@ sub process {
                ERROR("NOT_UNIFIED_DIFF",
                      "Does not appear to be a unified-diff format patch\n");
        }
-       if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) {
-               ERROR("MISSING_SIGN_OFF",
-                     "Missing Signed-off-by: line(s)\n");
+       if ($is_patch && $has_commit_log && $chk_signoff) {
+               if ($signoff == 0) {
+                       ERROR("MISSING_SIGN_OFF",
+                             "Missing Signed-off-by: line(s)\n");
+               } elsif (!$authorsignoff) {
+                       WARN("NO_AUTHOR_SIGN_OFF",
+                            "Missing Signed-off-by: line by nominal patch author '$author'\n");
+               }
        }
 
        print report_dump();
index dbf0a31eb111c9ea166f090f78932a0b51d68faa..e65fbc3079d47bec7474aba6f3fbf96d258f2d99 100755 (executable)
@@ -12,7 +12,7 @@
 
 compiler="$*"
 
-if !( $compiler --version | grep -q clang) ; then
+if ! ( $compiler --version | grep -q clang) ; then
        echo 0
        exit 1
 fi
index 92b20913055f9c911451a3a4ff0205da29237b21..d819275b7fde99601de25f7afc7cf841e69778a6 100644 (file)
@@ -35,8 +35,7 @@ statement S;
 
 * x = (T)\(kmalloc(E1, ...)\|vmalloc(E1)\|dma_alloc_coherent(...,E1,...)\|
   kmalloc_node(E1, ...)\|kmem_cache_alloc(...)\|kmem_alloc(E1, ...)\|
-  devm_kmalloc(...,E1,...)\|kvmalloc(E1, ...)\|pci_alloc_consistent(...,E1,...)\|
-  kvmalloc_node(E1,...)\);
+  devm_kmalloc(...,E1,...)\|kvmalloc(E1, ...)\|kvmalloc_node(E1,...)\);
   if ((x==NULL) || ...) S
 * memset((T2)x,0,E1);
 
@@ -124,15 +123,6 @@ statement S;
 - x = (T)kvmalloc(E1,E2);
 + x = (T)kvzalloc(E1,E2);
 |
-- x = pci_alloc_consistent(E2,E1,E3);
-+ x = pci_zalloc_consistent(E2,E1,E3);
-|
-- x = (T *)pci_alloc_consistent(E2,E1,E3);
-+ x = pci_zalloc_consistent(E2,E1,E3);
-|
-- x = (T)pci_alloc_consistent(E2,E1,E3);
-+ x = (T)pci_zalloc_consistent(E2,E1,E3);
-|
 - x = kvmalloc_node(E1,E2,E3);
 + x = kvzalloc_node(E1,E2,E3);
 |
@@ -388,35 +378,6 @@ x << r7.x;
 msg="WARNING: kvzalloc should be used for %s, instead of kvmalloc/memset" % (x)
 coccilib.report.print_report(p[0], msg)
 
-//-----------------------------------------------------------------
-@r8 depends on org || report@
-type T, T2;
-expression x;
-expression E1,E2,E3;
-statement S;
-position p;
-@@
-
- x = (T)pci_alloc_consistent@p(E2,E1,E3);
- if ((x==NULL) || ...) S
- memset((T2)x,0,E1);
-
-@script:python depends on org@
-p << r8.p;
-x << r8.x;
-@@
-
-msg="%s" % (x)
-msg_safe=msg.replace("[","@(").replace("]",")")
-coccilib.org.print_todo(p[0], msg_safe)
-
-@script:python depends on report@
-p << r8.p;
-x << r8.x;
-@@
-
-msg="WARNING: pci_zalloc_consistent should be used for %s, instead of pci_alloc_consistent/memset" % (x)
-coccilib.report.print_report(p[0], msg)
 //-----------------------------------------------------------------
 @r9 depends on org || report@
 type T, T2;
index 999d585eaa7358dd813b8b0d5a204fc1ea48ca3c..e083bcae343f3e71290e433b7fd50861fd819ca4 100755 (executable)
@@ -11,13 +11,14 @@ DEPMOD=$1
 KERNELRELEASE=$2
 
 if ! test -r System.map ; then
+       echo "Warning: modules_install: missing 'System.map' file. Skipping depmod." >&2
        exit 0
 fi
 
 if [ -z $(command -v $DEPMOD) ]; then
-       echo "'make modules_install' requires $DEPMOD. Please install it." >&2
+       echo "Warning: 'make modules_install' requires $DEPMOD. Please install it." >&2
        echo "This is probably in the kmod package." >&2
-       exit 1
+       exit 0
 fi
 
 # older versions of depmod require the version string to start with three
index 9cac65b7419c6aeb93252e7016d7cbfda070cb8d..1c943e03eaf2f838dee90edc7e908476f3b2eced 100644 (file)
@@ -9,21 +9,11 @@ dtc-objs      := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \
 dtc-objs       += dtc-lexer.lex.o dtc-parser.tab.o
 
 # Source files need to get at the userspace version of libfdt_env.h to compile
+HOST_EXTRACFLAGS := -I$(src)/libfdt
 
-HOSTCFLAGS_DTC := -I$(src) -I$(src)/libfdt
-
-HOSTCFLAGS_checks.o := $(HOSTCFLAGS_DTC)
-HOSTCFLAGS_data.o := $(HOSTCFLAGS_DTC)
-HOSTCFLAGS_dtc.o := $(HOSTCFLAGS_DTC)
-HOSTCFLAGS_flattree.o := $(HOSTCFLAGS_DTC)
-HOSTCFLAGS_fstree.o := $(HOSTCFLAGS_DTC)
-HOSTCFLAGS_livetree.o := $(HOSTCFLAGS_DTC)
-HOSTCFLAGS_srcpos.o := $(HOSTCFLAGS_DTC)
-HOSTCFLAGS_treesource.o := $(HOSTCFLAGS_DTC)
-HOSTCFLAGS_util.o := $(HOSTCFLAGS_DTC)
-
-HOSTCFLAGS_dtc-lexer.lex.o := $(HOSTCFLAGS_DTC)
-HOSTCFLAGS_dtc-parser.tab.o := $(HOSTCFLAGS_DTC)
+# Generated files need one more search path to include headers in source tree
+HOSTCFLAGS_dtc-lexer.lex.o := -I$(src)
+HOSTCFLAGS_dtc-parser.tab.o := -I$(src)
 
 # dependencies on generated files need to be listed explicitly
 $(obj)/dtc-lexer.lex.o: $(obj)/dtc-parser.tab.h
index 7430a7c77a4a1ddb586519d5d38f215cd300c675..cb0c889e13aa05818e222bbfd2cef9f082a29655 100644 (file)
@@ -2,7 +2,7 @@ preferred-plugin-hostcc := $(if-success,[ $(gcc-version) -ge 40800 ],$(HOSTCXX),
 
 config PLUGIN_HOSTCC
        string
-       default "$(shell,$(srctree)/scripts/gcc-plugin.sh "$(preferred-plugin-hostcc)" "$(HOSTCXX)" "$(CC)")"
+       default "$(shell,$(srctree)/scripts/gcc-plugin.sh "$(preferred-plugin-hostcc)" "$(HOSTCXX)" "$(CC)")" if CC_IS_GCC
        help
          Host compiler used to build GCC plugins.  This can be $(HOSTCXX),
          $(HOSTCC), or a null string if GCC plugin is unsupported.
diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh
deleted file mode 100755 (executable)
index 10e528b..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-#!/bin/sh
-# Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org>
-# Copyright (C) 2006 Sam Ravnborg <sam@ravnborg.org>
-#
-# Released under the terms of the GNU GPL
-#
-# Generate a cpio packed initramfs. It uses gen_init_cpio to generate
-# the cpio archive, and then compresses it.
-# The script may also be used to generate the inputfile used for gen_init_cpio
-# This script assumes that gen_init_cpio is located in usr/ directory
-
-# error out on errors
-set -e
-
-usage() {
-cat << EOF
-Usage:
-$0 [-o <file>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ...
-       -o <file>      Create compressed initramfs file named <file> using
-                      gen_init_cpio and compressor depending on the extension
-       -u <uid>       User ID to map to user ID 0 (root).
-                      <uid> is only meaningful if <cpio_source> is a
-                      directory.  "squash" forces all files to uid 0.
-       -g <gid>       Group ID to map to group ID 0 (root).
-                      <gid> is only meaningful if <cpio_source> is a
-                      directory.  "squash" forces all files to gid 0.
-       <cpio_source>  File list or directory for cpio archive.
-                      If <cpio_source> is a .cpio file it will be used
-                      as direct input to initramfs.
-       -d             Output the default cpio list.
-
-All options except -o and -l may be repeated and are interpreted
-sequentially and immediately.  -u and -g states are preserved across
-<cpio_source> options so an explicit "-u 0 -g 0" is required
-to reset the root/group mapping.
-EOF
-}
-
-# awk style field access
-# $1 - field number; rest is argument string
-field() {
-       shift $1 ; echo $1
-}
-
-list_default_initramfs() {
-       # echo usr/kinit/kinit
-       :
-}
-
-default_initramfs() {
-       cat <<-EOF >> ${output}
-               # This is a very simple, default initramfs
-
-               dir /dev 0755 0 0
-               nod /dev/console 0600 0 0 c 5 1
-               dir /root 0700 0 0
-               # file /kinit usr/kinit/kinit 0755 0 0
-               # slink /init kinit 0755 0 0
-       EOF
-}
-
-filetype() {
-       local argv1="$1"
-
-       # symlink test must come before file test
-       if [ -L "${argv1}" ]; then
-               echo "slink"
-       elif [ -f "${argv1}" ]; then
-               echo "file"
-       elif [ -d "${argv1}" ]; then
-               echo "dir"
-       elif [ -b "${argv1}" -o -c "${argv1}" ]; then
-               echo "nod"
-       elif [ -p "${argv1}" ]; then
-               echo "pipe"
-       elif [ -S "${argv1}" ]; then
-               echo "sock"
-       else
-               echo "invalid"
-       fi
-       return 0
-}
-
-list_print_mtime() {
-       :
-}
-
-print_mtime() {
-       local my_mtime="0"
-
-       if [ -e "$1" ]; then
-               my_mtime=$(find "$1" -printf "%T@\n" | sort -r | head -n 1)
-       fi
-
-       echo "# Last modified: ${my_mtime}" >> ${output}
-       echo "" >> ${output}
-}
-
-list_parse() {
-       if [ -L "$1" ]; then
-               return
-       fi
-       echo "$1" | sed 's/:/\\:/g; s/$/ \\/'
-}
-
-# for each file print a line in following format
-# <filetype> <name> <path to file> <octal mode> <uid> <gid>
-# for links, devices etc the format differs. See gen_init_cpio for details
-parse() {
-       local location="$1"
-       local name="/${location#${srcdir}}"
-       # change '//' into '/'
-       name=$(echo "$name" | sed -e 's://*:/:g')
-       local mode="$2"
-       local uid="$3"
-       local gid="$4"
-       local ftype=$(filetype "${location}")
-       # remap uid/gid to 0 if necessary
-       [ "$root_uid" = "squash" ] && uid=0 || [ "$uid" -eq "$root_uid" ] && uid=0
-       [ "$root_gid" = "squash" ] && gid=0 || [ "$gid" -eq "$root_gid" ] && gid=0
-       local str="${mode} ${uid} ${gid}"
-
-       [ "${ftype}" = "invalid" ] && return 0
-       [ "${location}" = "${srcdir}" ] && return 0
-
-       case "${ftype}" in
-               "file")
-                       str="${ftype} ${name} ${location} ${str}"
-                       ;;
-               "nod")
-                       local dev=`LC_ALL=C ls -l "${location}"`
-                       local maj=`field 5 ${dev}`
-                       local min=`field 6 ${dev}`
-                       maj=${maj%,}
-
-                       [ -b "${location}" ] && dev="b" || dev="c"
-
-                       str="${ftype} ${name} ${str} ${dev} ${maj} ${min}"
-                       ;;
-               "slink")
-                       local target=`readlink "${location}"`
-                       str="${ftype} ${name} ${target} ${str}"
-                       ;;
-               *)
-                       str="${ftype} ${name} ${str}"
-                       ;;
-       esac
-
-       echo "${str}" >> ${output}
-
-       return 0
-}
-
-unknown_option() {
-       printf "ERROR: unknown option \"$arg\"\n" >&2
-       printf "If the filename validly begins with '-', " >&2
-       printf "then it must be prefixed\n" >&2
-       printf "by './' so that it won't be interpreted as an option." >&2
-       printf "\n" >&2
-       usage >&2
-       exit 1
-}
-
-list_header() {
-       :
-}
-
-header() {
-       printf "\n#####################\n# $1\n" >> ${output}
-}
-
-# process one directory (incl sub-directories)
-dir_filelist() {
-       ${dep_list}header "$1"
-
-       srcdir=$(echo "$1" | sed -e 's://*:/:g')
-       dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | sort)
-
-       # If $dirlist is only one line, then the directory is empty
-       if [  "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then
-               ${dep_list}print_mtime "$1"
-
-               echo "${dirlist}" | \
-               while read x; do
-                       ${dep_list}parse ${x}
-               done
-       fi
-}
-
-# if only one file is specified and it is .cpio file then use it direct as fs
-# if a directory is specified then add all files in given direcotry to fs
-# if a regular file is specified assume it is in gen_initramfs format
-input_file() {
-       source="$1"
-       if [ -f "$1" ]; then
-               ${dep_list}header "$1"
-               is_cpio="$(echo "$1" | sed 's/^.*\.cpio\(\..*\)\{0,1\}/cpio/')"
-               if [ $2 -eq 0 -a ${is_cpio} = "cpio" ]; then
-                       cpio_file=$1
-                       echo "$1" | grep -q '^.*\.cpio\..*' && is_cpio_compressed="compressed"
-                       [ ! -z ${dep_list} ] && echo "$1"
-                       return 0
-               fi
-               if [ -z ${dep_list} ]; then
-                       print_mtime "$1" >> ${output}
-                       cat "$1"         >> ${output}
-               else
-                       echo "$1 \\"
-                       cat "$1" | while read type dir file perm ; do
-                               if [ "$type" = "file" ]; then
-                                       echo "$file \\";
-                               fi
-                       done
-               fi
-       elif [ -d "$1" ]; then
-               dir_filelist "$1"
-       else
-               echo "  ${prog}: Cannot open '$1'" >&2
-               exit 1
-       fi
-}
-
-prog=$0
-root_uid=0
-root_gid=0
-dep_list=
-cpio_file=
-cpio_list=
-output="/dev/stdout"
-output_file=""
-is_cpio_compressed=
-compr="gzip -n -9 -f"
-
-arg="$1"
-case "$arg" in
-       "-l")   # files included in initramfs - used by kbuild
-               dep_list="list_"
-               echo "deps_initramfs := $0 \\"
-               shift
-               ;;
-       "-o")   # generate compressed cpio image named $1
-               shift
-               output_file="$1"
-               cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)"
-               output=${cpio_list}
-               echo "$output_file" | grep -q "\.gz$" \
-                && [ -x "`which gzip 2> /dev/null`" ] \
-                && compr="gzip -n -9 -f"
-               echo "$output_file" | grep -q "\.bz2$" \
-                && [ -x "`which bzip2 2> /dev/null`" ] \
-                && compr="bzip2 -9 -f"
-               echo "$output_file" | grep -q "\.lzma$" \
-                && [ -x "`which lzma 2> /dev/null`" ] \
-                && compr="lzma -9 -f"
-               echo "$output_file" | grep -q "\.xz$" \
-                && [ -x "`which xz 2> /dev/null`" ] \
-                && compr="xz --check=crc32 --lzma2=dict=1MiB"
-               echo "$output_file" | grep -q "\.lzo$" \
-                && [ -x "`which lzop 2> /dev/null`" ] \
-                && compr="lzop -9 -f"
-               echo "$output_file" | grep -q "\.lz4$" \
-                && [ -x "`which lz4 2> /dev/null`" ] \
-                && compr="lz4 -l -9 -f"
-               echo "$output_file" | grep -q "\.cpio$" && compr="cat"
-               shift
-               ;;
-esac
-while [ $# -gt 0 ]; do
-       arg="$1"
-       shift
-       case "$arg" in
-               "-u")   # map $1 to uid=0 (root)
-                       root_uid="$1"
-                       [ "$root_uid" = "-1" ] && root_uid=$(id -u || echo 0)
-                       shift
-                       ;;
-               "-g")   # map $1 to gid=0 (root)
-                       root_gid="$1"
-                       [ "$root_gid" = "-1" ] && root_gid=$(id -g || echo 0)
-                       shift
-                       ;;
-               "-d")   # display default initramfs list
-                       default_list="$arg"
-                       ${dep_list}default_initramfs
-                       ;;
-               "-h")
-                       usage
-                       exit 0
-                       ;;
-               *)
-                       case "$arg" in
-                               "-"*)
-                                       unknown_option
-                                       ;;
-                               *)      # input file/dir - process it
-                                       input_file "$arg" "$#"
-                                       ;;
-                       esac
-                       ;;
-       esac
-done
-
-# If output_file is set we will generate cpio archive and compress it
-# we are careful to delete tmp files
-if [ ! -z ${output_file} ]; then
-       if [ -z ${cpio_file} ]; then
-               timestamp=
-               if test -n "$KBUILD_BUILD_TIMESTAMP"; then
-                       timestamp="$(date -d"$KBUILD_BUILD_TIMESTAMP" +%s || :)"
-                       if test -n "$timestamp"; then
-                               timestamp="-t $timestamp"
-                       fi
-               fi
-               cpio_tfile="$(mktemp ${TMPDIR:-/tmp}/cpiofile.XXXXXX)"
-               usr/gen_init_cpio $timestamp ${cpio_list} > ${cpio_tfile}
-       else
-               cpio_tfile=${cpio_file}
-       fi
-       rm ${cpio_list}
-       if [ "${is_cpio_compressed}" = "compressed" ]; then
-               cat ${cpio_tfile} > ${output_file}
-       else
-               (cat ${cpio_tfile} | ${compr}  - > ${output_file}) \
-               || (rm -f ${output_file} ; false)
-       fi
-       [ -z ${cpio_file} ] && rm ${cpio_tfile}
-fi
-exit 0
index c87fa734e3e195c70ee284da73e17b7b9d70193e..c1c088ef1420e68aa6a56bf041dd019aa82e64ee 100755 (executable)
@@ -48,6 +48,7 @@ my $output_roles = 0;
 my $output_rolestats = 1;
 my $output_section_maxlen = 50;
 my $scm = 0;
+my $tree = 1;
 my $web = 0;
 my $subsystem = 0;
 my $status = 0;
@@ -61,7 +62,7 @@ my $self_test = undef;
 my $version = 0;
 my $help = 0;
 my $find_maintainer_files = 0;
-
+my $maintainer_path;
 my $vcs_used = 0;
 
 my $exit = 0;
@@ -255,6 +256,7 @@ if (!GetOptions(
                'subsystem!' => \$subsystem,
                'status!' => \$status,
                'scm!' => \$scm,
+               'tree!' => \$tree,
                'web!' => \$web,
                'letters=s' => \$letters,
                'pattern-depth=i' => \$pattern_depth,
@@ -263,6 +265,7 @@ if (!GetOptions(
                'fe|file-emails!' => \$file_emails,
                'f|file' => \$from_filename,
                'find-maintainer-files' => \$find_maintainer_files,
+               'mpath|maintainer-path=s' => \$maintainer_path,
                'self-test:s' => \$self_test,
                'v|version' => \$version,
                'h|help|usage' => \$help,
@@ -319,7 +322,7 @@ if ($email &&
     die "$P: Please select at least 1 email option\n";
 }
 
-if (!top_of_kernel_tree($lk_path)) {
+if ($tree && !top_of_kernel_tree($lk_path)) {
     die "$P: The current directory does not appear to be "
        . "a linux kernel source tree.\n";
 }
@@ -384,26 +387,36 @@ sub find_ignore_git {
 read_all_maintainer_files();
 
 sub read_all_maintainer_files {
-    if (-d "${lk_path}MAINTAINERS") {
-        opendir(DIR, "${lk_path}MAINTAINERS") or die $!;
-        my @files = readdir(DIR);
-        closedir(DIR);
-        foreach my $file (@files) {
-            push(@mfiles, "${lk_path}MAINTAINERS/$file") if ($file !~ /^\./);
-        }
-    }
-
-    if ($find_maintainer_files) {
-        find( { wanted => \&find_is_maintainer_file,
-                preprocess => \&find_ignore_git,
-                no_chdir => 1,
-        }, "${lk_path}");
+    my $path = "${lk_path}MAINTAINERS";
+    if (defined $maintainer_path) {
+       $path = $maintainer_path;
+       # Perl Cookbook tilde expansion if necessary
+       $path =~ s@^~([^/]*)@ $1 ? (getpwnam($1))[7] : ( $ENV{HOME} || $ENV{LOGDIR} || (getpwuid($<))[7])@ex;
+    }
+
+    if (-d $path) {
+       $path .= '/' if ($path !~ m@/$@);
+       if ($find_maintainer_files) {
+           find( { wanted => \&find_is_maintainer_file,
+                   preprocess => \&find_ignore_git,
+                   no_chdir => 1,
+               }, "$path");
+       } else {
+           opendir(DIR, "$path") or die $!;
+           my @files = readdir(DIR);
+           closedir(DIR);
+           foreach my $file (@files) {
+               push(@mfiles, "$path$file") if ($file !~ /^\./);
+           }
+       }
+    } elsif (-f "$path") {
+       push(@mfiles, "$path");
     } else {
-        push(@mfiles, "${lk_path}MAINTAINERS") if -f "${lk_path}MAINTAINERS";
+       die "$P: MAINTAINER file not found '$path'\n";
     }
-
+    die "$P: No MAINTAINER files found in '$path'\n" if (scalar(@mfiles) == 0);
     foreach my $file (@mfiles) {
-        read_maintainer_file("$file");
+       read_maintainer_file("$file");
     }
 }
 
@@ -1031,13 +1044,14 @@ Other options:
   --sections => print all of the subsystem sections with pattern matches
   --letters => print all matching 'letter' types from all matching sections
   --mailmap => use .mailmap file (default: $email_use_mailmap)
+  --no-tree => run without a kernel tree
   --self-test => show potential issues with MAINTAINERS file content
   --version => show version
   --help => show this help information
 
 Default options:
-  [--email --nogit --git-fallback --m --r --n --l --multiline --pattern-depth=0
-   --remove-duplicates --rolestats]
+  [--email --tree --nogit --git-fallback --m --r --n --l --multiline
+   --pattern-depth=0 --remove-duplicates --rolestats]
 
 Notes:
   Using "-f directory" may give unexpected results:
index 8d8791069abf8626209ccc6ccb40714b8a3ef82a..67ed9f6ccdf8f09d8cb193d864950ed4e14ed9f7 100644 (file)
@@ -3,7 +3,8 @@
 # Kernel configuration targets
 # These targets are used from top-level makefile
 
-PHONY += xconfig gconfig menuconfig config localmodconfig localyesconfig
+PHONY += xconfig gconfig menuconfig config localmodconfig localyesconfig \
+       build_menuconfig build_nconfig build_gconfig build_xconfig
 
 ifdef KBUILD_KCONFIG
 Kconfig := $(KBUILD_KCONFIG)
@@ -33,6 +34,14 @@ config: $(obj)/conf
 nconfig: $(obj)/nconf
        $< $(silent) $(Kconfig)
 
+build_menuconfig: $(obj)/mconf
+
+build_nconfig: $(obj)/nconf
+
+build_gconfig: $(obj)/gconf
+
+build_xconfig: $(obj)/qconf
+
 localyesconfig localmodconfig: $(obj)/conf
        $(Q)perl $(srctree)/$(src)/streamline_config.pl --$@ $(srctree) $(Kconfig) > .tmp.config
        $(Q)if [ -f .config ]; then                                     \
@@ -169,7 +178,7 @@ HOSTLDLIBS_nconf    = $(shell . $(obj)/.nconf-cfg && echo $$libs)
 HOSTCFLAGS_nconf.o     = $(shell . $(obj)/.nconf-cfg && echo $$cflags)
 HOSTCFLAGS_nconf.gui.o = $(shell . $(obj)/.nconf-cfg && echo $$cflags)
 
-$(obj)/nconf.o: $(obj)/.nconf-cfg
+$(obj)/nconf.o $(obj)/nconf.gui.o: $(obj)/.nconf-cfg
 
 # mconf: Used for the menuconfig target based on lxdialog
 hostprogs-y    += mconf
@@ -180,7 +189,8 @@ HOSTLDLIBS_mconf = $(shell . $(obj)/.mconf-cfg && echo $$libs)
 $(foreach f, mconf.o $(lxdialog), \
   $(eval HOSTCFLAGS_$f = $$(shell . $(obj)/.mconf-cfg && echo $$$$cflags)))
 
-$(addprefix $(obj)/, mconf.o $(lxdialog)): $(obj)/.mconf-cfg
+$(obj)/mconf.o: $(obj)/.mconf-cfg
+$(addprefix $(obj)/lxdialog/, $(lxdialog)): $(obj)/.mconf-cfg
 
 # qconf: Used for the xconfig target based on Qt
 hostprogs-y    += qconf
@@ -211,7 +221,6 @@ $(obj)/zconf.tab.o: $(obj)/zconf.lex.c
 
 # check if necessary packages are available, and configure build flags
 define filechk_conf_cfg
-       $(CONFIG_SHELL) $(srctree)/scripts/kconfig/check-pkgconfig.sh; \
        $(CONFIG_SHELL) $<
 endef
 
diff --git a/scripts/kconfig/check-pkgconfig.sh b/scripts/kconfig/check-pkgconfig.sh
deleted file mode 100644 (file)
index 7a1c40b..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-# Check for pkg-config presence
-
-if [ -z $(command -v pkg-config) ]; then
-       echo "'make *config' requires 'pkg-config'. Please install it." 1>&2
-       exit 1
-fi
index b35cc93039791a1383e3d0d790ff7837be569a7d..7b2b37260669e333390f0c995990fe0fb65c9f06 100644 (file)
@@ -508,6 +508,11 @@ int main(int ac, char **av)
                input_mode = (enum input_mode)opt;
                switch (opt) {
                case syncconfig:
+                       /*
+                        * syncconfig is invoked during the build stage.
+                        * Suppress distracting "configuration written to ..."
+                        */
+                       conf_set_message_callback(NULL);
                        sync_kconfig = 1;
                        break;
                case defconfig:
index 533b3d8f8f08dbab20fda2b3488d342f47ede5a2..480ecd8b9f415693c0747478b2021b5e972a42bb 100755 (executable)
@@ -3,6 +3,13 @@
 
 PKG="gtk+-2.0 gmodule-2.0 libglade-2.0"
 
+if [ -z "$(command -v pkg-config)" ]; then
+       echo >&2 "*"
+       echo >&2 "* 'make gconfig' requires 'pkg-config'. Please install it."
+       echo >&2 "*"
+       exit 1
+fi
+
 if ! pkg-config --exists $PKG; then
        echo >&2 "*"
        echo >&2 "* Unable to find the GTK+ installation. Please make sure that"
index e6f9facd00772f3779c6072d88f174c7302aa6dc..c812872d7f9d78697d40debbe636674419e646a4 100755 (executable)
@@ -4,20 +4,23 @@
 PKG="ncursesw"
 PKG2="ncurses"
 
-if pkg-config --exists $PKG; then
-       echo cflags=\"$(pkg-config --cflags $PKG)\"
-       echo libs=\"$(pkg-config --libs $PKG)\"
-       exit 0
-fi
+if [ -n "$(command -v pkg-config)" ]; then
+       if pkg-config --exists $PKG; then
+               echo cflags=\"$(pkg-config --cflags $PKG)\"
+               echo libs=\"$(pkg-config --libs $PKG)\"
+               exit 0
+       fi
 
-if pkg-config --exists $PKG2; then
-       echo cflags=\"$(pkg-config --cflags $PKG2)\"
-       echo libs=\"$(pkg-config --libs $PKG2)\"
-       exit 0
+       if pkg-config --exists $PKG2; then
+               echo cflags=\"$(pkg-config --cflags $PKG2)\"
+               echo libs=\"$(pkg-config --libs $PKG2)\"
+               exit 0
+       fi
 fi
 
-# Unfortunately, some distributions (e.g. openSUSE) cannot find ncurses
-# by pkg-config.
+# Check the default paths in case pkg-config is not installed.
+# (Even if it is installed, some distributions such as openSUSE cannot
+# find ncurses by pkg-config.)
 if [ -f /usr/include/ncursesw/ncurses.h ]; then
        echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncursesw\"
        echo libs=\"-lncursesw\"
index 83b5836615fb04a9cf389a2c978b75d4f5aa4f50..143c05fec1614bafe2f5f70dec85da3849e8225e 100644 (file)
@@ -490,7 +490,6 @@ static void build_conf(struct menu *menu)
                        switch (prop->type) {
                        case P_MENU:
                                child_count++;
-                               prompt = prompt;
                                if (single_menu_mode) {
                                        item_make("%s%*c%s",
                                                  menu->data ? "-->" : "++>",
index 42f5ac73548e4ba002506f4d38db920f8368e3c7..001559ef0a60b539c8615c23d4bcc94be5eaf59f 100644 (file)
@@ -4,20 +4,23 @@
 PKG="ncursesw menuw panelw"
 PKG2="ncurses menu panel"
 
-if pkg-config --exists $PKG; then
-       echo cflags=\"$(pkg-config --cflags $PKG)\"
-       echo libs=\"$(pkg-config --libs $PKG)\"
-       exit 0
-fi
+if [ -n "$(command -v pkg-config)" ]; then
+       if pkg-config --exists $PKG; then
+               echo cflags=\"$(pkg-config --cflags $PKG)\"
+               echo libs=\"$(pkg-config --libs $PKG)\"
+               exit 0
+       fi
 
-if pkg-config --exists $PKG2; then
-       echo cflags=\"$(pkg-config --cflags $PKG2)\"
-       echo libs=\"$(pkg-config --libs $PKG2)\"
-       exit 0
+       if pkg-config --exists $PKG2; then
+               echo cflags=\"$(pkg-config --cflags $PKG2)\"
+               echo libs=\"$(pkg-config --libs $PKG2)\"
+               exit 0
+       fi
 fi
 
-# Unfortunately, some distributions (e.g. openSUSE) cannot find ncurses
-# by pkg-config.
+# Check the default paths in case pkg-config is not installed.
+# (Even if it is installed, some distributions such as openSUSE cannot
+# find ncurses by pkg-config.)
 if [ -f /usr/include/ncursesw/ncurses.h ]; then
        echo cflags=\"-D_GNU_SOURCE -I/usr/include/ncursesw\"
        echo libs=\"-lncursesw -lmenuw -lpanelw\"
index 0862e15625366058f421d8b4346eb7e795d5a1e5..02ccc0ae103187a4a1f9c56bac3eca08823087b8 100755 (executable)
@@ -4,6 +4,13 @@
 PKG="Qt5Core Qt5Gui Qt5Widgets"
 PKG2="QtCore QtGui"
 
+if [ -z "$(command -v pkg-config)" ]; then
+       echo >&2 "*"
+       echo >&2 "* 'make xconfig' requires 'pkg-config'. Please install it."
+       echo >&2 "*"
+       exit 1
+fi
+
 if pkg-config --exists $PKG; then
        echo cflags=\"-std=c++11 -fPIC $(pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets)\"
        echo libs=\"$(pkg-config --libs $PKG)\"
index 4ec8b1f0d42c533480054136088b3d157b1be545..703b9b899ee9c6fd0b2f2de9411d8be5b4413cbe 100644 (file)
@@ -1011,7 +1011,7 @@ static struct dep_stack {
        struct dep_stack *prev, *next;
        struct symbol *sym;
        struct property *prop;
-       struct expr *expr;
+       struct expr **expr;
 } *check_top;
 
 static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
@@ -1076,31 +1076,42 @@ static void sym_check_print_recursive(struct symbol *last_sym)
                        fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
                                prop->file->name, prop->lineno);
 
-               if (stack->expr) {
-                       fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
-                               prop->file->name, prop->lineno,
+               if (sym_is_choice(sym)) {
+                       fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
+                               menu->file->name, menu->lineno,
                                sym->name ? sym->name : "<choice>",
-                               prop_get_type_name(prop->type),
                                next_sym->name ? next_sym->name : "<choice>");
-               } else if (stack->prop) {
+               } else if (sym_is_choice_value(sym)) {
+                       fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
+                               menu->file->name, menu->lineno,
+                               sym->name ? sym->name : "<choice>",
+                               next_sym->name ? next_sym->name : "<choice>");
+               } else if (stack->expr == &sym->dir_dep.expr) {
                        fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
                                prop->file->name, prop->lineno,
                                sym->name ? sym->name : "<choice>",
                                next_sym->name ? next_sym->name : "<choice>");
-               } else if (sym_is_choice(sym)) {
-                       fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
-                               menu->file->name, menu->lineno,
+               } else if (stack->expr == &sym->rev_dep.expr) {
+                       fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
+                               prop->file->name, prop->lineno,
                                sym->name ? sym->name : "<choice>",
                                next_sym->name ? next_sym->name : "<choice>");
-               } else if (sym_is_choice_value(sym)) {
-                       fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
-                               menu->file->name, menu->lineno,
+               } else if (stack->expr == &sym->implied.expr) {
+                       fprintf(stderr, "%s:%d:\tsymbol %s is implied by %s\n",
+                               prop->file->name, prop->lineno,
+                               sym->name ? sym->name : "<choice>",
+                               next_sym->name ? next_sym->name : "<choice>");
+               } else if (stack->expr) {
+                       fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
+                               prop->file->name, prop->lineno,
                                sym->name ? sym->name : "<choice>",
+                               prop_get_type_name(prop->type),
                                next_sym->name ? next_sym->name : "<choice>");
                } else {
-                       fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
+                       fprintf(stderr, "%s:%d:\tsymbol %s %s is visible depending on %s\n",
                                prop->file->name, prop->lineno,
                                sym->name ? sym->name : "<choice>",
+                               prop_get_type_name(prop->type),
                                next_sym->name ? next_sym->name : "<choice>");
                }
        }
@@ -1157,12 +1168,26 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
 
        dep_stack_insert(&stack, sym);
 
+       stack.expr = &sym->dir_dep.expr;
+       sym2 = sym_check_expr_deps(sym->dir_dep.expr);
+       if (sym2)
+               goto out;
+
+       stack.expr = &sym->rev_dep.expr;
        sym2 = sym_check_expr_deps(sym->rev_dep.expr);
        if (sym2)
                goto out;
 
+       stack.expr = &sym->implied.expr;
+       sym2 = sym_check_expr_deps(sym->implied.expr);
+       if (sym2)
+               goto out;
+
+       stack.expr = NULL;
+
        for (prop = sym->prop; prop; prop = prop->next) {
-               if (prop->type == P_CHOICE || prop->type == P_SELECT)
+               if (prop->type == P_CHOICE || prop->type == P_SELECT ||
+                   prop->type == P_IMPLY)
                        continue;
                stack.prop = prop;
                sym2 = sym_check_expr_deps(prop->visible.expr);
@@ -1170,7 +1195,7 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
                        break;
                if (prop->type != P_DEFAULT || sym_is_choice(sym))
                        continue;
-               stack.expr = prop->expr;
+               stack.expr = &prop->expr;
                sym2 = sym_check_expr_deps(prop->expr);
                if (sym2)
                        break;
@@ -1248,9 +1273,6 @@ struct symbol *sym_check_deps(struct symbol *sym)
                sym->flags &= ~SYMBOL_CHECK;
        }
 
-       if (sym2 && sym2 == sym)
-               sym2 = NULL;
-
        return sym2;
 }
 
diff --git a/scripts/kconfig/tests/err_recursive_dep/Kconfig b/scripts/kconfig/tests/err_recursive_dep/Kconfig
new file mode 100644 (file)
index 0000000..ebdb3ff
--- /dev/null
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# depends on itself
+
+config A
+       bool "A"
+       depends on A
+
+# select itself
+
+config B
+       bool
+       select B
+
+# depends on each other
+
+config C1
+       bool "C1"
+       depends on C2
+
+config C2
+       bool "C2"
+       depends on C1
+
+# depends on and select
+
+config D1
+       bool "D1"
+       depends on D2
+       select D2
+
+config D2
+       bool
+
+# depends on and imply
+
+config E1
+       bool "E1"
+       depends on E2
+       imply E2
+
+config E2
+       bool "E2"
+
+# property
+
+config F1
+       bool "F1"
+       default F2
+
+config F2
+       bool "F2"
+       depends on F1
+
+# menu
+
+menu "menu depending on its content"
+       depends on G
+
+config G
+       bool "G"
+
+endmenu
diff --git a/scripts/kconfig/tests/err_recursive_dep/__init__.py b/scripts/kconfig/tests/err_recursive_dep/__init__.py
new file mode 100644 (file)
index 0000000..5f3821b
--- /dev/null
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+"""
+Detect recursive dependency error.
+
+Recursive dependency should be treated as an error.
+"""
+
+def test(conf):
+    assert conf.oldaskconfig() == 1
+    assert conf.stderr_contains('expected_stderr')
diff --git a/scripts/kconfig/tests/err_recursive_dep/expected_stderr b/scripts/kconfig/tests/err_recursive_dep/expected_stderr
new file mode 100644 (file)
index 0000000..84679b1
--- /dev/null
@@ -0,0 +1,38 @@
+Kconfig:11:error: recursive dependency detected!
+Kconfig:11:    symbol B is selected by B
+For a resolution refer to Documentation/kbuild/kconfig-language.txt
+subsection "Kconfig recursive dependency limitations"
+
+Kconfig:5:error: recursive dependency detected!
+Kconfig:5:     symbol A depends on A
+For a resolution refer to Documentation/kbuild/kconfig-language.txt
+subsection "Kconfig recursive dependency limitations"
+
+Kconfig:17:error: recursive dependency detected!
+Kconfig:17:    symbol C1 depends on C2
+Kconfig:21:    symbol C2 depends on C1
+For a resolution refer to Documentation/kbuild/kconfig-language.txt
+subsection "Kconfig recursive dependency limitations"
+
+Kconfig:32:error: recursive dependency detected!
+Kconfig:32:    symbol D2 is selected by D1
+Kconfig:27:    symbol D1 depends on D2
+For a resolution refer to Documentation/kbuild/kconfig-language.txt
+subsection "Kconfig recursive dependency limitations"
+
+Kconfig:37:error: recursive dependency detected!
+Kconfig:37:    symbol E1 depends on E2
+Kconfig:42:    symbol E2 is implied by E1
+For a resolution refer to Documentation/kbuild/kconfig-language.txt
+subsection "Kconfig recursive dependency limitations"
+
+Kconfig:60:error: recursive dependency detected!
+Kconfig:60:    symbol G depends on G
+For a resolution refer to Documentation/kbuild/kconfig-language.txt
+subsection "Kconfig recursive dependency limitations"
+
+Kconfig:51:error: recursive dependency detected!
+Kconfig:51:    symbol F2 depends on F1
+Kconfig:49:    symbol F1 default value contains F2
+For a resolution refer to Documentation/kbuild/kconfig-language.txt
+subsection "Kconfig recursive dependency limitations"
diff --git a/scripts/kconfig/tests/warn_recursive_dep/Kconfig b/scripts/kconfig/tests/warn_recursive_dep/Kconfig
deleted file mode 100644 (file)
index a65bfcb..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-# depends on itself
-
-config A
-       bool "A"
-       depends on A
-
-# select itself
-
-config B
-       bool
-       select B
-
-# depends on each other
-
-config C1
-       bool "C1"
-       depends on C2
-
-config C2
-       bool "C2"
-       depends on C1
-
-# depends on and select
-
-config D1
-       bool "D1"
-       depends on D2
-       select D2
-
-config D2
-       bool
-
-# depends on and imply
-# This is not recursive dependency
-
-config E1
-       bool "E1"
-       depends on E2
-       imply E2
-
-config E2
-       bool "E2"
-
-# property
-
-config F1
-       bool "F1"
-       default F2
-
-config F2
-       bool "F2"
-       depends on F1
-
-# menu
-
-menu "menu depending on its content"
-       depends on G
-
-config G
-       bool "G"
-
-endmenu
diff --git a/scripts/kconfig/tests/warn_recursive_dep/__init__.py b/scripts/kconfig/tests/warn_recursive_dep/__init__.py
deleted file mode 100644 (file)
index adb2195..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-"""
-Warn recursive inclusion.
-
-Recursive dependency should be warned.
-"""
-
-def test(conf):
-    assert conf.oldaskconfig() == 0
-    assert conf.stderr_contains('expected_stderr')
diff --git a/scripts/kconfig/tests/warn_recursive_dep/expected_stderr b/scripts/kconfig/tests/warn_recursive_dep/expected_stderr
deleted file mode 100644 (file)
index 3de807d..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-Kconfig:9:error: recursive dependency detected!
-Kconfig:9:     symbol B is selected by B
-For a resolution refer to Documentation/kbuild/kconfig-language.txt
-subsection "Kconfig recursive dependency limitations"
-
-Kconfig:3:error: recursive dependency detected!
-Kconfig:3:     symbol A depends on A
-For a resolution refer to Documentation/kbuild/kconfig-language.txt
-subsection "Kconfig recursive dependency limitations"
-
-Kconfig:15:error: recursive dependency detected!
-Kconfig:15:    symbol C1 depends on C2
-Kconfig:19:    symbol C2 depends on C1
-For a resolution refer to Documentation/kbuild/kconfig-language.txt
-subsection "Kconfig recursive dependency limitations"
-
-Kconfig:30:error: recursive dependency detected!
-Kconfig:30:    symbol D2 is selected by D1
-Kconfig:25:    symbol D1 depends on D2
-For a resolution refer to Documentation/kbuild/kconfig-language.txt
-subsection "Kconfig recursive dependency limitations"
-
-Kconfig:59:error: recursive dependency detected!
-Kconfig:59:    symbol G depends on G
-For a resolution refer to Documentation/kbuild/kconfig-language.txt
-subsection "Kconfig recursive dependency limitations"
-
-Kconfig:50:error: recursive dependency detected!
-Kconfig:50:    symbol F2 depends on F1
-Kconfig:48:    symbol F1 default value contains F2
index 4bf811c09f5940eb6b2b21821e38446884a3f413..c8cf45362bd6f223dc15be63438b1ce71dcbefa3 100755 (executable)
@@ -75,7 +75,7 @@ modpost_link()
                ${KBUILD_VMLINUX_LIBS}                          \
                --end-group"
 
-       ${LD} ${LDFLAGS} -r -o ${1} ${objects}
+       ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${objects}
 }
 
 # Link of vmlinux
@@ -95,7 +95,7 @@ vmlinux_link()
                        --end-group                             \
                        ${1}"
 
-               ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2}     \
+               ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} -o ${2}      \
                        -T ${lds} ${objects}
        else
                objects="-Wl,--whole-archive                    \
index dc6d714e4dcb310817de378ec88e136263ab8030..0d998c54564dfdc5793faa968f72e8e985bce6c8 100644 (file)
@@ -672,7 +672,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
                        if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
                                break;
                        if (symname[0] == '.') {
-                               char *munged = strdup(symname);
+                               char *munged = NOFAIL(strdup(symname));
                                munged[0] = '_';
                                munged[1] = toupper(munged[1]);
                                symname = munged;
@@ -1318,7 +1318,7 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
 static char *sec2annotation(const char *s)
 {
        if (match(s, init_exit_sections)) {
-               char *p = malloc(20);
+               char *p = NOFAIL(malloc(20));
                char *r = p;
 
                *p++ = '_';
@@ -1338,7 +1338,7 @@ static char *sec2annotation(const char *s)
                        strcat(p, " ");
                return r;
        } else {
-               return strdup("");
+               return NOFAIL(strdup(""));
        }
 }
 
@@ -2036,7 +2036,7 @@ void buf_write(struct buffer *buf, const char *s, int len)
 {
        if (buf->size - buf->pos < len) {
                buf->size += len + SZ;
-               buf->p = realloc(buf->p, buf->size);
+               buf->p = NOFAIL(realloc(buf->p, buf->size));
        }
        strncpy(buf->p + buf->pos, s, len);
        buf->pos += len;
index fe06e77c15eb7072d1cb9c09d9481048984e03d7..f599031260d5178d10dd83554ac20d957c8b82af 100755 (executable)
@@ -389,6 +389,9 @@ if ($arch eq "x86_64") {
     $mcount_regex = "^\\s*([0-9a-fA-F]+):\\sR_RISCV_CALL\\s_mcount\$";
     $type = ".quad";
     $alignment = 2;
+} elsif ($arch eq "nds32") {
+    $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_NDS32_HI20_RELA\\s+_mcount\$";
+    $alignment = 2;
 } else {
     die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
 }
index 71f39410691b6be14774102000507c834c8ad493..79f7dd57d571e749dc3e36ed95a473cd599e0056 100755 (executable)
@@ -74,7 +74,7 @@ scm_version()
                fi
 
                # Check for uncommitted changes
-               if git diff-index --name-only HEAD | grep -qv "^scripts/package"; then
+               if git status -uno --porcelain | grep -qv '^.. scripts/package'; then
                        printf '%s' -dirty
                fi
 
index 9a058cff49d4a1d8fec6c6151cedffffc03d8232..517d0c3f83dfcf0d97b32b41d755dfcb01192807 100644 (file)
@@ -10,6 +10,8 @@
 abandonning||abandoning
 abigious||ambiguous
 abitrate||arbitrate
+abord||abort
+aboslute||absolute
 abov||above
 abreviated||abbreviated
 absense||absence
@@ -25,6 +27,7 @@ accessable||accessible
 accesss||access
 accidentaly||accidentally
 accidentually||accidentally
+acclerated||accelerated
 accoding||according
 accomodate||accommodate
 accomodates||accommodates
@@ -58,12 +61,15 @@ addres||address
 adddress||address
 addreses||addresses
 addresss||address
+addrress||address
 aditional||additional
 aditionally||additionally
 aditionaly||additionally
 adminstrative||administrative
 adress||address
 adresses||addresses
+adrresses||addresses
+advertisment||advertisement
 adviced||advised
 afecting||affecting
 againt||against
@@ -100,6 +106,7 @@ alue||value
 ambigious||ambiguous
 amoung||among
 amout||amount
+amplifer||amplifier
 an union||a union
 an user||a user
 an userspace||a userspace
@@ -145,11 +152,15 @@ assistent||assistant
 assocation||association
 associcated||associated
 assotiated||associated
+asssert||assert
 assum||assume
 assumtpion||assumption
 asuming||assuming
 asycronous||asynchronous
 asynchnous||asynchronous
+asynchromous||asynchronous
+asymetric||asymmetric
+asymmeric||asymmetric
 atomatically||automatically
 atomicly||atomically
 atempt||attempt
@@ -172,6 +183,7 @@ avaible||available
 availabe||available
 availabled||available
 availablity||availability
+availaible||available
 availale||available
 availavility||availability
 availble||available
@@ -206,8 +218,11 @@ borad||board
 boundry||boundary
 brievely||briefly
 broadcat||broadcast
+bufufer||buffer
 cacluated||calculated
+caculate||calculate
 caculation||calculation
+cadidate||candidate
 calender||calendar
 calescing||coalescing
 calle||called
@@ -221,12 +236,14 @@ capabilty||capability
 capabitilies||capabilities
 capatibilities||capabilities
 capapbilities||capabilities
+caputure||capture
 carefuly||carefully
 cariage||carriage
 catagory||category
 cehck||check
 challange||challenge
 challanges||challenges
+chache||cache
 chanell||channel
 changable||changeable
 chanined||chained
@@ -240,6 +257,7 @@ charaters||characters
 charcter||character
 chcek||check
 chck||check
+checksumed||checksummed
 checksuming||checksumming
 childern||children
 childs||children
@@ -292,8 +310,10 @@ comunication||communication
 conbination||combination
 conditionaly||conditionally
 conected||connected
+conector||connector
 connecetd||connected
 configuartion||configuration
+configuation||configuration
 configuratoin||configuration
 configuraton||configuration
 configuretion||configuration
@@ -315,6 +335,7 @@ continous||continuous
 continously||continuously
 continueing||continuing
 contraints||constraints
+contruct||construct
 contol||control
 contoller||controller
 controled||controlled
@@ -343,6 +364,7 @@ dafault||default
 deafult||default
 deamon||daemon
 decompres||decompress
+decsribed||described
 decription||description
 dectected||detected
 defailt||default
@@ -379,6 +401,7 @@ desctiptor||descriptor
 desriptor||descriptor
 desriptors||descriptors
 destionation||destination
+destoried||destroyed
 destory||destroy
 destoryed||destroyed
 destorys||destroys
@@ -400,22 +423,30 @@ didnt||didn't
 diferent||different
 differrence||difference
 diffrent||different
+differenciate||differentiate
 diffrentiate||differentiate
 difinition||definition
 dimesions||dimensions
 diplay||display
+directon||direction
 direectly||directly
+diregard||disregard
 disassocation||disassociation
 disapear||disappear
 disapeared||disappeared
 disappared||disappeared
+disbale||disable
+disbaled||disabled
 disble||disable
 disbled||disabled
 disconnet||disconnect
 discontinous||discontinuous
+disharge||discharge
 dispertion||dispersion
 dissapears||disappears
 distiction||distinction
+divisable||divisible
+divsiors||divisors
 docuentation||documentation
 documantation||documentation
 documentaion||documentation
@@ -427,6 +458,7 @@ downlad||download
 downlads||downloads
 druing||during
 dynmaic||dynamic
+eanable||enable
 easilly||easily
 ecspecially||especially
 edditable||editable
@@ -484,9 +516,12 @@ exprimental||experimental
 extened||extended
 extensability||extensibility
 extention||extension
+extenstion||extension
 extracter||extractor
+faield||failed
 falied||failed
 faild||failed
+failer||failure
 faill||fail
 failied||failed
 faillure||failure
@@ -520,6 +555,7 @@ forseeable||foreseeable
 forse||force
 fortan||fortran
 forwardig||forwarding
+frambuffer||framebuffer
 framming||framing
 framwork||framework
 frequncy||frequency
@@ -527,6 +563,7 @@ frome||from
 fucntion||function
 fuction||function
 fuctions||functions
+funcation||function
 funcion||function
 functionallity||functionality
 functionaly||functionally
@@ -540,6 +577,7 @@ futrue||future
 gaurenteed||guaranteed
 generiously||generously
 genereate||generate
+genereted||generated
 genric||generic
 globel||global
 grabing||grabbing
@@ -553,6 +591,7 @@ guarentee||guarantee
 halfs||halves
 hander||handler
 handfull||handful
+hanlde||handle
 hanled||handled
 happend||happened
 harware||hardware
@@ -561,6 +600,7 @@ helpfull||helpful
 hybernate||hibernate
 hierachy||hierarchy
 hierarchie||hierarchy
+homogenous||homogeneous
 howver||however
 hsould||should
 hypervior||hypervisor
@@ -568,6 +608,8 @@ hypter||hyper
 identidier||identifier
 iligal||illegal
 illigal||illegal
+illgal||illegal
+iomaped||iomapped
 imblance||imbalance
 immeadiately||immediately
 immedaite||immediate
@@ -618,12 +660,15 @@ initation||initiation
 initators||initiators
 initialiazation||initialization
 initializiation||initialization
+initialze||initialize
 initialzed||initialized
 initilization||initialization
 initilize||initialize
 inofficial||unofficial
+inrerface||interface
 insititute||institute
 instal||install
+instanciate||instantiate
 instanciated||instantiated
 inteface||interface
 integreated||integrated
@@ -657,6 +702,7 @@ intregral||integral
 intrrupt||interrupt
 intterrupt||interrupt
 intuative||intuitive
+inavlid||invalid
 invaid||invalid
 invald||invalid
 invalde||invalid
@@ -683,6 +729,7 @@ langauge||language
 langugage||language
 lauch||launch
 layed||laid
+legnth||length
 leightweight||lightweight
 lengh||length
 lenght||length
@@ -696,6 +743,7 @@ licenceing||licencing
 loggging||logging
 loggin||login
 logile||logfile
+loobpack||loopback
 loosing||losing
 losted||lost
 machinary||machinery
@@ -703,6 +751,7 @@ maintainance||maintenance
 maintainence||maintenance
 maintan||maintain
 makeing||making
+mailformed||malformed
 malplaced||misplaced
 malplace||misplace
 managable||manageable
@@ -710,6 +759,7 @@ managment||management
 mangement||management
 manoeuvering||maneuvering
 mappping||mapping
+matchs||matches
 mathimatical||mathematical
 mathimatic||mathematic
 mathimatics||mathematics
@@ -725,6 +775,7 @@ messsage||message
 messsages||messages
 micropone||microphone
 microprocesspr||microprocessor
+migrateable||migratable
 milliseonds||milliseconds
 minium||minimum
 minimam||minimum
@@ -741,6 +792,7 @@ missmatch||mismatch
 miximum||maximum
 mmnemonic||mnemonic
 mnay||many
+modfiy||modify
 modulues||modules
 momery||memory
 memomry||memory
@@ -777,6 +829,7 @@ notifed||notified
 numebr||number
 numner||number
 obtaion||obtain
+obusing||abusing
 occassionally||occasionally
 occationally||occasionally
 occurance||occurrence
@@ -787,6 +840,7 @@ occure||occurred
 occured||occurred
 occuring||occurring
 offet||offset
+offloded||offloaded
 omited||omitted
 omiting||omitting
 omitt||omit
@@ -829,6 +883,7 @@ parametes||parameters
 parametised||parametrised
 paramter||parameter
 paramters||parameters
+parmaters||parameters
 particuarly||particularly
 particularily||particularly
 partiton||partition
@@ -837,6 +892,7 @@ passin||passing
 pathes||paths
 pecularities||peculiarities
 peformance||performance
+peforming||performing
 peice||piece
 pendantic||pedantic
 peprocessor||preprocessor
@@ -846,6 +902,7 @@ peroid||period
 persistance||persistence
 persistant||persistent
 plalform||platform
+platfoem||platform
 platfrom||platform
 plattform||platform
 pleaes||please
@@ -858,6 +915,7 @@ posible||possible
 positon||position
 possibilites||possibilities
 powerfull||powerful
+preamle||preamble
 preample||preamble
 preapre||prepare
 preceeded||preceded
@@ -870,6 +928,7 @@ prefered||preferred
 prefferably||preferably
 premption||preemption
 prepaired||prepared
+preperation||preparation
 pressre||pressure
 primative||primitive
 princliple||principle
@@ -935,6 +994,7 @@ recommanded||recommended
 recyle||recycle
 redircet||redirect
 redirectrion||redirection
+redundacy||redundancy
 reename||rename
 refcounf||refcount
 refence||reference
@@ -945,6 +1005,7 @@ refernces||references
 refernnce||reference
 refrence||reference
 registerd||registered
+registeration||registration
 registeresd||registered
 registerred||registered
 registes||registers
@@ -973,7 +1034,9 @@ requirment||requirement
 requred||required
 requried||required
 requst||request
+reregisteration||reregistration
 reseting||resetting
+reseverd||reserved
 resizeable||resizable
 resouce||resource
 resouces||resources
@@ -982,6 +1045,7 @@ responce||response
 ressizes||resizes
 ressource||resource
 ressources||resources
+restesting||retesting
 retransmited||retransmitted
 retreived||retrieved
 retreive||retrieve
@@ -1006,6 +1070,7 @@ sacrifying||sacrificing
 safly||safely
 safty||safety
 savable||saveable
+scaleing||scaling
 scaned||scanned
 scaning||scanning
 scarch||search
@@ -1014,6 +1079,8 @@ searchs||searches
 secquence||sequence
 secund||second
 segement||segment
+semaphone||semaphore
+senario||scenario
 senarios||scenarios
 sentivite||sensitive
 separatly||separately
@@ -1025,9 +1092,13 @@ seperate||separate
 seperatly||separately
 seperator||separator
 sepperate||separate
+seqeunce||sequence
+seqeuncer||sequencer
+seqeuencer||sequencer
 sequece||sequence
 sequencial||sequential
 serveral||several
+servive||service
 setts||sets
 settting||setting
 shotdown||shutdown
@@ -1073,6 +1144,7 @@ standartization||standardization
 standart||standard
 staticly||statically
 stoped||stopped
+stoping||stopping
 stoppped||stopped
 straming||streaming
 struc||struct
@@ -1085,6 +1157,7 @@ subdirectoires||subdirectories
 suble||subtle
 substract||subtract
 submition||submission
+suceed||succeed
 succesfully||successfully
 succesful||successful
 successed||succeeded
@@ -1108,6 +1181,7 @@ surpressed||suppressed
 surpresses||suppresses
 susbsystem||subsystem
 suspeneded||suspended
+suspsend||suspend
 suspicously||suspiciously
 swaping||swapping
 switchs||switches
@@ -1122,6 +1196,7 @@ swtich||switch
 symetric||symmetric
 synax||syntax
 synchonized||synchronized
+synchronuously||synchronously
 syncronize||synchronize
 syncronized||synchronized
 syncronizing||synchronizing
@@ -1130,11 +1205,14 @@ syste||system
 sytem||system
 sythesis||synthesis
 taht||that
+tansmit||transmit
 targetted||targeted
 targetting||targeting
+taskelt||tasklet
 teh||the
 temorary||temporary
 temproarily||temporarily
+thead||thread
 therfore||therefore
 thier||their
 threds||threads
@@ -1143,11 +1221,14 @@ thresold||threshold
 throught||through
 troughput||throughput
 thses||these
+tiggers||triggers
 tiggered||triggered
 tipically||typically
+timeing||timing
 timout||timeout
 tmis||this
 torerable||tolerable
+traking||tracking
 tramsmitted||transmitted
 tramsmit||transmit
 tranasction||transaction
@@ -1162,6 +1243,7 @@ transormed||transformed
 trasfer||transfer
 trasmission||transmission
 treshold||threshold
+trigerred||triggered
 trigerring||triggering
 trun||turn
 tunning||tuning
@@ -1169,6 +1251,8 @@ ture||true
 tyep||type
 udpate||update
 uesd||used
+uknown||unknown
+usupported||unsupported
 uncommited||uncommitted
 unconditionaly||unconditionally
 underun||underrun
@@ -1181,11 +1265,14 @@ unexpeted||unexpected
 unexpexted||unexpected
 unfortunatelly||unfortunately
 unifiy||unify
+uniterrupted||uninterrupted
 unintialized||uninitialized
 unkmown||unknown
 unknonw||unknown
 unknow||unknown
 unkown||unknown
+unamed||unnamed
+uneeded||unneeded
 unneded||unneeded
 unneccecary||unnecessary
 unneccesary||unnecessary
@@ -1210,6 +1297,7 @@ usefull||useful
 usege||usage
 usera||users
 usualy||usually
+usupported||unsupported
 utilites||utilities
 utillities||utilities
 utilties||utilities
@@ -1233,7 +1321,9 @@ virtaul||virtual
 virtiual||virtual
 visiters||visitors
 vitual||virtual
+vunerable||vulnerable
 wakeus||wakeups
+wathdog||watchdog
 wating||waiting
 wiat||wait
 wether||whether
index 949dd8a48164a3efe2618356ddffc3a7c96d79cc..e09fe4d7307cd02f85919aefccacc19276e96be9 100644 (file)
@@ -603,7 +603,7 @@ static const struct file_operations aa_fs_ns_revision_fops = {
 static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
                             const char *match_str, size_t match_len)
 {
-       struct aa_perms tmp;
+       struct aa_perms tmp = { };
        struct aa_dfa *dfa;
        unsigned int state = 0;
 
@@ -613,7 +613,6 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
                dfa = profile->file.dfa;
                state = aa_dfa_match_len(dfa, profile->file.start,
                                         match_str + 1, match_len - 1);
-               tmp = nullperms;
                if (state) {
                        struct path_cond cond = { };
 
@@ -627,8 +626,6 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
                                         match_str, match_len);
                if (state)
                        aa_compute_perms(dfa, state, &tmp);
-               else
-                       tmp = nullperms;
        }
        aa_apply_modes_to_perms(profile, &tmp);
        aa_perms_accum_raw(perms, &tmp);
index 098d546d8253d920737d368fab9966b4d60dcc30..08c88de0ffdadcb4d68450cff103408cba3a7746 100644 (file)
@@ -1036,7 +1036,7 @@ static struct aa_label *build_change_hat(struct aa_profile *profile,
 audit:
        aa_audit_file(profile, &nullperms, OP_CHANGE_HAT, AA_MAY_CHANGEHAT,
                      name, hat ? hat->base.hname : NULL,
-                     hat ? &hat->label : NULL, GLOBAL_ROOT_UID, NULL,
+                     hat ? &hat->label : NULL, GLOBAL_ROOT_UID, info,
                      error);
        if (!hat || (error && error != -ENOENT))
                return ERR_PTR(error);
index 224b2fef93cadff32cd3dbd213ad3e2498d2e009..4285943f7260f36f271b7d7ad773345fb84d97f0 100644 (file)
@@ -47,7 +47,8 @@ static void audit_file_mask(struct audit_buffer *ab, u32 mask)
 {
        char str[10];
 
-       aa_perm_mask_to_str(str, aa_file_perm_chrs, map_mask_to_chr_mask(mask));
+       aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
+                           map_mask_to_chr_mask(mask));
        audit_log_string(ab, str);
 }
 
index 38aa6247d00f9ce51320bbaf3c50016cbe81ea3b..b94ec114d1a4505f1abfc6d7058af559aa6ae201 100644 (file)
@@ -137,7 +137,8 @@ extern struct aa_perms allperms;
        xcheck(fn_for_each((L1), (P), (FN1)), fn_for_each((L2), (P), (FN2)))
 
 
-void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask);
+void aa_perm_mask_to_str(char *str, size_t str_size, const char *chrs,
+                        u32 mask);
 void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names,
                         u32 mask);
 void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
index a7b3f681b80e19aed6b0733ad0edf863b20c0c9b..974affe505314bcd5ecef87966ba698de1dd853e 100644 (file)
@@ -198,15 +198,24 @@ const char *aa_file_perm_names[] = {
 /**
  * aa_perm_mask_to_str - convert a perm mask to its short string
  * @str: character buffer to store string in (at least 10 characters)
+ * @str_size: size of the @str buffer
+ * @chrs: NUL-terminated character buffer of permission characters
  * @mask: permission mask to convert
  */
-void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask)
+void aa_perm_mask_to_str(char *str, size_t str_size, const char *chrs, u32 mask)
 {
        unsigned int i, perm = 1;
+       size_t num_chrs = strlen(chrs);
+
+       for (i = 0; i < num_chrs; perm <<= 1, i++) {
+               if (mask & perm) {
+                       /* Ensure that one byte is left for NUL-termination */
+                       if (WARN_ON_ONCE(str_size <= 1))
+                               break;
 
-       for (i = 0; i < 32; perm <<= 1, i++) {
-               if (mask & perm)
                        *str++ = chrs[i];
+                       str_size--;
+               }
        }
        *str = '\0';
 }
@@ -236,7 +245,7 @@ void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
 
        audit_log_format(ab, "\"");
        if ((mask & chrsmask) && chrs) {
-               aa_perm_mask_to_str(str, chrs, mask & chrsmask);
+               aa_perm_mask_to_str(str, sizeof(str), chrs, mask & chrsmask);
                mask &= ~chrsmask;
                audit_log_format(ab, "%s", str);
                if (mask & namesmask)
index b0f9dc3f765a9d7a19003ae2f3bd327b58df98a9..1a7cec5d9cac64f2ab2e29afca385dee2e1b04c6 100644 (file)
@@ -255,7 +255,7 @@ static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name,
 
        ns = alloc_ns(parent->base.hname, name);
        if (!ns)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
        ns->level = parent->level + 1;
        mutex_lock_nested(&ns->lock, ns->level);
        error = __aafs_ns_mkdir(ns, ns_subns_dir(parent), name, dir);
index 0e566a01d217c8dee874f7a063c18ef3eb190523..21cb384d712a2865d1da6f8d12625c250993b28e 100644 (file)
@@ -389,32 +389,6 @@ static int unpack_strdup(struct aa_ext *e, char **string, const char *name)
        return res;
 }
 
-#define DFA_VALID_PERM_MASK            0xffffffff
-#define DFA_VALID_PERM2_MASK           0xffffffff
-
-/**
- * verify_accept - verify the accept tables of a dfa
- * @dfa: dfa to verify accept tables of (NOT NULL)
- * @flags: flags governing dfa
- *
- * Returns: 1 if valid accept tables else 0 if error
- */
-static bool verify_accept(struct aa_dfa *dfa, int flags)
-{
-       int i;
-
-       /* verify accept permissions */
-       for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
-               int mode = ACCEPT_TABLE(dfa)[i];
-
-               if (mode & ~DFA_VALID_PERM_MASK)
-                       return 0;
-
-               if (ACCEPT_TABLE2(dfa)[i] & ~DFA_VALID_PERM2_MASK)
-                       return 0;
-       }
-       return 1;
-}
 
 /**
  * unpack_dfa - unpack a file rule dfa
@@ -445,15 +419,9 @@ static struct aa_dfa *unpack_dfa(struct aa_ext *e)
                if (IS_ERR(dfa))
                        return dfa;
 
-               if (!verify_accept(dfa, flags))
-                       goto fail;
        }
 
        return dfa;
-
-fail:
-       aa_put_dfa(dfa);
-       return ERR_PTR(-EPROTO);
 }
 
 /**
index f2f22d00db18893a917006794c5a09e341aae2b0..4ccec1bcf6f54f261542a546458cab77c6af9e52 100644 (file)
@@ -79,7 +79,6 @@ int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
        struct aa_label *label = aa_secid_to_label(secid);
        int len;
 
-       AA_BUG(!secdata);
        AA_BUG(!seclen);
 
        if (!label)
index f4c33abd99596c6122bcb5f7a4864917a0ca97b7..2e489d6a3ac810459fec065783fad855a8738216 100644 (file)
@@ -388,7 +388,7 @@ int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer,
        if (strcmp(name, "capability") != 0)
                return -EOPNOTSUPP;
 
-       dentry = d_find_alias(inode);
+       dentry = d_find_any_alias(inode);
        if (!dentry)
                return -EINVAL;
 
index 711e89d8c4153b6123678772e83efe1092f4ae1f..3b602a1e27fa224e3a7628436ac6f93309a54c4a 100644 (file)
@@ -300,7 +300,7 @@ long __keyctl_dh_compute(struct keyctl_dh_params __user *params,
        }
        dh_inputs.g_size = dlen;
 
-       dlen = dh_data_from_key(pcopy.private, &dh_inputs.key);
+       dlen = dh_data_from_key(pcopy.dh_private, &dh_inputs.key);
        if (dlen < 0) {
                ret = dlen;
                goto out2;
index 47cfff01d7ec01c522620aeef60643781577e5ed..736e78da1ab9d09271b2f34ace7a247c91fd5778 100644 (file)
@@ -48,14 +48,17 @@ static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
 static void __init do_security_initcalls(void)
 {
        int ret;
-       initcall_t *call;
-       call = __security_initcall_start;
+       initcall_t call;
+       initcall_entry_t *ce;
+
+       ce = __security_initcall_start;
        trace_initcall_level("security");
-       while (call < __security_initcall_end) {
-               trace_initcall_start((*call));
-               ret = (*call) ();
-               trace_initcall_finish((*call), ret);
-               call++;
+       while (ce < __security_initcall_end) {
+               call = initcall_from_entry(ce);
+               trace_initcall_start(call);
+               ret = call();
+               trace_initcall_finish(call, ret);
+               ce++;
        }
 }
 
index 7a0dfca03a57d5b4cd7cbb00d73da095aa076679..9f0c480489ef04384445b35f8786c020dfc9d7fa 100644 (file)
@@ -529,7 +529,7 @@ static int ac97_bus_remove(struct device *dev)
        int ret;
 
        ret = pm_runtime_get_sync(dev);
-       if (ret)
+       if (ret < 0)
                return ret;
 
        ret = adrv->remove(adev);
@@ -537,6 +537,8 @@ static int ac97_bus_remove(struct device *dev)
        if (ret == 0)
                ac97_put_disable_clk(adev);
 
+       pm_runtime_disable(dev);
+
        return ret;
 }
 
index 61544e0d8de472f99754ba29d4a6dacdb746c0d1..8bab44f74bb8573fb45610b07a9aa081db9091a6 100644 (file)
 
 #include "ac97_core.h"
 
+static void compat_ac97_release(struct device *dev)
+{
+       kfree(to_ac97_t(dev));
+}
+
 static void compat_ac97_reset(struct snd_ac97 *ac97)
 {
        struct ac97_codec_device *adev = to_ac97_device(ac97->private_data);
@@ -65,21 +70,31 @@ static struct snd_ac97_bus compat_soc_ac97_bus = {
 struct snd_ac97 *snd_ac97_compat_alloc(struct ac97_codec_device *adev)
 {
        struct snd_ac97 *ac97;
+       int ret;
 
        ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
        if (ac97 == NULL)
                return ERR_PTR(-ENOMEM);
 
-       ac97->dev = adev->dev;
        ac97->private_data = adev;
        ac97->bus = &compat_soc_ac97_bus;
+
+       ac97->dev.parent = &adev->dev;
+       ac97->dev.release = compat_ac97_release;
+       dev_set_name(&ac97->dev, "%s-compat", dev_name(&adev->dev));
+       ret = device_register(&ac97->dev);
+       if (ret) {
+               put_device(&ac97->dev);
+               return ERR_PTR(ret);
+       }
+
        return ac97;
 }
 EXPORT_SYMBOL_GPL(snd_ac97_compat_alloc);
 
 void snd_ac97_compat_release(struct snd_ac97 *ac97)
 {
-       kfree(ac97);
+       device_unregister(&ac97->dev);
 }
 EXPORT_SYMBOL_GPL(snd_ac97_compat_release);
 
index 69517e18ef07fc241d18335e7f209a2b1ded96d1..08d5662039e38123e349bc5352c2b674280048f3 100644 (file)
@@ -129,7 +129,7 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
                runtime->avail = 0;
        else
                runtime->avail = runtime->buffer_size;
-       runtime->buffer = kvmalloc(runtime->buffer_size, GFP_KERNEL);
+       runtime->buffer = kvzalloc(runtime->buffer_size, GFP_KERNEL);
        if (!runtime->buffer) {
                kfree(runtime);
                return -ENOMEM;
@@ -655,7 +655,7 @@ static int resize_runtime_buffer(struct snd_rawmidi_runtime *runtime,
        if (params->avail_min < 1 || params->avail_min > params->buffer_size)
                return -EINVAL;
        if (params->buffer_size != runtime->buffer_size) {
-               newbuf = kvmalloc(params->buffer_size, GFP_KERNEL);
+               newbuf = kvzalloc(params->buffer_size, GFP_KERNEL);
                if (!newbuf)
                        return -ENOMEM;
                spin_lock_irq(&runtime->lock);
index a2f1c6b586930d740cc8b674b0ea9dce4f06bf17..cb988efd1ed0d666494f76f23797fbde6a7e833e 100644 (file)
@@ -149,8 +149,9 @@ static void snd_vmidi_output_work(struct work_struct *work)
        /* discard the outputs in dispatch mode unless subscribed */
        if (vmidi->seq_mode == SNDRV_VIRMIDI_SEQ_DISPATCH &&
            !(vmidi->rdev->flags & SNDRV_VIRMIDI_SUBSCRIBE)) {
-               while (!snd_rawmidi_transmit_empty(substream))
-                       snd_rawmidi_transmit_ack(substream, 1);
+               char buf[32];
+               while (snd_rawmidi_transmit(substream, buf, sizeof(buf)) > 0)
+                       ; /* ignored */
                return;
        }
 
index 1bd27576db98d50cc12382c209c3938fe9fe5e14..a835558ddbc9b560a5e456a1594693350263c3d9 100644 (file)
@@ -146,7 +146,8 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_decouple);
  */
 void snd_hdac_ext_link_stream_start(struct hdac_ext_stream *stream)
 {
-       snd_hdac_updatel(stream->pplc_addr, AZX_REG_PPLCCTL, 0, AZX_PPLCCTL_RUN);
+       snd_hdac_updatel(stream->pplc_addr, AZX_REG_PPLCCTL,
+                        AZX_PPLCCTL_RUN, AZX_PPLCCTL_RUN);
 }
 EXPORT_SYMBOL_GPL(snd_hdac_ext_link_stream_start);
 
@@ -171,7 +172,8 @@ void snd_hdac_ext_link_stream_reset(struct hdac_ext_stream *stream)
 
        snd_hdac_ext_link_stream_clear(stream);
 
-       snd_hdac_updatel(stream->pplc_addr, AZX_REG_PPLCCTL, 0, AZX_PPLCCTL_STRST);
+       snd_hdac_updatel(stream->pplc_addr, AZX_REG_PPLCCTL,
+                        AZX_PPLCCTL_STRST, AZX_PPLCCTL_STRST);
        udelay(3);
        timeout = 50;
        do {
@@ -242,7 +244,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_link_set_stream_id);
 void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link,
                                 int stream)
 {
-       snd_hdac_updatew(link->ml_addr, AZX_REG_ML_LOSIDV, 0, (1 << stream));
+       snd_hdac_updatew(link->ml_addr, AZX_REG_ML_LOSIDV, (1 << stream), 0);
 }
 EXPORT_SYMBOL_GPL(snd_hdac_ext_link_clear_stream_id);
 
@@ -415,7 +417,6 @@ void snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *bus,
                                 bool enable, int index)
 {
        u32 mask = 0;
-       u32 register_mask = 0;
 
        if (!bus->spbcap) {
                dev_err(bus->dev, "Address of SPB capability is NULL\n");
@@ -424,12 +425,8 @@ void snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *bus,
 
        mask |= (1 << index);
 
-       register_mask = readl(bus->spbcap + AZX_REG_SPB_SPBFCCTL);
-
-       mask |= register_mask;
-
        if (enable)
-               snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, 0, mask);
+               snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, mask);
        else
                snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, 0);
 }
@@ -503,7 +500,6 @@ void snd_hdac_ext_stream_drsm_enable(struct hdac_bus *bus,
                                bool enable, int index)
 {
        u32 mask = 0;
-       u32 register_mask = 0;
 
        if (!bus->drsmcap) {
                dev_err(bus->dev, "Address of DRSM capability is NULL\n");
@@ -512,12 +508,8 @@ void snd_hdac_ext_stream_drsm_enable(struct hdac_bus *bus,
 
        mask |= (1 << index);
 
-       register_mask = readl(bus->drsmcap + AZX_REG_SPB_SPBFCCTL);
-
-       mask |= register_mask;
-
        if (enable)
-               snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, 0, mask);
+               snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, mask, mask);
        else
                snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, mask, 0);
 }
index 0a50855370348e37a52a2788463bc0a5ead4a5d1..26d348b47867d6d595aa8701a3cd779bf01d6204 100644 (file)
@@ -3935,7 +3935,8 @@ void snd_hda_bus_reset_codecs(struct hda_bus *bus)
 
        list_for_each_codec(codec, bus) {
                /* FIXME: maybe a better way needed for forced reset */
-               cancel_delayed_work_sync(&codec->jackpoll_work);
+               if (current_work() != &codec->jackpoll_work.work)
+                       cancel_delayed_work_sync(&codec->jackpoll_work);
 #ifdef CONFIG_PM
                if (hda_codec_is_power_on(codec)) {
                        hda_call_codec_suspend(codec);
index b20974ef1e13a72036f3ebdd94b639c81861ca1d..1d117f00d04d5620e767500a00f478fa9fc2b94a 100644 (file)
@@ -5494,6 +5494,7 @@ enum {
        ALC255_FIXUP_DUMMY_LINEOUT_VERB,
        ALC255_FIXUP_DELL_HEADSET_MIC,
        ALC295_FIXUP_HP_X360,
+       ALC221_FIXUP_HP_HEADSET_MIC,
 };
 
 static const struct hda_fixup alc269_fixups[] = {
@@ -6351,7 +6352,16 @@ static const struct hda_fixup alc269_fixups[] = {
                .v.func = alc295_fixup_hp_top_speakers,
                .chained = true,
                .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC3
-       }
+       },
+       [ALC221_FIXUP_HP_HEADSET_MIC] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x19, 0x0181313f},
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC269_FIXUP_HEADSET_MIC
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -6777,6 +6787,12 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
        {0x21, 0x03211020}
 
 static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+       SND_HDA_PIN_QUIRK(0x10ec0221, 0x103c, "HP Workstation", ALC221_FIXUP_HP_HEADSET_MIC,
+               {0x14, 0x01014020},
+               {0x17, 0x90170110},
+               {0x18, 0x02a11030},
+               {0x19, 0x0181303F},
+               {0x21, 0x0221102f}),
        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
                {0x12, 0x90a601c0},
                {0x14, 0x90171120},
index 8734040d64d379f5ad4849f529e61b31aceb6670..363145716a6d6fed73b6271c9a07fdeab6655125 100644 (file)
@@ -153,7 +153,7 @@ struct sst_block_allocator {
 };
 
 /*
- * Runtime Module Instance - A module object can be instanciated multiple
+ * Runtime Module Instance - A module object can be instantiated multiple
  * times within the DSP FW.
  */
 struct sst_module_runtime {
@@ -193,7 +193,7 @@ enum sst_module_state {
  *
  * Each Firmware file can consist of 1..N modules. A module can span multiple
  * ADSP memory blocks. The simplest FW will be a file with 1 module. A module
- * can be instanciated multiple times in the DSP.
+ * can be instantiated multiple times in the DSP.
  */
 struct sst_module {
        struct sst_dsp *dsp;
index 64aaa3f5f36ca2c6cb43f7ab5d02c0e8510a010d..89a048c2faec7f8a818d1a461ccd7fa67eca0fd9 100644 (file)
 #define X86_FEATURE_STIBP              ( 7*32+27) /* Single Thread Indirect Branch Predictors */
 #define X86_FEATURE_ZEN                        ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */
 #define X86_FEATURE_L1TF_PTEINV                ( 7*32+29) /* "" L1TF workaround PTE inversion */
+#define X86_FEATURE_IBRS_ENHANCED      ( 7*32+30) /* Enhanced IBRS */
 
 /* Virtualization flags: Linux defined, word 8 */
 #define X86_FEATURE_TPR_SHADOW         ( 8*32+ 0) /* Intel TPR Shadow */
 
 #define X86_FEATURE_VMMCALL            ( 8*32+15) /* Prefer VMMCALL to VMCALL */
 #define X86_FEATURE_XENPV              ( 8*32+16) /* "" Xen paravirtual guest */
-
+#define X86_FEATURE_EPT_AD             ( 8*32+17) /* Intel Extended Page Table access-dirty bit */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:0 (EBX), word 9 */
 #define X86_FEATURE_FSGSBASE           ( 9*32+ 0) /* RDFSBASE, WRFSBASE, RDGSBASE, WRGSBASE instructions*/
index 298ef1479240b6b899fb4185a5204d5ad56b8785..3b24dc05251c7ce908cc2be48befb971b5b8f564 100644 (file)
@@ -256,7 +256,7 @@ ENTRY(__memcpy_mcsafe)
 
        /* Copy successful. Return zero */
 .L_done_memcpy_trap:
-       xorq %rax, %rax
+       xorl %eax, %eax
        ret
 ENDPROC(__memcpy_mcsafe)
 EXPORT_SYMBOL_GPL(__memcpy_mcsafe)
index b2ec20e562bd5a3b0adf77b5f40be365bf255efa..b455930a3eaf7fd9095e116cfd9536e621a5cd1f 100644 (file)
@@ -68,6 +68,7 @@ static const char * const map_type_name[] = {
        [BPF_MAP_TYPE_DEVMAP]           = "devmap",
        [BPF_MAP_TYPE_SOCKMAP]          = "sockmap",
        [BPF_MAP_TYPE_CPUMAP]           = "cpumap",
+       [BPF_MAP_TYPE_XSKMAP]           = "xskmap",
        [BPF_MAP_TYPE_SOCKHASH]         = "sockhash",
        [BPF_MAP_TYPE_CGROUP_STORAGE]   = "cgroup_storage",
 };
index 1832100d1b274db7b71045e4dfe9e7e00e534ae0..6d41323be291bbf7e18348375aa88006d36facda 100644 (file)
@@ -194,8 +194,10 @@ int do_event_pipe(int argc, char **argv)
        }
 
        while (argc) {
-               if (argc < 2)
+               if (argc < 2) {
                        BAD_ARG();
+                       goto err_close_map;
+               }
 
                if (is_prefix(*argv, "cpu")) {
                        char *endptr;
@@ -221,6 +223,7 @@ int do_event_pipe(int argc, char **argv)
                        NEXT_ARG();
                } else {
                        BAD_ARG();
+                       goto err_close_map;
                }
 
                do_all = false;
index 63440cc8d618486af1c970499138738b7882485c..e63662db131ba525c36e79232150fc5f62e2f758 100644 (file)
@@ -96,6 +96,23 @@ static inline int test_and_set_bit(int nr, unsigned long *addr)
        return (old & mask) != 0;
 }
 
+/**
+ * test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ */
+static inline int test_and_clear_bit(int nr, unsigned long *addr)
+{
+       unsigned long mask = BIT_MASK(nr);
+       unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+       unsigned long old;
+
+       old = *p;
+       *p = old & ~mask;
+
+       return (old & mask) != 0;
+}
+
 /**
  * bitmap_alloc - Allocate bitmap
  * @nbits: Number of bits
index 56c4b3f8a01beaa414e2526020dcfcfbfc142b9b..439b8a27488d371fe323f879ba225650df23a359 100755 (executable)
@@ -759,12 +759,18 @@ class DebugfsProvider(Provider):
             if len(vms) == 0:
                 self.do_read = False
 
-            self.paths = filter(lambda x: "{}-".format(pid) in x, vms)
+            self.paths = list(filter(lambda x: "{}-".format(pid) in x, vms))
 
         else:
             self.paths = []
             self.do_read = True
-        self.reset()
+
+    def _verify_paths(self):
+        """Remove invalid paths"""
+        for path in self.paths:
+            if not os.path.exists(os.path.join(PATH_DEBUGFS_KVM, path)):
+                self.paths.remove(path)
+                continue
 
     def read(self, reset=0, by_guest=0):
         """Returns a dict with format:'file name / field -> current value'.
@@ -780,6 +786,7 @@ class DebugfsProvider(Provider):
         # If no debugfs filtering support is available, then don't read.
         if not self.do_read:
             return results
+        self._verify_paths()
 
         paths = self.paths
         if self._pid == 0:
@@ -1096,15 +1103,16 @@ class Tui(object):
             pid = self.stats.pid_filter
         self.screen.erase()
         gname = self.get_gname_from_pid(pid)
+        self._gname = gname
         if gname:
             gname = ('({})'.format(gname[:MAX_GUEST_NAME_LEN] + '...'
                                    if len(gname) > MAX_GUEST_NAME_LEN
                                    else gname))
         if pid > 0:
-            self.screen.addstr(0, 0, 'kvm statistics - pid {0} {1}'
-                               .format(pid, gname), curses.A_BOLD)
+            self._headline = 'kvm statistics - pid {0} {1}'.format(pid, gname)
         else:
-            self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD)
+            self._headline = 'kvm statistics - summary'
+        self.screen.addstr(0, 0, self._headline, curses.A_BOLD)
         if self.stats.fields_filter:
             regex = self.stats.fields_filter
             if len(regex) > MAX_REGEX_LEN:
@@ -1162,6 +1170,19 @@ class Tui(object):
 
             return sorted_items
 
+        if not self._is_running_guest(self.stats.pid_filter):
+            if self._gname:
+                try: # ...to identify the guest by name in case it's back
+                    pids = self.get_pid_from_gname(self._gname)
+                    if len(pids) == 1:
+                        self._refresh_header(pids[0])
+                        self._update_pid(pids[0])
+                        return
+                except:
+                    pass
+            self._display_guest_dead()
+            # leave final data on screen
+            return
         row = 3
         self.screen.move(row, 0)
         self.screen.clrtobot()
@@ -1184,6 +1205,7 @@ class Tui(object):
         # print events
         tavg = 0
         tcur = 0
+        guest_removed = False
         for key, values in get_sorted_events(self, stats):
             if row >= self.screen.getmaxyx()[0] - 1 or values == (0, 0):
                 break
@@ -1191,7 +1213,10 @@ class Tui(object):
                 key = self.get_gname_from_pid(key)
                 if not key:
                     continue
-            cur = int(round(values.delta / sleeptime)) if values.delta else ''
+            cur = int(round(values.delta / sleeptime)) if values.delta else 0
+            if cur < 0:
+                guest_removed = True
+                continue
             if key[0] != ' ':
                 if values.delta:
                     tcur += values.delta
@@ -1204,13 +1229,21 @@ class Tui(object):
                                values.value * 100 / float(ltotal), cur))
             row += 1
         if row == 3:
-            self.screen.addstr(4, 1, 'No matching events reported yet')
+            if guest_removed:
+                self.screen.addstr(4, 1, 'Guest removed, updating...')
+            else:
+                self.screen.addstr(4, 1, 'No matching events reported yet')
         if row > 4:
             tavg = int(round(tcur / sleeptime)) if tcur > 0 else ''
             self.screen.addstr(row, 1, '%-40s %10d        %8s' %
                                ('Total', total, tavg), curses.A_BOLD)
         self.screen.refresh()
 
+    def _display_guest_dead(self):
+        marker = '   Guest is DEAD   '
+        y = min(len(self._headline), 80 - len(marker))
+        self.screen.addstr(0, y, marker, curses.A_BLINK | curses.A_STANDOUT)
+
     def _show_msg(self, text):
         """Display message centered text and exit on key press"""
         hint = 'Press any key to continue'
@@ -1219,10 +1252,10 @@ class Tui(object):
         (x, term_width) = self.screen.getmaxyx()
         row = 2
         for line in text:
-            start = (term_width - len(line)) / 2
+            start = (term_width - len(line)) // 2
             self.screen.addstr(row, start, line)
             row += 1
-        self.screen.addstr(row + 1, (term_width - len(hint)) / 2, hint,
+        self.screen.addstr(row + 1, (term_width - len(hint)) // 2, hint,
                            curses.A_STANDOUT)
         self.screen.getkey()
 
@@ -1319,6 +1352,12 @@ class Tui(object):
                 msg = '"' + str(val) + '": Invalid value'
         self._refresh_header()
 
+    def _is_running_guest(self, pid):
+        """Check if pid is still a running process."""
+        if not pid:
+            return True
+        return os.path.isdir(os.path.join('/proc/', str(pid)))
+
     def _show_vm_selection_by_guest(self):
         """Draws guest selection mask.
 
@@ -1346,7 +1385,7 @@ class Tui(object):
             if not guest or guest == '0':
                 break
             if guest.isdigit():
-                if not os.path.isdir(os.path.join('/proc/', guest)):
+                if not self._is_running_guest(guest):
                     msg = '"' + guest + '": Not a running process'
                     continue
                 pid = int(guest)
index 9b0ca3ad1ef3863a8d6f877a74e75a0ce40f6dd5..9dafb8cb752fe066284dd9ea6d34e59ee97c5741 100644 (file)
@@ -129,12 +129,12 @@ $(OUTPUT)liblockdep.a: $(LIB_IN)
 tags:  force
        $(RM) tags
        find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \
-       --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/'
+       --regex-c++='/_PE\(([^,)]*).*/TEP_ERRNO__\1/'
 
 TAGS:  force
        $(RM) TAGS
        find . -name '*.[ch]' | xargs etags \
-       --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/'
+       --regex='/_PE(\([^,)]*\).*/TEP_ERRNO__\1/'
 
 define do_install
        $(print_install)                                \
index 46cd5f871ad76d48bc7a34f725a31fa12ed5614c..0b4e833088a4dc9653fe065cba012141a815c014 100644 (file)
@@ -233,12 +233,12 @@ endef
 tags:  force
        $(RM) tags
        find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \
-       --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/'
+       --regex-c++='/_PE\(([^,)]*).*/TEP_ERRNO__\1/'
 
 TAGS:  force
        $(RM) TAGS
        find . -name '*.[ch]' | xargs etags \
-       --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/'
+       --regex='/_PE(\([^,)]*\).*/TEP_ERRNO__\1/'
 
 define do_install_mkdir
        if [ ! -d '$(DESTDIR_SQ)$1' ]; then             \
index e5f2acbb70cc1db3f7274e2b2846594b5ca6d14d..ce1e20227c64d4e0789b6dad21a407988de720d9 100644 (file)
@@ -1,21 +1,7 @@
+// SPDX-License-Identifier: LGPL-2.1
 /*
  * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
  *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License (not later!)
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not,  see <http://www.gnu.org/licenses>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
  *  The parts for function graph printing was taken and modified from the
  *  Linux Kernel that were written by
@@ -73,12 +59,12 @@ static void init_input_buf(const char *buf, unsigned long long size)
        input_buf_ptr = 0;
 }
 
-const char *pevent_get_input_buf(void)
+const char *tep_get_input_buf(void)
 {
        return input_buf;
 }
 
-unsigned long long pevent_get_input_buf_ptr(void)
+unsigned long long tep_get_input_buf_ptr(void)
 {
        return input_buf_ptr;
 }
@@ -88,21 +74,21 @@ struct event_handler {
        int                             id;
        const char                      *sys_name;
        const char                      *event_name;
-       pevent_event_handler_func       func;
+       tep_event_handler_func          func;
        void                            *context;
 };
 
-struct pevent_func_params {
-       struct pevent_func_params       *next;
-       enum pevent_func_arg_type       type;
+struct func_params {
+       struct func_params      *next;
+       enum tep_func_arg_type  type;
 };
 
-struct pevent_function_handler {
-       struct pevent_function_handler  *next;
-       enum pevent_func_arg_type       ret_type;
+struct tep_function_handler {
+       struct tep_function_handler     *next;
+       enum tep_func_arg_type          ret_type;
        char                            *name;
-       pevent_func_handler             func;
-       struct pevent_func_params       *params;
+       tep_func_handler                func;
+       struct func_params              *params;
        int                             nr_args;
 };
 
@@ -110,17 +96,17 @@ static unsigned long long
 process_defined_func(struct trace_seq *s, void *data, int size,
                     struct event_format *event, struct print_arg *arg);
 
-static void free_func_handle(struct pevent_function_handler *func);
+static void free_func_handle(struct tep_function_handler *func);
 
 /**
- * pevent_buffer_init - init buffer for parsing
+ * tep_buffer_init - init buffer for parsing
  * @buf: buffer to parse
  * @size: the size of the buffer
  *
- * For use with pevent_read_token(), this initializes the internal
- * buffer that pevent_read_token() will parse.
+ * For use with tep_read_token(), this initializes the internal
+ * buffer that tep_read_token() will parse.
  */
-void pevent_buffer_init(const char *buf, unsigned long long size)
+void tep_buffer_init(const char *buf, unsigned long long size)
 {
        init_input_buf(buf, size);
 }
@@ -160,7 +146,7 @@ struct cmdline_list {
        int                     pid;
 };
 
-static int cmdline_init(struct pevent *pevent)
+static int cmdline_init(struct tep_handle *pevent)
 {
        struct cmdline_list *cmdlist = pevent->cmdlist;
        struct cmdline_list *item;
@@ -189,7 +175,7 @@ static int cmdline_init(struct pevent *pevent)
        return 0;
 }
 
-static const char *find_cmdline(struct pevent *pevent, int pid)
+static const char *find_cmdline(struct tep_handle *pevent, int pid)
 {
        const struct cmdline *comm;
        struct cmdline key;
@@ -211,14 +197,14 @@ static const char *find_cmdline(struct pevent *pevent, int pid)
 }
 
 /**
- * pevent_pid_is_registered - return if a pid has a cmdline registered
+ * tep_pid_is_registered - return if a pid has a cmdline registered
  * @pevent: handle for the pevent
  * @pid: The pid to check if it has a cmdline registered with.
  *
  * Returns 1 if the pid has a cmdline mapped to it
  * 0 otherwise.
  */
-int pevent_pid_is_registered(struct pevent *pevent, int pid)
+int tep_pid_is_registered(struct tep_handle *pevent, int pid)
 {
        const struct cmdline *comm;
        struct cmdline key;
@@ -244,7 +230,7 @@ int pevent_pid_is_registered(struct pevent *pevent, int pid)
  * we must add this pid. This is much slower than when cmdlines
  * are added before the array is initialized.
  */
-static int add_new_comm(struct pevent *pevent, const char *comm, int pid)
+static int add_new_comm(struct tep_handle *pevent, const char *comm, int pid)
 {
        struct cmdline *cmdlines = pevent->cmdlines;
        const struct cmdline *cmdline;
@@ -288,7 +274,7 @@ static int add_new_comm(struct pevent *pevent, const char *comm, int pid)
 }
 
 /**
- * pevent_register_comm - register a pid / comm mapping
+ * tep_register_comm - register a pid / comm mapping
  * @pevent: handle for the pevent
  * @comm: the command line to register
  * @pid: the pid to map the command line to
@@ -296,7 +282,7 @@ static int add_new_comm(struct pevent *pevent, const char *comm, int pid)
  * This adds a mapping to search for command line names with
  * a given pid. The comm is duplicated.
  */
-int pevent_register_comm(struct pevent *pevent, const char *comm, int pid)
+int tep_register_comm(struct tep_handle *pevent, const char *comm, int pid)
 {
        struct cmdline_list *item;
 
@@ -324,7 +310,7 @@ int pevent_register_comm(struct pevent *pevent, const char *comm, int pid)
        return 0;
 }
 
-int pevent_register_trace_clock(struct pevent *pevent, const char *trace_clock)
+int tep_register_trace_clock(struct tep_handle *pevent, const char *trace_clock)
 {
        pevent->trace_clock = strdup(trace_clock);
        if (!pevent->trace_clock) {
@@ -381,7 +367,7 @@ static int func_bcmp(const void *a, const void *b)
        return 1;
 }
 
-static int func_map_init(struct pevent *pevent)
+static int func_map_init(struct tep_handle *pevent)
 {
        struct func_list *funclist;
        struct func_list *item;
@@ -421,7 +407,7 @@ static int func_map_init(struct pevent *pevent)
 }
 
 static struct func_map *
-__find_func(struct pevent *pevent, unsigned long long addr)
+__find_func(struct tep_handle *pevent, unsigned long long addr)
 {
        struct func_map *func;
        struct func_map key;
@@ -438,13 +424,13 @@ __find_func(struct pevent *pevent, unsigned long long addr)
 }
 
 struct func_resolver {
-       pevent_func_resolver_t *func;
-       void                   *priv;
-       struct func_map        map;
+       tep_func_resolver_t     *func;
+       void                    *priv;
+       struct func_map         map;
 };
 
 /**
- * pevent_set_function_resolver - set an alternative function resolver
+ * tep_set_function_resolver - set an alternative function resolver
  * @pevent: handle for the pevent
  * @resolver: function to be used
  * @priv: resolver function private state.
@@ -453,8 +439,8 @@ struct func_resolver {
  * keep using it instead of duplicating all the entries inside
  * pevent->funclist.
  */
-int pevent_set_function_resolver(struct pevent *pevent,
-                                pevent_func_resolver_t *func, void *priv)
+int tep_set_function_resolver(struct tep_handle *pevent,
+                             tep_func_resolver_t *func, void *priv)
 {
        struct func_resolver *resolver = malloc(sizeof(*resolver));
 
@@ -471,20 +457,20 @@ int pevent_set_function_resolver(struct pevent *pevent,
 }
 
 /**
- * pevent_reset_function_resolver - reset alternative function resolver
+ * tep_reset_function_resolver - reset alternative function resolver
  * @pevent: handle for the pevent
  *
  * Stop using whatever alternative resolver was set, use the default
  * one instead.
  */
-void pevent_reset_function_resolver(struct pevent *pevent)
+void tep_reset_function_resolver(struct tep_handle *pevent)
 {
        free(pevent->func_resolver);
        pevent->func_resolver = NULL;
 }
 
 static struct func_map *
-find_func(struct pevent *pevent, unsigned long long addr)
+find_func(struct tep_handle *pevent, unsigned long long addr)
 {
        struct func_map *map;
 
@@ -503,7 +489,7 @@ find_func(struct pevent *pevent, unsigned long long addr)
 }
 
 /**
- * pevent_find_function - find a function by a given address
+ * tep_find_function - find a function by a given address
  * @pevent: handle for the pevent
  * @addr: the address to find the function with
  *
@@ -511,7 +497,7 @@ find_func(struct pevent *pevent, unsigned long long addr)
  * address. Note, the address does not have to be exact, it
  * will select the function that would contain the address.
  */
-const char *pevent_find_function(struct pevent *pevent, unsigned long long addr)
+const char *tep_find_function(struct tep_handle *pevent, unsigned long long addr)
 {
        struct func_map *map;
 
@@ -523,16 +509,16 @@ const char *pevent_find_function(struct pevent *pevent, unsigned long long addr)
 }
 
 /**
- * pevent_find_function_address - find a function address by a given address
+ * tep_find_function_address - find a function address by a given address
  * @pevent: handle for the pevent
  * @addr: the address to find the function with
  *
  * Returns the address the function starts at. This can be used in
- * conjunction with pevent_find_function to print both the function
+ * conjunction with tep_find_function to print both the function
  * name and the function offset.
  */
 unsigned long long
-pevent_find_function_address(struct pevent *pevent, unsigned long long addr)
+tep_find_function_address(struct tep_handle *pevent, unsigned long long addr)
 {
        struct func_map *map;
 
@@ -544,7 +530,7 @@ pevent_find_function_address(struct pevent *pevent, unsigned long long addr)
 }
 
 /**
- * pevent_register_function - register a function with a given address
+ * tep_register_function - register a function with a given address
  * @pevent: handle for the pevent
  * @function: the function name to register
  * @addr: the address the function starts at
@@ -553,8 +539,8 @@ pevent_find_function_address(struct pevent *pevent, unsigned long long addr)
  * This registers a function name with an address and module.
  * The @func passed in is duplicated.
  */
-int pevent_register_function(struct pevent *pevent, char *func,
-                            unsigned long long addr, char *mod)
+int tep_register_function(struct tep_handle *pevent, char *func,
+                         unsigned long long addr, char *mod)
 {
        struct func_list *item = malloc(sizeof(*item));
 
@@ -589,12 +575,12 @@ out_free:
 }
 
 /**
- * pevent_print_funcs - print out the stored functions
+ * tep_print_funcs - print out the stored functions
  * @pevent: handle for the pevent
  *
  * This prints out the stored functions.
  */
-void pevent_print_funcs(struct pevent *pevent)
+void tep_print_funcs(struct tep_handle *pevent)
 {
        int i;
 
@@ -636,7 +622,7 @@ static int printk_cmp(const void *a, const void *b)
        return 0;
 }
 
-static int printk_map_init(struct pevent *pevent)
+static int printk_map_init(struct tep_handle *pevent)
 {
        struct printk_list *printklist;
        struct printk_list *item;
@@ -668,7 +654,7 @@ static int printk_map_init(struct pevent *pevent)
 }
 
 static struct printk_map *
-find_printk(struct pevent *pevent, unsigned long long addr)
+find_printk(struct tep_handle *pevent, unsigned long long addr)
 {
        struct printk_map *printk;
        struct printk_map key;
@@ -685,7 +671,7 @@ find_printk(struct pevent *pevent, unsigned long long addr)
 }
 
 /**
- * pevent_register_print_string - register a string by its address
+ * tep_register_print_string - register a string by its address
  * @pevent: handle for the pevent
  * @fmt: the string format to register
  * @addr: the address the string was located at
@@ -693,8 +679,8 @@ find_printk(struct pevent *pevent, unsigned long long addr)
  * This registers a string by the address it was stored in the kernel.
  * The @fmt passed in is duplicated.
  */
-int pevent_register_print_string(struct pevent *pevent, const char *fmt,
-                                unsigned long long addr)
+int tep_register_print_string(struct tep_handle *pevent, const char *fmt,
+                             unsigned long long addr)
 {
        struct printk_list *item = malloc(sizeof(*item));
        char *p;
@@ -732,12 +718,12 @@ out_free:
 }
 
 /**
- * pevent_print_printk - print out the stored strings
+ * tep_print_printk - print out the stored strings
  * @pevent: handle for the pevent
  *
  * This prints the string formats that were stored.
  */
-void pevent_print_printk(struct pevent *pevent)
+void tep_print_printk(struct tep_handle *pevent)
 {
        int i;
 
@@ -756,7 +742,7 @@ static struct event_format *alloc_event(void)
        return calloc(1, sizeof(struct event_format));
 }
 
-static int add_event(struct pevent *pevent, struct event_format *event)
+static int add_event(struct tep_handle *pevent, struct event_format *event)
 {
        int i;
        struct event_format **events = realloc(pevent->events, sizeof(event) *
@@ -913,11 +899,11 @@ static int __peek_char(void)
 }
 
 /**
- * pevent_peek_char - peek at the next character that will be read
+ * tep_peek_char - peek at the next character that will be read
  *
  * Returns the next character read, or -1 if end of buffer.
  */
-int pevent_peek_char(void)
+int tep_peek_char(void)
 {
        return __peek_char();
 }
@@ -1157,24 +1143,24 @@ static enum event_type read_token(char **tok)
 }
 
 /**
- * pevent_read_token - access to utilites to use the pevent parser
+ * tep_read_token - access to utilites to use the pevent parser
  * @tok: The token to return
  *
  * This will parse tokens from the string given by
- * pevent_init_data().
+ * tep_init_data().
  *
  * Returns the token type.
  */
-enum event_type pevent_read_token(char **tok)
+enum event_type tep_read_token(char **tok)
 {
        return read_token(tok);
 }
 
 /**
- * pevent_free_token - free a token returned by pevent_read_token
+ * tep_free_token - free a token returned by tep_read_token
  * @token: the token to free
  */
-void pevent_free_token(char *token)
+void tep_free_token(char *token)
 {
        free_token(token);
 }
@@ -2101,11 +2087,11 @@ process_entry(struct event_format *event __maybe_unused, struct print_arg *arg,
        arg->field.name = field;
 
        if (is_flag_field) {
-               arg->field.field = pevent_find_any_field(event, arg->field.name);
+               arg->field.field = tep_find_any_field(event, arg->field.name);
                arg->field.field->flags |= FIELD_IS_FLAG;
                is_flag_field = 0;
        } else if (is_symbolic_field) {
-               arg->field.field = pevent_find_any_field(event, arg->field.name);
+               arg->field.field = tep_find_any_field(event, arg->field.name);
                arg->field.field->flags |= FIELD_IS_SYMBOLIC;
                is_symbolic_field = 0;
        }
@@ -2714,7 +2700,7 @@ process_dynamic_array(struct event_format *event, struct print_arg *arg, char **
 
        /* Find the field */
 
-       field = pevent_find_field(event, token);
+       field = tep_find_field(event, token);
        if (!field)
                goto out_free;
 
@@ -2771,7 +2757,7 @@ process_dynamic_array_len(struct event_format *event, struct print_arg *arg,
        arg->type = PRINT_DYNAMIC_ARRAY_LEN;
 
        /* Find the field */
-       field = pevent_find_field(event, token);
+       field = tep_find_field(event, token);
        if (!field)
                goto out_free;
 
@@ -2914,10 +2900,10 @@ process_bitmask(struct event_format *event __maybe_unused, struct print_arg *arg
        return EVENT_ERROR;
 }
 
-static struct pevent_function_handler *
-find_func_handler(struct pevent *pevent, char *func_name)
+static struct tep_function_handler *
+find_func_handler(struct tep_handle *pevent, char *func_name)
 {
-       struct pevent_function_handler *func;
+       struct tep_function_handler *func;
 
        if (!pevent)
                return NULL;
@@ -2930,10 +2916,10 @@ find_func_handler(struct pevent *pevent, char *func_name)
        return func;
 }
 
-static void remove_func_handler(struct pevent *pevent, char *func_name)
+static void remove_func_handler(struct tep_handle *pevent, char *func_name)
 {
-       struct pevent_function_handler *func;
-       struct pevent_function_handler **next;
+       struct tep_function_handler *func;
+       struct tep_function_handler **next;
 
        next = &pevent->func_handlers;
        while ((func = *next)) {
@@ -2947,7 +2933,7 @@ static void remove_func_handler(struct pevent *pevent, char *func_name)
 }
 
 static enum event_type
-process_func_handler(struct event_format *event, struct pevent_function_handler *func,
+process_func_handler(struct event_format *event, struct tep_function_handler *func,
                     struct print_arg *arg, char **tok)
 {
        struct print_arg **next_arg;
@@ -3008,7 +2994,7 @@ static enum event_type
 process_function(struct event_format *event, struct print_arg *arg,
                 char *token, char **tok)
 {
-       struct pevent_function_handler *func;
+       struct tep_function_handler *func;
 
        if (strcmp(token, "__print_flags") == 0) {
                free_token(token);
@@ -3265,7 +3251,7 @@ static int event_read_print(struct event_format *event)
 }
 
 /**
- * pevent_find_common_field - return a common field by event
+ * tep_find_common_field - return a common field by event
  * @event: handle for the event
  * @name: the name of the common field to return
  *
@@ -3273,7 +3259,7 @@ static int event_read_print(struct event_format *event)
  * This only searchs the common fields and not all field.
  */
 struct format_field *
-pevent_find_common_field(struct event_format *event, const char *name)
+tep_find_common_field(struct event_format *event, const char *name)
 {
        struct format_field *format;
 
@@ -3287,7 +3273,7 @@ pevent_find_common_field(struct event_format *event, const char *name)
 }
 
 /**
- * pevent_find_field - find a non-common field
+ * tep_find_field - find a non-common field
  * @event: handle for the event
  * @name: the name of the non-common field
  *
@@ -3295,7 +3281,7 @@ pevent_find_common_field(struct event_format *event, const char *name)
  * This does not search common fields.
  */
 struct format_field *
-pevent_find_field(struct event_format *event, const char *name)
+tep_find_field(struct event_format *event, const char *name)
 {
        struct format_field *format;
 
@@ -3309,7 +3295,7 @@ pevent_find_field(struct event_format *event, const char *name)
 }
 
 /**
- * pevent_find_any_field - find any field by name
+ * tep_find_any_field - find any field by name
  * @event: handle for the event
  * @name: the name of the field
  *
@@ -3318,18 +3304,18 @@ pevent_find_field(struct event_format *event, const char *name)
  * the non-common ones if a common one was not found.
  */
 struct format_field *
-pevent_find_any_field(struct event_format *event, const char *name)
+tep_find_any_field(struct event_format *event, const char *name)
 {
        struct format_field *format;
 
-       format = pevent_find_common_field(event, name);
+       format = tep_find_common_field(event, name);
        if (format)
                return format;
-       return pevent_find_field(event, name);
+       return tep_find_field(event, name);
 }
 
 /**
- * pevent_read_number - read a number from data
+ * tep_read_number - read a number from data
  * @pevent: handle for the pevent
  * @ptr: the raw data
  * @size: the size of the data that holds the number
@@ -3337,8 +3323,8 @@ pevent_find_any_field(struct event_format *event, const char *name)
  * Returns the number (converted to host) from the
  * raw data.
  */
-unsigned long long pevent_read_number(struct pevent *pevent,
-                                     const void *ptr, int size)
+unsigned long long tep_read_number(struct tep_handle *pevent,
+                                  const void *ptr, int size)
 {
        switch (size) {
        case 1:
@@ -3356,7 +3342,7 @@ unsigned long long pevent_read_number(struct pevent *pevent,
 }
 
 /**
- * pevent_read_number_field - read a number from data
+ * tep_read_number_field - read a number from data
  * @field: a handle to the field
  * @data: the raw data to read
  * @value: the value to place the number in
@@ -3366,8 +3352,8 @@ unsigned long long pevent_read_number(struct pevent *pevent,
  *
  * Returns 0 on success, -1 otherwise.
  */
-int pevent_read_number_field(struct format_field *field, const void *data,
-                            unsigned long long *value)
+int tep_read_number_field(struct format_field *field, const void *data,
+                         unsigned long long *value)
 {
        if (!field)
                return -1;
@@ -3376,15 +3362,15 @@ int pevent_read_number_field(struct format_field *field, const void *data,
        case 2:
        case 4:
        case 8:
-               *value = pevent_read_number(field->event->pevent,
-                                           data + field->offset, field->size);
+               *value = tep_read_number(field->event->pevent,
+                                        data + field->offset, field->size);
                return 0;
        default:
                return -1;
        }
 }
 
-static int get_common_info(struct pevent *pevent,
+static int get_common_info(struct tep_handle *pevent,
                           const char *type, int *offset, int *size)
 {
        struct event_format *event;
@@ -3400,7 +3386,7 @@ static int get_common_info(struct pevent *pevent,
        }
 
        event = pevent->events[0];
-       field = pevent_find_common_field(event, type);
+       field = tep_find_common_field(event, type);
        if (!field)
                return -1;
 
@@ -3410,7 +3396,7 @@ static int get_common_info(struct pevent *pevent,
        return 0;
 }
 
-static int __parse_common(struct pevent *pevent, void *data,
+static int __parse_common(struct tep_handle *pevent, void *data,
                          int *size, int *offset, const char *name)
 {
        int ret;
@@ -3420,45 +3406,45 @@ static int __parse_common(struct pevent *pevent, void *data,
                if (ret < 0)
                        return ret;
        }
-       return pevent_read_number(pevent, data + *offset, *size);
+       return tep_read_number(pevent, data + *offset, *size);
 }
 
-static int trace_parse_common_type(struct pevent *pevent, void *data)
+static int trace_parse_common_type(struct tep_handle *pevent, void *data)
 {
        return __parse_common(pevent, data,
                              &pevent->type_size, &pevent->type_offset,
                              "common_type");
 }
 
-static int parse_common_pid(struct pevent *pevent, void *data)
+static int parse_common_pid(struct tep_handle *pevent, void *data)
 {
        return __parse_common(pevent, data,
                              &pevent->pid_size, &pevent->pid_offset,
                              "common_pid");
 }
 
-static int parse_common_pc(struct pevent *pevent, void *data)
+static int parse_common_pc(struct tep_handle *pevent, void *data)
 {
        return __parse_common(pevent, data,
                              &pevent->pc_size, &pevent->pc_offset,
                              "common_preempt_count");
 }
 
-static int parse_common_flags(struct pevent *pevent, void *data)
+static int parse_common_flags(struct tep_handle *pevent, void *data)
 {
        return __parse_common(pevent, data,
                              &pevent->flags_size, &pevent->flags_offset,
                              "common_flags");
 }
 
-static int parse_common_lock_depth(struct pevent *pevent, void *data)
+static int parse_common_lock_depth(struct tep_handle *pevent, void *data)
 {
        return __parse_common(pevent, data,
                              &pevent->ld_size, &pevent->ld_offset,
                              "common_lock_depth");
 }
 
-static int parse_common_migrate_disable(struct pevent *pevent, void *data)
+static int parse_common_migrate_disable(struct tep_handle *pevent, void *data)
 {
        return __parse_common(pevent, data,
                              &pevent->ld_size, &pevent->ld_offset,
@@ -3468,13 +3454,13 @@ static int parse_common_migrate_disable(struct pevent *pevent, void *data)
 static int events_id_cmp(const void *a, const void *b);
 
 /**
- * pevent_find_event - find an event by given id
+ * tep_find_event - find an event by given id
  * @pevent: a handle to the pevent
  * @id: the id of the event
  *
  * Returns an event that has a given @id.
  */
-struct event_format *pevent_find_event(struct pevent *pevent, int id)
+struct event_format *tep_find_event(struct tep_handle *pevent, int id)
 {
        struct event_format **eventptr;
        struct event_format key;
@@ -3498,7 +3484,7 @@ struct event_format *pevent_find_event(struct pevent *pevent, int id)
 }
 
 /**
- * pevent_find_event_by_name - find an event by given name
+ * tep_find_event_by_name - find an event by given name
  * @pevent: a handle to the pevent
  * @sys: the system name to search for
  * @name: the name of the event to search for
@@ -3507,8 +3493,8 @@ struct event_format *pevent_find_event(struct pevent *pevent, int id)
  * @sys. If @sys is NULL the first event with @name is returned.
  */
 struct event_format *
-pevent_find_event_by_name(struct pevent *pevent,
-                         const char *sys, const char *name)
+tep_find_event_by_name(struct tep_handle *pevent,
+                      const char *sys, const char *name)
 {
        struct event_format *event;
        int i;
@@ -3537,7 +3523,7 @@ pevent_find_event_by_name(struct pevent *pevent,
 static unsigned long long
 eval_num_arg(void *data, int size, struct event_format *event, struct print_arg *arg)
 {
-       struct pevent *pevent = event->pevent;
+       struct tep_handle *pevent = event->pevent;
        unsigned long long val = 0;
        unsigned long long left, right;
        struct print_arg *typearg = NULL;
@@ -3553,14 +3539,14 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
                return strtoull(arg->atom.atom, NULL, 0);
        case PRINT_FIELD:
                if (!arg->field.field) {
-                       arg->field.field = pevent_find_any_field(event, arg->field.name);
+                       arg->field.field = tep_find_any_field(event, arg->field.name);
                        if (!arg->field.field)
                                goto out_warning_field;
                        
                }
                /* must be a number */
-               val = pevent_read_number(pevent, data + arg->field.field->offset,
-                               arg->field.field->size);
+               val = tep_read_number(pevent, data + arg->field.field->offset,
+                                     arg->field.field->size);
                break;
        case PRINT_FLAGS:
        case PRINT_SYMBOL:
@@ -3603,7 +3589,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
 
                        switch (larg->type) {
                        case PRINT_DYNAMIC_ARRAY:
-                               offset = pevent_read_number(pevent,
+                               offset = tep_read_number(pevent,
                                                   data + larg->dynarray.field->offset,
                                                   larg->dynarray.field->size);
                                if (larg->dynarray.field->elementsize)
@@ -3619,7 +3605,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
                        case PRINT_FIELD:
                                if (!larg->field.field) {
                                        larg->field.field =
-                                               pevent_find_any_field(event, larg->field.name);
+                                               tep_find_any_field(event, larg->field.name);
                                        if (!larg->field.field) {
                                                arg = larg;
                                                goto out_warning_field;
@@ -3632,8 +3618,8 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
                        default:
                                goto default_op; /* oops, all bets off */
                        }
-                       val = pevent_read_number(pevent,
-                                                data + offset, field_size);
+                       val = tep_read_number(pevent,
+                                             data + offset, field_size);
                        if (typearg)
                                val = eval_type(val, typearg, 1);
                        break;
@@ -3733,9 +3719,9 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
                }
                break;
        case PRINT_DYNAMIC_ARRAY_LEN:
-               offset = pevent_read_number(pevent,
-                                           data + arg->dynarray.field->offset,
-                                           arg->dynarray.field->size);
+               offset = tep_read_number(pevent,
+                                        data + arg->dynarray.field->offset,
+                                        arg->dynarray.field->size);
                /*
                 * The total allocated length of the dynamic array is
                 * stored in the top half of the field, and the offset
@@ -3745,9 +3731,9 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
                break;
        case PRINT_DYNAMIC_ARRAY:
                /* Without [], we pass the address to the dynamic data */
-               offset = pevent_read_number(pevent,
-                                           data + arg->dynarray.field->offset,
-                                           arg->dynarray.field->size);
+               offset = tep_read_number(pevent,
+                                        data + arg->dynarray.field->offset,
+                                        arg->dynarray.field->size);
                /*
                 * The total allocated length of the dynamic array is
                 * stored in the top half of the field, and the offset
@@ -3820,7 +3806,7 @@ static void print_str_to_seq(struct trace_seq *s, const char *format,
                trace_seq_printf(s, format, str);
 }
 
-static void print_bitmask_to_seq(struct pevent *pevent,
+static void print_bitmask_to_seq(struct tep_handle *pevent,
                                 struct trace_seq *s, const char *format,
                                 int len_arg, const void *data, int size)
 {
@@ -3878,7 +3864,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
                          struct event_format *event, const char *format,
                          int len_arg, struct print_arg *arg)
 {
-       struct pevent *pevent = event->pevent;
+       struct tep_handle *pevent = event->pevent;
        struct print_flag_sym *flag;
        struct format_field *field;
        struct printk_map *printk;
@@ -3899,7 +3885,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
        case PRINT_FIELD:
                field = arg->field.field;
                if (!field) {
-                       field = pevent_find_any_field(event, arg->field.name);
+                       field = tep_find_any_field(event, arg->field.name);
                        if (!field) {
                                str = arg->field.name;
                                goto out_warning_field;
@@ -3992,7 +3978,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
        case PRINT_HEX_STR:
                if (arg->hex.field->type == PRINT_DYNAMIC_ARRAY) {
                        unsigned long offset;
-                       offset = pevent_read_number(pevent,
+                       offset = tep_read_number(pevent,
                                data + arg->hex.field->dynarray.field->offset,
                                arg->hex.field->dynarray.field->size);
                        hex = data + (offset & 0xffff);
@@ -4000,7 +3986,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
                        field = arg->hex.field->field.field;
                        if (!field) {
                                str = arg->hex.field->field.name;
-                               field = pevent_find_any_field(event, str);
+                               field = tep_find_any_field(event, str);
                                if (!field)
                                        goto out_warning_field;
                                arg->hex.field->field.field = field;
@@ -4023,15 +4009,15 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
                        unsigned long offset;
                        struct format_field *field =
                                arg->int_array.field->dynarray.field;
-                       offset = pevent_read_number(pevent,
-                                                   data + field->offset,
-                                                   field->size);
+                       offset = tep_read_number(pevent,
+                                                data + field->offset,
+                                                field->size);
                        num = data + (offset & 0xffff);
                } else {
                        field = arg->int_array.field->field.field;
                        if (!field) {
                                str = arg->int_array.field->field.name;
-                               field = pevent_find_any_field(event, str);
+                               field = tep_find_any_field(event, str);
                                if (!field)
                                        goto out_warning_field;
                                arg->int_array.field->field.field = field;
@@ -4071,7 +4057,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
                if (arg->string.offset == -1) {
                        struct format_field *f;
 
-                       f = pevent_find_any_field(event, arg->string.string);
+                       f = tep_find_any_field(event, arg->string.string);
                        arg->string.offset = f->offset;
                }
                str_offset = data2host4(pevent, data + arg->string.offset);
@@ -4089,7 +4075,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
                if (arg->bitmask.offset == -1) {
                        struct format_field *f;
 
-                       f = pevent_find_any_field(event, arg->bitmask.bitmask);
+                       f = tep_find_any_field(event, arg->bitmask.bitmask);
                        arg->bitmask.offset = f->offset;
                }
                bitmask_offset = data2host4(pevent, data + arg->bitmask.offset);
@@ -4132,8 +4118,8 @@ static unsigned long long
 process_defined_func(struct trace_seq *s, void *data, int size,
                     struct event_format *event, struct print_arg *arg)
 {
-       struct pevent_function_handler *func_handle = arg->func.func;
-       struct pevent_func_params *param;
+       struct tep_function_handler *func_handle = arg->func.func;
+       struct func_params *param;
        unsigned long long *args;
        unsigned long long ret;
        struct print_arg *farg;
@@ -4159,12 +4145,12 @@ process_defined_func(struct trace_seq *s, void *data, int size,
 
        for (i = 0; i < func_handle->nr_args; i++) {
                switch (param->type) {
-               case PEVENT_FUNC_ARG_INT:
-               case PEVENT_FUNC_ARG_LONG:
-               case PEVENT_FUNC_ARG_PTR:
+               case TEP_FUNC_ARG_INT:
+               case TEP_FUNC_ARG_LONG:
+               case TEP_FUNC_ARG_PTR:
                        args[i] = eval_num_arg(data, size, event, farg);
                        break;
-               case PEVENT_FUNC_ARG_STRING:
+               case TEP_FUNC_ARG_STRING:
                        trace_seq_init(&str);
                        print_str_arg(&str, data, size, event, "%s", -1, farg);
                        trace_seq_terminate(&str);
@@ -4227,7 +4213,7 @@ static void free_args(struct print_arg *args)
 
 static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event_format *event)
 {
-       struct pevent *pevent = event->pevent;
+       struct tep_handle *pevent = event->pevent;
        struct format_field *field, *ip_field;
        struct print_arg *args, *arg, **next;
        unsigned long long ip, val;
@@ -4239,12 +4225,12 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
        ip_field = pevent->bprint_ip_field;
 
        if (!field) {
-               field = pevent_find_field(event, "buf");
+               field = tep_find_field(event, "buf");
                if (!field) {
                        do_warning_event(event, "can't find buffer field for binary printk");
                        return NULL;
                }
-               ip_field = pevent_find_field(event, "ip");
+               ip_field = tep_find_field(event, "ip");
                if (!ip_field) {
                        do_warning_event(event, "can't find ip field for binary printk");
                        return NULL;
@@ -4253,7 +4239,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
                pevent->bprint_ip_field = ip_field;
        }
 
-       ip = pevent_read_number(pevent, data + ip_field->offset, ip_field->size);
+       ip = tep_read_number(pevent, data + ip_field->offset, ip_field->size);
 
        /*
         * The first arg is the IP pointer.
@@ -4347,7 +4333,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
                                /* the pointers are always 4 bytes aligned */
                                bptr = (void *)(((unsigned long)bptr + 3) &
                                                ~3);
-                               val = pevent_read_number(pevent, bptr, vsize);
+                               val = tep_read_number(pevent, bptr, vsize);
                                bptr += vsize;
                                arg = alloc_arg();
                                if (!arg) {
@@ -4404,7 +4390,7 @@ static char *
 get_bprint_format(void *data, int size __maybe_unused,
                  struct event_format *event)
 {
-       struct pevent *pevent = event->pevent;
+       struct tep_handle *pevent = event->pevent;
        unsigned long long addr;
        struct format_field *field;
        struct printk_map *printk;
@@ -4413,7 +4399,7 @@ get_bprint_format(void *data, int size __maybe_unused,
        field = pevent->bprint_fmt_field;
 
        if (!field) {
-               field = pevent_find_field(event, "fmt");
+               field = tep_find_field(event, "fmt");
                if (!field) {
                        do_warning_event(event, "can't find format field for binary printk");
                        return NULL;
@@ -4421,7 +4407,7 @@ get_bprint_format(void *data, int size __maybe_unused,
                pevent->bprint_fmt_field = field;
        }
 
-       addr = pevent_read_number(pevent, data + field->offset, field->size);
+       addr = tep_read_number(pevent, data + field->offset, field->size);
 
        printk = find_printk(pevent, addr);
        if (!printk) {
@@ -4457,7 +4443,7 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
                fmt = "%.2x%.2x%.2x%.2x%.2x%.2x";
        if (!arg->field.field) {
                arg->field.field =
-                       pevent_find_any_field(event, arg->field.name);
+                       tep_find_any_field(event, arg->field.name);
                if (!arg->field.field) {
                        do_warning_event(event, "%s: field %s not found",
                                         __func__, arg->field.name);
@@ -4607,7 +4593,7 @@ static int print_ipv4_arg(struct trace_seq *s, const char *ptr, char i,
 
        if (!arg->field.field) {
                arg->field.field =
-                       pevent_find_any_field(event, arg->field.name);
+                       tep_find_any_field(event, arg->field.name);
                if (!arg->field.field) {
                        do_warning("%s: field %s not found",
                                   __func__, arg->field.name);
@@ -4653,7 +4639,7 @@ static int print_ipv6_arg(struct trace_seq *s, const char *ptr, char i,
 
        if (!arg->field.field) {
                arg->field.field =
-                       pevent_find_any_field(event, arg->field.name);
+                       tep_find_any_field(event, arg->field.name);
                if (!arg->field.field) {
                        do_warning("%s: field %s not found",
                                   __func__, arg->field.name);
@@ -4711,7 +4697,7 @@ static int print_ipsa_arg(struct trace_seq *s, const char *ptr, char i,
 
        if (!arg->field.field) {
                arg->field.field =
-                       pevent_find_any_field(event, arg->field.name);
+                       tep_find_any_field(event, arg->field.name);
                if (!arg->field.field) {
                        do_warning("%s: field %s not found",
                                   __func__, arg->field.name);
@@ -4800,18 +4786,18 @@ static int is_printable_array(char *p, unsigned int len)
        return 1;
 }
 
-void pevent_print_field(struct trace_seq *s, void *data,
-                       struct format_field *field)
+void tep_print_field(struct trace_seq *s, void *data,
+                    struct format_field *field)
 {
        unsigned long long val;
        unsigned int offset, len, i;
-       struct pevent *pevent = field->event->pevent;
+       struct tep_handle *pevent = field->event->pevent;
 
        if (field->flags & FIELD_IS_ARRAY) {
                offset = field->offset;
                len = field->size;
                if (field->flags & FIELD_IS_DYNAMIC) {
-                       val = pevent_read_number(pevent, data + offset, len);
+                       val = tep_read_number(pevent, data + offset, len);
                        offset = val;
                        len = offset >> 16;
                        offset &= 0xffff;
@@ -4831,8 +4817,8 @@ void pevent_print_field(struct trace_seq *s, void *data,
                        field->flags &= ~FIELD_IS_STRING;
                }
        } else {
-               val = pevent_read_number(pevent, data + field->offset,
-                                        field->size);
+               val = tep_read_number(pevent, data + field->offset,
+                                     field->size);
                if (field->flags & FIELD_IS_POINTER) {
                        trace_seq_printf(s, "0x%llx", val);
                } else if (field->flags & FIELD_IS_SIGNED) {
@@ -4865,22 +4851,22 @@ void pevent_print_field(struct trace_seq *s, void *data,
        }
 }
 
-void pevent_print_fields(struct trace_seq *s, void *data,
-                        int size __maybe_unused, struct event_format *event)
+void tep_print_fields(struct trace_seq *s, void *data,
+                     int size __maybe_unused, struct event_format *event)
 {
        struct format_field *field;
 
        field = event->format.fields;
        while (field) {
                trace_seq_printf(s, " %s=", field->name);
-               pevent_print_field(s, data, field);
+               tep_print_field(s, data, field);
                field = field->next;
        }
 }
 
 static void pretty_print(struct trace_seq *s, void *data, int size, struct event_format *event)
 {
-       struct pevent *pevent = event->pevent;
+       struct tep_handle *pevent = event->pevent;
        struct print_fmt *print_fmt = &event->print_fmt;
        struct print_arg *arg = print_fmt->args;
        struct print_arg *args = NULL;
@@ -4899,7 +4885,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
 
        if (event->flags & EVENT_FL_FAILED) {
                trace_seq_printf(s, "[FAILED TO PARSE]");
-               pevent_print_fields(s, data, size, event);
+               tep_print_fields(s, data, size, event);
                return;
        }
 
@@ -5140,7 +5126,7 @@ out_failed:
 }
 
 /**
- * pevent_data_lat_fmt - parse the data for the latency format
+ * tep_data_lat_fmt - parse the data for the latency format
  * @pevent: a handle to the pevent
  * @s: the trace_seq to write to
  * @record: the record to read from
@@ -5149,8 +5135,8 @@ out_failed:
  * need rescheduling, in hard/soft interrupt, preempt count
  * and lock depth) and places it into the trace_seq.
  */
-void pevent_data_lat_fmt(struct pevent *pevent,
-                        struct trace_seq *s, struct pevent_record *record)
+void tep_data_lat_fmt(struct tep_handle *pevent,
+                     struct trace_seq *s, struct tep_record *record)
 {
        static int check_lock_depth = 1;
        static int check_migrate_disable = 1;
@@ -5223,55 +5209,55 @@ void pevent_data_lat_fmt(struct pevent *pevent,
 }
 
 /**
- * pevent_data_type - parse out the given event type
+ * tep_data_type - parse out the given event type
  * @pevent: a handle to the pevent
  * @rec: the record to read from
  *
  * This returns the event id from the @rec.
  */
-int pevent_data_type(struct pevent *pevent, struct pevent_record *rec)
+int tep_data_type(struct tep_handle *pevent, struct tep_record *rec)
 {
        return trace_parse_common_type(pevent, rec->data);
 }
 
 /**
- * pevent_data_event_from_type - find the event by a given type
+ * tep_data_event_from_type - find the event by a given type
  * @pevent: a handle to the pevent
  * @type: the type of the event.
  *
  * This returns the event form a given @type;
  */
-struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type)
+struct event_format *tep_data_event_from_type(struct tep_handle *pevent, int type)
 {
-       return pevent_find_event(pevent, type);
+       return tep_find_event(pevent, type);
 }
 
 /**
- * pevent_data_pid - parse the PID from record
+ * tep_data_pid - parse the PID from record
  * @pevent: a handle to the pevent
  * @rec: the record to parse
  *
  * This returns the PID from a record.
  */
-int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec)
+int tep_data_pid(struct tep_handle *pevent, struct tep_record *rec)
 {
        return parse_common_pid(pevent, rec->data);
 }
 
 /**
- * pevent_data_preempt_count - parse the preempt count from the record
+ * tep_data_preempt_count - parse the preempt count from the record
  * @pevent: a handle to the pevent
  * @rec: the record to parse
  *
  * This returns the preempt count from a record.
  */
-int pevent_data_preempt_count(struct pevent *pevent, struct pevent_record *rec)
+int tep_data_preempt_count(struct tep_handle *pevent, struct tep_record *rec)
 {
        return parse_common_pc(pevent, rec->data);
 }
 
 /**
- * pevent_data_flags - parse the latency flags from the record
+ * tep_data_flags - parse the latency flags from the record
  * @pevent: a handle to the pevent
  * @rec: the record to parse
  *
@@ -5279,20 +5265,20 @@ int pevent_data_preempt_count(struct pevent *pevent, struct pevent_record *rec)
  *
  *  Use trace_flag_type enum for the flags (see event-parse.h).
  */
-int pevent_data_flags(struct pevent *pevent, struct pevent_record *rec)
+int tep_data_flags(struct tep_handle *pevent, struct tep_record *rec)
 {
        return parse_common_flags(pevent, rec->data);
 }
 
 /**
- * pevent_data_comm_from_pid - return the command line from PID
+ * tep_data_comm_from_pid - return the command line from PID
  * @pevent: a handle to the pevent
  * @pid: the PID of the task to search for
  *
  * This returns a pointer to the command line that has the given
  * @pid.
  */
-const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid)
+const char *tep_data_comm_from_pid(struct tep_handle *pevent, int pid)
 {
        const char *comm;
 
@@ -5301,7 +5287,7 @@ const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid)
 }
 
 static struct cmdline *
-pid_from_cmdlist(struct pevent *pevent, const char *comm, struct cmdline *next)
+pid_from_cmdlist(struct tep_handle *pevent, const char *comm, struct cmdline *next)
 {
        struct cmdline_list *cmdlist = (struct cmdline_list *)next;
 
@@ -5317,7 +5303,7 @@ pid_from_cmdlist(struct pevent *pevent, const char *comm, struct cmdline *next)
 }
 
 /**
- * pevent_data_pid_from_comm - return the pid from a given comm
+ * tep_data_pid_from_comm - return the pid from a given comm
  * @pevent: a handle to the pevent
  * @comm: the cmdline to find the pid from
  * @next: the cmdline structure to find the next comm
@@ -5329,8 +5315,8 @@ pid_from_cmdlist(struct pevent *pevent, const char *comm, struct cmdline *next)
  * next pid.
  * Also, it does a linear seach, so it may be slow.
  */
-struct cmdline *pevent_data_pid_from_comm(struct pevent *pevent, const char *comm,
-                                         struct cmdline *next)
+struct cmdline *tep_data_pid_from_comm(struct tep_handle *pevent, const char *comm,
+                                      struct cmdline *next)
 {
        struct cmdline *cmdline;
 
@@ -5365,13 +5351,13 @@ struct cmdline *pevent_data_pid_from_comm(struct pevent *pevent, const char *com
 }
 
 /**
- * pevent_cmdline_pid - return the pid associated to a given cmdline
+ * tep_cmdline_pid - return the pid associated to a given cmdline
  * @cmdline: The cmdline structure to get the pid from
  *
  * Returns the pid for a give cmdline. If @cmdline is NULL, then
  * -1 is returned.
  */
-int pevent_cmdline_pid(struct pevent *pevent, struct cmdline *cmdline)
+int tep_cmdline_pid(struct tep_handle *pevent, struct cmdline *cmdline)
 {
        struct cmdline_list *cmdlist = (struct cmdline_list *)cmdline;
 
@@ -5391,7 +5377,7 @@ int pevent_cmdline_pid(struct pevent *pevent, struct cmdline *cmdline)
 }
 
 /**
- * pevent_data_comm_from_pid - parse the data into the print format
+ * tep_event_info - parse the data into the print format
  * @s: the trace_seq to write to
  * @event: the handle to the event
  * @record: the record to read from
@@ -5399,13 +5385,13 @@ int pevent_cmdline_pid(struct pevent *pevent, struct cmdline *cmdline)
  * This parses the raw @data using the given @event information and
  * writes the print format into the trace_seq.
  */
-void pevent_event_info(struct trace_seq *s, struct event_format *event,
-                      struct pevent_record *record)
+void tep_event_info(struct trace_seq *s, struct event_format *event,
+                   struct tep_record *record)
 {
        int print_pretty = 1;
 
        if (event->pevent->print_raw || (event->flags & EVENT_FL_PRINTRAW))
-               pevent_print_fields(s, record->data, record->size, event);
+               tep_print_fields(s, record->data, record->size, event);
        else {
 
                if (event->handler && !(event->flags & EVENT_FL_NOHANDLE))
@@ -5433,7 +5419,7 @@ static bool is_timestamp_in_us(char *trace_clock, bool use_trace_clock)
 }
 
 /**
- * pevent_find_event_by_record - return the event from a given record
+ * tep_find_event_by_record - return the event from a given record
  * @pevent: a handle to the pevent
  * @record: The record to get the event from
  *
@@ -5441,7 +5427,7 @@ static bool is_timestamp_in_us(char *trace_clock, bool use_trace_clock)
  * is found.
  */
 struct event_format *
-pevent_find_event_by_record(struct pevent *pevent, struct pevent_record *record)
+tep_find_event_by_record(struct tep_handle *pevent, struct tep_record *record)
 {
        int type;
 
@@ -5452,11 +5438,11 @@ pevent_find_event_by_record(struct pevent *pevent, struct pevent_record *record)
 
        type = trace_parse_common_type(pevent, record->data);
 
-       return pevent_find_event(pevent, type);
+       return tep_find_event(pevent, type);
 }
 
 /**
- * pevent_print_event_task - Write the event task comm, pid and CPU
+ * tep_print_event_task - Write the event task comm, pid and CPU
  * @pevent: a handle to the pevent
  * @s: the trace_seq to write to
  * @event: the handle to the record's event
@@ -5464,9 +5450,9 @@ pevent_find_event_by_record(struct pevent *pevent, struct pevent_record *record)
  *
  * Writes the tasks comm, pid and CPU to @s.
  */
-void pevent_print_event_task(struct pevent *pevent, struct trace_seq *s,
-                            struct event_format *event,
-                            struct pevent_record *record)
+void tep_print_event_task(struct tep_handle *pevent, struct trace_seq *s,
+                         struct event_format *event,
+                         struct tep_record *record)
 {
        void *data = record->data;
        const char *comm;
@@ -5483,7 +5469,7 @@ void pevent_print_event_task(struct pevent *pevent, struct trace_seq *s,
 }
 
 /**
- * pevent_print_event_time - Write the event timestamp
+ * tep_print_event_time - Write the event timestamp
  * @pevent: a handle to the pevent
  * @s: the trace_seq to write to
  * @event: the handle to the record's event
@@ -5492,10 +5478,10 @@ void pevent_print_event_task(struct pevent *pevent, struct trace_seq *s,
  *
  * Writes the timestamp of the record into @s.
  */
-void pevent_print_event_time(struct pevent *pevent, struct trace_seq *s,
-                            struct event_format *event,
-                            struct pevent_record *record,
-                            bool use_trace_clock)
+void tep_print_event_time(struct tep_handle *pevent, struct trace_seq *s,
+                         struct event_format *event,
+                         struct tep_record *record,
+                         bool use_trace_clock)
 {
        unsigned long secs;
        unsigned long usecs;
@@ -5511,11 +5497,11 @@ void pevent_print_event_time(struct pevent *pevent, struct trace_seq *s,
        }
 
        if (pevent->latency_format) {
-               pevent_data_lat_fmt(pevent, s, record);
+               tep_data_lat_fmt(pevent, s, record);
        }
 
        if (use_usec_format) {
-               if (pevent->flags & PEVENT_NSEC_OUTPUT) {
+               if (pevent->flags & TEP_NSEC_OUTPUT) {
                        usecs = nsecs;
                        p = 9;
                } else {
@@ -5534,7 +5520,7 @@ void pevent_print_event_time(struct pevent *pevent, struct trace_seq *s,
 }
 
 /**
- * pevent_print_event_data - Write the event data section
+ * tep_print_event_data - Write the event data section
  * @pevent: a handle to the pevent
  * @s: the trace_seq to write to
  * @event: the handle to the record's event
@@ -5542,9 +5528,9 @@ void pevent_print_event_time(struct pevent *pevent, struct trace_seq *s,
  *
  * Writes the parsing of the record's data to @s.
  */
-void pevent_print_event_data(struct pevent *pevent, struct trace_seq *s,
-                            struct event_format *event,
-                            struct pevent_record *record)
+void tep_print_event_data(struct tep_handle *pevent, struct trace_seq *s,
+                         struct event_format *event,
+                         struct tep_record *record)
 {
        static const char *spaces = "                    "; /* 20 spaces */
        int len;
@@ -5556,15 +5542,15 @@ void pevent_print_event_data(struct pevent *pevent, struct trace_seq *s,
        if (len < 20)
                trace_seq_printf(s, "%.*s", 20 - len, spaces);
 
-       pevent_event_info(s, event, record);
+       tep_event_info(s, event, record);
 }
 
-void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
-                       struct pevent_record *record, bool use_trace_clock)
+void tep_print_event(struct tep_handle *pevent, struct trace_seq *s,
+                    struct tep_record *record, bool use_trace_clock)
 {
        struct event_format *event;
 
-       event = pevent_find_event_by_record(pevent, record);
+       event = tep_find_event_by_record(pevent, record);
        if (!event) {
                int i;
                int type = trace_parse_common_type(pevent, record->data);
@@ -5577,9 +5563,9 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
                return;
        }
 
-       pevent_print_event_task(pevent, s, event, record);
-       pevent_print_event_time(pevent, s, event, record, use_trace_clock);
-       pevent_print_event_data(pevent, s, event, record);
+       tep_print_event_task(pevent, s, event, record);
+       tep_print_event_time(pevent, s, event, record, use_trace_clock);
+       tep_print_event_data(pevent, s, event, record);
 }
 
 static int events_id_cmp(const void *a, const void *b)
@@ -5630,7 +5616,7 @@ static int events_system_cmp(const void *a, const void *b)
        return events_id_cmp(a, b);
 }
 
-struct event_format **pevent_list_events(struct pevent *pevent, enum event_sort_type sort_type)
+struct event_format **tep_list_events(struct tep_handle *pevent, enum event_sort_type sort_type)
 {
        struct event_format **events;
        int (*sort)(const void *a, const void *b);
@@ -5709,13 +5695,13 @@ get_event_fields(const char *type, const char *name,
 }
 
 /**
- * pevent_event_common_fields - return a list of common fields for an event
+ * tep_event_common_fields - return a list of common fields for an event
  * @event: the event to return the common fields of.
  *
  * Returns an allocated array of fields. The last item in the array is NULL.
  * The array must be freed with free().
  */
-struct format_field **pevent_event_common_fields(struct event_format *event)
+struct format_field **tep_event_common_fields(struct event_format *event)
 {
        return get_event_fields("common", event->name,
                                event->format.nr_common,
@@ -5723,13 +5709,13 @@ struct format_field **pevent_event_common_fields(struct event_format *event)
 }
 
 /**
- * pevent_event_fields - return a list of event specific fields for an event
+ * tep_event_fields - return a list of event specific fields for an event
  * @event: the event to return the fields of.
  *
  * Returns an allocated array of fields. The last item in the array is NULL.
  * The array must be freed with free().
  */
-struct format_field **pevent_event_fields(struct event_format *event)
+struct format_field **tep_event_fields(struct event_format *event)
 {
        return get_event_fields("event", event->name,
                                event->format.nr_fields,
@@ -5930,7 +5916,7 @@ static void parse_header_field(const char *field,
 }
 
 /**
- * pevent_parse_header_page - parse the data stored in the header page
+ * tep_parse_header_page - parse the data stored in the header page
  * @pevent: the handle to the pevent
  * @buf: the buffer storing the header page format string
  * @size: the size of @buf
@@ -5941,8 +5927,8 @@ static void parse_header_field(const char *field,
  *
  * /sys/kernel/debug/tracing/events/header_page
  */
-int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size,
-                            int long_size)
+int tep_parse_header_page(struct tep_handle *pevent, char *buf, unsigned long size,
+                         int long_size)
 {
        int ignore;
 
@@ -5994,7 +5980,7 @@ static void free_handler(struct event_handler *handle)
        free(handle);
 }
 
-static int find_event_handle(struct pevent *pevent, struct event_format *event)
+static int find_event_handle(struct tep_handle *pevent, struct event_format *event)
 {
        struct event_handler *handle, **next;
 
@@ -6023,7 +6009,7 @@ static int find_event_handle(struct pevent *pevent, struct event_format *event)
 }
 
 /**
- * __pevent_parse_format - parse the event format
+ * __tep_parse_format - parse the event format
  * @buf: the buffer storing the event format string
  * @size: the size of @buf
  * @sys: the system the event belongs to
@@ -6035,9 +6021,9 @@ static int find_event_handle(struct pevent *pevent, struct event_format *event)
  *
  * /sys/kernel/debug/tracing/events/.../.../format
  */
-enum pevent_errno __pevent_parse_format(struct event_format **eventp,
-                                       struct pevent *pevent, const char *buf,
-                                       unsigned long size, const char *sys)
+enum tep_errno __tep_parse_format(struct event_format **eventp,
+                                 struct tep_handle *pevent, const char *buf,
+                                 unsigned long size, const char *sys)
 {
        struct event_format *event;
        int ret;
@@ -6046,12 +6032,12 @@ enum pevent_errno __pevent_parse_format(struct event_format **eventp,
 
        *eventp = event = alloc_event();
        if (!event)
-               return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+               return TEP_ERRNO__MEM_ALLOC_FAILED;
 
        event->name = event_read_name();
        if (!event->name) {
                /* Bad event? */
-               ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
+               ret = TEP_ERRNO__MEM_ALLOC_FAILED;
                goto event_alloc_failed;
        }
 
@@ -6064,7 +6050,7 @@ enum pevent_errno __pevent_parse_format(struct event_format **eventp,
                
        event->id = event_read_id();
        if (event->id < 0) {
-               ret = PEVENT_ERRNO__READ_ID_FAILED;
+               ret = TEP_ERRNO__READ_ID_FAILED;
                /*
                 * This isn't an allocation error actually.
                 * But as the ID is critical, just bail out.
@@ -6074,7 +6060,7 @@ enum pevent_errno __pevent_parse_format(struct event_format **eventp,
 
        event->system = strdup(sys);
        if (!event->system) {
-               ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
+               ret = TEP_ERRNO__MEM_ALLOC_FAILED;
                goto event_alloc_failed;
        }
 
@@ -6083,7 +6069,7 @@ enum pevent_errno __pevent_parse_format(struct event_format **eventp,
 
        ret = event_read_format(event);
        if (ret < 0) {
-               ret = PEVENT_ERRNO__READ_FORMAT_FAILED;
+               ret = TEP_ERRNO__READ_FORMAT_FAILED;
                goto event_parse_failed;
        }
 
@@ -6098,7 +6084,7 @@ enum pevent_errno __pevent_parse_format(struct event_format **eventp,
        show_warning = 1;
 
        if (ret < 0) {
-               ret = PEVENT_ERRNO__READ_PRINT_FAILED;
+               ret = TEP_ERRNO__READ_PRINT_FAILED;
                goto event_parse_failed;
        }
 
@@ -6112,14 +6098,14 @@ enum pevent_errno __pevent_parse_format(struct event_format **eventp,
                        arg = alloc_arg();
                        if (!arg) {
                                event->flags |= EVENT_FL_FAILED;
-                               return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED;
+                               return TEP_ERRNO__OLD_FTRACE_ARG_FAILED;
                        }
                        arg->type = PRINT_FIELD;
                        arg->field.name = strdup(field->name);
                        if (!arg->field.name) {
                                event->flags |= EVENT_FL_FAILED;
                                free_arg(arg);
-                               return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED;
+                               return TEP_ERRNO__OLD_FTRACE_ARG_FAILED;
                        }
                        arg->field.field = field;
                        *list = arg;
@@ -6142,20 +6128,20 @@ enum pevent_errno __pevent_parse_format(struct event_format **eventp,
        return ret;
 }
 
-static enum pevent_errno
-__pevent_parse_event(struct pevent *pevent,
-                    struct event_format **eventp,
-                    const char *buf, unsigned long size,
-                    const char *sys)
+static enum tep_errno
+__parse_event(struct tep_handle *pevent,
+             struct event_format **eventp,
+             const char *buf, unsigned long size,
+             const char *sys)
 {
-       int ret = __pevent_parse_format(eventp, pevent, buf, size, sys);
+       int ret = __tep_parse_format(eventp, pevent, buf, size, sys);
        struct event_format *event = *eventp;
 
        if (event == NULL)
                return ret;
 
        if (pevent && add_event(pevent, event)) {
-               ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
+               ret = TEP_ERRNO__MEM_ALLOC_FAILED;
                goto event_add_failed;
        }
 
@@ -6166,12 +6152,12 @@ __pevent_parse_event(struct pevent *pevent,
        return 0;
 
 event_add_failed:
-       pevent_free_format(event);
+       tep_free_format(event);
        return ret;
 }
 
 /**
- * pevent_parse_format - parse the event format
+ * tep_parse_format - parse the event format
  * @pevent: the handle to the pevent
  * @eventp: returned format
  * @buf: the buffer storing the event format string
@@ -6185,16 +6171,16 @@ event_add_failed:
  *
  * /sys/kernel/debug/tracing/events/.../.../format
  */
-enum pevent_errno pevent_parse_format(struct pevent *pevent,
-                                     struct event_format **eventp,
-                                     const char *buf,
-                                     unsigned long size, const char *sys)
+enum tep_errno tep_parse_format(struct tep_handle *pevent,
+                               struct event_format **eventp,
+                               const char *buf,
+                               unsigned long size, const char *sys)
 {
-       return __pevent_parse_event(pevent, eventp, buf, size, sys);
+       return __parse_event(pevent, eventp, buf, size, sys);
 }
 
 /**
- * pevent_parse_event - parse the event format
+ * tep_parse_event - parse the event format
  * @pevent: the handle to the pevent
  * @buf: the buffer storing the event format string
  * @size: the size of @buf
@@ -6207,22 +6193,22 @@ enum pevent_errno pevent_parse_format(struct pevent *pevent,
  *
  * /sys/kernel/debug/tracing/events/.../.../format
  */
-enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
-                                    unsigned long size, const char *sys)
+enum tep_errno tep_parse_event(struct tep_handle *pevent, const char *buf,
+                              unsigned long size, const char *sys)
 {
        struct event_format *event = NULL;
-       return __pevent_parse_event(pevent, &event, buf, size, sys);
+       return __parse_event(pevent, &event, buf, size, sys);
 }
 
 #undef _PE
 #define _PE(code, str) str
-static const char * const pevent_error_str[] = {
-       PEVENT_ERRORS
+static const char * const tep_error_str[] = {
+       TEP_ERRORS
 };
 #undef _PE
 
-int pevent_strerror(struct pevent *pevent __maybe_unused,
-                   enum pevent_errno errnum, char *buf, size_t buflen)
+int tep_strerror(struct tep_handle *pevent __maybe_unused,
+                enum tep_errno errnum, char *buf, size_t buflen)
 {
        int idx;
        const char *msg;
@@ -6232,19 +6218,19 @@ int pevent_strerror(struct pevent *pevent __maybe_unused,
                return 0;
        }
 
-       if (errnum <= __PEVENT_ERRNO__START ||
-           errnum >= __PEVENT_ERRNO__END)
+       if (errnum <= __TEP_ERRNO__START ||
+           errnum >= __TEP_ERRNO__END)
                return -1;
 
-       idx = errnum - __PEVENT_ERRNO__START - 1;
-       msg = pevent_error_str[idx];
+       idx = errnum - __TEP_ERRNO__START - 1;
+       msg = tep_error_str[idx];
        snprintf(buf, buflen, "%s", msg);
 
        return 0;
 }
 
 int get_field_val(struct trace_seq *s, struct format_field *field,
-                 const char *name, struct pevent_record *record,
+                 const char *name, struct tep_record *record,
                  unsigned long long *val, int err)
 {
        if (!field) {
@@ -6253,7 +6239,7 @@ int get_field_val(struct trace_seq *s, struct format_field *field,
                return -1;
        }
 
-       if (pevent_read_number_field(field, record->data, val)) {
+       if (tep_read_number_field(field, record->data, val)) {
                if (err)
                        trace_seq_printf(s, " %s=INVALID", name);
                return -1;
@@ -6263,7 +6249,7 @@ int get_field_val(struct trace_seq *s, struct format_field *field,
 }
 
 /**
- * pevent_get_field_raw - return the raw pointer into the data field
+ * tep_get_field_raw - return the raw pointer into the data field
  * @s: The seq to print to on error
  * @event: the event that the field is for
  * @name: The name of the field
@@ -6276,9 +6262,9 @@ int get_field_val(struct trace_seq *s, struct format_field *field,
  *
  * On failure, it returns NULL.
  */
-void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
-                          const char *name, struct pevent_record *record,
-                          int *len, int err)
+void *tep_get_field_raw(struct trace_seq *s, struct event_format *event,
+                       const char *name, struct tep_record *record,
+                       int *len, int err)
 {
        struct format_field *field;
        void *data = record->data;
@@ -6288,7 +6274,7 @@ void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
        if (!event)
                return NULL;
 
-       field = pevent_find_field(event, name);
+       field = tep_find_field(event, name);
 
        if (!field) {
                if (err)
@@ -6302,7 +6288,7 @@ void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
 
        offset = field->offset;
        if (field->flags & FIELD_IS_DYNAMIC) {
-               offset = pevent_read_number(event->pevent,
+               offset = tep_read_number(event->pevent,
                                            data + offset, field->size);
                *len = offset >> 16;
                offset &= 0xffff;
@@ -6313,7 +6299,7 @@ void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
 }
 
 /**
- * pevent_get_field_val - find a field and return its value
+ * tep_get_field_val - find a field and return its value
  * @s: The seq to print to on error
  * @event: the event that the field is for
  * @name: The name of the field
@@ -6323,22 +6309,22 @@ void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
  *
  * Returns 0 on success -1 on field not found.
  */
-int pevent_get_field_val(struct trace_seq *s, struct event_format *event,
-                        const char *name, struct pevent_record *record,
-                        unsigned long long *val, int err)
+int tep_get_field_val(struct trace_seq *s, struct event_format *event,
+                     const char *name, struct tep_record *record,
+                     unsigned long long *val, int err)
 {
        struct format_field *field;
 
        if (!event)
                return -1;
 
-       field = pevent_find_field(event, name);
+       field = tep_find_field(event, name);
 
        return get_field_val(s, field, name, record, val, err);
 }
 
 /**
- * pevent_get_common_field_val - find a common field and return its value
+ * tep_get_common_field_val - find a common field and return its value
  * @s: The seq to print to on error
  * @event: the event that the field is for
  * @name: The name of the field
@@ -6348,22 +6334,22 @@ int pevent_get_field_val(struct trace_seq *s, struct event_format *event,
  *
  * Returns 0 on success -1 on field not found.
  */
-int pevent_get_common_field_val(struct trace_seq *s, struct event_format *event,
-                               const char *name, struct pevent_record *record,
-                               unsigned long long *val, int err)
+int tep_get_common_field_val(struct trace_seq *s, struct event_format *event,
+                            const char *name, struct tep_record *record,
+                            unsigned long long *val, int err)
 {
        struct format_field *field;
 
        if (!event)
                return -1;
 
-       field = pevent_find_common_field(event, name);
+       field = tep_find_common_field(event, name);
 
        return get_field_val(s, field, name, record, val, err);
 }
 
 /**
- * pevent_get_any_field_val - find a any field and return its value
+ * tep_get_any_field_val - find a any field and return its value
  * @s: The seq to print to on error
  * @event: the event that the field is for
  * @name: The name of the field
@@ -6373,22 +6359,22 @@ int pevent_get_common_field_val(struct trace_seq *s, struct event_format *event,
  *
  * Returns 0 on success -1 on field not found.
  */
-int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event,
-                            const char *name, struct pevent_record *record,
-                            unsigned long long *val, int err)
+int tep_get_any_field_val(struct trace_seq *s, struct event_format *event,
+                         const char *name, struct tep_record *record,
+                         unsigned long long *val, int err)
 {
        struct format_field *field;
 
        if (!event)
                return -1;
 
-       field = pevent_find_any_field(event, name);
+       field = tep_find_any_field(event, name);
 
        return get_field_val(s, field, name, record, val, err);
 }
 
 /**
- * pevent_print_num_field - print a field and a format
+ * tep_print_num_field - print a field and a format
  * @s: The seq to print to
  * @fmt: The printf format to print the field with.
  * @event: the event that the field is for
@@ -6398,17 +6384,17 @@ int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event,
  *
  * Returns: 0 on success, -1 field not found, or 1 if buffer is full.
  */
-int pevent_print_num_field(struct trace_seq *s, const char *fmt,
-                          struct event_format *event, const char *name,
-                          struct pevent_record *record, int err)
+int tep_print_num_field(struct trace_seq *s, const char *fmt,
+                       struct event_format *event, const char *name,
+                       struct tep_record *record, int err)
 {
-       struct format_field *field = pevent_find_field(event, name);
+       struct format_field *field = tep_find_field(event, name);
        unsigned long long val;
 
        if (!field)
                goto failed;
 
-       if (pevent_read_number_field(field, record->data, &val))
+       if (tep_read_number_field(field, record->data, &val))
                goto failed;
 
        return trace_seq_printf(s, fmt, val);
@@ -6420,7 +6406,7 @@ int pevent_print_num_field(struct trace_seq *s, const char *fmt,
 }
 
 /**
- * pevent_print_func_field - print a field and a format for function pointers
+ * tep_print_func_field - print a field and a format for function pointers
  * @s: The seq to print to
  * @fmt: The printf format to print the field with.
  * @event: the event that the field is for
@@ -6430,12 +6416,12 @@ int pevent_print_num_field(struct trace_seq *s, const char *fmt,
  *
  * Returns: 0 on success, -1 field not found, or 1 if buffer is full.
  */
-int pevent_print_func_field(struct trace_seq *s, const char *fmt,
-                           struct event_format *event, const char *name,
-                           struct pevent_record *record, int err)
+int tep_print_func_field(struct trace_seq *s, const char *fmt,
+                        struct event_format *event, const char *name,
+                        struct tep_record *record, int err)
 {
-       struct format_field *field = pevent_find_field(event, name);
-       struct pevent *pevent = event->pevent;
+       struct format_field *field = tep_find_field(event, name);
+       struct tep_handle *pevent = event->pevent;
        unsigned long long val;
        struct func_map *func;
        char tmp[128];
@@ -6443,7 +6429,7 @@ int pevent_print_func_field(struct trace_seq *s, const char *fmt,
        if (!field)
                goto failed;
 
-       if (pevent_read_number_field(field, record->data, &val))
+       if (tep_read_number_field(field, record->data, &val))
                goto failed;
 
        func = find_func(pevent, val);
@@ -6461,9 +6447,9 @@ int pevent_print_func_field(struct trace_seq *s, const char *fmt,
        return -1;
 }
 
-static void free_func_handle(struct pevent_function_handler *func)
+static void free_func_handle(struct tep_function_handler *func)
 {
-       struct pevent_func_params *params;
+       struct func_params *params;
 
        free(func->name);
 
@@ -6477,29 +6463,29 @@ static void free_func_handle(struct pevent_function_handler *func)
 }
 
 /**
- * pevent_register_print_function - register a helper function
+ * tep_register_print_function - register a helper function
  * @pevent: the handle to the pevent
  * @func: the function to process the helper function
  * @ret_type: the return type of the helper function
  * @name: the name of the helper function
- * @parameters: A list of enum pevent_func_arg_type
+ * @parameters: A list of enum tep_func_arg_type
  *
  * Some events may have helper functions in the print format arguments.
  * This allows a plugin to dynamically create a way to process one
  * of these functions.
  *
- * The @parameters is a variable list of pevent_func_arg_type enums that
- * must end with PEVENT_FUNC_ARG_VOID.
+ * The @parameters is a variable list of tep_func_arg_type enums that
+ * must end with TEP_FUNC_ARG_VOID.
  */
-int pevent_register_print_function(struct pevent *pevent,
-                                  pevent_func_handler func,
-                                  enum pevent_func_arg_type ret_type,
-                                  char *name, ...)
-{
-       struct pevent_function_handler *func_handle;
-       struct pevent_func_params **next_param;
-       struct pevent_func_params *param;
-       enum pevent_func_arg_type type;
+int tep_register_print_function(struct tep_handle *pevent,
+                               tep_func_handler func,
+                               enum tep_func_arg_type ret_type,
+                               char *name, ...)
+{
+       struct tep_function_handler *func_handle;
+       struct func_params **next_param;
+       struct func_params *param;
+       enum tep_func_arg_type type;
        va_list ap;
        int ret;
 
@@ -6517,7 +6503,7 @@ int pevent_register_print_function(struct pevent *pevent,
        func_handle = calloc(1, sizeof(*func_handle));
        if (!func_handle) {
                do_warning("Failed to allocate function handler");
-               return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+               return TEP_ERRNO__MEM_ALLOC_FAILED;
        }
 
        func_handle->ret_type = ret_type;
@@ -6526,26 +6512,26 @@ int pevent_register_print_function(struct pevent *pevent,
        if (!func_handle->name) {
                do_warning("Failed to allocate function name");
                free(func_handle);
-               return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+               return TEP_ERRNO__MEM_ALLOC_FAILED;
        }
 
        next_param = &(func_handle->params);
        va_start(ap, name);
        for (;;) {
-               type = va_arg(ap, enum pevent_func_arg_type);
-               if (type == PEVENT_FUNC_ARG_VOID)
+               type = va_arg(ap, enum tep_func_arg_type);
+               if (type == TEP_FUNC_ARG_VOID)
                        break;
 
-               if (type >= PEVENT_FUNC_ARG_MAX_TYPES) {
+               if (type >= TEP_FUNC_ARG_MAX_TYPES) {
                        do_warning("Invalid argument type %d", type);
-                       ret = PEVENT_ERRNO__INVALID_ARG_TYPE;
+                       ret = TEP_ERRNO__INVALID_ARG_TYPE;
                        goto out_free;
                }
 
                param = malloc(sizeof(*param));
                if (!param) {
                        do_warning("Failed to allocate function param");
-                       ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
+                       ret = TEP_ERRNO__MEM_ALLOC_FAILED;
                        goto out_free;
                }
                param->type = type;
@@ -6569,7 +6555,7 @@ int pevent_register_print_function(struct pevent *pevent,
 }
 
 /**
- * pevent_unregister_print_function - unregister a helper function
+ * tep_unregister_print_function - unregister a helper function
  * @pevent: the handle to the pevent
  * @func: the function to process the helper function
  * @name: the name of the helper function
@@ -6578,10 +6564,10 @@ int pevent_register_print_function(struct pevent *pevent,
  *
  * Returns 0 if the handler was removed successully, -1 otherwise.
  */
-int pevent_unregister_print_function(struct pevent *pevent,
-                                    pevent_func_handler func, char *name)
+int tep_unregister_print_function(struct tep_handle *pevent,
+                                 tep_func_handler func, char *name)
 {
-       struct pevent_function_handler *func_handle;
+       struct tep_function_handler *func_handle;
 
        func_handle = find_func_handler(pevent, name);
        if (func_handle && func_handle->func == func) {
@@ -6591,15 +6577,15 @@ int pevent_unregister_print_function(struct pevent *pevent,
        return -1;
 }
 
-static struct event_format *pevent_search_event(struct pevent *pevent, int id,
-                                               const char *sys_name,
-                                               const char *event_name)
+static struct event_format *search_event(struct tep_handle *pevent, int id,
+                                        const char *sys_name,
+                                        const char *event_name)
 {
        struct event_format *event;
 
        if (id >= 0) {
                /* search by id */
-               event = pevent_find_event(pevent, id);
+               event = tep_find_event(pevent, id);
                if (!event)
                        return NULL;
                if (event_name && (strcmp(event_name, event->name) != 0))
@@ -6607,7 +6593,7 @@ static struct event_format *pevent_search_event(struct pevent *pevent, int id,
                if (sys_name && (strcmp(sys_name, event->system) != 0))
                        return NULL;
        } else {
-               event = pevent_find_event_by_name(pevent, sys_name, event_name);
+               event = tep_find_event_by_name(pevent, sys_name, event_name);
                if (!event)
                        return NULL;
        }
@@ -6615,7 +6601,7 @@ static struct event_format *pevent_search_event(struct pevent *pevent, int id,
 }
 
 /**
- * pevent_register_event_handler - register a way to parse an event
+ * tep_register_event_handler - register a way to parse an event
  * @pevent: the handle to the pevent
  * @id: the id of the event to register
  * @sys_name: the system name the event belongs to
@@ -6631,14 +6617,14 @@ static struct event_format *pevent_search_event(struct pevent *pevent, int id,
  * If @id is >= 0, then it is used to find the event.
  * else @sys_name and @event_name are used.
  */
-int pevent_register_event_handler(struct pevent *pevent, int id,
-                                 const char *sys_name, const char *event_name,
-                                 pevent_event_handler_func func, void *context)
+int tep_register_event_handler(struct tep_handle *pevent, int id,
+                              const char *sys_name, const char *event_name,
+                              tep_event_handler_func func, void *context)
 {
        struct event_format *event;
        struct event_handler *handle;
 
-       event = pevent_search_event(pevent, id, sys_name, event_name);
+       event = search_event(pevent, id, sys_name, event_name);
        if (event == NULL)
                goto not_found;
 
@@ -6654,7 +6640,7 @@ int pevent_register_event_handler(struct pevent *pevent, int id,
        handle = calloc(1, sizeof(*handle));
        if (!handle) {
                do_warning("Failed to allocate event handler");
-               return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+               return TEP_ERRNO__MEM_ALLOC_FAILED;
        }
 
        handle->id = id;
@@ -6669,7 +6655,7 @@ int pevent_register_event_handler(struct pevent *pevent, int id,
                free((void *)handle->event_name);
                free((void *)handle->sys_name);
                free(handle);
-               return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+               return TEP_ERRNO__MEM_ALLOC_FAILED;
        }
 
        handle->func = func;
@@ -6682,7 +6668,7 @@ int pevent_register_event_handler(struct pevent *pevent, int id,
 
 static int handle_matches(struct event_handler *handler, int id,
                          const char *sys_name, const char *event_name,
-                         pevent_event_handler_func func, void *context)
+                         tep_event_handler_func func, void *context)
 {
        if (id >= 0 && id != handler->id)
                return 0;
@@ -6700,7 +6686,7 @@ static int handle_matches(struct event_handler *handler, int id,
 }
 
 /**
- * pevent_unregister_event_handler - unregister an existing event handler
+ * tep_unregister_event_handler - unregister an existing event handler
  * @pevent: the handle to the pevent
  * @id: the id of the event to unregister
  * @sys_name: the system name the handler belongs to
@@ -6715,15 +6701,15 @@ static int handle_matches(struct event_handler *handler, int id,
  *
  * Returns 0 if handler was removed successfully, -1 if event was not found.
  */
-int pevent_unregister_event_handler(struct pevent *pevent, int id,
-                                   const char *sys_name, const char *event_name,
-                                   pevent_event_handler_func func, void *context)
+int tep_unregister_event_handler(struct tep_handle *pevent, int id,
+                                const char *sys_name, const char *event_name,
+                                tep_event_handler_func func, void *context)
 {
        struct event_format *event;
        struct event_handler *handle;
        struct event_handler **next;
 
-       event = pevent_search_event(pevent, id, sys_name, event_name);
+       event = search_event(pevent, id, sys_name, event_name);
        if (event == NULL)
                goto not_found;
 
@@ -6754,11 +6740,11 @@ not_found:
 }
 
 /**
- * pevent_alloc - create a pevent handle
+ * tep_alloc - create a pevent handle
  */
-struct pevent *pevent_alloc(void)
+struct tep_handle *tep_alloc(void)
 {
-       struct pevent *pevent = calloc(1, sizeof(*pevent));
+       struct tep_handle *pevent = calloc(1, sizeof(*pevent));
 
        if (pevent)
                pevent->ref_count = 1;
@@ -6766,12 +6752,12 @@ struct pevent *pevent_alloc(void)
        return pevent;
 }
 
-void pevent_ref(struct pevent *pevent)
+void tep_ref(struct tep_handle *pevent)
 {
        pevent->ref_count++;
 }
 
-void pevent_free_format_field(struct format_field *field)
+void tep_free_format_field(struct format_field *field)
 {
        free(field->type);
        if (field->alias != field->name)
@@ -6786,7 +6772,7 @@ static void free_format_fields(struct format_field *field)
 
        while (field) {
                next = field->next;
-               pevent_free_format_field(field);
+               tep_free_format_field(field);
                field = next;
        }
 }
@@ -6797,7 +6783,7 @@ static void free_formats(struct format *format)
        free_format_fields(format->fields);
 }
 
-void pevent_free_format(struct event_format *event)
+void tep_free_format(struct event_format *event)
 {
        free(event->name);
        free(event->system);
@@ -6811,15 +6797,15 @@ void pevent_free_format(struct event_format *event)
 }
 
 /**
- * pevent_free - free a pevent handle
+ * tep_free - free a pevent handle
  * @pevent: the pevent handle to free
  */
-void pevent_free(struct pevent *pevent)
+void tep_free(struct tep_handle *pevent)
 {
        struct cmdline_list *cmdlist, *cmdnext;
        struct func_list *funclist, *funcnext;
        struct printk_list *printklist, *printknext;
-       struct pevent_function_handler *func_handler;
+       struct tep_function_handler *func_handler;
        struct event_handler *handle;
        int i;
 
@@ -6883,7 +6869,7 @@ void pevent_free(struct pevent *pevent)
        }
 
        for (i = 0; i < pevent->nr_events; i++)
-               pevent_free_format(pevent->events[i]);
+               tep_free_format(pevent->events[i]);
 
        while (pevent->handlers) {
                handle = pevent->handlers;
@@ -6899,7 +6885,7 @@ void pevent_free(struct pevent *pevent)
        free(pevent);
 }
 
-void pevent_unref(struct pevent *pevent)
+void tep_unref(struct tep_handle *pevent)
 {
-       pevent_free(pevent);
+       tep_free(pevent);
 }
index 0c03538df74c01a1ecedc353e21b6c81083ee1e1..44b7c2d41f9fca7f912008ad743f7f5105f74751 100644 (file)
@@ -41,7 +41,7 @@
 #define DEBUG_RECORD 0
 #endif
 
-struct pevent_record {
+struct tep_record {
        unsigned long long      ts;
        unsigned long long      offset;
        long long               missed_events;  /* buffer dropped events before */
@@ -53,8 +53,8 @@ struct pevent_record {
        int                     locked;         /* Do not free, even if ref_count is zero */
        void                    *priv;
 #if DEBUG_RECORD
-       struct pevent_record    *prev;
-       struct pevent_record    *next;
+       struct tep_record       *prev;
+       struct tep_record       *next;
        long                    alloc_addr;
 #endif
 };
@@ -98,19 +98,19 @@ extern int trace_seq_do_printf(struct trace_seq *s);
 
 /* ----------------------- pevent ----------------------- */
 
-struct pevent;
+struct tep_handle;
 struct event_format;
 
-typedef int (*pevent_event_handler_func)(struct trace_seq *s,
-                                        struct pevent_record *record,
-                                        struct event_format *event,
-                                        void *context);
+typedef int (*tep_event_handler_func)(struct trace_seq *s,
+                                     struct tep_record *record,
+                                     struct event_format *event,
+                                     void *context);
 
-typedef int (*pevent_plugin_load_func)(struct pevent *pevent);
-typedef int (*pevent_plugin_unload_func)(struct pevent *pevent);
+typedef int (*tep_plugin_load_func)(struct tep_handle *pevent);
+typedef int (*tep_plugin_unload_func)(struct tep_handle *pevent);
 
-struct pevent_plugin_option {
-       struct pevent_plugin_option     *next;
+struct tep_plugin_option {
+       struct tep_plugin_option        *next;
        void                            *handle;
        char                            *file;
        char                            *name;
@@ -124,20 +124,20 @@ struct pevent_plugin_option {
 /*
  * Plugin hooks that can be called:
  *
- * PEVENT_PLUGIN_LOADER:  (required)
+ * TEP_PLUGIN_LOADER:  (required)
  *   The function name to initialized the plugin.
  *
- *   int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+ *   int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
  *
- * PEVENT_PLUGIN_UNLOADER:  (optional)
+ * TEP_PLUGIN_UNLOADER:  (optional)
  *   The function called just before unloading
  *
- *   int PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
+ *   int TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
  *
- * PEVENT_PLUGIN_OPTIONS:  (optional)
+ * TEP_PLUGIN_OPTIONS:  (optional)
  *   Plugin options that can be set before loading
  *
- *   struct pevent_plugin_option PEVENT_PLUGIN_OPTIONS[] = {
+ *   struct tep_plugin_option TEP_PLUGIN_OPTIONS[] = {
  *     {
  *             .name = "option-name",
  *             .plugin_alias = "override-file-name", (optional)
@@ -158,19 +158,19 @@ struct pevent_plugin_option {
  *   .set will be processed. If .value is defined, then it is considered
  *   a string option and .set will be ignored.
  *
- * PEVENT_PLUGIN_ALIAS: (optional)
+ * TEP_PLUGIN_ALIAS: (optional)
  *   The name to use for finding options (uses filename if not defined)
  */
-#define PEVENT_PLUGIN_LOADER pevent_plugin_loader
-#define PEVENT_PLUGIN_UNLOADER pevent_plugin_unloader
-#define PEVENT_PLUGIN_OPTIONS pevent_plugin_options
-#define PEVENT_PLUGIN_ALIAS pevent_plugin_alias
+#define TEP_PLUGIN_LOADER tep_plugin_loader
+#define TEP_PLUGIN_UNLOADER tep_plugin_unloader
+#define TEP_PLUGIN_OPTIONS tep_plugin_options
+#define TEP_PLUGIN_ALIAS tep_plugin_alias
 #define _MAKE_STR(x)   #x
 #define MAKE_STR(x)    _MAKE_STR(x)
-#define PEVENT_PLUGIN_LOADER_NAME MAKE_STR(PEVENT_PLUGIN_LOADER)
-#define PEVENT_PLUGIN_UNLOADER_NAME MAKE_STR(PEVENT_PLUGIN_UNLOADER)
-#define PEVENT_PLUGIN_OPTIONS_NAME MAKE_STR(PEVENT_PLUGIN_OPTIONS)
-#define PEVENT_PLUGIN_ALIAS_NAME MAKE_STR(PEVENT_PLUGIN_ALIAS)
+#define TEP_PLUGIN_LOADER_NAME MAKE_STR(TEP_PLUGIN_LOADER)
+#define TEP_PLUGIN_UNLOADER_NAME MAKE_STR(TEP_PLUGIN_UNLOADER)
+#define TEP_PLUGIN_OPTIONS_NAME MAKE_STR(TEP_PLUGIN_OPTIONS)
+#define TEP_PLUGIN_ALIAS_NAME MAKE_STR(TEP_PLUGIN_ALIAS)
 
 enum format_flags {
        FIELD_IS_ARRAY          = 1,
@@ -269,10 +269,10 @@ struct print_arg_op {
        struct print_arg        *right;
 };
 
-struct pevent_function_handler;
+struct tep_function_handler;
 
 struct print_arg_func {
-       struct pevent_function_handler  *func;
+       struct tep_function_handler     *func;
        struct print_arg                *args;
 };
 
@@ -320,14 +320,14 @@ struct print_fmt {
 };
 
 struct event_format {
-       struct pevent           *pevent;
+       struct tep_handle       *pevent;
        char                    *name;
        int                     id;
        int                     flags;
        struct format           format;
        struct print_fmt        print_fmt;
        char                    *system;
-       pevent_event_handler_func handler;
+       tep_event_handler_func  handler;
        void                    *context;
 };
 
@@ -361,25 +361,25 @@ enum event_type {
        EVENT_SQUOTE,
 };
 
-typedef unsigned long long (*pevent_func_handler)(struct trace_seq *s,
-                                            unsigned long long *args);
+typedef unsigned long long (*tep_func_handler)(struct trace_seq *s,
+                                              unsigned long long *args);
 
-enum pevent_func_arg_type {
-       PEVENT_FUNC_ARG_VOID,
-       PEVENT_FUNC_ARG_INT,
-       PEVENT_FUNC_ARG_LONG,
-       PEVENT_FUNC_ARG_STRING,
-       PEVENT_FUNC_ARG_PTR,
-       PEVENT_FUNC_ARG_MAX_TYPES
+enum tep_func_arg_type {
+       TEP_FUNC_ARG_VOID,
+       TEP_FUNC_ARG_INT,
+       TEP_FUNC_ARG_LONG,
+       TEP_FUNC_ARG_STRING,
+       TEP_FUNC_ARG_PTR,
+       TEP_FUNC_ARG_MAX_TYPES
 };
 
-enum pevent_flag {
-       PEVENT_NSEC_OUTPUT              = 1,    /* output in NSECS */
-       PEVENT_DISABLE_SYS_PLUGINS      = 1 << 1,
-       PEVENT_DISABLE_PLUGINS          = 1 << 2,
+enum tep_flag {
+       TEP_NSEC_OUTPUT         = 1,    /* output in NSECS */
+       TEP_DISABLE_SYS_PLUGINS = 1 << 1,
+       TEP_DISABLE_PLUGINS     = 1 << 2,
 };
 
-#define PEVENT_ERRORS                                                        \
+#define TEP_ERRORS                                                           \
        _PE(MEM_ALLOC_FAILED,   "failed to allocate memory"),                 \
        _PE(PARSE_EVENT_FAILED, "failed to parse event"),                     \
        _PE(READ_ID_FAILED,     "failed to read event id"),                   \
@@ -411,10 +411,10 @@ enum pevent_flag {
        _PE(FILTER_MISS,        "record does not match to filter")
 
 #undef _PE
-#define _PE(__code, __str) PEVENT_ERRNO__ ## __code
-enum pevent_errno {
-       PEVENT_ERRNO__SUCCESS                   = 0,
-       PEVENT_ERRNO__FILTER_MATCH              = PEVENT_ERRNO__SUCCESS,
+#define _PE(__code, __str) TEP_ERRNO__ ## __code
+enum tep_errno {
+       TEP_ERRNO__SUCCESS                      = 0,
+       TEP_ERRNO__FILTER_MATCH                 = TEP_ERRNO__SUCCESS,
 
        /*
         * Choose an arbitrary negative big number not to clash with standard
@@ -423,11 +423,11 @@ enum pevent_errno {
         *
         * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
         */
-       __PEVENT_ERRNO__START                   = -100000,
+       __TEP_ERRNO__START                      = -100000,
 
-       PEVENT_ERRORS,
+       TEP_ERRORS,
 
-       __PEVENT_ERRNO__END,
+       __TEP_ERRNO__END,
 };
 #undef _PE
 
@@ -435,17 +435,17 @@ struct plugin_list;
 
 #define INVALID_PLUGIN_LIST_OPTION     ((char **)((unsigned long)-1))
 
-struct plugin_list *traceevent_load_plugins(struct pevent *pevent);
-void traceevent_unload_plugins(struct plugin_list *plugin_list,
-                              struct pevent *pevent);
-char **traceevent_plugin_list_options(void);
-void traceevent_plugin_free_options_list(char **list);
-int traceevent_plugin_add_options(const char *name,
-                                 struct pevent_plugin_option *options);
-void traceevent_plugin_remove_options(struct pevent_plugin_option *options);
-void traceevent_print_plugins(struct trace_seq *s,
-                             const char *prefix, const char *suffix,
-                             const struct plugin_list *list);
+struct plugin_list *tep_load_plugins(struct tep_handle *pevent);
+void tep_unload_plugins(struct plugin_list *plugin_list,
+                       struct tep_handle *pevent);
+char **tep_plugin_list_options(void);
+void tep_plugin_free_options_list(char **list);
+int tep_plugin_add_options(const char *name,
+                          struct tep_plugin_option *options);
+void tep_plugin_remove_options(struct tep_plugin_option *options);
+void tep_print_plugins(struct trace_seq *s,
+                       const char *prefix, const char *suffix,
+                       const struct plugin_list *list);
 
 struct cmdline;
 struct cmdline_list;
@@ -454,10 +454,10 @@ struct func_list;
 struct event_handler;
 struct func_resolver;
 
-typedef char *(pevent_func_resolver_t)(void *priv,
-                                      unsigned long long *addrp, char **modp);
+typedef char *(tep_func_resolver_t)(void *priv,
+                                   unsigned long long *addrp, char **modp);
 
-struct pevent {
+struct tep_handle {
        int ref_count;
 
        int header_page_ts_offset;
@@ -524,7 +524,7 @@ struct pevent {
        struct format_field *bprint_buf_field;
 
        struct event_handler *handlers;
-       struct pevent_function_handler *func_handlers;
+       struct tep_function_handler *func_handlers;
 
        /* cache */
        struct event_format *last_event;
@@ -532,13 +532,13 @@ struct pevent {
        char *trace_clock;
 };
 
-static inline void pevent_set_flag(struct pevent *pevent, int flag)
+static inline void tep_set_flag(struct tep_handle *pevent, int flag)
 {
        pevent->flags |= flag;
 }
 
 static inline unsigned short
-__data2host2(struct pevent *pevent, unsigned short data)
+__data2host2(struct tep_handle *pevent, unsigned short data)
 {
        unsigned short swap;
 
@@ -552,7 +552,7 @@ __data2host2(struct pevent *pevent, unsigned short data)
 }
 
 static inline unsigned int
-__data2host4(struct pevent *pevent, unsigned int data)
+__data2host4(struct tep_handle *pevent, unsigned int data)
 {
        unsigned int swap;
 
@@ -568,7 +568,7 @@ __data2host4(struct pevent *pevent, unsigned int data)
 }
 
 static inline unsigned long long
-__data2host8(struct pevent *pevent, unsigned long long data)
+__data2host8(struct tep_handle *pevent, unsigned long long data)
 {
        unsigned long long swap;
 
@@ -597,7 +597,7 @@ __data2host8(struct pevent *pevent, unsigned long long data)
        __data2host8(pevent, __val);                            \
 })
 
-static inline int traceevent_host_bigendian(void)
+static inline int tep_host_bigendian(void)
 {
        unsigned char str[] = { 0x1, 0x2, 0x3, 0x4 };
        unsigned int val;
@@ -615,198 +615,198 @@ enum trace_flag_type {
        TRACE_FLAG_SOFTIRQ              = 0x10,
 };
 
-int pevent_set_function_resolver(struct pevent *pevent,
-                                pevent_func_resolver_t *func, void *priv);
-void pevent_reset_function_resolver(struct pevent *pevent);
-int pevent_register_comm(struct pevent *pevent, const char *comm, int pid);
-int pevent_register_trace_clock(struct pevent *pevent, const char *trace_clock);
-int pevent_register_function(struct pevent *pevent, char *name,
-                            unsigned long long addr, char *mod);
-int pevent_register_print_string(struct pevent *pevent, const char *fmt,
-                                unsigned long long addr);
-int pevent_pid_is_registered(struct pevent *pevent, int pid);
-
-void pevent_print_event_task(struct pevent *pevent, struct trace_seq *s,
-                            struct event_format *event,
-                            struct pevent_record *record);
-void pevent_print_event_time(struct pevent *pevent, struct trace_seq *s,
-                            struct event_format *event,
-                            struct pevent_record *record,
-                            bool use_trace_clock);
-void pevent_print_event_data(struct pevent *pevent, struct trace_seq *s,
-                            struct event_format *event,
-                            struct pevent_record *record);
-void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
-                       struct pevent_record *record, bool use_trace_clock);
-
-int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size,
-                            int long_size);
-
-enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
-                                    unsigned long size, const char *sys);
-enum pevent_errno pevent_parse_format(struct pevent *pevent,
-                                     struct event_format **eventp,
-                                     const char *buf,
-                                     unsigned long size, const char *sys);
-void pevent_free_format(struct event_format *event);
-void pevent_free_format_field(struct format_field *field);
-
-void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
-                          const char *name, struct pevent_record *record,
-                          int *len, int err);
-
-int pevent_get_field_val(struct trace_seq *s, struct event_format *event,
-                        const char *name, struct pevent_record *record,
-                        unsigned long long *val, int err);
-int pevent_get_common_field_val(struct trace_seq *s, struct event_format *event,
-                               const char *name, struct pevent_record *record,
-                               unsigned long long *val, int err);
-int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event,
-                            const char *name, struct pevent_record *record,
+int tep_set_function_resolver(struct tep_handle *pevent,
+                             tep_func_resolver_t *func, void *priv);
+void tep_reset_function_resolver(struct tep_handle *pevent);
+int tep_register_comm(struct tep_handle *pevent, const char *comm, int pid);
+int tep_register_trace_clock(struct tep_handle *pevent, const char *trace_clock);
+int tep_register_function(struct tep_handle *pevent, char *name,
+                         unsigned long long addr, char *mod);
+int tep_register_print_string(struct tep_handle *pevent, const char *fmt,
+                             unsigned long long addr);
+int tep_pid_is_registered(struct tep_handle *pevent, int pid);
+
+void tep_print_event_task(struct tep_handle *pevent, struct trace_seq *s,
+                         struct event_format *event,
+                         struct tep_record *record);
+void tep_print_event_time(struct tep_handle *pevent, struct trace_seq *s,
+                         struct event_format *event,
+                         struct tep_record *record,
+                         bool use_trace_clock);
+void tep_print_event_data(struct tep_handle *pevent, struct trace_seq *s,
+                         struct event_format *event,
+                         struct tep_record *record);
+void tep_print_event(struct tep_handle *pevent, struct trace_seq *s,
+                    struct tep_record *record, bool use_trace_clock);
+
+int tep_parse_header_page(struct tep_handle *pevent, char *buf, unsigned long size,
+                         int long_size);
+
+enum tep_errno tep_parse_event(struct tep_handle *pevent, const char *buf,
+                              unsigned long size, const char *sys);
+enum tep_errno tep_parse_format(struct tep_handle *pevent,
+                               struct event_format **eventp,
+                               const char *buf,
+                               unsigned long size, const char *sys);
+void tep_free_format(struct event_format *event);
+void tep_free_format_field(struct format_field *field);
+
+void *tep_get_field_raw(struct trace_seq *s, struct event_format *event,
+                       const char *name, struct tep_record *record,
+                       int *len, int err);
+
+int tep_get_field_val(struct trace_seq *s, struct event_format *event,
+                     const char *name, struct tep_record *record,
+                     unsigned long long *val, int err);
+int tep_get_common_field_val(struct trace_seq *s, struct event_format *event,
+                            const char *name, struct tep_record *record,
                             unsigned long long *val, int err);
+int tep_get_any_field_val(struct trace_seq *s, struct event_format *event,
+                         const char *name, struct tep_record *record,
+                         unsigned long long *val, int err);
 
-int pevent_print_num_field(struct trace_seq *s, const char *fmt,
+int tep_print_num_field(struct trace_seq *s, const char *fmt,
                           struct event_format *event, const char *name,
-                          struct pevent_record *record, int err);
-
-int pevent_print_func_field(struct trace_seq *s, const char *fmt,
-                          struct event_format *event, const char *name,
-                          struct pevent_record *record, int err);
-
-int pevent_register_event_handler(struct pevent *pevent, int id,
-                                 const char *sys_name, const char *event_name,
-                                 pevent_event_handler_func func, void *context);
-int pevent_unregister_event_handler(struct pevent *pevent, int id,
-                                   const char *sys_name, const char *event_name,
-                                   pevent_event_handler_func func, void *context);
-int pevent_register_print_function(struct pevent *pevent,
-                                  pevent_func_handler func,
-                                  enum pevent_func_arg_type ret_type,
-                                  char *name, ...);
-int pevent_unregister_print_function(struct pevent *pevent,
-                                    pevent_func_handler func, char *name);
-
-struct format_field *pevent_find_common_field(struct event_format *event, const char *name);
-struct format_field *pevent_find_field(struct event_format *event, const char *name);
-struct format_field *pevent_find_any_field(struct event_format *event, const char *name);
-
-const char *pevent_find_function(struct pevent *pevent, unsigned long long addr);
+                          struct tep_record *record, int err);
+
+int tep_print_func_field(struct trace_seq *s, const char *fmt,
+                        struct event_format *event, const char *name,
+                        struct tep_record *record, int err);
+
+int tep_register_event_handler(struct tep_handle *pevent, int id,
+                              const char *sys_name, const char *event_name,
+                              tep_event_handler_func func, void *context);
+int tep_unregister_event_handler(struct tep_handle *pevent, int id,
+                                const char *sys_name, const char *event_name,
+                                tep_event_handler_func func, void *context);
+int tep_register_print_function(struct tep_handle *pevent,
+                               tep_func_handler func,
+                               enum tep_func_arg_type ret_type,
+                               char *name, ...);
+int tep_unregister_print_function(struct tep_handle *pevent,
+                                 tep_func_handler func, char *name);
+
+struct format_field *tep_find_common_field(struct event_format *event, const char *name);
+struct format_field *tep_find_field(struct event_format *event, const char *name);
+struct format_field *tep_find_any_field(struct event_format *event, const char *name);
+
+const char *tep_find_function(struct tep_handle *pevent, unsigned long long addr);
 unsigned long long
-pevent_find_function_address(struct pevent *pevent, unsigned long long addr);
-unsigned long long pevent_read_number(struct pevent *pevent, const void *ptr, int size);
-int pevent_read_number_field(struct format_field *field, const void *data,
-                            unsigned long long *value);
+tep_find_function_address(struct tep_handle *pevent, unsigned long long addr);
+unsigned long long tep_read_number(struct tep_handle *pevent, const void *ptr, int size);
+int tep_read_number_field(struct format_field *field, const void *data,
+                         unsigned long long *value);
 
-struct event_format *pevent_find_event(struct pevent *pevent, int id);
+struct event_format *tep_find_event(struct tep_handle *pevent, int id);
 
 struct event_format *
-pevent_find_event_by_name(struct pevent *pevent, const char *sys, const char *name);
+tep_find_event_by_name(struct tep_handle *pevent, const char *sys, const char *name);
 
 struct event_format *
-pevent_find_event_by_record(struct pevent *pevent, struct pevent_record *record);
-
-void pevent_data_lat_fmt(struct pevent *pevent,
-                        struct trace_seq *s, struct pevent_record *record);
-int pevent_data_type(struct pevent *pevent, struct pevent_record *rec);
-struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type);
-int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec);
-int pevent_data_preempt_count(struct pevent *pevent, struct pevent_record *rec);
-int pevent_data_flags(struct pevent *pevent, struct pevent_record *rec);
-const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid);
+tep_find_event_by_record(struct tep_handle *pevent, struct tep_record *record);
+
+void tep_data_lat_fmt(struct tep_handle *pevent,
+                     struct trace_seq *s, struct tep_record *record);
+int tep_data_type(struct tep_handle *pevent, struct tep_record *rec);
+struct event_format *tep_data_event_from_type(struct tep_handle *pevent, int type);
+int tep_data_pid(struct tep_handle *pevent, struct tep_record *rec);
+int tep_data_preempt_count(struct tep_handle *pevent, struct tep_record *rec);
+int tep_data_flags(struct tep_handle *pevent, struct tep_record *rec);
+const char *tep_data_comm_from_pid(struct tep_handle *pevent, int pid);
 struct cmdline;
-struct cmdline *pevent_data_pid_from_comm(struct pevent *pevent, const char *comm,
-                                         struct cmdline *next);
-int pevent_cmdline_pid(struct pevent *pevent, struct cmdline *cmdline);
-
-void pevent_print_field(struct trace_seq *s, void *data,
-                       struct format_field *field);
-void pevent_print_fields(struct trace_seq *s, void *data,
-                        int size __maybe_unused, struct event_format *event);
-void pevent_event_info(struct trace_seq *s, struct event_format *event,
-                      struct pevent_record *record);
-int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum,
+struct cmdline *tep_data_pid_from_comm(struct tep_handle *pevent, const char *comm,
+                                      struct cmdline *next);
+int tep_cmdline_pid(struct tep_handle *pevent, struct cmdline *cmdline);
+
+void tep_print_field(struct trace_seq *s, void *data,
+                    struct format_field *field);
+void tep_print_fields(struct trace_seq *s, void *data,
+                     int size __maybe_unused, struct event_format *event);
+void tep_event_info(struct trace_seq *s, struct event_format *event,
+                      struct tep_record *record);
+int tep_strerror(struct tep_handle *pevent, enum tep_errno errnum,
                    char *buf, size_t buflen);
 
-struct event_format **pevent_list_events(struct pevent *pevent, enum event_sort_type);
-struct format_field **pevent_event_common_fields(struct event_format *event);
-struct format_field **pevent_event_fields(struct event_format *event);
+struct event_format **tep_list_events(struct tep_handle *pevent, enum event_sort_type);
+struct format_field **tep_event_common_fields(struct event_format *event);
+struct format_field **tep_event_fields(struct event_format *event);
 
-static inline int pevent_get_cpus(struct pevent *pevent)
+static inline int tep_get_cpus(struct tep_handle *pevent)
 {
        return pevent->cpus;
 }
 
-static inline void pevent_set_cpus(struct pevent *pevent, int cpus)
+static inline void tep_set_cpus(struct tep_handle *pevent, int cpus)
 {
        pevent->cpus = cpus;
 }
 
-static inline int pevent_get_long_size(struct pevent *pevent)
+static inline int tep_get_long_size(struct tep_handle *pevent)
 {
        return pevent->long_size;
 }
 
-static inline void pevent_set_long_size(struct pevent *pevent, int long_size)
+static inline void tep_set_long_size(struct tep_handle *pevent, int long_size)
 {
        pevent->long_size = long_size;
 }
 
-static inline int pevent_get_page_size(struct pevent *pevent)
+static inline int tep_get_page_size(struct tep_handle *pevent)
 {
        return pevent->page_size;
 }
 
-static inline void pevent_set_page_size(struct pevent *pevent, int _page_size)
+static inline void tep_set_page_size(struct tep_handle *pevent, int _page_size)
 {
        pevent->page_size = _page_size;
 }
 
-static inline int pevent_is_file_bigendian(struct pevent *pevent)
+static inline int tep_is_file_bigendian(struct tep_handle *pevent)
 {
        return pevent->file_bigendian;
 }
 
-static inline void pevent_set_file_bigendian(struct pevent *pevent, int endian)
+static inline void tep_set_file_bigendian(struct tep_handle *pevent, int endian)
 {
        pevent->file_bigendian = endian;
 }
 
-static inline int pevent_is_host_bigendian(struct pevent *pevent)
+static inline int tep_is_host_bigendian(struct tep_handle *pevent)
 {
        return pevent->host_bigendian;
 }
 
-static inline void pevent_set_host_bigendian(struct pevent *pevent, int endian)
+static inline void tep_set_host_bigendian(struct tep_handle *pevent, int endian)
 {
        pevent->host_bigendian = endian;
 }
 
-static inline int pevent_is_latency_format(struct pevent *pevent)
+static inline int tep_is_latency_format(struct tep_handle *pevent)
 {
        return pevent->latency_format;
 }
 
-static inline void pevent_set_latency_format(struct pevent *pevent, int lat)
+static inline void tep_set_latency_format(struct tep_handle *pevent, int lat)
 {
        pevent->latency_format = lat;
 }
 
-struct pevent *pevent_alloc(void);
-void pevent_free(struct pevent *pevent);
-void pevent_ref(struct pevent *pevent);
-void pevent_unref(struct pevent *pevent);
+struct tep_handle *tep_alloc(void);
+void tep_free(struct tep_handle *pevent);
+void tep_ref(struct tep_handle *pevent);
+void tep_unref(struct tep_handle *pevent);
 
 /* access to the internal parser */
-void pevent_buffer_init(const char *buf, unsigned long long size);
-enum event_type pevent_read_token(char **tok);
-void pevent_free_token(char *token);
-int pevent_peek_char(void);
-const char *pevent_get_input_buf(void);
-unsigned long long pevent_get_input_buf_ptr(void);
+void tep_buffer_init(const char *buf, unsigned long long size);
+enum event_type tep_read_token(char **tok);
+void tep_free_token(char *token);
+int tep_peek_char(void);
+const char *tep_get_input_buf(void);
+unsigned long long tep_get_input_buf_ptr(void);
 
 /* for debugging */
-void pevent_print_funcs(struct pevent *pevent);
-void pevent_print_printk(struct pevent *pevent);
+void tep_print_funcs(struct tep_handle *pevent);
+void tep_print_printk(struct tep_handle *pevent);
 
 /* ----------------------- filtering ----------------------- */
 
@@ -930,22 +930,22 @@ struct filter_type {
        struct filter_arg       *filter;
 };
 
-#define PEVENT_FILTER_ERROR_BUFSZ  1024
+#define TEP_FILTER_ERROR_BUFSZ  1024
 
 struct event_filter {
-       struct pevent           *pevent;
+       struct tep_handle       *pevent;
        int                     filters;
        struct filter_type      *event_filters;
-       char                    error_buffer[PEVENT_FILTER_ERROR_BUFSZ];
+       char                    error_buffer[TEP_FILTER_ERROR_BUFSZ];
 };
 
-struct event_filter *pevent_filter_alloc(struct pevent *pevent);
+struct event_filter *tep_filter_alloc(struct tep_handle *pevent);
 
 /* for backward compatibility */
-#define FILTER_NONE            PEVENT_ERRNO__NO_FILTER
-#define FILTER_NOEXIST         PEVENT_ERRNO__FILTER_NOT_FOUND
-#define FILTER_MISS            PEVENT_ERRNO__FILTER_MISS
-#define FILTER_MATCH           PEVENT_ERRNO__FILTER_MATCH
+#define FILTER_NONE            TEP_ERRNO__NO_FILTER
+#define FILTER_NOEXIST         TEP_ERRNO__FILTER_NOT_FOUND
+#define FILTER_MISS            TEP_ERRNO__FILTER_MISS
+#define FILTER_MATCH           TEP_ERRNO__FILTER_MATCH
 
 enum filter_trivial_type {
        FILTER_TRIVIAL_FALSE,
@@ -953,39 +953,39 @@ enum filter_trivial_type {
        FILTER_TRIVIAL_BOTH,
 };
 
-enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
-                                              const char *filter_str);
+enum tep_errno tep_filter_add_filter_str(struct event_filter *filter,
+                                        const char *filter_str);
 
-enum pevent_errno pevent_filter_match(struct event_filter *filter,
-                                     struct pevent_record *record);
+enum tep_errno tep_filter_match(struct event_filter *filter,
+                               struct tep_record *record);
 
-int pevent_filter_strerror(struct event_filter *filter, enum pevent_errno err,
-                          char *buf, size_t buflen);
+int tep_filter_strerror(struct event_filter *filter, enum tep_errno err,
+                       char *buf, size_t buflen);
 
-int pevent_event_filtered(struct event_filter *filter,
-                         int event_id);
+int tep_event_filtered(struct event_filter *filter,
+                      int event_id);
 
-void pevent_filter_reset(struct event_filter *filter);
+void tep_filter_reset(struct event_filter *filter);
 
-int pevent_filter_clear_trivial(struct event_filter *filter,
-                                enum filter_trivial_type type);
+int tep_filter_clear_trivial(struct event_filter *filter,
+                            enum filter_trivial_type type);
 
-void pevent_filter_free(struct event_filter *filter);
+void tep_filter_free(struct event_filter *filter);
 
-char *pevent_filter_make_string(struct event_filter *filter, int event_id);
+char *tep_filter_make_string(struct event_filter *filter, int event_id);
 
-int pevent_filter_remove_event(struct event_filter *filter,
-                              int event_id);
+int tep_filter_remove_event(struct event_filter *filter,
+                           int event_id);
 
-int pevent_filter_event_has_trivial(struct event_filter *filter,
-                                   int event_id,
-                                   enum filter_trivial_type type);
+int tep_filter_event_has_trivial(struct event_filter *filter,
+                                int event_id,
+                                enum filter_trivial_type type);
 
-int pevent_filter_copy(struct event_filter *dest, struct event_filter *source);
+int tep_filter_copy(struct event_filter *dest, struct event_filter *source);
 
-int pevent_update_trivial(struct event_filter *dest, struct event_filter *source,
-                         enum filter_trivial_type type);
+int tep_update_trivial(struct event_filter *dest, struct event_filter *source,
+                       enum filter_trivial_type type);
 
-int pevent_filter_compare(struct event_filter *filter1, struct event_filter *filter2);
+int tep_filter_compare(struct event_filter *filter1, struct event_filter *filter2);
 
 #endif /* _PARSE_EVENTS_H */
index d542cb60ca1a94bc54cb54245d219e1159c9e16d..f17e25097e1e2573f218639f601ecb6102f67b8e 100644 (file)
@@ -1,21 +1,7 @@
+// SPDX-License-Identifier: LGPL-2.1
 /*
  * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
  *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License (not later!)
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not,  see <http://www.gnu.org/licenses>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 
 #include <ctype.h>
@@ -34,7 +20,7 @@
 
 static struct registered_plugin_options {
        struct registered_plugin_options        *next;
-       struct pevent_plugin_option             *options;
+       struct tep_plugin_option                *options;
 } *registered_options;
 
 static struct trace_plugin_options {
@@ -58,7 +44,7 @@ static void lower_case(char *str)
                *str = tolower(*str);
 }
 
-static int update_option_value(struct pevent_plugin_option *op, const char *val)
+static int update_option_value(struct tep_plugin_option *op, const char *val)
 {
        char *op_val;
 
@@ -97,7 +83,7 @@ static int update_option_value(struct pevent_plugin_option *op, const char *val)
 }
 
 /**
- * traceevent_plugin_list_options - get list of plugin options
+ * tep_plugin_list_options - get list of plugin options
  *
  * Returns an array of char strings that list the currently registered
  * plugin options in the format of <plugin>:<option>. This list can be
@@ -106,12 +92,12 @@ static int update_option_value(struct pevent_plugin_option *op, const char *val)
  * Returns NULL if there's no options registered. On error it returns
  * INVALID_PLUGIN_LIST_OPTION
  *
- * Must be freed with traceevent_plugin_free_options_list().
+ * Must be freed with tep_plugin_free_options_list().
  */
-char **traceevent_plugin_list_options(void)
+char **tep_plugin_list_options(void)
 {
        struct registered_plugin_options *reg;
-       struct pevent_plugin_option *op;
+       struct tep_plugin_option *op;
        char **list = NULL;
        char *name;
        int count = 0;
@@ -146,7 +132,7 @@ char **traceevent_plugin_list_options(void)
        return INVALID_PLUGIN_LIST_OPTION;
 }
 
-void traceevent_plugin_free_options_list(char **list)
+void tep_plugin_free_options_list(char **list)
 {
        int i;
 
@@ -163,7 +149,7 @@ void traceevent_plugin_free_options_list(char **list)
 }
 
 static int
-update_option(const char *file, struct pevent_plugin_option *option)
+update_option(const char *file, struct tep_plugin_option *option)
 {
        struct trace_plugin_options *op;
        char *plugin;
@@ -215,14 +201,14 @@ update_option(const char *file, struct pevent_plugin_option *option)
 }
 
 /**
- * traceevent_plugin_add_options - Add a set of options by a plugin
+ * tep_plugin_add_options - Add a set of options by a plugin
  * @name: The name of the plugin adding the options
  * @options: The set of options being loaded
  *
  * Sets the options with the values that have been added by user.
  */
-int traceevent_plugin_add_options(const char *name,
-                                 struct pevent_plugin_option *options)
+int tep_plugin_add_options(const char *name,
+                          struct tep_plugin_option *options)
 {
        struct registered_plugin_options *reg;
 
@@ -241,10 +227,10 @@ int traceevent_plugin_add_options(const char *name,
 }
 
 /**
- * traceevent_plugin_remove_options - remove plugin options that were registered
- * @options: Options to removed that were registered with traceevent_plugin_add_options
+ * tep_plugin_remove_options - remove plugin options that were registered
+ * @options: Options to removed that were registered with tep_plugin_add_options
  */
-void traceevent_plugin_remove_options(struct pevent_plugin_option *options)
+void tep_plugin_remove_options(struct tep_plugin_option *options)
 {
        struct registered_plugin_options **last;
        struct registered_plugin_options *reg;
@@ -260,19 +246,19 @@ void traceevent_plugin_remove_options(struct pevent_plugin_option *options)
 }
 
 /**
- * traceevent_print_plugins - print out the list of plugins loaded
+ * tep_print_plugins - print out the list of plugins loaded
  * @s: the trace_seq descripter to write to
  * @prefix: The prefix string to add before listing the option name
  * @suffix: The suffix string ot append after the option name
- * @list: The list of plugins (usually returned by traceevent_load_plugins()
+ * @list: The list of plugins (usually returned by tep_load_plugins()
  *
  * Writes to the trace_seq @s the list of plugins (files) that is
- * returned by traceevent_load_plugins(). Use @prefix and @suffix for formating:
+ * returned by tep_load_plugins(). Use @prefix and @suffix for formating:
  * @prefix = "  ", @suffix = "\n".
  */
-void traceevent_print_plugins(struct trace_seq *s,
-                             const char *prefix, const char *suffix,
-                             const struct plugin_list *list)
+void tep_print_plugins(struct trace_seq *s,
+                      const char *prefix, const char *suffix,
+                      const struct plugin_list *list)
 {
        while (list) {
                trace_seq_printf(s, "%s%s%s", prefix, list->name, suffix);
@@ -281,11 +267,11 @@ void traceevent_print_plugins(struct trace_seq *s,
 }
 
 static void
-load_plugin(struct pevent *pevent, const char *path,
+load_plugin(struct tep_handle *pevent, const char *path,
            const char *file, void *data)
 {
        struct plugin_list **plugin_list = data;
-       pevent_plugin_load_func func;
+       tep_plugin_load_func func;
        struct plugin_list *list;
        const char *alias;
        char *plugin;
@@ -305,14 +291,14 @@ load_plugin(struct pevent *pevent, const char *path,
                goto out_free;
        }
 
-       alias = dlsym(handle, PEVENT_PLUGIN_ALIAS_NAME);
+       alias = dlsym(handle, TEP_PLUGIN_ALIAS_NAME);
        if (!alias)
                alias = file;
 
-       func = dlsym(handle, PEVENT_PLUGIN_LOADER_NAME);
+       func = dlsym(handle, TEP_PLUGIN_LOADER_NAME);
        if (!func) {
                warning("could not find func '%s' in plugin '%s'\n%s\n",
-                       PEVENT_PLUGIN_LOADER_NAME, plugin, dlerror());
+                       TEP_PLUGIN_LOADER_NAME, plugin, dlerror());
                goto out_free;
        }
 
@@ -336,9 +322,9 @@ load_plugin(struct pevent *pevent, const char *path,
 }
 
 static void
-load_plugins_dir(struct pevent *pevent, const char *suffix,
+load_plugins_dir(struct tep_handle *pevent, const char *suffix,
                 const char *path,
-                void (*load_plugin)(struct pevent *pevent,
+                void (*load_plugin)(struct tep_handle *pevent,
                                     const char *path,
                                     const char *name,
                                     void *data),
@@ -378,8 +364,8 @@ load_plugins_dir(struct pevent *pevent, const char *suffix,
 }
 
 static void
-load_plugins(struct pevent *pevent, const char *suffix,
-            void (*load_plugin)(struct pevent *pevent,
+load_plugins(struct tep_handle *pevent, const char *suffix,
+            void (*load_plugin)(struct tep_handle *pevent,
                                 const char *path,
                                 const char *name,
                                 void *data),
@@ -390,7 +376,7 @@ load_plugins(struct pevent *pevent, const char *suffix,
        char *envdir;
        int ret;
 
-       if (pevent->flags & PEVENT_DISABLE_PLUGINS)
+       if (pevent->flags & TEP_DISABLE_PLUGINS)
                return;
 
        /*
@@ -398,7 +384,7 @@ load_plugins(struct pevent *pevent, const char *suffix,
         * check that first.
         */
 #ifdef PLUGIN_DIR
-       if (!(pevent->flags & PEVENT_DISABLE_SYS_PLUGINS))
+       if (!(pevent->flags & TEP_DISABLE_SYS_PLUGINS))
                load_plugins_dir(pevent, suffix, PLUGIN_DIR,
                                 load_plugin, data);
 #endif
@@ -431,7 +417,7 @@ load_plugins(struct pevent *pevent, const char *suffix,
 }
 
 struct plugin_list*
-traceevent_load_plugins(struct pevent *pevent)
+tep_load_plugins(struct tep_handle *pevent)
 {
        struct plugin_list *list = NULL;
 
@@ -440,15 +426,15 @@ traceevent_load_plugins(struct pevent *pevent)
 }
 
 void
-traceevent_unload_plugins(struct plugin_list *plugin_list, struct pevent *pevent)
+tep_unload_plugins(struct plugin_list *plugin_list, struct tep_handle *pevent)
 {
-       pevent_plugin_unload_func func;
+       tep_plugin_unload_func func;
        struct plugin_list *list;
 
        while (plugin_list) {
                list = plugin_list;
                plugin_list = list->next;
-               func = dlsym(list->handle, PEVENT_PLUGIN_UNLOADER_NAME);
+               func = dlsym(list->handle, TEP_PLUGIN_UNLOADER_NAME);
                if (func)
                        func(pevent);
                dlclose(list->handle);
index d1dc2170e4023dbf8cfec33b386bcecd15972035..0560b96a31d1b6e8f972870c7e76dd3dec6e2af5 100644 (file)
@@ -1,21 +1,7 @@
+/* SPDX-License-Identifier: LGPL-2.1 */
 /*
  * Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
  *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License (not later!)
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not,  see <http://www.gnu.org/licenses>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 #ifndef __UTIL_H
 #define __UTIL_H
index ca424b157e4653a009a078604a217bf3853a8ed8..af2a1f3b7424141483c514daf62260b3fba08cf7 100644 (file)
@@ -1,22 +1,7 @@
+// SPDX-License-Identifier: LGPL-2.1
 /*
  * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
  *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License (not later!)
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 #include <stdio.h>
 #include <stdlib.h>
index 431e8b309f6e1bb1d984e81959bf66d449d7645b..e76154c02ee7ac0a2c7c7a72cf2e4e04cf323b1f 100644 (file)
@@ -1,21 +1,7 @@
+// SPDX-License-Identifier: LGPL-2.1
 /*
  * Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
  *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License (not later!)
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not,  see <http://www.gnu.org/licenses>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 #include <stdio.h>
 #include <stdlib.h>
@@ -51,8 +37,8 @@ static void show_error(char *error_buf, const char *fmt, ...)
        int len;
        int i;
 
-       input = pevent_get_input_buf();
-       index = pevent_get_input_buf_ptr();
+       input = tep_get_input_buf();
+       index = tep_get_input_buf_ptr();
        len = input ? strlen(input) : 0;
 
        if (len) {
@@ -66,13 +52,13 @@ static void show_error(char *error_buf, const char *fmt, ...)
        }
 
        va_start(ap, fmt);
-       vsnprintf(error_buf + len, PEVENT_FILTER_ERROR_BUFSZ - len, fmt, ap);
+       vsnprintf(error_buf + len, TEP_FILTER_ERROR_BUFSZ - len, fmt, ap);
        va_end(ap);
 }
 
 static void free_token(char *token)
 {
-       pevent_free_token(token);
+       tep_free_token(token);
 }
 
 static enum event_type read_token(char **tok)
@@ -82,13 +68,13 @@ static enum event_type read_token(char **tok)
 
        do {
                free_token(token);
-               type = pevent_read_token(&token);
+               type = tep_read_token(&token);
        } while (type == EVENT_NEWLINE || type == EVENT_SPACE);
 
        /* If token is = or ! check to see if the next char is ~ */
        if (token &&
            (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) &&
-           pevent_peek_char() == '~') {
+           tep_peek_char() == '~') {
                /* append it */
                *tok = malloc(3);
                if (*tok == NULL) {
@@ -98,7 +84,7 @@ static enum event_type read_token(char **tok)
                sprintf(*tok, "%c%c", *token, '~');
                free_token(token);
                /* Now remove the '~' from the buffer */
-               pevent_read_token(&token);
+               tep_read_token(&token);
                free_token(token);
        } else
                *tok = token;
@@ -167,7 +153,7 @@ add_filter_type(struct event_filter *filter, int id)
 
        filter_type = &filter->event_filters[i];
        filter_type->event_id = id;
-       filter_type->event = pevent_find_event(filter->pevent, id);
+       filter_type->event = tep_find_event(filter->pevent, id);
        filter_type->filter = NULL;
 
        filter->filters++;
@@ -176,10 +162,10 @@ add_filter_type(struct event_filter *filter, int id)
 }
 
 /**
- * pevent_filter_alloc - create a new event filter
+ * tep_filter_alloc - create a new event filter
  * @pevent: The pevent that this filter is associated with
  */
-struct event_filter *pevent_filter_alloc(struct pevent *pevent)
+struct event_filter *tep_filter_alloc(struct tep_handle *pevent)
 {
        struct event_filter *filter;
 
@@ -189,7 +175,7 @@ struct event_filter *pevent_filter_alloc(struct pevent *pevent)
 
        memset(filter, 0, sizeof(*filter));
        filter->pevent = pevent;
-       pevent_ref(pevent);
+       tep_ref(pevent);
 
        return filter;
 }
@@ -268,8 +254,8 @@ static int event_match(struct event_format *event,
                !regexec(ereg, event->name, 0, NULL, 0);
 }
 
-static enum pevent_errno
-find_event(struct pevent *pevent, struct event_list **events,
+static enum tep_errno
+find_event(struct tep_handle *pevent, struct event_list **events,
           char *sys_name, char *event_name)
 {
        struct event_format *event;
@@ -289,26 +275,26 @@ find_event(struct pevent *pevent, struct event_list **events,
 
        ret = asprintf(&reg, "^%s$", event_name);
        if (ret < 0)
-               return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+               return TEP_ERRNO__MEM_ALLOC_FAILED;
 
        ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB);
        free(reg);
 
        if (ret)
-               return PEVENT_ERRNO__INVALID_EVENT_NAME;
+               return TEP_ERRNO__INVALID_EVENT_NAME;
 
        if (sys_name) {
                ret = asprintf(&reg, "^%s$", sys_name);
                if (ret < 0) {
                        regfree(&ereg);
-                       return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+                       return TEP_ERRNO__MEM_ALLOC_FAILED;
                }
 
                ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB);
                free(reg);
                if (ret) {
                        regfree(&ereg);
-                       return PEVENT_ERRNO__INVALID_EVENT_NAME;
+                       return TEP_ERRNO__INVALID_EVENT_NAME;
                }
        }
 
@@ -328,9 +314,9 @@ find_event(struct pevent *pevent, struct event_list **events,
                regfree(&sreg);
 
        if (!match)
-               return PEVENT_ERRNO__EVENT_NOT_FOUND;
+               return TEP_ERRNO__EVENT_NOT_FOUND;
        if (fail)
-               return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+               return TEP_ERRNO__MEM_ALLOC_FAILED;
 
        return 0;
 }
@@ -346,7 +332,7 @@ static void free_events(struct event_list *events)
        }
 }
 
-static enum pevent_errno
+static enum tep_errno
 create_arg_item(struct event_format *event, const char *token,
                enum event_type type, struct filter_arg **parg, char *error_str)
 {
@@ -356,7 +342,7 @@ create_arg_item(struct event_format *event, const char *token,
        arg = allocate_arg();
        if (arg == NULL) {
                show_error(error_str, "failed to allocate filter arg");
-               return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+               return TEP_ERRNO__MEM_ALLOC_FAILED;
        }
 
        switch (type) {
@@ -370,7 +356,7 @@ create_arg_item(struct event_format *event, const char *token,
                if (!arg->value.str) {
                        free_arg(arg);
                        show_error(error_str, "failed to allocate string filter arg");
-                       return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+                       return TEP_ERRNO__MEM_ALLOC_FAILED;
                }
                break;
        case EVENT_ITEM:
@@ -382,7 +368,7 @@ create_arg_item(struct event_format *event, const char *token,
                        break;
                }
                /* Consider this a field */
-               field = pevent_find_any_field(event, token);
+               field = tep_find_any_field(event, token);
                if (!field) {
                        /* If token is 'COMM' or 'CPU' then it is special */
                        if (strcmp(token, COMM) == 0) {
@@ -402,7 +388,7 @@ create_arg_item(struct event_format *event, const char *token,
        default:
                free_arg(arg);
                show_error(error_str, "expected a value but found %s", token);
-               return PEVENT_ERRNO__UNEXPECTED_TYPE;
+               return TEP_ERRNO__UNEXPECTED_TYPE;
        }
        *parg = arg;
        return 0;
@@ -454,7 +440,7 @@ create_arg_cmp(enum filter_cmp_type ctype)
        return arg;
 }
 
-static enum pevent_errno
+static enum tep_errno
 add_right(struct filter_arg *op, struct filter_arg *arg, char *error_str)
 {
        struct filter_arg *left;
@@ -487,7 +473,7 @@ add_right(struct filter_arg *op, struct filter_arg *arg, char *error_str)
                        break;
                default:
                        show_error(error_str, "Illegal rvalue");
-                       return PEVENT_ERRNO__ILLEGAL_RVALUE;
+                       return TEP_ERRNO__ILLEGAL_RVALUE;
                }
 
                /*
@@ -534,7 +520,7 @@ add_right(struct filter_arg *op, struct filter_arg *arg, char *error_str)
                        if (left->type != FILTER_ARG_FIELD) {
                                show_error(error_str,
                                           "Illegal lvalue for string comparison");
-                               return PEVENT_ERRNO__ILLEGAL_LVALUE;
+                               return TEP_ERRNO__ILLEGAL_LVALUE;
                        }
 
                        /* Make sure this is a valid string compare */
@@ -553,13 +539,13 @@ add_right(struct filter_arg *op, struct filter_arg *arg, char *error_str)
                                        show_error(error_str,
                                                   "RegEx '%s' did not compute",
                                                   str);
-                                       return PEVENT_ERRNO__INVALID_REGEX;
+                                       return TEP_ERRNO__INVALID_REGEX;
                                }
                                break;
                        default:
                                show_error(error_str,
                                           "Illegal comparison for string");
-                               return PEVENT_ERRNO__ILLEGAL_STRING_CMP;
+                               return TEP_ERRNO__ILLEGAL_STRING_CMP;
                        }
 
                        op->type = FILTER_ARG_STR;
@@ -568,7 +554,7 @@ add_right(struct filter_arg *op, struct filter_arg *arg, char *error_str)
                        op->str.val = strdup(str);
                        if (!op->str.val) {
                                show_error(error_str, "Failed to allocate string filter");
-                               return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+                               return TEP_ERRNO__MEM_ALLOC_FAILED;
                        }
                        /*
                         * Need a buffer to copy data for tests
@@ -576,7 +562,7 @@ add_right(struct filter_arg *op, struct filter_arg *arg, char *error_str)
                        op->str.buffer = malloc(op->str.field->size + 1);
                        if (!op->str.buffer) {
                                show_error(error_str, "Failed to allocate string filter");
-                               return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+                               return TEP_ERRNO__MEM_ALLOC_FAILED;
                        }
                        /* Null terminate this buffer */
                        op->str.buffer[op->str.field->size] = 0;
@@ -595,7 +581,7 @@ add_right(struct filter_arg *op, struct filter_arg *arg, char *error_str)
                        case FILTER_CMP_NOT_REGEX:
                                show_error(error_str,
                                           "Op not allowed with integers");
-                               return PEVENT_ERRNO__ILLEGAL_INTEGER_CMP;
+                               return TEP_ERRNO__ILLEGAL_INTEGER_CMP;
 
                        default:
                                break;
@@ -616,7 +602,7 @@ add_right(struct filter_arg *op, struct filter_arg *arg, char *error_str)
 
  out_fail:
        show_error(error_str, "Syntax error");
-       return PEVENT_ERRNO__SYNTAX_ERROR;
+       return TEP_ERRNO__SYNTAX_ERROR;
 }
 
 static struct filter_arg *
@@ -629,7 +615,7 @@ rotate_op_right(struct filter_arg *a, struct filter_arg *b)
        return arg;
 }
 
-static enum pevent_errno add_left(struct filter_arg *op, struct filter_arg *arg)
+static enum tep_errno add_left(struct filter_arg *op, struct filter_arg *arg)
 {
        switch (op->type) {
        case FILTER_ARG_EXP:
@@ -648,11 +634,11 @@ static enum pevent_errno add_left(struct filter_arg *op, struct filter_arg *arg)
                /* left arg of compares must be a field */
                if (arg->type != FILTER_ARG_FIELD &&
                    arg->type != FILTER_ARG_BOOLEAN)
-                       return PEVENT_ERRNO__INVALID_ARG_TYPE;
+                       return TEP_ERRNO__INVALID_ARG_TYPE;
                op->num.left = arg;
                break;
        default:
-               return PEVENT_ERRNO__INVALID_ARG_TYPE;
+               return TEP_ERRNO__INVALID_ARG_TYPE;
        }
        return 0;
 }
@@ -765,7 +751,7 @@ enum filter_vals {
        FILTER_VAL_TRUE,
 };
 
-static enum pevent_errno
+static enum tep_errno
 reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,
                struct filter_arg *arg, char *error_str)
 {
@@ -775,7 +761,7 @@ reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,
        if (parent->type != FILTER_ARG_OP &&
            arg->type != FILTER_ARG_OP) {
                show_error(error_str, "can not reparent other than OP");
-               return PEVENT_ERRNO__REPARENT_NOT_OP;
+               return TEP_ERRNO__REPARENT_NOT_OP;
        }
 
        /* Get the sibling */
@@ -787,7 +773,7 @@ reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,
                other_child = old_child->op.right;
        } else {
                show_error(error_str, "Error in reparent op, find other child");
-               return PEVENT_ERRNO__REPARENT_FAILED;
+               return TEP_ERRNO__REPARENT_FAILED;
        }
 
        /* Detach arg from old_child */
@@ -808,7 +794,7 @@ reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,
                ptr = &parent->op.left;
        else {
                show_error(error_str, "Error in reparent op");
-               return PEVENT_ERRNO__REPARENT_FAILED;
+               return TEP_ERRNO__REPARENT_FAILED;
        }
 
        *ptr = arg;
@@ -817,7 +803,7 @@ reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child,
        return 0;
 }
 
-/* Returns either filter_vals (success) or pevent_errno (failfure) */
+/* Returns either filter_vals (success) or tep_errno (failfure) */
 static int test_arg(struct filter_arg *parent, struct filter_arg *arg,
                    char *error_str)
 {
@@ -912,7 +898,7 @@ static int test_arg(struct filter_arg *parent, struct filter_arg *arg,
                return rval;
        default:
                show_error(error_str, "bad arg in filter tree");
-               return PEVENT_ERRNO__BAD_FILTER_ARG;
+               return TEP_ERRNO__BAD_FILTER_ARG;
        }
        return FILTER_VAL_NORM;
 }
@@ -937,7 +923,7 @@ static int collapse_tree(struct filter_arg *arg,
                        arg->boolean.value = ret == FILTER_VAL_TRUE;
                } else {
                        show_error(error_str, "Failed to allocate filter arg");
-                       ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
+                       ret = TEP_ERRNO__MEM_ALLOC_FAILED;
                }
                break;
 
@@ -952,7 +938,7 @@ static int collapse_tree(struct filter_arg *arg,
        return ret;
 }
 
-static enum pevent_errno
+static enum tep_errno
 process_filter(struct event_format *event, struct filter_arg **parg,
               char *error_str, int not)
 {
@@ -966,7 +952,7 @@ process_filter(struct event_format *event, struct filter_arg **parg,
        enum filter_op_type btype;
        enum filter_exp_type etype;
        enum filter_cmp_type ctype;
-       enum pevent_errno ret;
+       enum tep_errno ret;
 
        *parg = NULL;
 
@@ -1004,7 +990,7 @@ process_filter(struct event_format *event, struct filter_arg **parg,
                case EVENT_DELIM:
                        if (*token == ',') {
                                show_error(error_str, "Illegal token ','");
-                               ret = PEVENT_ERRNO__ILLEGAL_TOKEN;
+                               ret = TEP_ERRNO__ILLEGAL_TOKEN;
                                goto fail;
                        }
 
@@ -1012,22 +998,22 @@ process_filter(struct event_format *event, struct filter_arg **parg,
                                if (left_item) {
                                        show_error(error_str,
                                                   "Open paren can not come after item");
-                                       ret = PEVENT_ERRNO__INVALID_PAREN;
+                                       ret = TEP_ERRNO__INVALID_PAREN;
                                        goto fail;
                                }
                                if (current_exp) {
                                        show_error(error_str,
                                                   "Open paren can not come after expression");
-                                       ret = PEVENT_ERRNO__INVALID_PAREN;
+                                       ret = TEP_ERRNO__INVALID_PAREN;
                                        goto fail;
                                }
 
                                ret = process_filter(event, &arg, error_str, 0);
-                               if (ret != PEVENT_ERRNO__UNBALANCED_PAREN) {
+                               if (ret != TEP_ERRNO__UNBALANCED_PAREN) {
                                        if (ret == 0) {
                                                show_error(error_str,
                                                           "Unbalanced number of '('");
-                                               ret = PEVENT_ERRNO__UNBALANCED_PAREN;
+                                               ret = TEP_ERRNO__UNBALANCED_PAREN;
                                        }
                                        goto fail;
                                }
@@ -1064,7 +1050,7 @@ process_filter(struct event_format *event, struct filter_arg **parg,
                                else
                                        *parg = current_exp;
                                free(token);
-                               return PEVENT_ERRNO__UNBALANCED_PAREN;
+                               return TEP_ERRNO__UNBALANCED_PAREN;
                        }
                        break;
 
@@ -1091,7 +1077,7 @@ process_filter(struct event_format *event, struct filter_arg **parg,
                        case OP_NONE:
                                show_error(error_str,
                                           "Unknown op token %s", token);
-                               ret = PEVENT_ERRNO__UNKNOWN_TOKEN;
+                               ret = TEP_ERRNO__UNKNOWN_TOKEN;
                                goto fail;
                        }
 
@@ -1179,11 +1165,11 @@ process_filter(struct event_format *event, struct filter_arg **parg,
 
  fail_alloc:
        show_error(error_str, "failed to allocate filter arg");
-       ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
+       ret = TEP_ERRNO__MEM_ALLOC_FAILED;
        goto fail;
  fail_syntax:
        show_error(error_str, "Syntax error");
-       ret = PEVENT_ERRNO__SYNTAX_ERROR;
+       ret = TEP_ERRNO__SYNTAX_ERROR;
  fail:
        free_arg(current_op);
        free_arg(current_exp);
@@ -1192,13 +1178,13 @@ process_filter(struct event_format *event, struct filter_arg **parg,
        return ret;
 }
 
-static enum pevent_errno
+static enum tep_errno
 process_event(struct event_format *event, const char *filter_str,
              struct filter_arg **parg, char *error_str)
 {
        int ret;
 
-       pevent_buffer_init(filter_str, strlen(filter_str));
+       tep_buffer_init(filter_str, strlen(filter_str));
 
        ret = process_filter(event, parg, error_str, 0);
        if (ret < 0)
@@ -1208,7 +1194,7 @@ process_event(struct event_format *event, const char *filter_str,
        if (!*parg) {
                *parg = allocate_arg();
                if (*parg == NULL)
-                       return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+                       return TEP_ERRNO__MEM_ALLOC_FAILED;
 
                (*parg)->type = FILTER_ARG_BOOLEAN;
                (*parg)->boolean.value = FILTER_FALSE;
@@ -1217,13 +1203,13 @@ process_event(struct event_format *event, const char *filter_str,
        return 0;
 }
 
-static enum pevent_errno
+static enum tep_errno
 filter_event(struct event_filter *filter, struct event_format *event,
             const char *filter_str, char *error_str)
 {
        struct filter_type *filter_type;
        struct filter_arg *arg;
-       enum pevent_errno ret;
+       enum tep_errno ret;
 
        if (filter_str) {
                ret = process_event(event, filter_str, &arg, error_str);
@@ -1234,7 +1220,7 @@ filter_event(struct event_filter *filter, struct event_format *event,
                /* just add a TRUE arg */
                arg = allocate_arg();
                if (arg == NULL)
-                       return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+                       return TEP_ERRNO__MEM_ALLOC_FAILED;
 
                arg->type = FILTER_ARG_BOOLEAN;
                arg->boolean.value = FILTER_TRUE;
@@ -1242,7 +1228,7 @@ filter_event(struct event_filter *filter, struct event_format *event,
 
        filter_type = add_filter_type(filter, event->id);
        if (filter_type == NULL)
-               return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+               return TEP_ERRNO__MEM_ALLOC_FAILED;
 
        if (filter_type->filter)
                free_arg(filter_type->filter);
@@ -1254,23 +1240,23 @@ filter_event(struct event_filter *filter, struct event_format *event,
 static void filter_init_error_buf(struct event_filter *filter)
 {
        /* clear buffer to reset show error */
-       pevent_buffer_init("", 0);
+       tep_buffer_init("", 0);
        filter->error_buffer[0] = '\0';
 }
 
 /**
- * pevent_filter_add_filter_str - add a new filter
+ * tep_filter_add_filter_str - add a new filter
  * @filter: the event filter to add to
  * @filter_str: the filter string that contains the filter
  *
  * Returns 0 if the filter was successfully added or a
- * negative error code.  Use pevent_filter_strerror() to see
+ * negative error code.  Use tep_filter_strerror() to see
  * actual error message in case of error.
  */
-enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
-                                              const char *filter_str)
+enum tep_errno tep_filter_add_filter_str(struct event_filter *filter,
+                                        const char *filter_str)
 {
-       struct pevent *pevent = filter->pevent;
+       struct tep_handle *pevent = filter->pevent;
        struct event_list *event;
        struct event_list *events = NULL;
        const char *filter_start;
@@ -1279,7 +1265,7 @@ enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
        char *event_name = NULL;
        char *sys_name = NULL;
        char *sp;
-       enum pevent_errno rtn = 0; /* PEVENT_ERRNO__SUCCESS */
+       enum tep_errno rtn = 0; /* TEP_ERRNO__SUCCESS */
        int len;
        int ret;
 
@@ -1305,7 +1291,7 @@ enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
                if (this_event == NULL) {
                        /* This can only happen when events is NULL, but still */
                        free_events(events);
-                       return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+                       return TEP_ERRNO__MEM_ALLOC_FAILED;
                }
                memcpy(this_event, filter_str, len);
                this_event[len] = 0;
@@ -1322,7 +1308,7 @@ enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
                        /* This can only happen when events is NULL, but still */
                        free_events(events);
                        free(this_event);
-                       return PEVENT_ERRNO__FILTER_NOT_FOUND;
+                       return TEP_ERRNO__FILTER_NOT_FOUND;
                }
 
                /* Find this event */
@@ -1349,7 +1335,7 @@ enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
 
                if (ret >= 0 && pevent->test_filters) {
                        char *test;
-                       test = pevent_filter_make_string(filter, event->event->id);
+                       test = tep_filter_make_string(filter, event->event->id);
                        if (test) {
                                printf(" '%s: %s'\n", event->event->name, test);
                                free(test);
@@ -1371,7 +1357,7 @@ static void free_filter_type(struct filter_type *filter_type)
 }
 
 /**
- * pevent_filter_strerror - fill error message in a buffer
+ * tep_filter_strerror - fill error message in a buffer
  * @filter: the event filter contains error
  * @err: the error code
  * @buf: the buffer to be filled in
@@ -1379,10 +1365,10 @@ static void free_filter_type(struct filter_type *filter_type)
  *
  * Returns 0 if message was filled successfully, -1 if error
  */
-int pevent_filter_strerror(struct event_filter *filter, enum pevent_errno err,
-                          char *buf, size_t buflen)
+int tep_filter_strerror(struct event_filter *filter, enum tep_errno err,
+                       char *buf, size_t buflen)
 {
-       if (err <= __PEVENT_ERRNO__START || err >= __PEVENT_ERRNO__END)
+       if (err <= __TEP_ERRNO__START || err >= __TEP_ERRNO__END)
                return -1;
 
        if (strlen(filter->error_buffer) > 0) {
@@ -1393,11 +1379,11 @@ int pevent_filter_strerror(struct event_filter *filter, enum pevent_errno err,
                return 0;
        }
 
-       return pevent_strerror(filter->pevent, err, buf, buflen);
+       return tep_strerror(filter->pevent, err, buf, buflen);
 }
 
 /**
- * pevent_filter_remove_event - remove a filter for an event
+ * tep_filter_remove_event - remove a filter for an event
  * @filter: the event filter to remove from
  * @event_id: the event to remove a filter for
  *
@@ -1407,8 +1393,8 @@ int pevent_filter_strerror(struct event_filter *filter, enum pevent_errno err,
  * Returns 1: if an event was removed
  *   0: if the event was not found
  */
-int pevent_filter_remove_event(struct event_filter *filter,
-                              int event_id)
+int tep_filter_remove_event(struct event_filter *filter,
+                           int event_id)
 {
        struct filter_type *filter_type;
        unsigned long len;
@@ -1437,12 +1423,12 @@ int pevent_filter_remove_event(struct event_filter *filter,
 }
 
 /**
- * pevent_filter_reset - clear all filters in a filter
+ * tep_filter_reset - clear all filters in a filter
  * @filter: the event filter to reset
  *
  * Removes all filters from a filter and resets it.
  */
-void pevent_filter_reset(struct event_filter *filter)
+void tep_filter_reset(struct event_filter *filter)
 {
        int i;
 
@@ -1454,11 +1440,11 @@ void pevent_filter_reset(struct event_filter *filter)
        filter->event_filters = NULL;
 }
 
-void pevent_filter_free(struct event_filter *filter)
+void tep_filter_free(struct event_filter *filter)
 {
-       pevent_unref(filter->pevent);
+       tep_unref(filter->pevent);
 
-       pevent_filter_reset(filter);
+       tep_filter_reset(filter);
 
        free(filter);
 }
@@ -1478,7 +1464,7 @@ static int copy_filter_type(struct event_filter *filter,
        /* Can't assume that the pevent's are the same */
        sys = filter_type->event->system;
        name = filter_type->event->name;
-       event = pevent_find_event_by_name(filter->pevent, sys, name);
+       event = tep_find_event_by_name(filter->pevent, sys, name);
        if (!event)
                return -1;
 
@@ -1515,18 +1501,18 @@ static int copy_filter_type(struct event_filter *filter,
 }
 
 /**
- * pevent_filter_copy - copy a filter using another filter
+ * tep_filter_copy - copy a filter using another filter
  * @dest - the filter to copy to
  * @source - the filter to copy from
  *
  * Returns 0 on success and -1 if not all filters were copied
  */
-int pevent_filter_copy(struct event_filter *dest, struct event_filter *source)
+int tep_filter_copy(struct event_filter *dest, struct event_filter *source)
 {
        int ret = 0;
        int i;
 
-       pevent_filter_reset(dest);
+       tep_filter_reset(dest);
 
        for (i = 0; i < source->filters; i++) {
                if (copy_filter_type(dest, source, &source->event_filters[i]))
@@ -1537,7 +1523,7 @@ int pevent_filter_copy(struct event_filter *dest, struct event_filter *source)
 
 
 /**
- * pevent_update_trivial - update the trivial filters with the given filter
+ * tep_update_trivial - update the trivial filters with the given filter
  * @dest - the filter to update
  * @source - the filter as the source of the update
  * @type - the type of trivial filter to update.
@@ -1547,11 +1533,11 @@ int pevent_filter_copy(struct event_filter *dest, struct event_filter *source)
  * Returns 0 on success and -1 if there was a problem updating, but
  *   events may have still been updated on error.
  */
-int pevent_update_trivial(struct event_filter *dest, struct event_filter *source,
-                         enum filter_trivial_type type)
+int tep_update_trivial(struct event_filter *dest, struct event_filter *source,
+                      enum filter_trivial_type type)
 {
-       struct pevent *src_pevent;
-       struct pevent *dest_pevent;
+       struct tep_handle *src_pevent;
+       struct tep_handle *dest_pevent;
        struct event_format *event;
        struct filter_type *filter_type;
        struct filter_arg *arg;
@@ -1578,14 +1564,14 @@ int pevent_update_trivial(struct event_filter *dest, struct event_filter *source
 
                if (src_pevent != dest_pevent) {
                        /* do a look up */
-                       event = pevent_find_event_by_name(src_pevent,
-                                                         event->system,
-                                                         event->name);
+                       event = tep_find_event_by_name(src_pevent,
+                                                      event->system,
+                                                      event->name);
                        if (!event)
                                return -1;
                }
 
-               str = pevent_filter_make_string(source, event->id);
+               str = tep_filter_make_string(source, event->id);
                if (!str)
                        continue;
 
@@ -1598,7 +1584,7 @@ int pevent_update_trivial(struct event_filter *dest, struct event_filter *source
 }
 
 /**
- * pevent_filter_clear_trivial - clear TRUE and FALSE filters
+ * tep_filter_clear_trivial - clear TRUE and FALSE filters
  * @filter: the filter to remove trivial filters from
  * @type: remove only true, false, or both
  *
@@ -1606,8 +1592,8 @@ int pevent_update_trivial(struct event_filter *dest, struct event_filter *source
  *
  * Returns 0 on success and -1 if there was a problem.
  */
-int pevent_filter_clear_trivial(struct event_filter *filter,
-                                enum filter_trivial_type type)
+int tep_filter_clear_trivial(struct event_filter *filter,
+                            enum filter_trivial_type type)
 {
        struct filter_type *filter_type;
        int count = 0;
@@ -1653,14 +1639,14 @@ int pevent_filter_clear_trivial(struct event_filter *filter,
                return 0;
 
        for (i = 0; i < count; i++)
-               pevent_filter_remove_event(filter, ids[i]);
+               tep_filter_remove_event(filter, ids[i]);
 
        free(ids);
        return 0;
 }
 
 /**
- * pevent_filter_event_has_trivial - return true event contains trivial filter
+ * tep_filter_event_has_trivial - return true event contains trivial filter
  * @filter: the filter with the information
  * @event_id: the id of the event to test
  * @type: trivial type to test for (TRUE, FALSE, EITHER)
@@ -1668,9 +1654,9 @@ int pevent_filter_clear_trivial(struct event_filter *filter,
  * Returns 1 if the event contains a matching trivial type
  *  otherwise 0.
  */
-int pevent_filter_event_has_trivial(struct event_filter *filter,
-                                   int event_id,
-                                   enum filter_trivial_type type)
+int tep_filter_event_has_trivial(struct event_filter *filter,
+                                int event_id,
+                                enum filter_trivial_type type)
 {
        struct filter_type *filter_type;
 
@@ -1697,22 +1683,22 @@ int pevent_filter_event_has_trivial(struct event_filter *filter,
 }
 
 static int test_filter(struct event_format *event, struct filter_arg *arg,
-                      struct pevent_record *record, enum pevent_errno *err);
+                      struct tep_record *record, enum tep_errno *err);
 
 static const char *
-get_comm(struct event_format *event, struct pevent_record *record)
+get_comm(struct event_format *event, struct tep_record *record)
 {
        const char *comm;
        int pid;
 
-       pid = pevent_data_pid(event->pevent, record);
-       comm = pevent_data_comm_from_pid(event->pevent, pid);
+       pid = tep_data_pid(event->pevent, record);
+       comm = tep_data_comm_from_pid(event->pevent, pid);
        return comm;
 }
 
 static unsigned long long
 get_value(struct event_format *event,
-         struct format_field *field, struct pevent_record *record)
+         struct format_field *field, struct tep_record *record)
 {
        unsigned long long val;
 
@@ -1728,7 +1714,7 @@ get_value(struct event_format *event,
        if (field == &cpu)
                return record->cpu;
 
-       pevent_read_number_field(field, record->data, &val);
+       tep_read_number_field(field, record->data, &val);
 
        if (!(field->flags & FIELD_IS_SIGNED))
                return val;
@@ -1748,11 +1734,11 @@ get_value(struct event_format *event,
 
 static unsigned long long
 get_arg_value(struct event_format *event, struct filter_arg *arg,
-             struct pevent_record *record, enum pevent_errno *err);
+             struct tep_record *record, enum tep_errno *err);
 
 static unsigned long long
 get_exp_value(struct event_format *event, struct filter_arg *arg,
-             struct pevent_record *record, enum pevent_errno *err)
+             struct tep_record *record, enum tep_errno *err)
 {
        unsigned long long lval, rval;
 
@@ -1800,14 +1786,14 @@ get_exp_value(struct event_format *event, struct filter_arg *arg,
        case FILTER_EXP_NOT:
        default:
                if (!*err)
-                       *err = PEVENT_ERRNO__INVALID_EXP_TYPE;
+                       *err = TEP_ERRNO__INVALID_EXP_TYPE;
        }
        return 0;
 }
 
 static unsigned long long
 get_arg_value(struct event_format *event, struct filter_arg *arg,
-             struct pevent_record *record, enum pevent_errno *err)
+             struct tep_record *record, enum tep_errno *err)
 {
        switch (arg->type) {
        case FILTER_ARG_FIELD:
@@ -1816,7 +1802,7 @@ get_arg_value(struct event_format *event, struct filter_arg *arg,
        case FILTER_ARG_VALUE:
                if (arg->value.type != FILTER_NUMBER) {
                        if (!*err)
-                               *err = PEVENT_ERRNO__NOT_A_NUMBER;
+                               *err = TEP_ERRNO__NOT_A_NUMBER;
                }
                return arg->value.val;
 
@@ -1825,13 +1811,13 @@ get_arg_value(struct event_format *event, struct filter_arg *arg,
 
        default:
                if (!*err)
-                       *err = PEVENT_ERRNO__INVALID_ARG_TYPE;
+                       *err = TEP_ERRNO__INVALID_ARG_TYPE;
        }
        return 0;
 }
 
 static int test_num(struct event_format *event, struct filter_arg *arg,
-                   struct pevent_record *record, enum pevent_errno *err)
+                   struct tep_record *record, enum tep_errno *err)
 {
        unsigned long long lval, rval;
 
@@ -1866,15 +1852,15 @@ static int test_num(struct event_format *event, struct filter_arg *arg,
 
        default:
                if (!*err)
-                       *err = PEVENT_ERRNO__ILLEGAL_INTEGER_CMP;
+                       *err = TEP_ERRNO__ILLEGAL_INTEGER_CMP;
                return 0;
        }
 }
 
-static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record)
+static const char *get_field_str(struct filter_arg *arg, struct tep_record *record)
 {
        struct event_format *event;
-       struct pevent *pevent;
+       struct tep_handle *pevent;
        unsigned long long addr;
        const char *val = NULL;
        unsigned int size;
@@ -1909,7 +1895,7 @@ static const char *get_field_str(struct filter_arg *arg, struct pevent_record *r
 
                if (arg->str.field->flags & (FIELD_IS_POINTER | FIELD_IS_LONG))
                        /* convert to a kernel symbol */
-                       val = pevent_find_function(pevent, addr);
+                       val = tep_find_function(pevent, addr);
 
                if (val == NULL) {
                        /* just use the hex of the string name */
@@ -1922,7 +1908,7 @@ static const char *get_field_str(struct filter_arg *arg, struct pevent_record *r
 }
 
 static int test_str(struct event_format *event, struct filter_arg *arg,
-                   struct pevent_record *record, enum pevent_errno *err)
+                   struct tep_record *record, enum tep_errno *err)
 {
        const char *val;
 
@@ -1947,13 +1933,13 @@ static int test_str(struct event_format *event, struct filter_arg *arg,
 
        default:
                if (!*err)
-                       *err = PEVENT_ERRNO__ILLEGAL_STRING_CMP;
+                       *err = TEP_ERRNO__ILLEGAL_STRING_CMP;
                return 0;
        }
 }
 
 static int test_op(struct event_format *event, struct filter_arg *arg,
-                  struct pevent_record *record, enum pevent_errno *err)
+                  struct tep_record *record, enum tep_errno *err)
 {
        switch (arg->op.type) {
        case FILTER_OP_AND:
@@ -1969,13 +1955,13 @@ static int test_op(struct event_format *event, struct filter_arg *arg,
 
        default:
                if (!*err)
-                       *err = PEVENT_ERRNO__INVALID_OP_TYPE;
+                       *err = TEP_ERRNO__INVALID_OP_TYPE;
                return 0;
        }
 }
 
 static int test_filter(struct event_format *event, struct filter_arg *arg,
-                      struct pevent_record *record, enum pevent_errno *err)
+                      struct tep_record *record, enum tep_errno *err)
 {
        if (*err) {
                /*
@@ -2009,20 +1995,20 @@ static int test_filter(struct event_format *event, struct filter_arg *arg,
 
        default:
                if (!*err)
-                       *err = PEVENT_ERRNO__INVALID_ARG_TYPE;
+                       *err = TEP_ERRNO__INVALID_ARG_TYPE;
                return 0;
        }
 }
 
 /**
- * pevent_event_filtered - return true if event has filter
+ * tep_event_filtered - return true if event has filter
  * @filter: filter struct with filter information
  * @event_id: event id to test if filter exists
  *
  * Returns 1 if filter found for @event_id
  *   otherwise 0;
  */
-int pevent_event_filtered(struct event_filter *filter, int event_id)
+int tep_event_filtered(struct event_filter *filter, int event_id)
 {
        struct filter_type *filter_type;
 
@@ -2035,42 +2021,42 @@ int pevent_event_filtered(struct event_filter *filter, int event_id)
 }
 
 /**
- * pevent_filter_match - test if a record matches a filter
+ * tep_filter_match - test if a record matches a filter
  * @filter: filter struct with filter information
  * @record: the record to test against the filter
  *
- * Returns: match result or error code (prefixed with PEVENT_ERRNO__)
+ * Returns: match result or error code (prefixed with TEP_ERRNO__)
  * FILTER_MATCH - filter found for event and @record matches
  * FILTER_MISS  - filter found for event and @record does not match
  * FILTER_NOT_FOUND - no filter found for @record's event
  * NO_FILTER - if no filters exist
  * otherwise - error occurred during test
  */
-enum pevent_errno pevent_filter_match(struct event_filter *filter,
-                                     struct pevent_record *record)
+enum tep_errno tep_filter_match(struct event_filter *filter,
+                               struct tep_record *record)
 {
-       struct pevent *pevent = filter->pevent;
+       struct tep_handle *pevent = filter->pevent;
        struct filter_type *filter_type;
        int event_id;
        int ret;
-       enum pevent_errno err = 0;
+       enum tep_errno err = 0;
 
        filter_init_error_buf(filter);
 
        if (!filter->filters)
-               return PEVENT_ERRNO__NO_FILTER;
+               return TEP_ERRNO__NO_FILTER;
 
-       event_id = pevent_data_type(pevent, record);
+       event_id = tep_data_type(pevent, record);
 
        filter_type = find_filter_type(filter, event_id);
        if (!filter_type)
-               return PEVENT_ERRNO__FILTER_NOT_FOUND;
+               return TEP_ERRNO__FILTER_NOT_FOUND;
 
        ret = test_filter(filter_type->event, filter_type->filter, record, &err);
        if (err)
                return err;
 
-       return ret ? PEVENT_ERRNO__FILTER_MATCH : PEVENT_ERRNO__FILTER_MISS;
+       return ret ? TEP_ERRNO__FILTER_MATCH : TEP_ERRNO__FILTER_MISS;
 }
 
 static char *op_to_str(struct event_filter *filter, struct filter_arg *arg)
@@ -2364,7 +2350,7 @@ static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg)
 }
 
 /**
- * pevent_filter_make_string - return a string showing the filter
+ * tep_filter_make_string - return a string showing the filter
  * @filter: filter struct with filter information
  * @event_id: the event id to return the filter string with
  *
@@ -2373,7 +2359,7 @@ static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg)
  *  NULL is returned if no filter is found or allocation failed.
  */
 char *
-pevent_filter_make_string(struct event_filter *filter, int event_id)
+tep_filter_make_string(struct event_filter *filter, int event_id)
 {
        struct filter_type *filter_type;
 
@@ -2389,7 +2375,7 @@ pevent_filter_make_string(struct event_filter *filter, int event_id)
 }
 
 /**
- * pevent_filter_compare - compare two filters and return if they are the same
+ * tep_filter_compare - compare two filters and return if they are the same
  * @filter1: Filter to compare with @filter2
  * @filter2: Filter to compare with @filter1
  *
@@ -2397,7 +2383,7 @@ pevent_filter_make_string(struct event_filter *filter, int event_id)
  *  1 if the two filters hold the same content.
  *  0 if they do not.
  */
-int pevent_filter_compare(struct event_filter *filter1, struct event_filter *filter2)
+int tep_filter_compare(struct event_filter *filter1, struct event_filter *filter2)
 {
        struct filter_type *filter_type1;
        struct filter_type *filter_type2;
index eda07fa31dca1058a72989669e1cc99bc5958ab3..77e4ec6402dd3fef5e7832cbe1afe41f83db3906 100644 (file)
@@ -1,21 +1,7 @@
+// SPDX-License-Identifier: LGPL-2.1
 /*
  * Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
  *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License (not later!)
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not,  see <http://www.gnu.org/licenses>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 #include <stdio.h>
 #include <stdlib.h>
index 8f8586912da7bab64a0e351b45ee4ea283ac7414..a51b366f47dad91500f540a3f2198013943556ae 100644 (file)
@@ -25,19 +25,19 @@ process___le16_to_cpup(struct trace_seq *s, unsigned long long *args)
        return val ? (long long) le16toh(*val) : 0;
 }
 
-int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
 {
-       pevent_register_print_function(pevent,
-                                      process___le16_to_cpup,
-                                      PEVENT_FUNC_ARG_INT,
-                                      "__le16_to_cpup",
-                                      PEVENT_FUNC_ARG_PTR,
-                                      PEVENT_FUNC_ARG_VOID);
+       tep_register_print_function(pevent,
+                                   process___le16_to_cpup,
+                                   TEP_FUNC_ARG_INT,
+                                   "__le16_to_cpup",
+                                   TEP_FUNC_ARG_PTR,
+                                   TEP_FUNC_ARG_VOID);
        return 0;
 }
 
-void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
+void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
 {
-       pevent_unregister_print_function(pevent, process___le16_to_cpup,
-                                        "__le16_to_cpup");
+       tep_unregister_print_function(pevent, process___le16_to_cpup,
+                                     "__le16_to_cpup");
 }
index 42dbf73758f3425f20c3401a5c64f024459ddfaf..424747475d37b727770566a983ae3b1ef57c0ec7 100644 (file)
@@ -33,7 +33,7 @@ static int cpus = -1;
 
 #define STK_BLK 10
 
-struct pevent_plugin_option plugin_options[] =
+struct tep_plugin_option plugin_options[] =
 {
        {
                .name = "parent",
@@ -53,8 +53,8 @@ struct pevent_plugin_option plugin_options[] =
        }
 };
 
-static struct pevent_plugin_option *ftrace_parent = &plugin_options[0];
-static struct pevent_plugin_option *ftrace_indent = &plugin_options[1];
+static struct tep_plugin_option *ftrace_parent = &plugin_options[0];
+static struct tep_plugin_option *ftrace_indent = &plugin_options[1];
 
 static void add_child(struct func_stack *stack, const char *child, int pos)
 {
@@ -122,25 +122,25 @@ static int add_and_get_index(const char *parent, const char *child, int cpu)
        return 0;
 }
 
-static int function_handler(struct trace_seq *s, struct pevent_record *record,
+static int function_handler(struct trace_seq *s, struct tep_record *record,
                            struct event_format *event, void *context)
 {
-       struct pevent *pevent = event->pevent;
+       struct tep_handle *pevent = event->pevent;
        unsigned long long function;
        unsigned long long pfunction;
        const char *func;
        const char *parent;
        int index = 0;
 
-       if (pevent_get_field_val(s, event, "ip", record, &function, 1))
+       if (tep_get_field_val(s, event, "ip", record, &function, 1))
                return trace_seq_putc(s, '!');
 
-       func = pevent_find_function(pevent, function);
+       func = tep_find_function(pevent, function);
 
-       if (pevent_get_field_val(s, event, "parent_ip", record, &pfunction, 1))
+       if (tep_get_field_val(s, event, "parent_ip", record, &pfunction, 1))
                return trace_seq_putc(s, '!');
 
-       parent = pevent_find_function(pevent, pfunction);
+       parent = tep_find_function(pevent, pfunction);
 
        if (parent && ftrace_indent->set)
                index = add_and_get_index(parent, func, record->cpu);
@@ -163,22 +163,22 @@ static int function_handler(struct trace_seq *s, struct pevent_record *record,
        return 0;
 }
 
-int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
 {
-       pevent_register_event_handler(pevent, -1, "ftrace", "function",
-                                     function_handler, NULL);
+       tep_register_event_handler(pevent, -1, "ftrace", "function",
+                                  function_handler, NULL);
 
-       traceevent_plugin_add_options("ftrace", plugin_options);
+       tep_plugin_add_options("ftrace", plugin_options);
 
        return 0;
 }
 
-void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
+void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
 {
        int i, x;
 
-       pevent_unregister_event_handler(pevent, -1, "ftrace", "function",
-                                       function_handler, NULL);
+       tep_unregister_event_handler(pevent, -1, "ftrace", "function",
+                                    function_handler, NULL);
 
        for (i = 0; i <= cpus; i++) {
                for (x = 0; x < fstack[i].size && fstack[i].stack[x]; x++)
@@ -186,7 +186,7 @@ void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
                free(fstack[i].stack);
        }
 
-       traceevent_plugin_remove_options(plugin_options);
+       tep_plugin_remove_options(plugin_options);
 
        free(fstack);
        fstack = NULL;
index 12bf14cc11529bbba356ce11b32294f84988c204..b43bfec565d83b34baa28357b33a8148e018a58c 100644 (file)
 #include "event-parse.h"
 
 static int timer_expire_handler(struct trace_seq *s,
-                               struct pevent_record *record,
+                               struct tep_record *record,
                                struct event_format *event, void *context)
 {
        trace_seq_printf(s, "hrtimer=");
 
-       if (pevent_print_num_field(s, "0x%llx", event, "timer",
-                                  record, 0) == -1)
-               pevent_print_num_field(s, "0x%llx", event, "hrtimer",
-                                      record, 1);
+       if (tep_print_num_field(s, "0x%llx", event, "timer",
+                               record, 0) == -1)
+               tep_print_num_field(s, "0x%llx", event, "hrtimer",
+                                   record, 1);
 
        trace_seq_printf(s, " now=");
 
-       pevent_print_num_field(s, "%llu", event, "now", record, 1);
+       tep_print_num_field(s, "%llu", event, "now", record, 1);
 
-       pevent_print_func_field(s, " function=%s", event, "function",
+       tep_print_func_field(s, " function=%s", event, "function",
                                record, 0);
        return 0;
 }
 
 static int timer_start_handler(struct trace_seq *s,
-                              struct pevent_record *record,
+                              struct tep_record *record,
                               struct event_format *event, void *context)
 {
        trace_seq_printf(s, "hrtimer=");
 
-       if (pevent_print_num_field(s, "0x%llx", event, "timer",
-                                  record, 0) == -1)
-               pevent_print_num_field(s, "0x%llx", event, "hrtimer",
-                                      record, 1);
+       if (tep_print_num_field(s, "0x%llx", event, "timer",
+                               record, 0) == -1)
+               tep_print_num_field(s, "0x%llx", event, "hrtimer",
+                                   record, 1);
 
-       pevent_print_func_field(s, " function=%s", event, "function",
-                               record, 0);
+       tep_print_func_field(s, " function=%s", event, "function",
+                            record, 0);
 
        trace_seq_printf(s, " expires=");
-       pevent_print_num_field(s, "%llu", event, "expires", record, 1);
+       tep_print_num_field(s, "%llu", event, "expires", record, 1);
 
        trace_seq_printf(s, " softexpires=");
-       pevent_print_num_field(s, "%llu", event, "softexpires", record, 1);
+       tep_print_num_field(s, "%llu", event, "softexpires", record, 1);
        return 0;
 }
 
-int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
 {
-       pevent_register_event_handler(pevent, -1,
-                                     "timer", "hrtimer_expire_entry",
-                                     timer_expire_handler, NULL);
+       tep_register_event_handler(pevent, -1,
+                                  "timer", "hrtimer_expire_entry",
+                                  timer_expire_handler, NULL);
 
-       pevent_register_event_handler(pevent, -1, "timer", "hrtimer_start",
-                                     timer_start_handler, NULL);
+       tep_register_event_handler(pevent, -1, "timer", "hrtimer_start",
+                                  timer_start_handler, NULL);
        return 0;
 }
 
-void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
+void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
 {
-       pevent_unregister_event_handler(pevent, -1,
-                                       "timer", "hrtimer_expire_entry",
-                                       timer_expire_handler, NULL);
+       tep_unregister_event_handler(pevent, -1,
+                                    "timer", "hrtimer_expire_entry",
+                                    timer_expire_handler, NULL);
 
-       pevent_unregister_event_handler(pevent, -1, "timer", "hrtimer_start",
-                                       timer_start_handler, NULL);
+       tep_unregister_event_handler(pevent, -1, "timer", "hrtimer_start",
+                                    timer_start_handler, NULL);
 }
index 5c23d5bd27ce815420fa8df5a7653f3c0f6d865d..45a9acd196409a638b8f53cd6d498556b5833a15 100644 (file)
@@ -47,29 +47,29 @@ process_jiffies_to_msecs(struct trace_seq *s, unsigned long long *args)
        return jiffies;
 }
 
-int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
 {
-       pevent_register_print_function(pevent,
-                                      process_jbd2_dev_to_name,
-                                      PEVENT_FUNC_ARG_STRING,
-                                      "jbd2_dev_to_name",
-                                      PEVENT_FUNC_ARG_INT,
-                                      PEVENT_FUNC_ARG_VOID);
+       tep_register_print_function(pevent,
+                                   process_jbd2_dev_to_name,
+                                   TEP_FUNC_ARG_STRING,
+                                   "jbd2_dev_to_name",
+                                   TEP_FUNC_ARG_INT,
+                                   TEP_FUNC_ARG_VOID);
 
-       pevent_register_print_function(pevent,
-                                      process_jiffies_to_msecs,
-                                      PEVENT_FUNC_ARG_LONG,
-                                      "jiffies_to_msecs",
-                                      PEVENT_FUNC_ARG_LONG,
-                                      PEVENT_FUNC_ARG_VOID);
+       tep_register_print_function(pevent,
+                                   process_jiffies_to_msecs,
+                                   TEP_FUNC_ARG_LONG,
+                                   "jiffies_to_msecs",
+                                   TEP_FUNC_ARG_LONG,
+                                   TEP_FUNC_ARG_VOID);
        return 0;
 }
 
-void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
+void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
 {
-       pevent_unregister_print_function(pevent, process_jbd2_dev_to_name,
-                                        "jbd2_dev_to_name");
+       tep_unregister_print_function(pevent, process_jbd2_dev_to_name,
+                                     "jbd2_dev_to_name");
 
-       pevent_unregister_print_function(pevent, process_jiffies_to_msecs,
-                                        "jiffies_to_msecs");
+       tep_unregister_print_function(pevent, process_jiffies_to_msecs,
+                                     "jiffies_to_msecs");
 }
index 70650ff48d78e4d7117396e796599294bbf2fa9c..73966b05abce3a726c104384edfca9d04766c30c 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "event-parse.h"
 
-static int call_site_handler(struct trace_seq *s, struct pevent_record *record,
+static int call_site_handler(struct trace_seq *s, struct tep_record *record,
                             struct event_format *event, void *context)
 {
        struct format_field *field;
@@ -31,64 +31,64 @@ static int call_site_handler(struct trace_seq *s, struct pevent_record *record,
        void *data = record->data;
        const char *func;
 
-       field = pevent_find_field(event, "call_site");
+       field = tep_find_field(event, "call_site");
        if (!field)
                return 1;
 
-       if (pevent_read_number_field(field, data, &val))
+       if (tep_read_number_field(field, data, &val))
                return 1;
 
-       func = pevent_find_function(event->pevent, val);
+       func = tep_find_function(event->pevent, val);
        if (!func)
                return 1;
 
-       addr = pevent_find_function_address(event->pevent, val);
+       addr = tep_find_function_address(event->pevent, val);
 
        trace_seq_printf(s, "(%s+0x%x) ", func, (int)(val - addr));
        return 1;
 }
 
-int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
 {
-       pevent_register_event_handler(pevent, -1, "kmem", "kfree",
-                                     call_site_handler, NULL);
+       tep_register_event_handler(pevent, -1, "kmem", "kfree",
+                                  call_site_handler, NULL);
 
-       pevent_register_event_handler(pevent, -1, "kmem", "kmalloc",
-                                     call_site_handler, NULL);
+       tep_register_event_handler(pevent, -1, "kmem", "kmalloc",
+                                  call_site_handler, NULL);
 
-       pevent_register_event_handler(pevent, -1, "kmem", "kmalloc_node",
-                                     call_site_handler, NULL);
+       tep_register_event_handler(pevent, -1, "kmem", "kmalloc_node",
+                                  call_site_handler, NULL);
 
-       pevent_register_event_handler(pevent, -1, "kmem", "kmem_cache_alloc",
-                                     call_site_handler, NULL);
+       tep_register_event_handler(pevent, -1, "kmem", "kmem_cache_alloc",
+                                  call_site_handler, NULL);
 
-       pevent_register_event_handler(pevent, -1, "kmem",
-                                     "kmem_cache_alloc_node",
-                                     call_site_handler, NULL);
+       tep_register_event_handler(pevent, -1, "kmem",
+                                  "kmem_cache_alloc_node",
+                                  call_site_handler, NULL);
 
-       pevent_register_event_handler(pevent, -1, "kmem", "kmem_cache_free",
-                                     call_site_handler, NULL);
+       tep_register_event_handler(pevent, -1, "kmem", "kmem_cache_free",
+                                  call_site_handler, NULL);
        return 0;
 }
 
-void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
+void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
 {
-       pevent_unregister_event_handler(pevent, -1, "kmem", "kfree",
-                                       call_site_handler, NULL);
+       tep_unregister_event_handler(pevent, -1, "kmem", "kfree",
+                                    call_site_handler, NULL);
 
-       pevent_unregister_event_handler(pevent, -1, "kmem", "kmalloc",
-                                       call_site_handler, NULL);
+       tep_unregister_event_handler(pevent, -1, "kmem", "kmalloc",
+                                    call_site_handler, NULL);
 
-       pevent_unregister_event_handler(pevent, -1, "kmem", "kmalloc_node",
-                                       call_site_handler, NULL);
+       tep_unregister_event_handler(pevent, -1, "kmem", "kmalloc_node",
+                                    call_site_handler, NULL);
 
-       pevent_unregister_event_handler(pevent, -1, "kmem", "kmem_cache_alloc",
-                                       call_site_handler, NULL);
+       tep_unregister_event_handler(pevent, -1, "kmem", "kmem_cache_alloc",
+                                    call_site_handler, NULL);
 
-       pevent_unregister_event_handler(pevent, -1, "kmem",
-                                       "kmem_cache_alloc_node",
-                                       call_site_handler, NULL);
+       tep_unregister_event_handler(pevent, -1, "kmem",
+                                    "kmem_cache_alloc_node",
+                                    call_site_handler, NULL);
 
-       pevent_unregister_event_handler(pevent, -1, "kmem", "kmem_cache_free",
-                                       call_site_handler, NULL);
+       tep_unregister_event_handler(pevent, -1, "kmem", "kmem_cache_free",
+                                    call_site_handler, NULL);
 }
index 18536f7565773b84dd29cb7a65b5df851dd4b005..1d0d159062251837f84e0133be46d922e4b4f9d9 100644 (file)
@@ -247,17 +247,17 @@ static const char *find_exit_reason(unsigned isa, int val)
        return strings[i].str;
 }
 
-static int print_exit_reason(struct trace_seq *s, struct pevent_record *record,
+static int print_exit_reason(struct trace_seq *s, struct tep_record *record,
                             struct event_format *event, const char *field)
 {
        unsigned long long isa;
        unsigned long long val;
        const char *reason;
 
-       if (pevent_get_field_val(s, event, field, record, &val, 1) < 0)
+       if (tep_get_field_val(s, event, field, record, &val, 1) < 0)
                return -1;
 
-       if (pevent_get_field_val(s, event, "isa", record, &isa, 0) < 0)
+       if (tep_get_field_val(s, event, "isa", record, &isa, 0) < 0)
                isa = 1;
 
        reason = find_exit_reason(isa, val);
@@ -268,7 +268,7 @@ static int print_exit_reason(struct trace_seq *s, struct pevent_record *record,
        return 0;
 }
 
-static int kvm_exit_handler(struct trace_seq *s, struct pevent_record *record,
+static int kvm_exit_handler(struct trace_seq *s, struct tep_record *record,
                            struct event_format *event, void *context)
 {
        unsigned long long info1 = 0, info2 = 0;
@@ -276,10 +276,10 @@ static int kvm_exit_handler(struct trace_seq *s, struct pevent_record *record,
        if (print_exit_reason(s, record, event, "exit_reason") < 0)
                return -1;
 
-       pevent_print_num_field(s, " rip 0x%lx", event, "guest_rip", record, 1);
+       tep_print_num_field(s, " rip 0x%lx", event, "guest_rip", record, 1);
 
-       if (pevent_get_field_val(s, event, "info1", record, &info1, 0) >= 0
-           && pevent_get_field_val(s, event, "info2", record, &info2, 0) >= 0)
+       if (tep_get_field_val(s, event, "info1", record, &info1, 0) >= 0
+           && tep_get_field_val(s, event, "info2", record, &info2, 0) >= 0)
                trace_seq_printf(s, " info %llx %llx", info1, info2);
 
        return 0;
@@ -291,7 +291,7 @@ static int kvm_exit_handler(struct trace_seq *s, struct pevent_record *record,
 #define KVM_EMUL_INSN_F_CS_L   (1 << 3)
 
 static int kvm_emulate_insn_handler(struct trace_seq *s,
-                                   struct pevent_record *record,
+                                   struct tep_record *record,
                                    struct event_format *event, void *context)
 {
        unsigned long long rip, csbase, len, flags, failed;
@@ -299,22 +299,22 @@ static int kvm_emulate_insn_handler(struct trace_seq *s,
        uint8_t *insn;
        const char *disasm;
 
-       if (pevent_get_field_val(s, event, "rip", record, &rip, 1) < 0)
+       if (tep_get_field_val(s, event, "rip", record, &rip, 1) < 0)
                return -1;
 
-       if (pevent_get_field_val(s, event, "csbase", record, &csbase, 1) < 0)
+       if (tep_get_field_val(s, event, "csbase", record, &csbase, 1) < 0)
                return -1;
 
-       if (pevent_get_field_val(s, event, "len", record, &len, 1) < 0)
+       if (tep_get_field_val(s, event, "len", record, &len, 1) < 0)
                return -1;
 
-       if (pevent_get_field_val(s, event, "flags", record, &flags, 1) < 0)
+       if (tep_get_field_val(s, event, "flags", record, &flags, 1) < 0)
                return -1;
 
-       if (pevent_get_field_val(s, event, "failed", record, &failed, 1) < 0)
+       if (tep_get_field_val(s, event, "failed", record, &failed, 1) < 0)
                return -1;
 
-       insn = pevent_get_field_raw(s, event, "insn", record, &llen, 1);
+       insn = tep_get_field_raw(s, event, "insn", record, &llen, 1);
        if (!insn)
                return -1;
 
@@ -330,24 +330,24 @@ static int kvm_emulate_insn_handler(struct trace_seq *s,
 }
 
 
-static int kvm_nested_vmexit_inject_handler(struct trace_seq *s, struct pevent_record *record,
+static int kvm_nested_vmexit_inject_handler(struct trace_seq *s, struct tep_record *record,
                                            struct event_format *event, void *context)
 {
        if (print_exit_reason(s, record, event, "exit_code") < 0)
                return -1;
 
-       pevent_print_num_field(s, " info1 %llx", event, "exit_info1", record, 1);
-       pevent_print_num_field(s, " info2 %llx", event, "exit_info2", record, 1);
-       pevent_print_num_field(s, " int_info %llx", event, "exit_int_info", record, 1);
-       pevent_print_num_field(s, " int_info_err %llx", event, "exit_int_info_err", record, 1);
+       tep_print_num_field(s, " info1 %llx", event, "exit_info1", record, 1);
+       tep_print_num_field(s, " info2 %llx", event, "exit_info2", record, 1);
+       tep_print_num_field(s, " int_info %llx", event, "exit_int_info", record, 1);
+       tep_print_num_field(s, " int_info_err %llx", event, "exit_int_info_err", record, 1);
 
        return 0;
 }
 
-static int kvm_nested_vmexit_handler(struct trace_seq *s, struct pevent_record *record,
+static int kvm_nested_vmexit_handler(struct trace_seq *s, struct tep_record *record,
                                     struct event_format *event, void *context)
 {
-       pevent_print_num_field(s, "rip %llx ", event, "rip", record, 1);
+       tep_print_num_field(s, "rip %llx ", event, "rip", record, 1);
 
        return kvm_nested_vmexit_inject_handler(s, record, event, context);
 }
@@ -370,7 +370,7 @@ union kvm_mmu_page_role {
        };
 };
 
-static int kvm_mmu_print_role(struct trace_seq *s, struct pevent_record *record,
+static int kvm_mmu_print_role(struct trace_seq *s, struct tep_record *record,
                              struct event_format *event, void *context)
 {
        unsigned long long val;
@@ -379,7 +379,7 @@ static int kvm_mmu_print_role(struct trace_seq *s, struct pevent_record *record,
        };
        union kvm_mmu_page_role role;
 
-       if (pevent_get_field_val(s, event, "role", record, &val, 1) < 0)
+       if (tep_get_field_val(s, event, "role", record, &val, 1) < 0)
                return -1;
 
        role.word = (int)val;
@@ -388,8 +388,8 @@ static int kvm_mmu_print_role(struct trace_seq *s, struct pevent_record *record,
         * We can only use the structure if file is of the same
         * endianess.
         */
-       if (pevent_is_file_bigendian(event->pevent) ==
-           pevent_is_host_bigendian(event->pevent)) {
+       if (tep_is_file_bigendian(event->pevent) ==
+           tep_is_host_bigendian(event->pevent)) {
 
                trace_seq_printf(s, "%u q%u%s %s%s %spae %snxe %swp%s%s%s",
                                 role.level,
@@ -406,10 +406,10 @@ static int kvm_mmu_print_role(struct trace_seq *s, struct pevent_record *record,
        } else
                trace_seq_printf(s, "WORD: %08x", role.word);
 
-       pevent_print_num_field(s, " root %u ",  event,
-                              "root_count", record, 1);
+       tep_print_num_field(s, " root %u ",  event,
+                           "root_count", record, 1);
 
-       if (pevent_get_field_val(s, event, "unsync", record, &val, 1) < 0)
+       if (tep_get_field_val(s, event, "unsync", record, &val, 1) < 0)
                return -1;
 
        trace_seq_printf(s, "%s%c",  val ? "unsync" : "sync", 0);
@@ -417,17 +417,17 @@ static int kvm_mmu_print_role(struct trace_seq *s, struct pevent_record *record,
 }
 
 static int kvm_mmu_get_page_handler(struct trace_seq *s,
-                                   struct pevent_record *record,
+                                   struct tep_record *record,
                                    struct event_format *event, void *context)
 {
        unsigned long long val;
 
-       if (pevent_get_field_val(s, event, "created", record, &val, 1) < 0)
+       if (tep_get_field_val(s, event, "created", record, &val, 1) < 0)
                return -1;
 
        trace_seq_printf(s, "%s ", val ? "new" : "existing");
 
-       if (pevent_get_field_val(s, event, "gfn", record, &val, 1) < 0)
+       if (tep_get_field_val(s, event, "gfn", record, &val, 1) < 0)
                return -1;
 
        trace_seq_printf(s, "sp gfn %llx ", val);
@@ -444,79 +444,79 @@ process_is_writable_pte(struct trace_seq *s, unsigned long long *args)
        return pte & PT_WRITABLE_MASK;
 }
 
-int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
 {
        init_disassembler();
 
-       pevent_register_event_handler(pevent, -1, "kvm", "kvm_exit",
-                                     kvm_exit_handler, NULL);
+       tep_register_event_handler(pevent, -1, "kvm", "kvm_exit",
+                                  kvm_exit_handler, NULL);
 
-       pevent_register_event_handler(pevent, -1, "kvm", "kvm_emulate_insn",
-                                     kvm_emulate_insn_handler, NULL);
+       tep_register_event_handler(pevent, -1, "kvm", "kvm_emulate_insn",
+                                  kvm_emulate_insn_handler, NULL);
 
-       pevent_register_event_handler(pevent, -1, "kvm", "kvm_nested_vmexit",
-                                     kvm_nested_vmexit_handler, NULL);
+       tep_register_event_handler(pevent, -1, "kvm", "kvm_nested_vmexit",
+                                  kvm_nested_vmexit_handler, NULL);
 
-       pevent_register_event_handler(pevent, -1, "kvm", "kvm_nested_vmexit_inject",
-                                     kvm_nested_vmexit_inject_handler, NULL);
+       tep_register_event_handler(pevent, -1, "kvm", "kvm_nested_vmexit_inject",
+                                  kvm_nested_vmexit_inject_handler, NULL);
 
-       pevent_register_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_get_page",
-                                     kvm_mmu_get_page_handler, NULL);
+       tep_register_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_get_page",
+                                  kvm_mmu_get_page_handler, NULL);
 
-       pevent_register_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_sync_page",
-                                     kvm_mmu_print_role, NULL);
+       tep_register_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_sync_page",
+                                  kvm_mmu_print_role, NULL);
 
-       pevent_register_event_handler(pevent, -1,
-                                     "kvmmmu", "kvm_mmu_unsync_page",
-                                     kvm_mmu_print_role, NULL);
+       tep_register_event_handler(pevent, -1,
+                                  "kvmmmu", "kvm_mmu_unsync_page",
+                                  kvm_mmu_print_role, NULL);
 
-       pevent_register_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_zap_page",
-                                     kvm_mmu_print_role, NULL);
+       tep_register_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_zap_page",
+                                  kvm_mmu_print_role, NULL);
 
-       pevent_register_event_handler(pevent, -1, "kvmmmu",
+       tep_register_event_handler(pevent, -1, "kvmmmu",
                        "kvm_mmu_prepare_zap_page", kvm_mmu_print_role,
                        NULL);
 
-       pevent_register_print_function(pevent,
-                                      process_is_writable_pte,
-                                      PEVENT_FUNC_ARG_INT,
-                                      "is_writable_pte",
-                                      PEVENT_FUNC_ARG_LONG,
-                                      PEVENT_FUNC_ARG_VOID);
+       tep_register_print_function(pevent,
+                                   process_is_writable_pte,
+                                   TEP_FUNC_ARG_INT,
+                                   "is_writable_pte",
+                                   TEP_FUNC_ARG_LONG,
+                                   TEP_FUNC_ARG_VOID);
        return 0;
 }
 
-void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
+void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
 {
-       pevent_unregister_event_handler(pevent, -1, "kvm", "kvm_exit",
-                                       kvm_exit_handler, NULL);
+       tep_unregister_event_handler(pevent, -1, "kvm", "kvm_exit",
+                                    kvm_exit_handler, NULL);
 
-       pevent_unregister_event_handler(pevent, -1, "kvm", "kvm_emulate_insn",
-                                       kvm_emulate_insn_handler, NULL);
+       tep_unregister_event_handler(pevent, -1, "kvm", "kvm_emulate_insn",
+                                    kvm_emulate_insn_handler, NULL);
 
-       pevent_unregister_event_handler(pevent, -1, "kvm", "kvm_nested_vmexit",
-                                       kvm_nested_vmexit_handler, NULL);
+       tep_unregister_event_handler(pevent, -1, "kvm", "kvm_nested_vmexit",
+                                    kvm_nested_vmexit_handler, NULL);
 
-       pevent_unregister_event_handler(pevent, -1, "kvm", "kvm_nested_vmexit_inject",
-                                       kvm_nested_vmexit_inject_handler, NULL);
+       tep_unregister_event_handler(pevent, -1, "kvm", "kvm_nested_vmexit_inject",
+                                    kvm_nested_vmexit_inject_handler, NULL);
 
-       pevent_unregister_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_get_page",
-                                       kvm_mmu_get_page_handler, NULL);
+       tep_unregister_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_get_page",
+                                    kvm_mmu_get_page_handler, NULL);
 
-       pevent_unregister_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_sync_page",
-                                       kvm_mmu_print_role, NULL);
+       tep_unregister_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_sync_page",
+                                    kvm_mmu_print_role, NULL);
 
-       pevent_unregister_event_handler(pevent, -1,
-                                       "kvmmmu", "kvm_mmu_unsync_page",
-                                       kvm_mmu_print_role, NULL);
+       tep_unregister_event_handler(pevent, -1,
+                                    "kvmmmu", "kvm_mmu_unsync_page",
+                                    kvm_mmu_print_role, NULL);
 
-       pevent_unregister_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_zap_page",
-                                       kvm_mmu_print_role, NULL);
+       tep_unregister_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_zap_page",
+                                    kvm_mmu_print_role, NULL);
 
-       pevent_unregister_event_handler(pevent, -1, "kvmmmu",
+       tep_unregister_event_handler(pevent, -1, "kvmmmu",
                        "kvm_mmu_prepare_zap_page", kvm_mmu_print_role,
                        NULL);
 
-       pevent_unregister_print_function(pevent, process_is_writable_pte,
-                                        "is_writable_pte");
+       tep_unregister_print_function(pevent, process_is_writable_pte,
+                                     "is_writable_pte");
 }
index 7e15a0f1c2fd280fd8f2365d0bbd214cd7415b87..de50a531620306e1f458aa85da65a64013b8dd34 100644 (file)
@@ -28,7 +28,7 @@
 static void print_string(struct trace_seq *s, struct event_format *event,
                         const char *name, const void *data)
 {
-       struct format_field *f = pevent_find_field(event, name);
+       struct format_field *f = tep_find_field(event, name);
        int offset;
        int length;
 
@@ -42,7 +42,7 @@ static void print_string(struct trace_seq *s, struct event_format *event,
 
        if (!strncmp(f->type, "__data_loc", 10)) {
                unsigned long long v;
-               if (pevent_read_number_field(f, data, &v)) {
+               if (tep_read_number_field(f, data, &v)) {
                        trace_seq_printf(s, "invalid_data_loc");
                        return;
                }
@@ -53,12 +53,12 @@ static void print_string(struct trace_seq *s, struct event_format *event,
        trace_seq_printf(s, "%.*s", length, (char *)data + offset);
 }
 
-#define SF(fn) pevent_print_num_field(s, fn ":%d", event, fn, record, 0)
-#define SFX(fn)        pevent_print_num_field(s, fn ":%#x", event, fn, record, 0)
+#define SF(fn) tep_print_num_field(s, fn ":%d", event, fn, record, 0)
+#define SFX(fn)        tep_print_num_field(s, fn ":%#x", event, fn, record, 0)
 #define SP()   trace_seq_putc(s, ' ')
 
 static int drv_bss_info_changed(struct trace_seq *s,
-                               struct pevent_record *record,
+                               struct tep_record *record,
                                struct event_format *event, void *context)
 {
        void *data = record->data;
@@ -66,7 +66,7 @@ static int drv_bss_info_changed(struct trace_seq *s,
        print_string(s, event, "wiphy_name", data);
        trace_seq_printf(s, " vif:");
        print_string(s, event, "vif_name", data);
-       pevent_print_num_field(s, "(%d)", event, "vif_type", record, 1);
+       tep_print_num_field(s, "(%d)", event, "vif_type", record, 1);
 
        trace_seq_printf(s, "\n%*s", INDENT, "");
        SF("assoc"); SP();
@@ -86,17 +86,17 @@ static int drv_bss_info_changed(struct trace_seq *s,
        return 0;
 }
 
-int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
 {
-       pevent_register_event_handler(pevent, -1, "mac80211",
-                                     "drv_bss_info_changed",
-                                     drv_bss_info_changed, NULL);
+       tep_register_event_handler(pevent, -1, "mac80211",
+                                  "drv_bss_info_changed",
+                                  drv_bss_info_changed, NULL);
        return 0;
 }
 
-void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
+void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
 {
-       pevent_unregister_event_handler(pevent, -1, "mac80211",
-                                       "drv_bss_info_changed",
-                                       drv_bss_info_changed, NULL);
+       tep_unregister_event_handler(pevent, -1, "mac80211",
+                                    "drv_bss_info_changed",
+                                    drv_bss_info_changed, NULL);
 }
index ec30c2fcbac05c2bef0268ac9494c0c5b4254a23..eecb4bd95c11b6c4807ad879fee21ff3fee35df8 100644 (file)
@@ -45,7 +45,7 @@ static void write_state(struct trace_seq *s, int val)
 }
 
 static void write_and_save_comm(struct format_field *field,
-                               struct pevent_record *record,
+                               struct tep_record *record,
                                struct trace_seq *s, int pid)
 {
        const char *comm;
@@ -61,100 +61,100 @@ static void write_and_save_comm(struct format_field *field,
        comm = &s->buffer[len];
 
        /* Help out the comm to ids. This will handle dups */
-       pevent_register_comm(field->event->pevent, comm, pid);
+       tep_register_comm(field->event->pevent, comm, pid);
 }
 
 static int sched_wakeup_handler(struct trace_seq *s,
-                               struct pevent_record *record,
+                               struct tep_record *record,
                                struct event_format *event, void *context)
 {
        struct format_field *field;
        unsigned long long val;
 
-       if (pevent_get_field_val(s, event, "pid", record, &val, 1))
+       if (tep_get_field_val(s, event, "pid", record, &val, 1))
                return trace_seq_putc(s, '!');
 
-       field = pevent_find_any_field(event, "comm");
+       field = tep_find_any_field(event, "comm");
        if (field) {
                write_and_save_comm(field, record, s, val);
                trace_seq_putc(s, ':');
        }
        trace_seq_printf(s, "%lld", val);
 
-       if (pevent_get_field_val(s, event, "prio", record, &val, 0) == 0)
+       if (tep_get_field_val(s, event, "prio", record, &val, 0) == 0)
                trace_seq_printf(s, " [%lld]", val);
 
-       if (pevent_get_field_val(s, event, "success", record, &val, 1) == 0)
+       if (tep_get_field_val(s, event, "success", record, &val, 1) == 0)
                trace_seq_printf(s, " success=%lld", val);
 
-       if (pevent_get_field_val(s, event, "target_cpu", record, &val, 0) == 0)
+       if (tep_get_field_val(s, event, "target_cpu", record, &val, 0) == 0)
                trace_seq_printf(s, " CPU:%03llu", val);
 
        return 0;
 }
 
 static int sched_switch_handler(struct trace_seq *s,
-                               struct pevent_record *record,
+                               struct tep_record *record,
                                struct event_format *event, void *context)
 {
        struct format_field *field;
        unsigned long long val;
 
-       if (pevent_get_field_val(s, event, "prev_pid", record, &val, 1))
+       if (tep_get_field_val(s, event, "prev_pid", record, &val, 1))
                return trace_seq_putc(s, '!');
 
-       field = pevent_find_any_field(event, "prev_comm");
+       field = tep_find_any_field(event, "prev_comm");
        if (field) {
                write_and_save_comm(field, record, s, val);
                trace_seq_putc(s, ':');
        }
        trace_seq_printf(s, "%lld ", val);
 
-       if (pevent_get_field_val(s, event, "prev_prio", record, &val, 0) == 0)
+       if (tep_get_field_val(s, event, "prev_prio", record, &val, 0) == 0)
                trace_seq_printf(s, "[%d] ", (int) val);
 
-       if (pevent_get_field_val(s,  event, "prev_state", record, &val, 0) == 0)
+       if (tep_get_field_val(s,  event, "prev_state", record, &val, 0) == 0)
                write_state(s, val);
 
        trace_seq_puts(s, " ==> ");
 
-       if (pevent_get_field_val(s, event, "next_pid", record, &val, 1))
+       if (tep_get_field_val(s, event, "next_pid", record, &val, 1))
                return trace_seq_putc(s, '!');
 
-       field = pevent_find_any_field(event, "next_comm");
+       field = tep_find_any_field(event, "next_comm");
        if (field) {
                write_and_save_comm(field, record, s, val);
                trace_seq_putc(s, ':');
        }
        trace_seq_printf(s, "%lld", val);
 
-       if (pevent_get_field_val(s, event, "next_prio", record, &val, 0) == 0)
+       if (tep_get_field_val(s, event, "next_prio", record, &val, 0) == 0)
                trace_seq_printf(s, " [%d]", (int) val);
 
        return 0;
 }
 
-int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
 {
-       pevent_register_event_handler(pevent, -1, "sched", "sched_switch",
-                                     sched_switch_handler, NULL);
+       tep_register_event_handler(pevent, -1, "sched", "sched_switch",
+                                  sched_switch_handler, NULL);
 
-       pevent_register_event_handler(pevent, -1, "sched", "sched_wakeup",
-                                     sched_wakeup_handler, NULL);
+       tep_register_event_handler(pevent, -1, "sched", "sched_wakeup",
+                                  sched_wakeup_handler, NULL);
 
-       pevent_register_event_handler(pevent, -1, "sched", "sched_wakeup_new",
-                                     sched_wakeup_handler, NULL);
+       tep_register_event_handler(pevent, -1, "sched", "sched_wakeup_new",
+                                  sched_wakeup_handler, NULL);
        return 0;
 }
 
-void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
+void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
 {
-       pevent_unregister_event_handler(pevent, -1, "sched", "sched_switch",
-                                       sched_switch_handler, NULL);
+       tep_unregister_event_handler(pevent, -1, "sched", "sched_switch",
+                                    sched_switch_handler, NULL);
 
-       pevent_unregister_event_handler(pevent, -1, "sched", "sched_wakeup",
-                                       sched_wakeup_handler, NULL);
+       tep_unregister_event_handler(pevent, -1, "sched", "sched_wakeup",
+                                    sched_wakeup_handler, NULL);
 
-       pevent_unregister_event_handler(pevent, -1, "sched", "sched_wakeup_new",
-                                       sched_wakeup_handler, NULL);
+       tep_unregister_event_handler(pevent, -1, "sched", "sched_wakeup_new",
+                                    sched_wakeup_handler, NULL);
 }
index 5e750af2b461f7e47bbf86ea21be1180a27c94b7..5ec346f6b8425cc33a52b8267680fad7d54d0d74 100644 (file)
@@ -413,21 +413,21 @@ unsigned long long process_scsi_trace_parse_cdb(struct trace_seq *s,
        return 0;
 }
 
-int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
 {
-       pevent_register_print_function(pevent,
-                                      process_scsi_trace_parse_cdb,
-                                      PEVENT_FUNC_ARG_STRING,
-                                      "scsi_trace_parse_cdb",
-                                      PEVENT_FUNC_ARG_PTR,
-                                      PEVENT_FUNC_ARG_PTR,
-                                      PEVENT_FUNC_ARG_INT,
-                                      PEVENT_FUNC_ARG_VOID);
+       tep_register_print_function(pevent,
+                                   process_scsi_trace_parse_cdb,
+                                   TEP_FUNC_ARG_STRING,
+                                   "scsi_trace_parse_cdb",
+                                   TEP_FUNC_ARG_PTR,
+                                   TEP_FUNC_ARG_PTR,
+                                   TEP_FUNC_ARG_INT,
+                                   TEP_FUNC_ARG_VOID);
        return 0;
 }
 
-void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
+void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
 {
-       pevent_unregister_print_function(pevent, process_scsi_trace_parse_cdb,
-                                        "scsi_trace_parse_cdb");
+       tep_unregister_print_function(pevent, process_scsi_trace_parse_cdb,
+                                     "scsi_trace_parse_cdb");
 }
index 690173bfa13edb51d82b2e2eb7b4529b190f2958..b2acbd6e9c86c5677fcf39e3fe966c21eb330bc4 100644 (file)
@@ -119,19 +119,19 @@ unsigned long long process_xen_hypercall_name(struct trace_seq *s,
        return 0;
 }
 
-int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
+int TEP_PLUGIN_LOADER(struct tep_handle *pevent)
 {
-       pevent_register_print_function(pevent,
-                                      process_xen_hypercall_name,
-                                      PEVENT_FUNC_ARG_STRING,
-                                      "xen_hypercall_name",
-                                      PEVENT_FUNC_ARG_INT,
-                                      PEVENT_FUNC_ARG_VOID);
+       tep_register_print_function(pevent,
+                                   process_xen_hypercall_name,
+                                   TEP_FUNC_ARG_STRING,
+                                   "xen_hypercall_name",
+                                   TEP_FUNC_ARG_INT,
+                                   TEP_FUNC_ARG_VOID);
        return 0;
 }
 
-void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
+void TEP_PLUGIN_UNLOADER(struct tep_handle *pevent)
 {
-       pevent_unregister_print_function(pevent, process_xen_hypercall_name,
-                                        "xen_hypercall_name");
+       tep_unregister_print_function(pevent, process_xen_hypercall_name,
+                                     "xen_hypercall_name");
 }
index 292dc9f1d2334f2a9cab35d70b1531d74f68fca4..e3bac4543d3b74b3414baa4cb1e3ba5418623e07 100644 (file)
@@ -1,21 +1,7 @@
+// SPDX-License-Identifier: LGPL-2.1
 /*
  * Copyright (C) 2009 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
  *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License (not later!)
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not,  see <http://www.gnu.org/licenses>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 #include <stdio.h>
 #include <stdlib.h>
index 749cc6055dac32ab1d30879bda29343eed3d887d..e8c972f89357d2dc47bbe57000e503f46d964f37 100644 (file)
@@ -118,6 +118,15 @@ OPTIONS
 --group::
        Show event group information together
 
+--percent-type::
+       Set annotation percent type from following choices:
+         global-period, local-period, global-hits, local-hits
+
+       The local/global keywords set if the percentage is computed
+       in the scope of the function (local) or the whole data (global).
+       The period/hits keywords set the base the percentage is computed
+       on - the samples period or the number of samples (hits).
+
 SEE ALSO
 --------
 linkperf:perf-record[1], linkperf:perf-report[1]
index 917e36fde6d8b5e30e2626a68ef4b01b2cae1929..474a4941f65dabdbc29911a7b324a0ff2fcd63e9 100644 (file)
@@ -477,6 +477,15 @@ include::itrace.txt[]
        Display monitored tasks stored in perf data. Displaying pid/tid/ppid
        plus the command string aligned to distinguish parent and child tasks.
 
+--percent-type::
+       Set annotation percent type from following choices:
+         global-period, local-period, global-hits, local-hits
+
+       The local/global keywords set if the percentage is computed
+       in the scope of the function (local) or the whole data (global).
+       The period/hits keywords set the base the percentage is computed
+       on - the samples period or the number of samples (hits).
+
 include::callchain-overhead-calculation.txt[]
 
 SEE ALSO
index 225454416ed54b2baea044ce46c794e23c708f71..7902a5681fc89f6eda64234de379fc8122567529 100644 (file)
@@ -84,10 +84,10 @@ endif # has_clean
 endif # MAKECMDGOALS
 
 #
-# The clean target is not really parallel, don't print the jobs info:
+# Explicitly disable parallelism for the clean target.
 #
 clean:
-       $(make)
+       $(make) -j1
 
 #
 # The build-test target is not really parallel, don't print the jobs info,
index 1120e39c1b001bb6f4915aa2c11dd821962b63ab..5ccfce87e6937794fd434f83b8e61bb159826510 100644 (file)
@@ -194,6 +194,7 @@ struct auxtrace_record *arm_spe_recording_init(int *err,
        sper->itr.read_finish = arm_spe_read_finish;
        sper->itr.alignment = 0;
 
+       *err = 0;
        return &sper->itr;
 }
 
index 53d83d7e6a096a4d49a0b6f0cbfafc15a27866af..20e7d74d86cd16e86c8fd60e5839222d476f6409 100644 (file)
@@ -141,8 +141,10 @@ void arch__post_process_probe_trace_events(struct perf_probe_event *pev,
        for (i = 0; i < ntevs; i++) {
                tev = &pev->tevs[i];
                map__for_each_symbol(map, sym, tmp) {
-                       if (map->unmap_ip(map, sym->start) == tev->point.address)
+                       if (map->unmap_ip(map, sym->start) == tev->point.address) {
                                arch__fix_tev_from_maps(pev, tev, map, sym);
+                               break;
+                       }
                }
        }
 }
index 3afe8256eff275ef94c277dfae9a8c865615d681..44c85738889740b6a81f444510274c64de497785 100644 (file)
@@ -30,6 +30,7 @@ cpumsf_info_fill(struct auxtrace_record *itr __maybe_unused,
                 struct auxtrace_info_event *auxtrace_info __maybe_unused,
                 size_t priv_size __maybe_unused)
 {
+       auxtrace_info->type = PERF_AUXTRACE_S390_CPUMSF;
        return 0;
 }
 
index 1a38e78117ce6f410cc0521e09fedeaa31cf8519..8cc6642fce7a6699e3e3fd816ced37d7ae627f5a 100644 (file)
@@ -19,9 +19,6 @@ systbl := $(sys)/syscalltbl.sh
 _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
 
 $(header): $(sys)/syscall_64.tbl $(systbl)
-       @(test -d ../../kernel -a -d ../../tools -a -d ../perf && ( \
-        (diff -B arch/x86/entry/syscalls/syscall_64.tbl ../../arch/x86/entry/syscalls/syscall_64.tbl >/dev/null) \
-        || echo "Warning: Kernel ABI header at 'tools/perf/arch/x86/entry/syscalls/syscall_64.tbl' differs from latest version at 'arch/x86/entry/syscalls/syscall_64.tbl'" >&2 )) || true
        $(Q)$(SHELL) '$(systbl)' $(sys)/syscall_64.tbl 'x86_64' > $@
 
 clean::
index 8180319285af3377810c30c0298f37c73cb9bb8d..830481b8db26ae379d7e9816c130bdb49be04bd7 100644 (file)
@@ -542,6 +542,10 @@ int cmd_annotate(int argc, const char **argv)
        OPT_CALLBACK_DEFAULT(0, "stdio-color", NULL, "mode",
                             "'always' (default), 'never' or 'auto' only applicable to --stdio mode",
                             stdio__config_color, "always"),
+       OPT_CALLBACK(0, "percent-type", &annotate.opts, "local-period",
+                    "Set percent type local/global-period/hits",
+                    annotate_parse_percent_type),
+
        OPT_END()
        };
        int ret;
index 54d3f21b0e623eced87ba6b57589b05152150f55..b63bca4b0c2a6ec466caac6aa094bc2d41e823ee 100644 (file)
@@ -729,7 +729,7 @@ static char *compact_gfp_string(unsigned long gfp_flags)
 static int parse_gfp_flags(struct perf_evsel *evsel, struct perf_sample *sample,
                           unsigned int gfp_flags)
 {
-       struct pevent_record record = {
+       struct tep_record record = {
                .cpu = sample->cpu,
                .data = sample->raw_data,
                .size = sample->raw_size,
@@ -747,7 +747,7 @@ static int parse_gfp_flags(struct perf_evsel *evsel, struct perf_sample *sample,
        }
 
        trace_seq_init(&seq);
-       pevent_event_info(&seq, evsel->tp_format, &record);
+       tep_event_info(&seq, evsel->tp_format, &record);
 
        str = strtok_r(seq.buffer, " ", &pos);
        while (str) {
@@ -1974,7 +1974,7 @@ int cmd_kmem(int argc, const char **argv)
                        goto out_delete;
                }
 
-               kmem_page_size = pevent_get_page_size(evsel->tp_format->pevent);
+               kmem_page_size = tep_get_page_size(evsel->tp_format->pevent);
                symbol_conf.use_callchain = true;
        }
 
index 02f7a3c27761f717b9e8c5cf39d4788b2014297b..76e12bcd17654a3185fdeeb88ab9a56b7e10c6ee 100644 (file)
@@ -1124,6 +1124,9 @@ int cmd_report(int argc, const char **argv)
                   "Time span of interest (start,stop)"),
        OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
                    "Show inline function"),
+       OPT_CALLBACK(0, "percent-type", &report.annotation_opts, "local-period",
+                    "Set percent type local/global-period/hits",
+                    annotate_parse_percent_type),
        OPT_END()
        };
        struct perf_data data = {
@@ -1366,9 +1369,9 @@ repeat:
        }
 
        if (session->tevent.pevent &&
-           pevent_set_function_resolver(session->tevent.pevent,
-                                        machine__resolve_kernel_addr,
-                                        &session->machines.host) < 0) {
+           tep_set_function_resolver(session->tevent.pevent,
+                                     machine__resolve_kernel_addr,
+                                     &session->machines.host) < 0) {
                pr_err("%s: failed to set libtraceevent function resolver\n",
                       __func__);
                return -1;
index 568ddfac3213e084c1f4c6077cd73943bf0644b9..ba481d73f910fbdf2388d02d24afe8747528ab2e 100644 (file)
@@ -3429,9 +3429,9 @@ int cmd_script(int argc, const char **argv)
                symbol_conf.use_callchain = false;
 
        if (session->tevent.pevent &&
-           pevent_set_function_resolver(session->tevent.pevent,
-                                        machine__resolve_kernel_addr,
-                                        &session->machines.host) < 0) {
+           tep_set_function_resolver(session->tevent.pevent,
+                                     machine__resolve_kernel_addr,
+                                     &session->machines.host) < 0) {
                pr_err("%s: failed to set libtraceevent function resolver\n", __func__);
                err = -1;
                goto out_delete;
index 88561eed79505f737570aeacd10cd0ec0b8db0b8..22ab8e67c7600865d7fc7a884feba24f15bbe66b 100644 (file)
@@ -77,7 +77,8 @@ struct trace {
                struct syscall  *table;
                struct {
                        struct perf_evsel *sys_enter,
-                                         *sys_exit;
+                                         *sys_exit,
+                                         *augmented;
                }               events;
        } syscalls;
        struct record_opts      opts;
@@ -121,7 +122,6 @@ struct trace {
        bool                    force;
        bool                    vfs_getname;
        int                     trace_pgfaults;
-       int                     open_id;
 };
 
 struct tp_field {
@@ -157,13 +157,11 @@ TP_UINT_FIELD__SWAPPED(16);
 TP_UINT_FIELD__SWAPPED(32);
 TP_UINT_FIELD__SWAPPED(64);
 
-static int tp_field__init_uint(struct tp_field *field,
-                              struct format_field *format_field,
-                              bool needs_swap)
+static int __tp_field__init_uint(struct tp_field *field, int size, int offset, bool needs_swap)
 {
-       field->offset = format_field->offset;
+       field->offset = offset;
 
-       switch (format_field->size) {
+       switch (size) {
        case 1:
                field->integer = tp_field__u8;
                break;
@@ -183,18 +181,28 @@ static int tp_field__init_uint(struct tp_field *field,
        return 0;
 }
 
+static int tp_field__init_uint(struct tp_field *field, struct format_field *format_field, bool needs_swap)
+{
+       return __tp_field__init_uint(field, format_field->size, format_field->offset, needs_swap);
+}
+
 static void *tp_field__ptr(struct tp_field *field, struct perf_sample *sample)
 {
        return sample->raw_data + field->offset;
 }
 
-static int tp_field__init_ptr(struct tp_field *field, struct format_field *format_field)
+static int __tp_field__init_ptr(struct tp_field *field, int offset)
 {
-       field->offset = format_field->offset;
+       field->offset = offset;
        field->pointer = tp_field__ptr;
        return 0;
 }
 
+static int tp_field__init_ptr(struct tp_field *field, struct format_field *format_field)
+{
+       return __tp_field__init_ptr(field, format_field->offset);
+}
+
 struct syscall_tp {
        struct tp_field id;
        union {
@@ -240,7 +248,47 @@ static void perf_evsel__delete_priv(struct perf_evsel *evsel)
        perf_evsel__delete(evsel);
 }
 
-static int perf_evsel__init_syscall_tp(struct perf_evsel *evsel, void *handler)
+static int perf_evsel__init_syscall_tp(struct perf_evsel *evsel)
+{
+       struct syscall_tp *sc = evsel->priv = malloc(sizeof(struct syscall_tp));
+
+       if (evsel->priv != NULL) {
+               if (perf_evsel__init_tp_uint_field(evsel, &sc->id, "__syscall_nr"))
+                       goto out_delete;
+               return 0;
+       }
+
+       return -ENOMEM;
+out_delete:
+       zfree(&evsel->priv);
+       return -ENOENT;
+}
+
+static int perf_evsel__init_augmented_syscall_tp(struct perf_evsel *evsel)
+{
+       struct syscall_tp *sc = evsel->priv = malloc(sizeof(struct syscall_tp));
+
+       if (evsel->priv != NULL) {       /* field, sizeof_field, offsetof_field */
+               if (__tp_field__init_uint(&sc->id, sizeof(long), sizeof(long long), evsel->needs_swap))
+                       goto out_delete;
+
+               return 0;
+       }
+
+       return -ENOMEM;
+out_delete:
+       zfree(&evsel->priv);
+       return -EINVAL;
+}
+
+static int perf_evsel__init_augmented_syscall_tp_args(struct perf_evsel *evsel)
+{
+       struct syscall_tp *sc = evsel->priv;
+
+       return __tp_field__init_ptr(&sc->args, sc->id.offset + sizeof(u64));
+}
+
+static int perf_evsel__init_raw_syscall_tp(struct perf_evsel *evsel, void *handler)
 {
        evsel->priv = malloc(sizeof(struct syscall_tp));
        if (evsel->priv != NULL) {
@@ -258,7 +306,7 @@ out_delete:
        return -ENOENT;
 }
 
-static struct perf_evsel *perf_evsel__syscall_newtp(const char *direction, void *handler)
+static struct perf_evsel *perf_evsel__raw_syscall_newtp(const char *direction, void *handler)
 {
        struct perf_evsel *evsel = perf_evsel__newtp("raw_syscalls", direction);
 
@@ -269,7 +317,7 @@ static struct perf_evsel *perf_evsel__syscall_newtp(const char *direction, void
        if (IS_ERR(evsel))
                return NULL;
 
-       if (perf_evsel__init_syscall_tp(evsel, handler))
+       if (perf_evsel__init_raw_syscall_tp(evsel, handler))
                goto out_delete;
 
        return evsel;
@@ -805,12 +853,17 @@ static struct syscall_fmt *syscall_fmt__find(const char *name)
        return bsearch(name, syscall_fmts, nmemb, sizeof(struct syscall_fmt), syscall_fmt__cmp);
 }
 
+/*
+ * is_exit: is this "exit" or "exit_group"?
+ * is_open: is this "open" or "openat"? To associate the fd returned in sys_exit with the pathname in sys_enter.
+ */
 struct syscall {
        struct event_format *tp_format;
        int                 nr_args;
+       bool                is_exit;
+       bool                is_open;
        struct format_field *args;
        const char          *name;
-       bool                is_exit;
        struct syscall_fmt  *fmt;
        struct syscall_arg_fmt *arg_fmt;
 };
@@ -1299,6 +1352,7 @@ static int trace__read_syscall_info(struct trace *trace, int id)
        }
 
        sc->is_exit = !strcmp(name, "exit_group") || !strcmp(name, "exit");
+       sc->is_open = !strcmp(name, "open") || !strcmp(name, "openat");
 
        return syscall__set_arg_fmts(sc);
 }
@@ -1661,6 +1715,37 @@ out_put:
        return err;
 }
 
+static int trace__fprintf_sys_enter(struct trace *trace, struct perf_evsel *evsel,
+                                   struct perf_sample *sample)
+{
+       struct thread_trace *ttrace;
+       struct thread *thread;
+       int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
+       struct syscall *sc = trace__syscall_info(trace, evsel, id);
+       char msg[1024];
+       void *args;
+
+       if (sc == NULL)
+               return -1;
+
+       thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
+       ttrace = thread__trace(thread, trace->output);
+       /*
+        * We need to get ttrace just to make sure it is there when syscall__scnprintf_args()
+        * and the rest of the beautifiers accessing it via struct syscall_arg touches it.
+        */
+       if (ttrace == NULL)
+               goto out_put;
+
+       args = perf_evsel__sc_tp_ptr(evsel, args, sample);
+       syscall__scnprintf_args(sc, msg, sizeof(msg), args, trace, thread);
+       fprintf(trace->output, "%s", msg);
+       err = 0;
+out_put:
+       thread__put(thread);
+       return err;
+}
+
 static int trace__resolve_callchain(struct trace *trace, struct perf_evsel *evsel,
                                    struct perf_sample *sample,
                                    struct callchain_cursor *cursor)
@@ -1722,7 +1807,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
 
        ret = perf_evsel__sc_tp_uint(evsel, ret, sample);
 
-       if (id == trace->open_id && ret >= 0 && ttrace->filename.pending_open) {
+       if (sc->is_open && ret >= 0 && ttrace->filename.pending_open) {
                trace__set_fd_pathname(thread, ret, ttrace->filename.name);
                ttrace->filename.pending_open = false;
                ++trace->stats.vfs_getname;
@@ -1957,11 +2042,17 @@ static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel,
        fprintf(trace->output, "%s:", evsel->name);
 
        if (perf_evsel__is_bpf_output(evsel)) {
-               bpf_output__fprintf(trace, sample);
+               if (evsel == trace->syscalls.events.augmented)
+                       trace__fprintf_sys_enter(trace, evsel, sample);
+               else
+                       bpf_output__fprintf(trace, sample);
        } else if (evsel->tp_format) {
-               event_format__fprintf(evsel->tp_format, sample->cpu,
-                                     sample->raw_data, sample->raw_size,
-                                     trace->output);
+               if (strncmp(evsel->tp_format->name, "sys_enter_", 10) ||
+                   trace__fprintf_sys_enter(trace, evsel, sample)) {
+                       event_format__fprintf(evsel->tp_format, sample->cpu,
+                                             sample->raw_data, sample->raw_size,
+                                             trace->output);
+               }
        }
 
        fprintf(trace->output, "\n");
@@ -2242,14 +2333,14 @@ static int trace__add_syscall_newtp(struct trace *trace)
        struct perf_evlist *evlist = trace->evlist;
        struct perf_evsel *sys_enter, *sys_exit;
 
-       sys_enter = perf_evsel__syscall_newtp("sys_enter", trace__sys_enter);
+       sys_enter = perf_evsel__raw_syscall_newtp("sys_enter", trace__sys_enter);
        if (sys_enter == NULL)
                goto out;
 
        if (perf_evsel__init_sc_tp_ptr_field(sys_enter, args))
                goto out_delete_sys_enter;
 
-       sys_exit = perf_evsel__syscall_newtp("sys_exit", trace__sys_exit);
+       sys_exit = perf_evsel__raw_syscall_newtp("sys_exit", trace__sys_exit);
        if (sys_exit == NULL)
                goto out_delete_sys_enter;
 
@@ -2671,7 +2762,7 @@ static int trace__replay(struct trace *trace)
                                                             "syscalls:sys_enter");
 
        if (evsel &&
-           (perf_evsel__init_syscall_tp(evsel, trace__sys_enter) < 0 ||
+           (perf_evsel__init_raw_syscall_tp(evsel, trace__sys_enter) < 0 ||
            perf_evsel__init_sc_tp_ptr_field(evsel, args))) {
                pr_err("Error during initialize raw_syscalls:sys_enter event\n");
                goto out;
@@ -2683,7 +2774,7 @@ static int trace__replay(struct trace *trace)
                evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
                                                             "syscalls:sys_exit");
        if (evsel &&
-           (perf_evsel__init_syscall_tp(evsel, trace__sys_exit) < 0 ||
+           (perf_evsel__init_raw_syscall_tp(evsel, trace__sys_exit) < 0 ||
            perf_evsel__init_sc_tp_uint_field(evsel, ret))) {
                pr_err("Error during initialize raw_syscalls:sys_exit event\n");
                goto out;
@@ -2923,6 +3014,36 @@ static void evlist__set_evsel_handler(struct perf_evlist *evlist, void *handler)
                evsel->handler = handler;
 }
 
+static int evlist__set_syscall_tp_fields(struct perf_evlist *evlist)
+{
+       struct perf_evsel *evsel;
+
+       evlist__for_each_entry(evlist, evsel) {
+               if (evsel->priv || !evsel->tp_format)
+                       continue;
+
+               if (strcmp(evsel->tp_format->system, "syscalls"))
+                       continue;
+
+               if (perf_evsel__init_syscall_tp(evsel))
+                       return -1;
+
+               if (!strncmp(evsel->tp_format->name, "sys_enter_", 10)) {
+                       struct syscall_tp *sc = evsel->priv;
+
+                       if (__tp_field__init_ptr(&sc->args, sc->id.offset + sizeof(u64)))
+                               return -1;
+               } else if (!strncmp(evsel->tp_format->name, "sys_exit_", 9)) {
+                       struct syscall_tp *sc = evsel->priv;
+
+                       if (__tp_field__init_uint(&sc->ret, sizeof(u64), sc->id.offset + sizeof(u64), evsel->needs_swap))
+                               return -1;
+               }
+       }
+
+       return 0;
+}
+
 /*
  * XXX: Hackish, just splitting the combined -e+--event (syscalls
  * (raw_syscalls:{sys_{enter,exit}} + events (tracepoints, HW, SW, etc) to use
@@ -3123,8 +3244,9 @@ int cmd_trace(int argc, const char **argv)
        };
        bool __maybe_unused max_stack_user_set = true;
        bool mmap_pages_user_set = true;
+       struct perf_evsel *evsel;
        const char * const trace_subcommands[] = { "record", NULL };
-       int err;
+       int err = -1;
        char bf[BUFSIZ];
 
        signal(SIGSEGV, sighandler_dump_stack);
@@ -3147,6 +3269,20 @@ int cmd_trace(int argc, const char **argv)
                                       "cgroup monitoring only available in system-wide mode");
        }
 
+       evsel = bpf__setup_output_event(trace.evlist, "__augmented_syscalls__");
+       if (IS_ERR(evsel)) {
+               bpf__strerror_setup_output_event(trace.evlist, PTR_ERR(evsel), bf, sizeof(bf));
+               pr_err("ERROR: Setup trace syscalls enter failed: %s\n", bf);
+               goto out;
+       }
+
+       if (evsel) {
+               if (perf_evsel__init_augmented_syscall_tp(evsel) ||
+                   perf_evsel__init_augmented_syscall_tp_args(evsel))
+                       goto out;
+               trace.syscalls.events.augmented = evsel;
+       }
+
        err = bpf__setup_stdout(trace.evlist);
        if (err) {
                bpf__strerror_setup_stdout(trace.evlist, err, bf, sizeof(bf));
@@ -3182,8 +3318,13 @@ int cmd_trace(int argc, const char **argv)
                symbol_conf.use_callchain = true;
        }
 
-       if (trace.evlist->nr_entries > 0)
+       if (trace.evlist->nr_entries > 0) {
                evlist__set_evsel_handler(trace.evlist, trace__event_handler);
+               if (evlist__set_syscall_tp_fields(trace.evlist)) {
+                       perror("failed to set syscalls:* tracepoint fields");
+                       goto out;
+               }
+       }
 
        if ((argc >= 1) && (strcmp(argv[0], "record") == 0))
                return trace__record(&trace, argc-1, &argv[1]);
@@ -3205,8 +3346,6 @@ int cmd_trace(int argc, const char **argv)
                }
        }
 
-       trace.open_id = syscalltbl__id(trace.sctbl, "open");
-
        err = target__validate(&trace.opts.target);
        if (err) {
                target__strerror(&trace.opts.target, err, bf, sizeof(bf));
index de28466c0186bf78652c99926c5449eaa5dc6a0b..466540ee8ea79f18743658bd76903531829cfffb 100755 (executable)
@@ -67,8 +67,12 @@ check_2 () {
 
   cmd="diff $* $file1 $file2 > /dev/null"
 
-  test -f $file2 &&
-  eval $cmd || echo "Warning: Kernel ABI header at 'tools/$file' differs from latest version at '$file'" >&2
+  test -f $file2 && {
+    eval $cmd || {
+      echo "Warning: Kernel ABI header at '$file1' differs from latest version at '$file2'" >&2
+      echo diff -u $file1 $file2
+    }
+  }
 }
 
 check () {
@@ -76,7 +80,7 @@ check () {
 
   shift
 
-  check_2 ../$file ../../$file $*
+  check_2 tools/$file $file $*
 }
 
 # Check if we have the kernel headers (tools/perf/../../include), else
@@ -84,6 +88,8 @@ check () {
 # differences.
 test -d ../../include || exit 0
 
+cd ../..
+
 # simple diff check
 for i in $HEADERS; do
   check $i -B
@@ -94,3 +100,8 @@ check arch/x86/lib/memcpy_64.S        '-I "^EXPORT_SYMBOL" -I "^#include <asm/ex
 check arch/x86/lib/memset_64.S        '-I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>"'
 check include/uapi/asm-generic/mman.h '-I "^#include <\(uapi/\)*asm-generic/mman-common.h>"'
 check include/uapi/linux/mman.h       '-I "^#include <\(uapi/\)*asm/mman.h>"'
+
+# diff non-symmetric files
+check_2 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscalls/syscall_64.tbl
+
+cd tools/perf
diff --git a/tools/perf/examples/bpf/augmented_syscalls.c b/tools/perf/examples/bpf/augmented_syscalls.c
new file mode 100644 (file)
index 0000000..69a3138
--- /dev/null
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Augment the openat syscall with the contents of the filename pointer argument.
+ *
+ * Test it with:
+ *
+ * perf trace -e tools/perf/examples/bpf/augmented_syscalls.c cat /etc/passwd > /dev/null
+ *
+ * It'll catch some openat syscalls related to the dynamic linked and
+ * the last one should be the one for '/etc/passwd'.
+ *
+ * This matches what is marshalled into the raw_syscall:sys_enter payload
+ * expected by the 'perf trace' beautifiers, and can be used by them unmodified,
+ * which will be done as that feature is implemented in the next csets, for now
+ * it will appear in a dump done by the default tracepoint handler in 'perf trace',
+ * that uses bpf_output__fprintf() to just dump those contents, as done with
+ * the bpf-output event associated with the __bpf_output__ map declared in
+ * tools/perf/include/bpf/stdio.h.
+ */
+
+#include <stdio.h>
+
+struct bpf_map SEC("maps") __augmented_syscalls__ = {
+       .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
+       .key_size = sizeof(int),
+       .value_size = sizeof(u32),
+       .max_entries = __NR_CPUS__,
+};
+
+struct syscall_enter_openat_args {
+       unsigned long long common_tp_fields;
+       long               syscall_nr;
+       long               dfd;
+       char               *filename_ptr;
+       long               flags;
+       long               mode;
+};
+
+struct augmented_enter_openat_args {
+       struct syscall_enter_openat_args args;
+       char                             filename[64];
+};
+
+int syscall_enter(openat)(struct syscall_enter_openat_args *args)
+{
+       struct augmented_enter_openat_args augmented_args;
+
+       probe_read(&augmented_args.args, sizeof(augmented_args.args), args);
+       probe_read_str(&augmented_args.filename, sizeof(augmented_args.filename), args->filename_ptr);
+       perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU,
+                         &augmented_args, sizeof(augmented_args));
+       return 1;
+}
+
+license(GPL);
diff --git a/tools/perf/examples/bpf/hello.c b/tools/perf/examples/bpf/hello.c
new file mode 100644 (file)
index 0000000..cf3c2fd
--- /dev/null
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int syscall_enter(openat)(void *args)
+{
+       puts("Hello, world\n");
+       return 0;
+}
+
+license(GPL);
diff --git a/tools/perf/examples/bpf/sys_enter_openat.c b/tools/perf/examples/bpf/sys_enter_openat.c
new file mode 100644 (file)
index 0000000..9cd124b
--- /dev/null
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Hook into 'openat' syscall entry tracepoint
+ *
+ * Test it with:
+ *
+ * perf trace -e tools/perf/examples/bpf/sys_enter_openat.c cat /etc/passwd > /dev/null
+ *
+ * It'll catch some openat syscalls related to the dynamic linked and
+ * the last one should be the one for '/etc/passwd'.
+ *
+ * The syscall_enter_openat_args can be used to get the syscall fields
+ * and use them for filtering calls, i.e. use in expressions for
+ * the return value.
+ */
+
+#include <bpf.h>
+
+struct syscall_enter_openat_args {
+       unsigned long long unused;
+       long               syscall_nr;
+       long               dfd;
+       char               *filename_ptr;
+       long               flags;
+       long               mode;
+};
+
+int syscall_enter(openat)(struct syscall_enter_openat_args *args)
+{
+       return 1;
+}
+
+license(GPL);
index a63aa6241b7f36dd4f21f46e2cae350e6823f791..47897d65e799b31e812ac3bf02ad0584756c823d 100644 (file)
@@ -4,13 +4,33 @@
 
 #include <uapi/linux/bpf.h>
 
+/*
+ * A helper structure used by eBPF C program to describe map attributes to
+ * elf_bpf loader, taken from tools/testing/selftests/bpf/bpf_helpers.h:
+ */
+struct bpf_map {
+        unsigned int type;
+        unsigned int key_size;
+        unsigned int value_size;
+        unsigned int max_entries;
+        unsigned int map_flags;
+        unsigned int inner_map_idx;
+        unsigned int numa_node;
+};
+
 #define SEC(NAME) __attribute__((section(NAME),  used))
 
 #define probe(function, vars) \
        SEC(#function "=" #function " " #vars) function
 
+#define syscall_enter(name) \
+       SEC("syscalls:sys_enter_" #name) syscall_enter_ ## name
+
 #define license(name) \
 char _license[] SEC("license") = #name; \
 int _version SEC("version") = LINUX_VERSION_CODE;
 
+static int (*probe_read)(void *dst, int size, const void *unsafe_addr) = (void *)BPF_FUNC_probe_read;
+static int (*probe_read_str)(void *dst, int size, const void *unsafe_addr) = (void *)BPF_FUNC_probe_read_str;
+
 #endif /* _PERF_BPF_H */
diff --git a/tools/perf/include/bpf/stdio.h b/tools/perf/include/bpf/stdio.h
new file mode 100644 (file)
index 0000000..2899cb7
--- /dev/null
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <bpf.h>
+
+struct bpf_map SEC("maps") __bpf_stdout__ = {
+       .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
+       .key_size = sizeof(int),
+       .value_size = sizeof(u32),
+       .max_entries = __NR_CPUS__,
+};
+
+static int (*perf_event_output)(void *, struct bpf_map *, int, void *, unsigned long) =
+       (void *)BPF_FUNC_perf_event_output;
+
+#define puts(from) \
+       ({ const int __len = sizeof(from); \
+          char __from[__len] = from; \
+          perf_event_output(args, &__bpf_stdout__, BPF_F_CURRENT_CPU, \
+                         &__from, __len & (sizeof(from) - 1)); })
diff --git a/tools/perf/pmu-events/arch/arm64/ampere/emag/core-imp-def.json b/tools/perf/pmu-events/arch/arm64/ampere/emag/core-imp-def.json
new file mode 100644 (file)
index 0000000..bc03c06
--- /dev/null
@@ -0,0 +1,32 @@
+[
+    {
+        "ArchStdEvent": "L1D_CACHE_RD",
+    },
+    {
+        "ArchStdEvent": "L1D_CACHE_WR",
+    },
+    {
+        "ArchStdEvent": "L1D_CACHE_REFILL_RD",
+    },
+    {
+        "ArchStdEvent": "L1D_CACHE_REFILL_WR",
+    },
+    {
+        "ArchStdEvent": "L1D_TLB_REFILL_RD",
+    },
+    {
+        "ArchStdEvent": "L1D_TLB_REFILL_WR",
+    },
+    {
+        "ArchStdEvent": "L1D_TLB_RD",
+    },
+    {
+        "ArchStdEvent": "L1D_TLB_WR",
+    },
+    {
+        "ArchStdEvent": "BUS_ACCESS_RD",
+   },
+   {
+        "ArchStdEvent": "BUS_ACCESS_WR",
+   }
+]
index f03e26ecb658ef8a4be4db8b6b0bfc09f8b8cfa7..59cd8604b0bd5757167faf5c1d8c82010e953015 100644 (file)
@@ -16,3 +16,4 @@
 0x00000000420f5160,v1,cavium/thunderx2,core
 0x00000000430f0af0,v1,cavium/thunderx2,core
 0x00000000480fd010,v1,hisilicon/hip08,core
+0x00000000500f0000,v1,ampere/emag,core
index 47bedf25ba6960b3c7cf8345396d86ff0304a1ee..96e7fc1ad3f95610dc01364a4f2e94a6d5ffa5bd 100644 (file)
@@ -16,8 +16,6 @@ static unsigned long *get_bitmap(const char *str, int nbits)
        bm = bitmap_alloc(nbits);
 
        if (map && bm) {
-               bitmap_zero(bm, nbits);
-
                for (i = 0; i < map->nr; i++)
                        set_bit(map->map[i], bm);
        }
index 4892bd2dc33e6b9a8a0d94ccad396b57e70f28c9..6b049f3f5cf4e794765b8ac94d8a73814ba7aba9 100644 (file)
@@ -232,6 +232,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
        u64 objdump_addr;
        const char *objdump_name;
        char decomp_name[KMOD_DECOMP_LEN];
+       bool decomp = false;
        int ret;
 
        pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr);
@@ -305,6 +306,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
                        return -1;
                }
 
+               decomp = true;
                objdump_name = decomp_name;
        }
 
@@ -312,7 +314,7 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode,
        objdump_addr = map__rip_2objdump(al.map, al.addr);
        ret = read_via_objdump(objdump_name, objdump_addr, buf2, len);
 
-       if (dso__needs_decompress(al.map->dso))
+       if (decomp)
                unlink(objdump_name);
 
        if (ret > 0) {
index 148dd31cc2019fcc0d40231d1a9c0465dcb795e1..0579a70bbbff139cfa6a4f2fffd20ac5cafd7dd0 100644 (file)
@@ -5,34 +5,28 @@
 #include "dso.h"
 #include "debug.h"
 
-static int test(const char *path, bool alloc_name, bool alloc_ext,
-               bool kmod, bool comp, const char *name, const char *ext)
+static int test(const char *path, bool alloc_name, bool kmod,
+               int comp, const char *name)
 {
        struct kmod_path m;
 
        memset(&m, 0x0, sizeof(m));
 
        TEST_ASSERT_VAL("kmod_path__parse",
-                       !__kmod_path__parse(&m, path, alloc_name, alloc_ext));
+                       !__kmod_path__parse(&m, path, alloc_name));
 
-       pr_debug("%s - alloc name %d, alloc ext %d, kmod %d, comp %d, name '%s', ext '%s'\n",
-                path, alloc_name, alloc_ext, m.kmod, m.comp, m.name, m.ext);
+       pr_debug("%s - alloc name %d, kmod %d, comp %d, name '%s'\n",
+                path, alloc_name, m.kmod, m.comp, m.name);
 
        TEST_ASSERT_VAL("wrong kmod", m.kmod == kmod);
        TEST_ASSERT_VAL("wrong comp", m.comp == comp);
 
-       if (ext)
-               TEST_ASSERT_VAL("wrong ext", m.ext && !strcmp(ext, m.ext));
-       else
-               TEST_ASSERT_VAL("wrong ext", !m.ext);
-
        if (name)
                TEST_ASSERT_VAL("wrong name", m.name && !strcmp(name, m.name));
        else
                TEST_ASSERT_VAL("wrong name", !m.name);
 
        free(m.name);
-       free(m.ext);
        return 0;
 }
 
@@ -45,118 +39,118 @@ static int test_is_kernel_module(const char *path, int cpumode, bool expect)
        return 0;
 }
 
-#define T(path, an, ae, k, c, n, e) \
-       TEST_ASSERT_VAL("failed", !test(path, an, ae, k, c, n, e))
+#define T(path, an, k, c, n) \
+       TEST_ASSERT_VAL("failed", !test(path, an, k, c, n))
 
 #define M(path, c, e) \
        TEST_ASSERT_VAL("failed", !test_is_kernel_module(path, c, e))
 
 int test__kmod_path__parse(struct test *t __maybe_unused, int subtest __maybe_unused)
 {
-       /* path                alloc_name  alloc_ext   kmod  comp   name     ext */
-       T("/xxxx/xxxx/x-x.ko", true      , true      , true, false, "[x_x]", NULL);
-       T("/xxxx/xxxx/x-x.ko", false     , true      , true, false, NULL   , NULL);
-       T("/xxxx/xxxx/x-x.ko", true      , false     , true, false, "[x_x]", NULL);
-       T("/xxxx/xxxx/x-x.ko", false     , false     , true, false, NULL   , NULL);
+       /* path                alloc_name  kmod  comp   name   */
+       T("/xxxx/xxxx/x-x.ko", true      , true, 0    , "[x_x]");
+       T("/xxxx/xxxx/x-x.ko", false     , true, 0    , NULL   );
+       T("/xxxx/xxxx/x-x.ko", true      , true, 0    , "[x_x]");
+       T("/xxxx/xxxx/x-x.ko", false     , true, 0    , NULL   );
        M("/xxxx/xxxx/x-x.ko", PERF_RECORD_MISC_CPUMODE_UNKNOWN, true);
        M("/xxxx/xxxx/x-x.ko", PERF_RECORD_MISC_KERNEL, true);
        M("/xxxx/xxxx/x-x.ko", PERF_RECORD_MISC_USER, false);
 
 #ifdef HAVE_ZLIB_SUPPORT
-       /* path                alloc_name  alloc_ext   kmod  comp  name   ext */
-       T("/xxxx/xxxx/x.ko.gz", true     , true      , true, true, "[x]", "gz");
-       T("/xxxx/xxxx/x.ko.gz", false    , true      , true, true, NULL , "gz");
-       T("/xxxx/xxxx/x.ko.gz", true     , false     , true, true, "[x]", NULL);
-       T("/xxxx/xxxx/x.ko.gz", false    , false     , true, true, NULL , NULL);
+       /* path                alloc_name   kmod  comp  name  */
+       T("/xxxx/xxxx/x.ko.gz", true     , true, 1   , "[x]");
+       T("/xxxx/xxxx/x.ko.gz", false    , true, 1   , NULL );
+       T("/xxxx/xxxx/x.ko.gz", true     , true, 1   , "[x]");
+       T("/xxxx/xxxx/x.ko.gz", false    , true, 1   , NULL );
        M("/xxxx/xxxx/x.ko.gz", PERF_RECORD_MISC_CPUMODE_UNKNOWN, true);
        M("/xxxx/xxxx/x.ko.gz", PERF_RECORD_MISC_KERNEL, true);
        M("/xxxx/xxxx/x.ko.gz", PERF_RECORD_MISC_USER, false);
 
-       /* path              alloc_name  alloc_ext  kmod   comp  name    ext */
-       T("/xxxx/xxxx/x.gz", true      , true     , false, true, "x.gz" ,"gz");
-       T("/xxxx/xxxx/x.gz", false     , true     , false, true, NULL   ,"gz");
-       T("/xxxx/xxxx/x.gz", true      , false    , false, true, "x.gz" , NULL);
-       T("/xxxx/xxxx/x.gz", false     , false    , false, true, NULL   , NULL);
+       /* path              alloc_name  kmod   comp  name  */
+       T("/xxxx/xxxx/x.gz", true      , false, 1   , "x.gz");
+       T("/xxxx/xxxx/x.gz", false     , false, 1   , NULL  );
+       T("/xxxx/xxxx/x.gz", true      , false, 1   , "x.gz");
+       T("/xxxx/xxxx/x.gz", false     , false, 1   , NULL  );
        M("/xxxx/xxxx/x.gz", PERF_RECORD_MISC_CPUMODE_UNKNOWN, false);
        M("/xxxx/xxxx/x.gz", PERF_RECORD_MISC_KERNEL, false);
        M("/xxxx/xxxx/x.gz", PERF_RECORD_MISC_USER, false);
 
-       /* path   alloc_name  alloc_ext  kmod   comp  name     ext */
-       T("x.gz", true      , true     , false, true, "x.gz", "gz");
-       T("x.gz", false     , true     , false, true, NULL  , "gz");
-       T("x.gz", true      , false    , false, true, "x.gz", NULL);
-       T("x.gz", false     , false    , false, true, NULL  , NULL);
+       /* path   alloc_name  kmod   comp  name   */
+       T("x.gz", true      , false, 1   , "x.gz");
+       T("x.gz", false     , false, 1   , NULL  );
+       T("x.gz", true      , false, 1   , "x.gz");
+       T("x.gz", false     , false, 1   , NULL  );
        M("x.gz", PERF_RECORD_MISC_CPUMODE_UNKNOWN, false);
        M("x.gz", PERF_RECORD_MISC_KERNEL, false);
        M("x.gz", PERF_RECORD_MISC_USER, false);
 
-       /* path      alloc_name  alloc_ext  kmod  comp  name  ext */
-       T("x.ko.gz", true      , true     , true, true, "[x]", "gz");
-       T("x.ko.gz", false     , true     , true, true, NULL , "gz");
-       T("x.ko.gz", true      , false    , true, true, "[x]", NULL);
-       T("x.ko.gz", false     , false    , true, true, NULL , NULL);
+       /* path      alloc_name  kmod  comp  name  */
+       T("x.ko.gz", true      , true, 1   , "[x]");
+       T("x.ko.gz", false     , true, 1   , NULL );
+       T("x.ko.gz", true      , true, 1   , "[x]");
+       T("x.ko.gz", false     , true, 1   , NULL );
        M("x.ko.gz", PERF_RECORD_MISC_CPUMODE_UNKNOWN, true);
        M("x.ko.gz", PERF_RECORD_MISC_KERNEL, true);
        M("x.ko.gz", PERF_RECORD_MISC_USER, false);
 #endif
 
-       /* path            alloc_name  alloc_ext  kmod  comp   name             ext */
-       T("[test_module]", true      , true     , true, false, "[test_module]", NULL);
-       T("[test_module]", false     , true     , true, false, NULL           , NULL);
-       T("[test_module]", true      , false    , true, false, "[test_module]", NULL);
-       T("[test_module]", false     , false    , true, false, NULL           , NULL);
+       /* path            alloc_name  kmod  comp   name           */
+       T("[test_module]", true      , true, false, "[test_module]");
+       T("[test_module]", false     , true, false, NULL           );
+       T("[test_module]", true      , true, false, "[test_module]");
+       T("[test_module]", false     , true, false, NULL           );
        M("[test_module]", PERF_RECORD_MISC_CPUMODE_UNKNOWN, true);
        M("[test_module]", PERF_RECORD_MISC_KERNEL, true);
        M("[test_module]", PERF_RECORD_MISC_USER, false);
 
-       /* path            alloc_name  alloc_ext  kmod  comp   name             ext */
-       T("[test.module]", true      , true     , true, false, "[test.module]", NULL);
-       T("[test.module]", false     , true     , true, false, NULL           , NULL);
-       T("[test.module]", true      , false    , true, false, "[test.module]", NULL);
-       T("[test.module]", false     , false    , true, false, NULL           , NULL);
+       /* path            alloc_name  kmod  comp   name           */
+       T("[test.module]", true      , true, false, "[test.module]");
+       T("[test.module]", false     , true, false, NULL           );
+       T("[test.module]", true      , true, false, "[test.module]");
+       T("[test.module]", false     , true, false, NULL           );
        M("[test.module]", PERF_RECORD_MISC_CPUMODE_UNKNOWN, true);
        M("[test.module]", PERF_RECORD_MISC_KERNEL, true);
        M("[test.module]", PERF_RECORD_MISC_USER, false);
 
-       /* path     alloc_name  alloc_ext  kmod   comp   name      ext */
-       T("[vdso]", true      , true     , false, false, "[vdso]", NULL);
-       T("[vdso]", false     , true     , false, false, NULL    , NULL);
-       T("[vdso]", true      , false    , false, false, "[vdso]", NULL);
-       T("[vdso]", false     , false    , false, false, NULL    , NULL);
+       /* path     alloc_name  kmod   comp   name    */
+       T("[vdso]", true      , false, false, "[vdso]");
+       T("[vdso]", false     , false, false, NULL    );
+       T("[vdso]", true      , false, false, "[vdso]");
+       T("[vdso]", false     , false, false, NULL    );
        M("[vdso]", PERF_RECORD_MISC_CPUMODE_UNKNOWN, false);
        M("[vdso]", PERF_RECORD_MISC_KERNEL, false);
        M("[vdso]", PERF_RECORD_MISC_USER, false);
 
-       T("[vdso32]", true      , true     , false, false, "[vdso32]", NULL);
-       T("[vdso32]", false     , true     , false, false, NULL    , NULL);
-       T("[vdso32]", true      , false    , false, false, "[vdso32]", NULL);
-       T("[vdso32]", false     , false    , false, false, NULL    , NULL);
+       T("[vdso32]", true      , false, false, "[vdso32]");
+       T("[vdso32]", false     , false, false, NULL      );
+       T("[vdso32]", true      , false, false, "[vdso32]");
+       T("[vdso32]", false     , false, false, NULL      );
        M("[vdso32]", PERF_RECORD_MISC_CPUMODE_UNKNOWN, false);
        M("[vdso32]", PERF_RECORD_MISC_KERNEL, false);
        M("[vdso32]", PERF_RECORD_MISC_USER, false);
 
-       T("[vdsox32]", true      , true     , false, false, "[vdsox32]", NULL);
-       T("[vdsox32]", false     , true     , false, false, NULL    , NULL);
-       T("[vdsox32]", true      , false    , false, false, "[vdsox32]", NULL);
-       T("[vdsox32]", false     , false    , false, false, NULL    , NULL);
+       T("[vdsox32]", true      , false, false, "[vdsox32]");
+       T("[vdsox32]", false     , false, false, NULL       );
+       T("[vdsox32]", true      , false, false, "[vdsox32]");
+       T("[vdsox32]", false     , false, false, NULL       );
        M("[vdsox32]", PERF_RECORD_MISC_CPUMODE_UNKNOWN, false);
        M("[vdsox32]", PERF_RECORD_MISC_KERNEL, false);
        M("[vdsox32]", PERF_RECORD_MISC_USER, false);
 
-       /* path         alloc_name  alloc_ext  kmod   comp   name          ext */
-       T("[vsyscall]", true      , true     , false, false, "[vsyscall]", NULL);
-       T("[vsyscall]", false     , true     , false, false, NULL        , NULL);
-       T("[vsyscall]", true      , false    , false, false, "[vsyscall]", NULL);
-       T("[vsyscall]", false     , false    , false, false, NULL        , NULL);
+       /* path         alloc_name  kmod   comp   name        */
+       T("[vsyscall]", true      , false, false, "[vsyscall]");
+       T("[vsyscall]", false     , false, false, NULL        );
+       T("[vsyscall]", true      , false, false, "[vsyscall]");
+       T("[vsyscall]", false     , false, false, NULL        );
        M("[vsyscall]", PERF_RECORD_MISC_CPUMODE_UNKNOWN, false);
        M("[vsyscall]", PERF_RECORD_MISC_KERNEL, false);
        M("[vsyscall]", PERF_RECORD_MISC_USER, false);
 
-       /* path                alloc_name  alloc_ext  kmod   comp   name      ext */
-       T("[kernel.kallsyms]", true      , true     , false, false, "[kernel.kallsyms]", NULL);
-       T("[kernel.kallsyms]", false     , true     , false, false, NULL               , NULL);
-       T("[kernel.kallsyms]", true      , false    , false, false, "[kernel.kallsyms]", NULL);
-       T("[kernel.kallsyms]", false     , false    , false, false, NULL               , NULL);
+       /* path                alloc_name  kmod   comp   name      */
+       T("[kernel.kallsyms]", true      , false, false, "[kernel.kallsyms]");
+       T("[kernel.kallsyms]", false     , false, false, NULL               );
+       T("[kernel.kallsyms]", true      , false, false, "[kernel.kallsyms]");
+       T("[kernel.kallsyms]", false     , false, false, NULL               );
        M("[kernel.kallsyms]", PERF_RECORD_MISC_CPUMODE_UNKNOWN, false);
        M("[kernel.kallsyms]", PERF_RECORD_MISC_KERNEL, false);
        M("[kernel.kallsyms]", PERF_RECORD_MISC_USER, false);
index 0c3c87f86e034b45ecbe65e162457b3ddf47a947..9e9e4d37cc771868c183e22fbba4eaa6c095ba1b 100644 (file)
@@ -24,8 +24,6 @@ static unsigned long *get_bitmap(const char *str, int nbits)
        bm = bitmap_alloc(nbits);
 
        if (map && bm) {
-               bitmap_zero(bm, nbits);
-
                for (i = 0; i < map->nr; i++) {
                        set_bit(map->map[i], bm);
                }
index 3b4f1c10ff57c8ae7b64baaee79ada7aec3b5ba1..1d00e5ec7906ebaf23b57a5d9e1471ed1cbab465 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <sys/ttydefaults.h>
+#include <asm/bug.h>
 
 struct disasm_line_samples {
        double                percent;
@@ -115,7 +116,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
        if (!browser->navkeypressed)
                ops.width += 1;
 
-       annotation_line__write(al, notes, &ops);
+       annotation_line__write(al, notes, &ops, ab->opts);
 
        if (ops.current_entry)
                ab->selection = al;
@@ -227,10 +228,10 @@ static int disasm__cmp(struct annotation_line *a, struct annotation_line *b)
 {
        int i;
 
-       for (i = 0; i < a->samples_nr; i++) {
-               if (a->samples[i].percent == b->samples[i].percent)
+       for (i = 0; i < a->data_nr; i++) {
+               if (a->data[i].percent == b->data[i].percent)
                        continue;
-               return a->samples[i].percent < b->samples[i].percent;
+               return a->data[i].percent < b->data[i].percent;
        }
        return 0;
 }
@@ -314,11 +315,14 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,
                        continue;
                }
 
-               for (i = 0; i < pos->al.samples_nr; i++) {
-                       struct annotation_data *sample = &pos->al.samples[i];
+               for (i = 0; i < pos->al.data_nr; i++) {
+                       double percent;
 
-                       if (max_percent < sample->percent)
-                               max_percent = sample->percent;
+                       percent = annotation_data__percent(&pos->al.data[i],
+                                                          browser->opts->percent_type);
+
+                       if (max_percent < percent)
+                               max_percent = percent;
                }
 
                if (max_percent < 0.01 && pos->al.ipc == 0) {
@@ -380,9 +384,10 @@ static void ui_browser__init_asm_mode(struct ui_browser *browser)
 #define SYM_TITLE_MAX_SIZE (PATH_MAX + 64)
 
 static int sym_title(struct symbol *sym, struct map *map, char *title,
-                    size_t sz)
+                    size_t sz, int percent_type)
 {
-       return snprintf(title, sz, "%s  %s", sym->name, map->dso->long_name);
+       return snprintf(title, sz, "%s  %s [Percent: %s]", sym->name, map->dso->long_name,
+                       percent_type_str(percent_type));
 }
 
 /*
@@ -420,7 +425,7 @@ static bool annotate_browser__callq(struct annotate_browser *browser,
 
        pthread_mutex_unlock(&notes->lock);
        symbol__tui_annotate(dl->ops.target.sym, ms->map, evsel, hbt, browser->opts);
-       sym_title(ms->sym, ms->map, title, sizeof(title));
+       sym_title(ms->sym, ms->map, title, sizeof(title), browser->opts->percent_type);
        ui_browser__show_title(&browser->b, title);
        return true;
 }
@@ -595,6 +600,7 @@ bool annotate_browser__continue_search_reverse(struct annotate_browser *browser,
 
 static int annotate_browser__show(struct ui_browser *browser, char *title, const char *help)
 {
+       struct annotate_browser *ab = container_of(browser, struct annotate_browser, b);
        struct map_symbol *ms = browser->priv;
        struct symbol *sym = ms->sym;
        char symbol_dso[SYM_TITLE_MAX_SIZE];
@@ -602,7 +608,7 @@ static int annotate_browser__show(struct ui_browser *browser, char *title, const
        if (ui_browser__show(browser, title, help) < 0)
                return -1;
 
-       sym_title(sym, ms->map, symbol_dso, sizeof(symbol_dso));
+       sym_title(sym, ms->map, symbol_dso, sizeof(symbol_dso), ab->opts->percent_type);
 
        ui_browser__gotorc_title(browser, 0, 0);
        ui_browser__set_color(browser, HE_COLORSET_ROOT);
@@ -610,6 +616,39 @@ static int annotate_browser__show(struct ui_browser *browser, char *title, const
        return 0;
 }
 
+static void
+switch_percent_type(struct annotation_options *opts, bool base)
+{
+       switch (opts->percent_type) {
+       case PERCENT_HITS_LOCAL:
+               if (base)
+                       opts->percent_type = PERCENT_PERIOD_LOCAL;
+               else
+                       opts->percent_type = PERCENT_HITS_GLOBAL;
+               break;
+       case PERCENT_HITS_GLOBAL:
+               if (base)
+                       opts->percent_type = PERCENT_PERIOD_GLOBAL;
+               else
+                       opts->percent_type = PERCENT_HITS_LOCAL;
+               break;
+       case PERCENT_PERIOD_LOCAL:
+               if (base)
+                       opts->percent_type = PERCENT_HITS_LOCAL;
+               else
+                       opts->percent_type = PERCENT_PERIOD_GLOBAL;
+               break;
+       case PERCENT_PERIOD_GLOBAL:
+               if (base)
+                       opts->percent_type = PERCENT_HITS_GLOBAL;
+               else
+                       opts->percent_type = PERCENT_PERIOD_LOCAL;
+               break;
+       default:
+               WARN_ON(1);
+       }
+}
+
 static int annotate_browser__run(struct annotate_browser *browser,
                                 struct perf_evsel *evsel,
                                 struct hist_browser_timer *hbt)
@@ -624,8 +663,7 @@ static int annotate_browser__run(struct annotate_browser *browser,
        char title[256];
        int key;
 
-       annotation__scnprintf_samples_period(notes, title, sizeof(title), evsel);
-
+       hists__scnprintf_title(hists, title, sizeof(title));
        if (annotate_browser__show(&browser->b, title, help) < 0)
                return -1;
 
@@ -701,6 +739,8 @@ static int annotate_browser__run(struct annotate_browser *browser,
                "k             Toggle line numbers\n"
                "P             Print to [symbol_name].annotation file.\n"
                "r             Run available scripts\n"
+               "p             Toggle percent type [local/global]\n"
+               "b             Toggle percent base [period/hits]\n"
                "?             Search string backwards\n");
                        continue;
                case 'r':
@@ -781,7 +821,7 @@ show_sup_ins:
                        continue;
                }
                case 'P':
-                       map_symbol__annotation_dump(ms, evsel);
+                       map_symbol__annotation_dump(ms, evsel, browser->opts);
                        continue;
                case 't':
                        if (notes->options->show_total_period) {
@@ -800,6 +840,12 @@ show_sup_ins:
                                notes->options->show_minmax_cycle = true;
                        annotation__update_column_widths(notes);
                        continue;
+               case 'p':
+               case 'b':
+                       switch_percent_type(browser->opts, key == 'b');
+                       hists__scnprintf_title(hists, title, sizeof(title));
+                       annotate_browser__show(&browser->b, title, help);
+                       continue;
                case K_LEFT:
                case K_ESC:
                case 'q':
index b604ef334dc956f77083908bed572eb5ba7be615..7efe15b9618d05b2cc40d3561a811f357189decb 100644 (file)
@@ -87,6 +87,7 @@ libperf-$(CONFIG_AUXTRACE) += intel-pt.o
 libperf-$(CONFIG_AUXTRACE) += intel-bts.o
 libperf-$(CONFIG_AUXTRACE) += arm-spe.o
 libperf-$(CONFIG_AUXTRACE) += arm-spe-pkt-decoder.o
+libperf-$(CONFIG_AUXTRACE) += s390-cpumsf.o
 
 ifdef CONFIG_LIBOPENCSD
 libperf-$(CONFIG_AUXTRACE) += cs-etm.o
index f91775b4bc3cb3d8eaf0aa9e936cd048dde58918..20061cf4228875bb43e34a081da7224d69531f49 100644 (file)
@@ -49,6 +49,7 @@ struct annotation_options annotation__default_options = {
        .jump_arrows    = true,
        .annotate_src   = true,
        .offset_level   = ANNOTATION__OFFSET_JUMP_TARGETS,
+       .percent_type   = PERCENT_PERIOD_LOCAL,
 };
 
 static regex_t  file_lineno;
@@ -1108,7 +1109,7 @@ annotation_line__new(struct annotate_args *args, size_t privsize)
        if (perf_evsel__is_group_event(evsel))
                nr = evsel->nr_members;
 
-       size += sizeof(al->samples[0]) * nr;
+       size += sizeof(al->data[0]) * nr;
 
        al = zalloc(size);
        if (al) {
@@ -1117,7 +1118,7 @@ annotation_line__new(struct annotate_args *args, size_t privsize)
                al->offset     = args->offset;
                al->line       = strdup(args->line);
                al->line_nr    = args->line_nr;
-               al->samples_nr = nr;
+               al->data_nr    = nr;
        }
 
        return al;
@@ -1297,7 +1298,8 @@ static int disasm_line__print(struct disasm_line *dl, u64 start, int addr_fmt_wi
 static int
 annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start,
                       struct perf_evsel *evsel, u64 len, int min_pcnt, int printed,
-                      int max_lines, struct annotation_line *queue, int addr_fmt_width)
+                      int max_lines, struct annotation_line *queue, int addr_fmt_width,
+                      int percent_type)
 {
        struct disasm_line *dl = container_of(al, struct disasm_line, al);
        static const char *prev_line;
@@ -1309,15 +1311,18 @@ annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start
                const char *color;
                struct annotation *notes = symbol__annotation(sym);
 
-               for (i = 0; i < al->samples_nr; i++) {
-                       struct annotation_data *sample = &al->samples[i];
+               for (i = 0; i < al->data_nr; i++) {
+                       double percent;
 
-                       if (sample->percent > max_percent)
-                               max_percent = sample->percent;
+                       percent = annotation_data__percent(&al->data[i],
+                                                          percent_type);
+
+                       if (percent > max_percent)
+                               max_percent = percent;
                }
 
-               if (al->samples_nr > nr_percent)
-                       nr_percent = al->samples_nr;
+               if (al->data_nr > nr_percent)
+                       nr_percent = al->data_nr;
 
                if (max_percent < min_pcnt)
                        return -1;
@@ -1330,7 +1335,8 @@ annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start
                                if (queue == al)
                                        break;
                                annotation_line__print(queue, sym, start, evsel, len,
-                                                      0, 0, 1, NULL, addr_fmt_width);
+                                                      0, 0, 1, NULL, addr_fmt_width,
+                                                      percent_type);
                        }
                }
 
@@ -1351,18 +1357,20 @@ annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start
                }
 
                for (i = 0; i < nr_percent; i++) {
-                       struct annotation_data *sample = &al->samples[i];
+                       struct annotation_data *data = &al->data[i];
+                       double percent;
 
-                       color = get_percent_color(sample->percent);
+                       percent = annotation_data__percent(data, percent_type);
+                       color = get_percent_color(percent);
 
                        if (symbol_conf.show_total_period)
                                color_fprintf(stdout, color, " %11" PRIu64,
-                                             sample->he.period);
+                                             data->he.period);
                        else if (symbol_conf.show_nr_samples)
                                color_fprintf(stdout, color, " %7" PRIu64,
-                                             sample->he.nr_samples);
+                                             data->he.nr_samples);
                        else
-                               color_fprintf(stdout, color, " %7.2f", sample->percent);
+                               color_fprintf(stdout, color, " %7.2f", percent);
                }
 
                printf(" : ");
@@ -1621,6 +1629,7 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
        char symfs_filename[PATH_MAX];
        struct kcore_extract kce;
        bool delete_extract = false;
+       bool decomp = false;
        int stdout_fd[2];
        int lineno = 0;
        int nline;
@@ -1654,6 +1663,7 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
                                                 tmp, sizeof(tmp)) < 0)
                        goto out;
 
+               decomp = true;
                strcpy(symfs_filename, tmp);
        }
 
@@ -1740,7 +1750,7 @@ out_free_command:
 out_remove_tmp:
        close(stdout_fd[0]);
 
-       if (dso__needs_decompress(dso))
+       if (decomp)
                unlink(symfs_filename);
 
        if (delete_extract)
@@ -1753,34 +1763,45 @@ out_close_stdout:
        goto out_free_command;
 }
 
-static void calc_percent(struct sym_hist *hist,
-                        struct annotation_data *sample,
+static void calc_percent(struct sym_hist *sym_hist,
+                        struct hists *hists,
+                        struct annotation_data *data,
                         s64 offset, s64 end)
 {
        unsigned int hits = 0;
        u64 period = 0;
 
        while (offset < end) {
-               hits   += hist->addr[offset].nr_samples;
-               period += hist->addr[offset].period;
+               hits   += sym_hist->addr[offset].nr_samples;
+               period += sym_hist->addr[offset].period;
                ++offset;
        }
 
-       if (hist->nr_samples) {
-               sample->he.period     = period;
-               sample->he.nr_samples = hits;
-               sample->percent = 100.0 * hits / hist->nr_samples;
+       if (sym_hist->nr_samples) {
+               data->he.period     = period;
+               data->he.nr_samples = hits;
+               data->percent[PERCENT_HITS_LOCAL] = 100.0 * hits / sym_hist->nr_samples;
        }
+
+       if (hists->stats.nr_non_filtered_samples)
+               data->percent[PERCENT_HITS_GLOBAL] = 100.0 * hits / hists->stats.nr_non_filtered_samples;
+
+       if (sym_hist->period)
+               data->percent[PERCENT_PERIOD_LOCAL] = 100.0 * period / sym_hist->period;
+
+       if (hists->stats.total_period)
+               data->percent[PERCENT_PERIOD_GLOBAL] = 100.0 * period / hists->stats.total_period;
 }
 
 static void annotation__calc_percent(struct annotation *notes,
-                                    struct perf_evsel *evsel, s64 len)
+                                    struct perf_evsel *leader, s64 len)
 {
        struct annotation_line *al, *next;
+       struct perf_evsel *evsel;
 
        list_for_each_entry(al, &notes->src->source, node) {
                s64 end;
-               int i;
+               int i = 0;
 
                if (al->offset == -1)
                        continue;
@@ -1788,14 +1809,17 @@ static void annotation__calc_percent(struct annotation *notes,
                next = annotation_line__next(al, &notes->src->source);
                end  = next ? next->offset : len;
 
-               for (i = 0; i < al->samples_nr; i++) {
-                       struct annotation_data *sample;
-                       struct sym_hist *hist;
+               for_each_group_evsel(evsel, leader) {
+                       struct hists *hists = evsel__hists(evsel);
+                       struct annotation_data *data;
+                       struct sym_hist *sym_hist;
+
+                       BUG_ON(i >= al->data_nr);
 
-                       hist   = annotation__histogram(notes, evsel->idx + i);
-                       sample = &al->samples[i];
+                       sym_hist = annotation__histogram(notes, evsel->idx);
+                       data = &al->data[i++];
 
-                       calc_percent(hist, sample, al->offset, end);
+                       calc_percent(sym_hist, hists, data, al->offset, end);
                }
        }
 }
@@ -1846,7 +1870,8 @@ int symbol__annotate(struct symbol *sym, struct map *map,
        return symbol__disassemble(sym, &args);
 }
 
-static void insert_source_line(struct rb_root *root, struct annotation_line *al)
+static void insert_source_line(struct rb_root *root, struct annotation_line *al,
+                              struct annotation_options *opts)
 {
        struct annotation_line *iter;
        struct rb_node **p = &root->rb_node;
@@ -1859,8 +1884,10 @@ static void insert_source_line(struct rb_root *root, struct annotation_line *al)
 
                ret = strcmp(iter->path, al->path);
                if (ret == 0) {
-                       for (i = 0; i < al->samples_nr; i++)
-                               iter->samples[i].percent_sum += al->samples[i].percent;
+                       for (i = 0; i < al->data_nr; i++) {
+                               iter->data[i].percent_sum += annotation_data__percent(&al->data[i],
+                                                                                     opts->percent_type);
+                       }
                        return;
                }
 
@@ -1870,8 +1897,10 @@ static void insert_source_line(struct rb_root *root, struct annotation_line *al)
                        p = &(*p)->rb_right;
        }
 
-       for (i = 0; i < al->samples_nr; i++)
-               al->samples[i].percent_sum = al->samples[i].percent;
+       for (i = 0; i < al->data_nr; i++) {
+               al->data[i].percent_sum = annotation_data__percent(&al->data[i],
+                                                                  opts->percent_type);
+       }
 
        rb_link_node(&al->rb_node, parent, p);
        rb_insert_color(&al->rb_node, root);
@@ -1881,10 +1910,10 @@ static int cmp_source_line(struct annotation_line *a, struct annotation_line *b)
 {
        int i;
 
-       for (i = 0; i < a->samples_nr; i++) {
-               if (a->samples[i].percent_sum == b->samples[i].percent_sum)
+       for (i = 0; i < a->data_nr; i++) {
+               if (a->data[i].percent_sum == b->data[i].percent_sum)
                        continue;
-               return a->samples[i].percent_sum > b->samples[i].percent_sum;
+               return a->data[i].percent_sum > b->data[i].percent_sum;
        }
 
        return 0;
@@ -1949,8 +1978,8 @@ static void print_summary(struct rb_root *root, const char *filename)
                int i;
 
                al = rb_entry(node, struct annotation_line, rb_node);
-               for (i = 0; i < al->samples_nr; i++) {
-                       percent = al->samples[i].percent_sum;
+               for (i = 0; i < al->data_nr; i++) {
+                       percent = al->data[i].percent_sum;
                        color = get_percent_color(percent);
                        color_fprintf(stdout, color, " %7.2f", percent);
 
@@ -2029,10 +2058,12 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map,
                evsel_name = buf;
        }
 
-       graph_dotted_len = printf(" %-*.*s|     Source code & Disassembly of %s for %s (%" PRIu64 " samples)\n",
+       graph_dotted_len = printf(" %-*.*s|     Source code & Disassembly of %s for %s (%" PRIu64 " samples, "
+                                 "percent: %s)\n",
                                  width, width, symbol_conf.show_total_period ? "Period" :
                                  symbol_conf.show_nr_samples ? "Samples" : "Percent",
-                                 d_filename, evsel_name, h->nr_samples);
+                                 d_filename, evsel_name, h->nr_samples,
+                                 percent_type_str(opts->percent_type));
 
        printf("%-*.*s----\n",
               graph_dotted_len, graph_dotted_len, graph_dotted_line);
@@ -2052,7 +2083,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map,
 
                err = annotation_line__print(pos, sym, start, evsel, len,
                                             opts->min_pcnt, printed, opts->max_lines,
-                                            queue, addr_fmt_width);
+                                            queue, addr_fmt_width, opts->percent_type);
 
                switch (err) {
                case 0:
@@ -2129,10 +2160,11 @@ static void FILE__write_graph(void *fp, int graph)
        fputs(s, fp);
 }
 
-int symbol__annotate_fprintf2(struct symbol *sym, FILE *fp)
+static int symbol__annotate_fprintf2(struct symbol *sym, FILE *fp,
+                                    struct annotation_options *opts)
 {
        struct annotation *notes = symbol__annotation(sym);
-       struct annotation_write_ops ops = {
+       struct annotation_write_ops wops = {
                .first_line              = true,
                .obj                     = fp,
                .set_color               = FILE__set_color,
@@ -2146,15 +2178,16 @@ int symbol__annotate_fprintf2(struct symbol *sym, FILE *fp)
        list_for_each_entry(al, &notes->src->source, node) {
                if (annotation_line__filter(al, notes))
                        continue;
-               annotation_line__write(al, notes, &ops);
+               annotation_line__write(al, notes, &wops, opts);
                fputc('\n', fp);
-               ops.first_line = false;
+               wops.first_line = false;
        }
 
        return 0;
 }
 
-int map_symbol__annotation_dump(struct map_symbol *ms, struct perf_evsel *evsel)
+int map_symbol__annotation_dump(struct map_symbol *ms, struct perf_evsel *evsel,
+                               struct annotation_options *opts)
 {
        const char *ev_name = perf_evsel__name(evsel);
        char buf[1024];
@@ -2176,7 +2209,7 @@ int map_symbol__annotation_dump(struct map_symbol *ms, struct perf_evsel *evsel)
 
        fprintf(fp, "%s() %s\nEvent: %s\n\n",
                ms->sym->name, ms->map->dso->long_name, ev_name);
-       symbol__annotate_fprintf2(ms->sym, fp);
+       symbol__annotate_fprintf2(ms->sym, fp, opts);
 
        fclose(fp);
        err = 0;
@@ -2346,7 +2379,8 @@ void annotation__update_column_widths(struct annotation *notes)
 }
 
 static void annotation__calc_lines(struct annotation *notes, struct map *map,
-                                 struct rb_root *root)
+                                  struct rb_root *root,
+                                  struct annotation_options *opts)
 {
        struct annotation_line *al;
        struct rb_root tmp_root = RB_ROOT;
@@ -2355,13 +2389,14 @@ static void annotation__calc_lines(struct annotation *notes, struct map *map,
                double percent_max = 0.0;
                int i;
 
-               for (i = 0; i < al->samples_nr; i++) {
-                       struct annotation_data *sample;
+               for (i = 0; i < al->data_nr; i++) {
+                       double percent;
 
-                       sample = &al->samples[i];
+                       percent = annotation_data__percent(&al->data[i],
+                                                          opts->percent_type);
 
-                       if (sample->percent > percent_max)
-                               percent_max = sample->percent;
+                       if (percent > percent_max)
+                               percent_max = percent;
                }
 
                if (percent_max <= 0.5)
@@ -2369,18 +2404,19 @@ static void annotation__calc_lines(struct annotation *notes, struct map *map,
 
                al->path = get_srcline(map->dso, notes->start + al->offset, NULL,
                                       false, true, notes->start + al->offset);
-               insert_source_line(&tmp_root, al);
+               insert_source_line(&tmp_root, al, opts);
        }
 
        resort_source_line(root, &tmp_root);
 }
 
 static void symbol__calc_lines(struct symbol *sym, struct map *map,
-                             struct rb_root *root)
+                              struct rb_root *root,
+                              struct annotation_options *opts)
 {
        struct annotation *notes = symbol__annotation(sym);
 
-       annotation__calc_lines(notes, map, root);
+       annotation__calc_lines(notes, map, root, opts);
 }
 
 int symbol__tty_annotate2(struct symbol *sym, struct map *map,
@@ -2389,7 +2425,7 @@ int symbol__tty_annotate2(struct symbol *sym, struct map *map,
 {
        struct dso *dso = map->dso;
        struct rb_root source_line = RB_ROOT;
-       struct annotation *notes = symbol__annotation(sym);
+       struct hists *hists = evsel__hists(evsel);
        char buf[1024];
 
        if (symbol__annotate2(sym, map, evsel, opts, NULL) < 0)
@@ -2397,13 +2433,14 @@ int symbol__tty_annotate2(struct symbol *sym, struct map *map,
 
        if (opts->print_lines) {
                srcline_full_filename = opts->full_path;
-               symbol__calc_lines(sym, map, &source_line);
+               symbol__calc_lines(sym, map, &source_line, opts);
                print_summary(&source_line, dso->long_name);
        }
 
-       annotation__scnprintf_samples_period(notes, buf, sizeof(buf), evsel);
-       fprintf(stdout, "%s\n%s() %s\n", buf, sym->name, dso->long_name);
-       symbol__annotate_fprintf2(sym, stdout);
+       hists__scnprintf_title(hists, buf, sizeof(buf));
+       fprintf(stdout, "%s, [percent: %s]\n%s() %s\n",
+               buf, percent_type_str(opts->percent_type), sym->name, dso->long_name);
+       symbol__annotate_fprintf2(sym, stdout, opts);
 
        annotated_source__purge(symbol__annotation(sym)->src);
 
@@ -2424,7 +2461,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
 
        if (opts->print_lines) {
                srcline_full_filename = opts->full_path;
-               symbol__calc_lines(sym, map, &source_line);
+               symbol__calc_lines(sym, map, &source_line, opts);
                print_summary(&source_line, dso->long_name);
        }
 
@@ -2441,14 +2478,21 @@ bool ui__has_annotation(void)
 }
 
 
-double annotation_line__max_percent(struct annotation_line *al, struct annotation *notes)
+static double annotation_line__max_percent(struct annotation_line *al,
+                                          struct annotation *notes,
+                                          unsigned int percent_type)
 {
        double percent_max = 0.0;
        int i;
 
        for (i = 0; i < notes->nr_events; i++) {
-               if (al->samples[i].percent > percent_max)
-                       percent_max = al->samples[i].percent;
+               double percent;
+
+               percent = annotation_data__percent(&al->data[i],
+                                                  percent_type);
+
+               if (percent > percent_max)
+                       percent_max = percent;
        }
 
        return percent_max;
@@ -2487,7 +2531,7 @@ call_like:
 
 static void __annotation_line__write(struct annotation_line *al, struct annotation *notes,
                                     bool first_line, bool current_entry, bool change_color, int width,
-                                    void *obj,
+                                    void *obj, unsigned int percent_type,
                                     int  (*obj__set_color)(void *obj, int color),
                                     void (*obj__set_percent_color)(void *obj, double percent, bool current),
                                     int  (*obj__set_jumps_percent_color)(void *obj, int nr, bool current),
@@ -2495,7 +2539,7 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati
                                     void (*obj__write_graph)(void *obj, int graph))
 
 {
-       double percent_max = annotation_line__max_percent(al, notes);
+       double percent_max = annotation_line__max_percent(al, notes, percent_type);
        int pcnt_width = annotation__pcnt_width(notes),
            cycles_width = annotation__cycles_width(notes);
        bool show_title = false;
@@ -2514,15 +2558,18 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati
                int i;
 
                for (i = 0; i < notes->nr_events; i++) {
-                       obj__set_percent_color(obj, al->samples[i].percent, current_entry);
+                       double percent;
+
+                       percent = annotation_data__percent(&al->data[i], percent_type);
+
+                       obj__set_percent_color(obj, percent, current_entry);
                        if (notes->options->show_total_period) {
-                               obj__printf(obj, "%11" PRIu64 " ", al->samples[i].he.period);
+                               obj__printf(obj, "%11" PRIu64 " ", al->data[i].he.period);
                        } else if (notes->options->show_nr_samples) {
                                obj__printf(obj, "%6" PRIu64 " ",
-                                                  al->samples[i].he.nr_samples);
+                                                  al->data[i].he.nr_samples);
                        } else {
-                               obj__printf(obj, "%6.2f ",
-                                                  al->samples[i].percent);
+                               obj__printf(obj, "%6.2f ", percent);
                        }
                }
        } else {
@@ -2640,13 +2687,15 @@ print_addr:
 }
 
 void annotation_line__write(struct annotation_line *al, struct annotation *notes,
-                           struct annotation_write_ops *ops)
+                           struct annotation_write_ops *wops,
+                           struct annotation_options *opts)
 {
-       __annotation_line__write(al, notes, ops->first_line, ops->current_entry,
-                                ops->change_color, ops->width, ops->obj,
-                                ops->set_color, ops->set_percent_color,
-                                ops->set_jumps_percent_color, ops->printf,
-                                ops->write_graph);
+       __annotation_line__write(al, notes, wops->first_line, wops->current_entry,
+                                wops->change_color, wops->width, wops->obj,
+                                opts->percent_type,
+                                wops->set_color, wops->set_percent_color,
+                                wops->set_jumps_percent_color, wops->printf,
+                                wops->write_graph);
 }
 
 int symbol__annotate2(struct symbol *sym, struct map *map, struct perf_evsel *evsel,
@@ -2688,46 +2737,6 @@ out_free_offsets:
        return -1;
 }
 
-int __annotation__scnprintf_samples_period(struct annotation *notes,
-                                          char *bf, size_t size,
-                                          struct perf_evsel *evsel,
-                                          bool show_freq)
-{
-       const char *ev_name = perf_evsel__name(evsel);
-       char buf[1024], ref[30] = " show reference callgraph, ";
-       char sample_freq_str[64] = "";
-       unsigned long nr_samples = 0;
-       int nr_members = 1;
-       bool enable_ref = false;
-       u64 nr_events = 0;
-       char unit;
-       int i;
-
-       if (perf_evsel__is_group_event(evsel)) {
-               perf_evsel__group_desc(evsel, buf, sizeof(buf));
-               ev_name = buf;
-                nr_members = evsel->nr_members;
-       }
-
-       for (i = 0; i < nr_members; i++) {
-               struct sym_hist *ah = annotation__histogram(notes, evsel->idx + i);
-
-               nr_samples += ah->nr_samples;
-               nr_events  += ah->period;
-       }
-
-       if (symbol_conf.show_ref_callgraph && strstr(ev_name, "call-graph=no"))
-               enable_ref = true;
-
-       if (show_freq)
-               scnprintf(sample_freq_str, sizeof(sample_freq_str), " %d Hz,", evsel->attr.sample_freq);
-
-       nr_samples = convert_unit(nr_samples, &unit);
-       return scnprintf(bf, size, "Samples: %lu%c of event%s '%s',%s%sEvent count (approx.): %" PRIu64,
-                        nr_samples, unit, evsel->nr_members > 1 ? "s" : "",
-                        ev_name, sample_freq_str, enable_ref ? ref : " ", nr_events);
-}
-
 #define ANNOTATION__CFG(n) \
        { .name = #n, .value = &annotation__default_options.n, }
 
@@ -2792,3 +2801,55 @@ void annotation_config__init(void)
        annotation__default_options.show_total_period = symbol_conf.show_total_period;
        annotation__default_options.show_nr_samples   = symbol_conf.show_nr_samples;
 }
+
+static unsigned int parse_percent_type(char *str1, char *str2)
+{
+       unsigned int type = (unsigned int) -1;
+
+       if (!strcmp("period", str1)) {
+               if (!strcmp("local", str2))
+                       type = PERCENT_PERIOD_LOCAL;
+               else if (!strcmp("global", str2))
+                       type = PERCENT_PERIOD_GLOBAL;
+       }
+
+       if (!strcmp("hits", str1)) {
+               if (!strcmp("local", str2))
+                       type = PERCENT_HITS_LOCAL;
+               else if (!strcmp("global", str2))
+                       type = PERCENT_HITS_GLOBAL;
+       }
+
+       return type;
+}
+
+int annotate_parse_percent_type(const struct option *opt, const char *_str,
+                               int unset __maybe_unused)
+{
+       struct annotation_options *opts = opt->value;
+       unsigned int type;
+       char *str1, *str2;
+       int err = -1;
+
+       str1 = strdup(_str);
+       if (!str1)
+               return -ENOMEM;
+
+       str2 = strchr(str1, '-');
+       if (!str2)
+               goto out;
+
+       *str2++ = 0;
+
+       type = parse_percent_type(str1, str2);
+       if (type == (unsigned int) -1)
+               type = parse_percent_type(str2, str1);
+       if (type != (unsigned int) -1) {
+               opts->percent_type = type;
+               err = 0;
+       }
+
+out:
+       free(str1);
+       return err;
+}
index a4c0d91907e662853aac249db5ce69dd3da9019b..005a5fe8a8c6bccc49ed7d6b1861952313ecb2df 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/list.h>
 #include <linux/rbtree.h>
 #include <pthread.h>
+#include <asm/bug.h>
 
 struct ins_ops;
 
@@ -82,6 +83,7 @@ struct annotation_options {
        int  context;
        const char *objdump_path;
        const char *disassembler_style;
+       unsigned int percent_type;
 };
 
 enum {
@@ -101,8 +103,16 @@ struct sym_hist_entry {
        u64             period;
 };
 
+enum {
+       PERCENT_HITS_LOCAL,
+       PERCENT_HITS_GLOBAL,
+       PERCENT_PERIOD_LOCAL,
+       PERCENT_PERIOD_GLOBAL,
+       PERCENT_MAX,
+};
+
 struct annotation_data {
-       double                   percent;
+       double                   percent[PERCENT_MAX];
        double                   percent_sum;
        struct sym_hist_entry    he;
 };
@@ -122,8 +132,8 @@ struct annotation_line {
        char                    *path;
        u32                      idx;
        int                      idx_asm;
-       int                      samples_nr;
-       struct annotation_data   samples[0];
+       int                      data_nr;
+       struct annotation_data   data[0];
 };
 
 struct disasm_line {
@@ -134,6 +144,27 @@ struct disasm_line {
        struct annotation_line   al;
 };
 
+static inline double annotation_data__percent(struct annotation_data *data,
+                                             unsigned int which)
+{
+       return which < PERCENT_MAX ? data->percent[which] : -1;
+}
+
+static inline const char *percent_type_str(unsigned int type)
+{
+       static const char *str[PERCENT_MAX] = {
+               "local hits",
+               "global hits",
+               "local period",
+               "global period",
+       };
+
+       if (WARN_ON(type >= PERCENT_MAX))
+               return "N/A";
+
+       return str[type];
+}
+
 static inline struct disasm_line *disasm_line(struct annotation_line *al)
 {
        return al ? container_of(al, struct disasm_line, al) : NULL;
@@ -169,22 +200,15 @@ struct annotation_write_ops {
        void (*write_graph)(void *obj, int graph);
 };
 
-double annotation_line__max_percent(struct annotation_line *al, struct annotation *notes);
 void annotation_line__write(struct annotation_line *al, struct annotation *notes,
-                           struct annotation_write_ops *ops);
+                           struct annotation_write_ops *ops,
+                           struct annotation_options *opts);
 
 int __annotation__scnprintf_samples_period(struct annotation *notes,
                                           char *bf, size_t size,
                                           struct perf_evsel *evsel,
                                           bool show_freq);
 
-static inline int annotation__scnprintf_samples_period(struct annotation *notes,
-                                                      char *bf, size_t size,
-                                                      struct perf_evsel *evsel)
-{
-       return __annotation__scnprintf_samples_period(notes, bf, size, evsel, true);
-}
-
 int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw);
 size_t disasm__fprintf(struct list_head *head, FILE *fp);
 void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel);
@@ -340,12 +364,12 @@ int symbol__strerror_disassemble(struct symbol *sym, struct map *map,
 int symbol__annotate_printf(struct symbol *sym, struct map *map,
                            struct perf_evsel *evsel,
                            struct annotation_options *options);
-int symbol__annotate_fprintf2(struct symbol *sym, FILE *fp);
 void symbol__annotate_zero_histogram(struct symbol *sym, int evidx);
 void symbol__annotate_decay_histogram(struct symbol *sym, int evidx);
 void annotated_source__purge(struct annotated_source *as);
 
-int map_symbol__annotation_dump(struct map_symbol *ms, struct perf_evsel *evsel);
+int map_symbol__annotation_dump(struct map_symbol *ms, struct perf_evsel *evsel,
+                               struct annotation_options *opts);
 
 bool ui__has_annotation(void);
 
@@ -373,4 +397,6 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
 
 void annotation_config__init(void);
 
+int annotate_parse_percent_type(const struct option *opt, const char *_str,
+                               int unset);
 #endif /* __PERF_ANNOTATE_H */
index d056447520a234cf759ac643fc2dd55b8eec47d9..db1511359c5e66b1040e42499cfc25df6677b026 100644 (file)
@@ -56,6 +56,7 @@
 #include "intel-pt.h"
 #include "intel-bts.h"
 #include "arm-spe.h"
+#include "s390-cpumsf.h"
 
 #include "sane_ctype.h"
 #include "symbol/kallsyms.h"
@@ -202,6 +203,9 @@ static int auxtrace_queues__grow(struct auxtrace_queues *queues,
        for (i = 0; i < queues->nr_queues; i++) {
                list_splice_tail(&queues->queue_array[i].head,
                                 &queue_array[i].head);
+               queue_array[i].tid = queues->queue_array[i].tid;
+               queue_array[i].cpu = queues->queue_array[i].cpu;
+               queue_array[i].set = queues->queue_array[i].set;
                queue_array[i].priv = queues->queue_array[i].priv;
        }
 
@@ -920,6 +924,8 @@ int perf_event__process_auxtrace_info(struct perf_tool *tool __maybe_unused,
                return arm_spe_process_auxtrace_info(event, session);
        case PERF_AUXTRACE_CS_ETM:
                return cs_etm__process_auxtrace_info(event, session);
+       case PERF_AUXTRACE_S390_CPUMSF:
+               return s390_cpumsf_process_auxtrace_info(event, session);
        case PERF_AUXTRACE_UNKNOWN:
        default:
                return -EINVAL;
index e731f55da072f604be21a42f7db7e94faf0ffa3e..71fc3bd742997b4bcbab07f72d88da869d8e089b 100644 (file)
@@ -44,6 +44,7 @@ enum auxtrace_type {
        PERF_AUXTRACE_INTEL_BTS,
        PERF_AUXTRACE_CS_ETM,
        PERF_AUXTRACE_ARM_SPE,
+       PERF_AUXTRACE_S390_CPUMSF,
 };
 
 enum itrace_period_type {
index 3d02ae38ec561279bfd7fb07a2314058ad9345ce..47aac41349a25764c39565343a051e79d7929247 100644 (file)
@@ -1529,13 +1529,13 @@ int bpf__apply_obj_config(void)
        bpf_object__for_each_safe(obj, objtmp)  \
                bpf_map__for_each(pos, obj)
 
-#define bpf__for_each_stdout_map(pos, obj, objtmp)     \
+#define bpf__for_each_map_named(pos, obj, objtmp, name)        \
        bpf__for_each_map(pos, obj, objtmp)             \
                if (bpf_map__name(pos) &&               \
-                       (strcmp("__bpf_stdout__",       \
+                       (strcmp(name,                   \
                                bpf_map__name(pos)) == 0))
 
-int bpf__setup_stdout(struct perf_evlist *evlist)
+struct perf_evsel *bpf__setup_output_event(struct perf_evlist *evlist, const char *name)
 {
        struct bpf_map_priv *tmpl_priv = NULL;
        struct bpf_object *obj, *tmp;
@@ -1544,11 +1544,11 @@ int bpf__setup_stdout(struct perf_evlist *evlist)
        int err;
        bool need_init = false;
 
-       bpf__for_each_stdout_map(map, obj, tmp) {
+       bpf__for_each_map_named(map, obj, tmp, name) {
                struct bpf_map_priv *priv = bpf_map__priv(map);
 
                if (IS_ERR(priv))
-                       return -BPF_LOADER_ERRNO__INTERNAL;
+                       return ERR_PTR(-BPF_LOADER_ERRNO__INTERNAL);
 
                /*
                 * No need to check map type: type should have been
@@ -1561,49 +1561,61 @@ int bpf__setup_stdout(struct perf_evlist *evlist)
        }
 
        if (!need_init)
-               return 0;
+               return NULL;
 
        if (!tmpl_priv) {
-               err = parse_events(evlist, "bpf-output/no-inherit=1,name=__bpf_stdout__/",
-                                  NULL);
+               char *event_definition = NULL;
+
+               if (asprintf(&event_definition, "bpf-output/no-inherit=1,name=%s/", name) < 0)
+                       return ERR_PTR(-ENOMEM);
+
+               err = parse_events(evlist, event_definition, NULL);
+               free(event_definition);
+
                if (err) {
-                       pr_debug("ERROR: failed to create bpf-output event\n");
-                       return -err;
+                       pr_debug("ERROR: failed to create the \"%s\" bpf-output event\n", name);
+                       return ERR_PTR(-err);
                }
 
                evsel = perf_evlist__last(evlist);
        }
 
-       bpf__for_each_stdout_map(map, obj, tmp) {
+       bpf__for_each_map_named(map, obj, tmp, name) {
                struct bpf_map_priv *priv = bpf_map__priv(map);
 
                if (IS_ERR(priv))
-                       return -BPF_LOADER_ERRNO__INTERNAL;
+                       return ERR_PTR(-BPF_LOADER_ERRNO__INTERNAL);
                if (priv)
                        continue;
 
                if (tmpl_priv) {
                        priv = bpf_map_priv__clone(tmpl_priv);
                        if (!priv)
-                               return -ENOMEM;
+                               return ERR_PTR(-ENOMEM);
 
                        err = bpf_map__set_priv(map, priv, bpf_map_priv__clear);
                        if (err) {
                                bpf_map_priv__clear(map, priv);
-                               return err;
+                               return ERR_PTR(err);
                        }
                } else if (evsel) {
                        struct bpf_map_op *op;
 
                        op = bpf_map__add_newop(map, NULL);
                        if (IS_ERR(op))
-                               return PTR_ERR(op);
+                               return ERR_PTR(PTR_ERR(op));
                        op->op_type = BPF_MAP_OP_SET_EVSEL;
                        op->v.evsel = evsel;
                }
        }
 
-       return 0;
+       return evsel;
+}
+
+int bpf__setup_stdout(struct perf_evlist *evlist)
+{
+       struct perf_evsel *evsel = bpf__setup_output_event(evlist, "__bpf_stdout__");
+       return IS_ERR(evsel) ? PTR_ERR(evsel) : 0;
 }
 
 #define ERRNO_OFFSET(e)                ((e) - __BPF_LOADER_ERRNO__START)
@@ -1780,8 +1792,8 @@ int bpf__strerror_apply_obj_config(int err, char *buf, size_t size)
        return 0;
 }
 
-int bpf__strerror_setup_stdout(struct perf_evlist *evlist __maybe_unused,
-                              int err, char *buf, size_t size)
+int bpf__strerror_setup_output_event(struct perf_evlist *evlist __maybe_unused,
+                                    int err, char *buf, size_t size)
 {
        bpf__strerror_head(err, buf, size);
        bpf__strerror_end(buf, size);
index 5d3aefd6fae7c6704c490599221d19e5fe357b28..62d245a90e1d96bf6f0888c9ffa78c7b3f43e72f 100644 (file)
@@ -43,6 +43,7 @@ enum bpf_loader_errno {
        __BPF_LOADER_ERRNO__END,
 };
 
+struct perf_evsel;
 struct bpf_object;
 struct parse_events_term;
 #define PERF_BPF_PROBE_GROUP "perf_bpf_probe"
@@ -82,9 +83,8 @@ int bpf__apply_obj_config(void);
 int bpf__strerror_apply_obj_config(int err, char *buf, size_t size);
 
 int bpf__setup_stdout(struct perf_evlist *evlist);
-int bpf__strerror_setup_stdout(struct perf_evlist *evlist, int err,
-                              char *buf, size_t size);
-
+struct perf_evsel *bpf__setup_output_event(struct perf_evlist *evlist, const char *name);
+int bpf__strerror_setup_output_event(struct perf_evlist *evlist, int err, char *buf, size_t size);
 #else
 #include <errno.h>
 
@@ -138,6 +138,12 @@ bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
        return 0;
 }
 
+static inline struct perf_evsel *
+bpf__setup_output_event(struct perf_evlist *evlist __maybe_unused, const char *name __maybe_unused)
+{
+       return NULL;
+}
+
 static inline int
 __bpf_strerror(char *buf, size_t size)
 {
@@ -193,11 +199,16 @@ bpf__strerror_apply_obj_config(int err __maybe_unused,
 }
 
 static inline int
-bpf__strerror_setup_stdout(struct perf_evlist *evlist __maybe_unused,
-                          int err __maybe_unused, char *buf,
-                          size_t size)
+bpf__strerror_setup_output_event(struct perf_evlist *evlist __maybe_unused,
+                                int err __maybe_unused, char *buf, size_t size)
 {
        return __bpf_strerror(buf, size);
 }
+
 #endif
+
+static inline int bpf__strerror_setup_stdout(struct perf_evlist *evlist, int err, char *buf, size_t size)
+{
+       return bpf__strerror_setup_output_event(evlist, err, buf, size);
+}
 #endif
index ecca688a25fb75977c542f6107e8b11f20345c70..892e92e7e7fc8e507baf198947eef5f6326afdf0 100644 (file)
@@ -4,10 +4,12 @@
 
 #ifdef HAVE_ZLIB_SUPPORT
 int gzip_decompress_to_file(const char *input, int output_fd);
+bool gzip_is_compressed(const char *input);
 #endif
 
 #ifdef HAVE_LZMA_SUPPORT
 int lzma_decompress_to_file(const char *input, int output_fd);
+bool lzma_is_compressed(const char *input);
 #endif
 
 #endif /* PERF_COMPRESS_H */
index 5744c12641a53d341ef46d548a3498272841cf54..abd38abf1d918ab81b360ed9691831eaac162161 100644 (file)
@@ -310,8 +310,8 @@ static int add_tracepoint_field_value(struct ctf_writer *cw,
        if (flags & FIELD_IS_DYNAMIC) {
                unsigned long long tmp_val;
 
-               tmp_val = pevent_read_number(fmtf->event->pevent,
-                               data + offset, len);
+               tmp_val = tep_read_number(fmtf->event->pevent,
+                                         data + offset, len);
                offset = tmp_val;
                len = offset >> 16;
                offset &= 0xffff;
@@ -353,7 +353,7 @@ static int add_tracepoint_field_value(struct ctf_writer *cw,
                else {
                        unsigned long long value_int;
 
-                       value_int = pevent_read_number(
+                       value_int = tep_read_number(
                                        fmtf->event->pevent,
                                        data + offset + i * len, len);
 
index 51cf82cf18822fc66920f5d5850b4430ad8614ee..bbed90e5d9bb841782ed878a0c2ce1ae752418f9 100644 (file)
@@ -189,28 +189,34 @@ int dso__read_binary_type_filename(const struct dso *dso,
        return ret;
 }
 
+enum {
+       COMP_ID__NONE = 0,
+};
+
 static const struct {
        const char *fmt;
        int (*decompress)(const char *input, int output);
+       bool (*is_compressed)(const char *input);
 } compressions[] = {
+       [COMP_ID__NONE] = { .fmt = NULL, },
 #ifdef HAVE_ZLIB_SUPPORT
-       { "gz", gzip_decompress_to_file },
+       { "gz", gzip_decompress_to_file, gzip_is_compressed },
 #endif
 #ifdef HAVE_LZMA_SUPPORT
-       { "xz", lzma_decompress_to_file },
+       { "xz", lzma_decompress_to_file, lzma_is_compressed },
 #endif
-       { NULL, NULL },
+       { NULL, NULL, NULL },
 };
 
-bool is_supported_compression(const char *ext)
+static int is_supported_compression(const char *ext)
 {
        unsigned i;
 
-       for (i = 0; compressions[i].fmt; i++) {
+       for (i = 1; compressions[i].fmt; i++) {
                if (!strcmp(ext, compressions[i].fmt))
-                       return true;
+                       return i;
        }
-       return false;
+       return COMP_ID__NONE;
 }
 
 bool is_kernel_module(const char *pathname, int cpumode)
@@ -239,80 +245,73 @@ bool is_kernel_module(const char *pathname, int cpumode)
        return m.kmod;
 }
 
-bool decompress_to_file(const char *ext, const char *filename, int output_fd)
-{
-       unsigned i;
-
-       for (i = 0; compressions[i].fmt; i++) {
-               if (!strcmp(ext, compressions[i].fmt))
-                       return !compressions[i].decompress(filename,
-                                                          output_fd);
-       }
-       return false;
-}
-
 bool dso__needs_decompress(struct dso *dso)
 {
        return dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
                dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
 }
 
-static int decompress_kmodule(struct dso *dso, const char *name, char *tmpbuf)
+static int decompress_kmodule(struct dso *dso, const char *name,
+                             char *pathname, size_t len)
 {
+       char tmpbuf[] = KMOD_DECOMP_NAME;
        int fd = -1;
-       struct kmod_path m;
 
        if (!dso__needs_decompress(dso))
                return -1;
 
-       if (kmod_path__parse_ext(&m, dso->long_name))
+       if (dso->comp == COMP_ID__NONE)
                return -1;
 
-       if (!m.comp)
-               goto out;
+       /*
+        * We have proper compression id for DSO and yet the file
+        * behind the 'name' can still be plain uncompressed object.
+        *
+        * The reason is behind the logic we open the DSO object files,
+        * when we try all possible 'debug' objects until we find the
+        * data. So even if the DSO is represented by 'krava.xz' module,
+        * we can end up here opening ~/.debug/....23432432/debug' file
+        * which is not compressed.
+        *
+        * To keep this transparent, we detect this and return the file
+        * descriptor to the uncompressed file.
+        */
+       if (!compressions[dso->comp].is_compressed(name))
+               return open(name, O_RDONLY);
 
        fd = mkstemp(tmpbuf);
        if (fd < 0) {
                dso->load_errno = errno;
-               goto out;
+               return -1;
        }
 
-       if (!decompress_to_file(m.ext, name, fd)) {
+       if (compressions[dso->comp].decompress(name, fd)) {
                dso->load_errno = DSO_LOAD_ERRNO__DECOMPRESSION_FAILURE;
                close(fd);
                fd = -1;
        }
 
-out:
-       free(m.ext);
+       if (!pathname || (fd < 0))
+               unlink(tmpbuf);
+
+       if (pathname && (fd >= 0))
+               strncpy(pathname, tmpbuf, len);
+
        return fd;
 }
 
 int dso__decompress_kmodule_fd(struct dso *dso, const char *name)
 {
-       char tmpbuf[] = KMOD_DECOMP_NAME;
-       int fd;
-
-       fd = decompress_kmodule(dso, name, tmpbuf);
-       unlink(tmpbuf);
-       return fd;
+       return decompress_kmodule(dso, name, NULL, 0);
 }
 
 int dso__decompress_kmodule_path(struct dso *dso, const char *name,
                                 char *pathname, size_t len)
 {
-       char tmpbuf[] = KMOD_DECOMP_NAME;
-       int fd;
+       int fd = decompress_kmodule(dso, name, pathname, len);
 
-       fd = decompress_kmodule(dso, name, tmpbuf);
-       if (fd < 0) {
-               unlink(tmpbuf);
-               return -1;
-       }
-
-       strncpy(pathname, tmpbuf, len);
        close(fd);
-       return 0;
+       return fd >= 0 ? 0 : -1;
 }
 
 /*
@@ -332,7 +331,7 @@ int dso__decompress_kmodule_path(struct dso *dso, const char *name,
  * Returns 0 if there's no strdup error, -ENOMEM otherwise.
  */
 int __kmod_path__parse(struct kmod_path *m, const char *path,
-                      bool alloc_name, bool alloc_ext)
+                      bool alloc_name)
 {
        const char *name = strrchr(path, '/');
        const char *ext  = strrchr(path, '.');
@@ -372,10 +371,9 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,
                return 0;
        }
 
-       if (is_supported_compression(ext + 1)) {
-               m->comp = true;
+       m->comp = is_supported_compression(ext + 1);
+       if (m->comp > COMP_ID__NONE)
                ext -= 3;
-       }
 
        /* Check .ko extension only if there's enough name left. */
        if (ext > name)
@@ -393,14 +391,6 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,
                strxfrchar(m->name, '-', '_');
        }
 
-       if (alloc_ext && m->comp) {
-               m->ext = strdup(ext + 4);
-               if (!m->ext) {
-                       free((void *) m->name);
-                       return -ENOMEM;
-               }
-       }
-
        return 0;
 }
 
@@ -413,8 +403,10 @@ void dso__set_module_info(struct dso *dso, struct kmod_path *m,
                dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
 
        /* _KMODULE_COMP should be next to _KMODULE */
-       if (m->kmod && m->comp)
+       if (m->kmod && m->comp) {
                dso->symtab_type++;
+               dso->comp = m->comp;
+       }
 
        dso__set_short_name(dso, strdup(m->name), true);
 }
@@ -468,6 +460,7 @@ static int __open_dso(struct dso *dso, struct machine *machine)
        int fd = -EINVAL;
        char *root_dir = (char *)"";
        char *name = malloc(PATH_MAX);
+       bool decomp = false;
 
        if (!name)
                return -ENOMEM;
@@ -491,12 +484,13 @@ static int __open_dso(struct dso *dso, struct machine *machine)
                        goto out;
                }
 
+               decomp = true;
                strcpy(name, newpath);
        }
 
        fd = do_open(name);
 
-       if (dso__needs_decompress(dso))
+       if (decomp)
                unlink(name);
 
 out:
@@ -1218,6 +1212,7 @@ struct dso *dso__new(const char *name)
                dso->a2l_fails = 1;
                dso->kernel = DSO_TYPE_USER;
                dso->needs_swap = DSO_SWAP__UNSET;
+               dso->comp = COMP_ID__NONE;
                RB_CLEAR_NODE(&dso->rb_node);
                dso->root = NULL;
                INIT_LIST_HEAD(&dso->node);
index ef69de2e69ea74bd1e20ae590cc19ea9d4d817ed..c5380500bed40b6afd03aa2721559bad8192b440 100644 (file)
@@ -175,6 +175,7 @@ struct dso {
        u16              short_name_len;
        void            *dwfl;                  /* DWARF debug info */
        struct auxtrace_cache *auxtrace_cache;
+       int              comp;
 
        /* dso data file */
        struct {
@@ -250,9 +251,7 @@ int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir);
 char dso__symtab_origin(const struct dso *dso);
 int dso__read_binary_type_filename(const struct dso *dso, enum dso_binary_type type,
                                   char *root_dir, char *filename, size_t size);
-bool is_supported_compression(const char *ext);
 bool is_kernel_module(const char *pathname, int cpumode);
-bool decompress_to_file(const char *ext, const char *filename, int output_fd);
 bool dso__needs_decompress(struct dso *dso);
 int dso__decompress_kmodule_fd(struct dso *dso, const char *name);
 int dso__decompress_kmodule_path(struct dso *dso, const char *name,
@@ -263,17 +262,15 @@ int dso__decompress_kmodule_path(struct dso *dso, const char *name,
 
 struct kmod_path {
        char *name;
-       char *ext;
-       bool  comp;
+       int   comp;
        bool  kmod;
 };
 
 int __kmod_path__parse(struct kmod_path *m, const char *path,
-                    bool alloc_name, bool alloc_ext);
+                    bool alloc_name);
 
-#define kmod_path__parse(__m, __p)      __kmod_path__parse(__m, __p, false, false)
-#define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true , false)
-#define kmod_path__parse_ext(__m, __p)  __kmod_path__parse(__m, __p, false, true)
+#define kmod_path__parse(__m, __p)      __kmod_path__parse(__m, __p, false)
+#define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true)
 
 void dso__set_module_info(struct dso *dso, struct kmod_path *m,
                          struct machine *machine);
index 0c8ecf0c78a40ac1088d40742d371cae7fa3d6e7..0cd42150f712e88b89614952c65293a9451dffe9 100644 (file)
@@ -541,10 +541,17 @@ static int __event__synthesize_thread(union perf_event *comm_event,
                                                      tgid, process, machine) < 0)
                        return -1;
 
+               /*
+                * send mmap only for thread group leader
+                * see thread__init_map_groups
+                */
+               if (pid == tgid &&
+                   perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
+                                                      process, machine, mmap_data,
+                                                      proc_map_timeout))
+                       return -1;
 
-               return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid,
-                                                         process, machine, mmap_data,
-                                                         proc_map_timeout);
+               return 0;
        }
 
        if (machine__is_default_guest(machine))
index e7a4b31a84fb5f2316549d7ab31378c46589c73a..be440df296150450b4e99e2ab2c5ab83175d29aa 100644 (file)
@@ -803,7 +803,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
                if (*output == -1) {
                        *output = fd;
 
-                       if (perf_mmap__mmap(&maps[idx], mp, *output < 0)
+                       if (perf_mmap__mmap(&maps[idx], mp, *output, evlist_cpu) < 0)
                                return -1;
                } else {
                        if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0)
index ddf84b941abf894de7299ee5f63d4f3992d6a006..c980bbff63536ebaba167d8ca045b65fc7060f56 100644 (file)
@@ -2683,7 +2683,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type,
 
 struct format_field *perf_evsel__field(struct perf_evsel *evsel, const char *name)
 {
-       return pevent_find_field(evsel->tp_format, name);
+       return tep_find_field(evsel->tp_format, name);
 }
 
 void *perf_evsel__rawptr(struct perf_evsel *evsel, struct perf_sample *sample,
index 973c03167947579ff424d8e181cdbf42eaedec2d..163c960614d336a62f943e2ccd2e4663e973a0ab 100644 (file)
@@ -452,11 +452,18 @@ static inline int perf_evsel__group_idx(struct perf_evsel *evsel)
        return evsel->idx - evsel->leader->idx;
 }
 
+/* Iterates group WITHOUT the leader. */
 #define for_each_group_member(_evsel, _leader)                                         \
 for ((_evsel) = list_entry((_leader)->node.next, struct perf_evsel, node);     \
      (_evsel) && (_evsel)->leader == (_leader);                                        \
      (_evsel) = list_entry((_evsel)->node.next, struct perf_evsel, node))
 
+/* Iterates group WITH the leader. */
+#define for_each_group_evsel(_evsel, _leader)                                  \
+for ((_evsel) = _leader;                                                       \
+     (_evsel) && (_evsel)->leader == (_leader);                                        \
+     (_evsel) = list_entry((_evsel)->node.next, struct perf_evsel, node))
+
 static inline bool perf_evsel__has_branch_callstack(const struct perf_evsel *evsel)
 {
        return evsel->attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK;
index 5af58aac91ad2b186079914809934acecdf34578..3cadc252dd8977f4117419db240ac87183e54bea 100644 (file)
@@ -279,8 +279,6 @@ static int do_read_bitmap(struct feat_fd *ff, unsigned long **pset, u64 *psize)
        if (!set)
                return -ENOMEM;
 
-       bitmap_zero(set, size);
-
        p = (u64 *) set;
 
        for (i = 0; (u64) i < BITS_TO_U64(size); i++) {
@@ -1285,7 +1283,6 @@ static int memory_node__read(struct memory_node *n, unsigned long idx)
                return -ENOMEM;
        }
 
-       bitmap_zero(n->set, size);
        n->node = idx;
        n->size = size;
 
@@ -3207,7 +3204,7 @@ static int read_attr(int fd, struct perf_header *ph,
 }
 
 static int perf_evsel__prepare_tracepoint_event(struct perf_evsel *evsel,
-                                               struct pevent *pevent)
+                                               struct tep_handle *pevent)
 {
        struct event_format *event;
        char bf[128];
@@ -3221,7 +3218,7 @@ static int perf_evsel__prepare_tracepoint_event(struct perf_evsel *evsel,
                return -1;
        }
 
-       event = pevent_find_event(pevent, evsel->attr.config);
+       event = tep_find_event(pevent, evsel->attr.config);
        if (event == NULL) {
                pr_debug("cannot find event format for %d\n", (int)evsel->attr.config);
                return -1;
@@ -3239,7 +3236,7 @@ static int perf_evsel__prepare_tracepoint_event(struct perf_evsel *evsel,
 }
 
 static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,
-                                                 struct pevent *pevent)
+                                                 struct tep_handle *pevent)
 {
        struct perf_evsel *pos;
 
index 5e94857dfca2c8c47ae289b79dd2a717ae4a82b5..19262f98cd4e1252c09ca77e6319a02d72db50c0 100644 (file)
                "$CLANG_OPTIONS $KERNEL_INC_OPTIONS $PERF_BPF_INC_OPTIONS " \
                "-Wno-unused-value -Wno-pointer-sign "          \
                "-working-directory $WORKING_DIR "              \
-               "-c \"$CLANG_SOURCE\" -target bpf -O2 -o -"
+               "-c \"$CLANG_SOURCE\" -target bpf $CLANG_EMIT_LLVM -O2 -o - $LLVM_OPTIONS_PIPE"
 
 struct llvm_param llvm_param = {
        .clang_path = "clang",
+       .llc_path = "llc",
        .clang_bpf_cmd_template = CLANG_BPF_CMD_DEFAULT_TEMPLATE,
        .clang_opt = NULL,
+       .opts = NULL,
        .kbuild_dir = NULL,
        .kbuild_opts = NULL,
        .user_set_param = false,
@@ -51,6 +53,8 @@ int perf_llvm_config(const char *var, const char *value)
                llvm_param.kbuild_opts = strdup(value);
        else if (!strcmp(var, "dump-obj"))
                llvm_param.dump_obj = !!perf_config_bool(var, value);
+       else if (!strcmp(var, "opts"))
+               llvm_param.opts = strdup(value);
        else {
                pr_debug("Invalid LLVM config option: %s\n", value);
                return -1;
@@ -430,11 +434,13 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
        unsigned int kernel_version;
        char linux_version_code_str[64];
        const char *clang_opt = llvm_param.clang_opt;
-       char clang_path[PATH_MAX], abspath[PATH_MAX], nr_cpus_avail_str[64];
+       char clang_path[PATH_MAX], llc_path[PATH_MAX], abspath[PATH_MAX], nr_cpus_avail_str[64];
        char serr[STRERR_BUFSIZE];
        char *kbuild_dir = NULL, *kbuild_include_opts = NULL,
             *perf_bpf_include_opts = NULL;
        const char *template = llvm_param.clang_bpf_cmd_template;
+       char *pipe_template = NULL;
+       const char *opts = llvm_param.opts;
        char *command_echo = NULL, *command_out;
        char *perf_include_dir = system_path(PERF_INCLUDE_DIR);
 
@@ -484,6 +490,26 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
        force_set_env("PERF_BPF_INC_OPTIONS", perf_bpf_include_opts);
        force_set_env("WORKING_DIR", kbuild_dir ? : ".");
 
+       if (opts) {
+               err = search_program(llvm_param.llc_path, "llc", llc_path);
+               if (err) {
+                       pr_err("ERROR:\tunable to find llc.\n"
+                              "Hint:\tTry to install latest clang/llvm to support BPF. Check your $PATH\n"
+                              "     \tand 'llc-path' option in [llvm] section of ~/.perfconfig.\n");
+                       version_notice();
+                       goto errout;
+               }
+
+               if (asprintf(&pipe_template, "%s -emit-llvm | %s -march=bpf %s -filetype=obj -o -",
+                             template, llc_path, opts) < 0) {
+                       pr_err("ERROR:\tnot enough memory to setup command line\n");
+                       goto errout;
+               }
+
+               template = pipe_template;
+
+       }
+
        /*
         * Since we may reset clang's working dir, path of source file
         * should be transferred into absolute path, except we want
@@ -535,6 +561,7 @@ errout:
        free(obj_buf);
        free(perf_bpf_include_opts);
        free(perf_include_dir);
+       free(pipe_template);
        if (p_obj_buf)
                *p_obj_buf = NULL;
        if (p_obj_buf_sz)
index d3ad8deb5db4d359e28d8cec4794fe78ee34bf15..bf3f3f4c4fe20539ca1ae0158da982c5103fc1c4 100644 (file)
@@ -11,6 +11,8 @@
 struct llvm_param {
        /* Path of clang executable */
        const char *clang_path;
+       /* Path of llc executable */
+       const char *llc_path;
        /*
         * Template of clang bpf compiling. 5 env variables
         * can be used:
@@ -23,6 +25,13 @@ struct llvm_param {
        const char *clang_bpf_cmd_template;
        /* Will be filled in $CLANG_OPTIONS */
        const char *clang_opt;
+       /*
+        * If present it'll add -emit-llvm to $CLANG_OPTIONS to pipe
+        * the clang output to llc, useful for new llvm options not
+        * yet selectable via 'clang -mllvm option', such as -mattr=dwarfris
+        * in clang 6.0/llvm 7
+        */
+       const char *opts;
        /* Where to find kbuild system */
        const char *kbuild_dir;
        /*
index 07498eaddc0836c7339155eb4e0439e3044047ea..b1dd29a9d915efac1953d0d04ad9b99a5f3425de 100644 (file)
@@ -3,9 +3,13 @@
 #include <lzma.h>
 #include <stdio.h>
 #include <linux/compiler.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 #include "compress.h"
 #include "util.h"
 #include "debug.h"
+#include <unistd.h>
 
 #define BUFSIZE 8192
 
@@ -99,3 +103,19 @@ err_fclose:
        fclose(infile);
        return err;
 }
+
+bool lzma_is_compressed(const char *input)
+{
+       int fd = open(input, O_RDONLY);
+       const uint8_t magic[6] = { 0xFD, '7', 'z', 'X', 'Z', 0x00 };
+       char buf[6] = { 0 };
+       ssize_t rc;
+
+       if (fd < 0)
+               return -1;
+
+       rc = read(fd, buf, sizeof(buf));
+       close(fd);
+       return rc == sizeof(buf) ?
+              memcmp(buf, magic, sizeof(buf)) == 0 : false;
+}
index b300a3973448a91fd4286af12605fd653fc2a74a..c4acd2001db0d054fd3c39f328f7fbf57aa0e8ea 100644 (file)
@@ -1212,8 +1212,10 @@ static int map_groups__set_module_path(struct map_groups *mg, const char *path,
         * Full name could reveal us kmod compression, so
         * we need to update the symtab_type if needed.
         */
-       if (m->comp && is_kmod_dso(map->dso))
+       if (m->comp && is_kmod_dso(map->dso)) {
                map->dso->symtab_type++;
+               map->dso->comp = m->comp;
+       }
 
        return 0;
 }
index 1de7660d93e97430382c00318dab288dd025ec39..d856b85862e23e9cd3026979ed29c0b75094d9de 100644 (file)
@@ -265,7 +265,7 @@ pid_t machine__get_current_tid(struct machine *machine, int cpu);
 int machine__set_current_tid(struct machine *machine, int cpu, pid_t pid,
                             pid_t tid);
 /*
- * For use with libtraceevent's pevent_set_function_resolver()
+ * For use with libtraceevent's tep_set_function_resolver()
  */
 char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, char **modp);
 
index 89ac5b5dc218e874024f41cc2d730cd40152f9f6..36d0763311efccec1adfb498cd39154266997f26 100644 (file)
@@ -381,20 +381,6 @@ struct map *map__clone(struct map *from)
        return map;
 }
 
-int map__overlap(struct map *l, struct map *r)
-{
-       if (l->start > r->start) {
-               struct map *t = l;
-               l = r;
-               r = t;
-       }
-
-       if (l->end > r->start)
-               return 1;
-
-       return 0;
-}
-
 size_t map__fprintf(struct map *map, FILE *fp)
 {
        return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
@@ -675,20 +661,42 @@ static void __map_groups__insert(struct map_groups *mg, struct map *map)
 static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
 {
        struct rb_root *root;
-       struct rb_node *next;
+       struct rb_node *next, *first;
        int err = 0;
 
        down_write(&maps->lock);
 
        root = &maps->entries;
-       next = rb_first(root);
 
+       /*
+        * Find first map where end > map->start.
+        * Same as find_vma() in kernel.
+        */
+       next = root->rb_node;
+       first = NULL;
+       while (next) {
+               struct map *pos = rb_entry(next, struct map, rb_node);
+
+               if (pos->end > map->start) {
+                       first = next;
+                       if (pos->start <= map->start)
+                               break;
+                       next = next->rb_left;
+               } else
+                       next = next->rb_right;
+       }
+
+       next = first;
        while (next) {
                struct map *pos = rb_entry(next, struct map, rb_node);
                next = rb_next(&pos->rb_node);
 
-               if (!map__overlap(pos, map))
-                       continue;
+               /*
+                * Stop if current map starts after map->end.
+                * Maps are ordered by start: next will not overlap for sure.
+                */
+               if (pos->start >= map->end)
+                       break;
 
                if (verbose >= 2) {
 
index 4cb90f242bed882e35821b5e6a12c4f2abe90ba8..e0f327b51e6605305e148843a4796c7b61f2376b 100644 (file)
@@ -166,7 +166,6 @@ static inline void __map__zput(struct map **map)
 
 #define map__zput(map) __map__zput(&map)
 
-int map__overlap(struct map *l, struct map *r);
 size_t map__fprintf(struct map *map, FILE *fp);
 size_t map__fprintf_dsoname(struct map *map, FILE *fp);
 char *map__srcline(struct map *map, u64 addr, struct symbol *sym);
index fc832676a7985f13c4ba7f419b380b7fa2425798..215f69f41672dcc44b6e57948ee3a9fbcdec2724 100644 (file)
@@ -164,7 +164,7 @@ void perf_mmap__munmap(struct perf_mmap *map)
        auxtrace_mmap__munmap(&map->auxtrace_mmap);
 }
 
-int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd)
+int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd, int cpu)
 {
        /*
         * The last one will be done at perf_mmap__consume(), so that we
@@ -191,6 +191,7 @@ int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd)
                return -1;
        }
        map->fd = fd;
+       map->cpu = cpu;
 
        if (auxtrace_mmap__mmap(&map->auxtrace_mmap,
                                &mp->auxtrace_mp, map->base, fd))
index d82294db1295333096eb1111349f1411ff7f8120..05a6d47c79561d5a62c04ae9d600a0ecd16f39b4 100644 (file)
@@ -18,6 +18,7 @@ struct perf_mmap {
        void             *base;
        int              mask;
        int              fd;
+       int              cpu;
        refcount_t       refcnt;
        u64              prev;
        u64              start;
@@ -60,7 +61,7 @@ struct mmap_params {
        struct auxtrace_mmap_params auxtrace_mp;
 };
 
-int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd);
+int perf_mmap__mmap(struct perf_mmap *map, struct mmap_params *mp, int fd, int cpu);
 void perf_mmap__munmap(struct perf_mmap *map);
 
 void perf_mmap__get(struct perf_mmap *map);
index 5be021701f34e758aae5eda1d95bb7a9ce49ebad..cf8bd123cf73fb017cde3d60c7b912743847b965 100644 (file)
@@ -139,6 +139,9 @@ struct nsinfo *nsinfo__copy(struct nsinfo *nsi)
 {
        struct nsinfo *nnsi;
 
+       if (nsi == NULL)
+               return NULL;
+
        nnsi = calloc(1, sizeof(*nnsi));
        if (nnsi != NULL) {
                nnsi->pid = nsi->pid;
index 15eec49e71a12ad89596f928e39874522c4a65df..f8cd3e7c918668cc1f593b539c6648d16b091726 100644 (file)
@@ -1991,8 +1991,11 @@ static int set_filter(struct perf_evsel *evsel, const void *arg)
        int nr_addr_filters = 0;
        struct perf_pmu *pmu = NULL;
 
-       if (evsel == NULL)
-               goto err;
+       if (evsel == NULL) {
+               fprintf(stderr,
+                       "--filter option should follow a -e tracepoint or HW tracer option\n");
+               return -1;
+       }
 
        if (evsel->attr.type == PERF_TYPE_TRACEPOINT) {
                if (perf_evsel__append_tp_filter(evsel, str) < 0) {
@@ -2014,8 +2017,11 @@ static int set_filter(struct perf_evsel *evsel, const void *arg)
                perf_pmu__scan_file(pmu, "nr_addr_filters",
                                    "%d", &nr_addr_filters);
 
-       if (!nr_addr_filters)
-               goto err;
+       if (!nr_addr_filters) {
+               fprintf(stderr,
+                       "This CPU does not support address filtering\n");
+               return -1;
+       }
 
        if (perf_evsel__append_addr_filter(evsel, str) < 0) {
                fprintf(stderr,
@@ -2024,12 +2030,6 @@ static int set_filter(struct perf_evsel *evsel, const void *arg)
        }
 
        return 0;
-
-err:
-       fprintf(stderr,
-               "--filter option should follow a -e tracepoint or HW tracer option\n");
-
-       return -1;
 }
 
 int parse_filter(const struct option *opt, const char *str,
index 863b61478edd6d21533b925dde01abef35354a80..ce501ba14b088b112ed75ae4402562b4bcbd8eb1 100644 (file)
@@ -11,6 +11,7 @@
 #include "cpumap.h"
 #include "print_binary.h"
 #include "thread_map.h"
+#include "mmap.h"
 
 #if PY_MAJOR_VERSION < 3
 #define _PyUnicode_FromString(arg) \
@@ -341,7 +342,7 @@ static bool is_tracepoint(struct pyrf_event *pevent)
 static PyObject*
 tracepoint_field(struct pyrf_event *pe, struct format_field *field)
 {
-       struct pevent *pevent = field->event->pevent;
+       struct tep_handle *pevent = field->event->pevent;
        void *data = pe->sample.raw_data;
        PyObject *ret = NULL;
        unsigned long long val;
@@ -351,7 +352,7 @@ tracepoint_field(struct pyrf_event *pe, struct format_field *field)
                offset = field->offset;
                len    = field->size;
                if (field->flags & FIELD_IS_DYNAMIC) {
-                       val     = pevent_read_number(pevent, data + offset, len);
+                       val     = tep_read_number(pevent, data + offset, len);
                        offset  = val;
                        len     = offset >> 16;
                        offset &= 0xffff;
@@ -364,8 +365,8 @@ tracepoint_field(struct pyrf_event *pe, struct format_field *field)
                        field->flags &= ~FIELD_IS_STRING;
                }
        } else {
-               val = pevent_read_number(pevent, data + field->offset,
-                                        field->size);
+               val = tep_read_number(pevent, data + field->offset,
+                                     field->size);
                if (field->flags & FIELD_IS_POINTER)
                        ret = PyLong_FromUnsignedLong((unsigned long) val);
                else if (field->flags & FIELD_IS_SIGNED)
@@ -394,7 +395,7 @@ get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name)
                evsel->tp_format = tp_format;
        }
 
-       field = pevent_find_any_field(evsel->tp_format, str);
+       field = tep_find_any_field(evsel->tp_format, str);
        if (!field)
                return NULL;
 
@@ -976,6 +977,20 @@ static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
        return Py_BuildValue("i", evlist->nr_entries);
 }
 
+static struct perf_mmap *get_md(struct perf_evlist *evlist, int cpu)
+{
+       int i;
+
+       for (i = 0; i < evlist->nr_mmaps; i++) {
+               struct perf_mmap *md = &evlist->mmap[i];
+
+               if (md->cpu == cpu)
+                       return md;
+       }
+
+       return NULL;
+}
+
 static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
                                          PyObject *args, PyObject *kwargs)
 {
@@ -990,7 +1005,10 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
                                         &cpu, &sample_id_all))
                return NULL;
 
-       md = &evlist->mmap[cpu];
+       md = get_md(evlist, cpu);
+       if (!md)
+               return NULL;
+
        if (perf_mmap__read_init(md) < 0)
                goto end;
 
diff --git a/tools/perf/util/s390-cpumsf-kernel.h b/tools/perf/util/s390-cpumsf-kernel.h
new file mode 100644 (file)
index 0000000..de8c7ad
--- /dev/null
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Auxtrace support for s390 CPU measurement sampling facility
+ *
+ *  Copyright IBM Corp. 2018
+ *  Author(s): Hendrik Brueckner <brueckner@linux.ibm.com>
+ *            Thomas Richter <tmricht@linux.ibm.com>
+ */
+#ifndef S390_CPUMSF_KERNEL_H
+#define S390_CPUMSF_KERNEL_H
+
+#define        S390_CPUMSF_PAGESZ      4096    /* Size of sample block units */
+#define        S390_CPUMSF_DIAG_DEF_FIRST      0x8001  /* Diagnostic entry lowest id */
+
+struct hws_basic_entry {
+       unsigned int def:16;        /* 0-15  Data Entry Format           */
+       unsigned int R:4;           /* 16-19 reserved                    */
+       unsigned int U:4;           /* 20-23 Number of unique instruct.  */
+       unsigned int z:2;           /* zeros                             */
+       unsigned int T:1;           /* 26 PSW DAT mode                   */
+       unsigned int W:1;           /* 27 PSW wait state                 */
+       unsigned int P:1;           /* 28 PSW Problem state              */
+       unsigned int AS:2;          /* 29-30 PSW address-space control   */
+       unsigned int I:1;           /* 31 entry valid or invalid         */
+       unsigned int CL:2;          /* 32-33 Configuration Level         */
+       unsigned int:14;
+       unsigned int prim_asn:16;   /* primary ASN                       */
+       unsigned long long ia;      /* Instruction Address               */
+       unsigned long long gpp;     /* Guest Program Parameter           */
+       unsigned long long hpp;     /* Host Program Parameter            */
+};
+
+struct hws_diag_entry {
+       unsigned int def:16;        /* 0-15  Data Entry Format           */
+       unsigned int R:15;          /* 16-19 and 20-30 reserved          */
+       unsigned int I:1;           /* 31 entry valid or invalid         */
+       u8           data[];        /* Machine-dependent sample data     */
+};
+
+struct hws_combined_entry {
+       struct hws_basic_entry  basic;  /* Basic-sampling data entry */
+       struct hws_diag_entry   diag;   /* Diagnostic-sampling data entry */
+};
+
+struct hws_trailer_entry {
+       union {
+               struct {
+                       unsigned int f:1;       /* 0 - Block Full Indicator   */
+                       unsigned int a:1;       /* 1 - Alert request control  */
+                       unsigned int t:1;       /* 2 - Timestamp format       */
+                       unsigned int:29;        /* 3 - 31: Reserved           */
+                       unsigned int bsdes:16;  /* 32-47: size of basic SDE   */
+                       unsigned int dsdes:16;  /* 48-63: size of diagnostic SDE */
+               };
+               unsigned long long flags;       /* 0 - 64: All indicators     */
+       };
+       unsigned long long overflow;     /* 64 - sample Overflow count        */
+       unsigned char timestamp[16];     /* 16 - 31 timestamp                 */
+       unsigned long long reserved1;    /* 32 -Reserved                      */
+       unsigned long long reserved2;    /*                                   */
+       union {                          /* 48 - reserved for programming use */
+               struct {
+                       unsigned long long clock_base:1; /* in progusage2 */
+                       unsigned long long progusage1:63;
+                       unsigned long long progusage2;
+               };
+               unsigned long long progusage[2];
+       };
+};
+
+#endif
diff --git a/tools/perf/util/s390-cpumsf.c b/tools/perf/util/s390-cpumsf.c
new file mode 100644 (file)
index 0000000..d2c78ff
--- /dev/null
@@ -0,0 +1,945 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright IBM Corp. 2018
+ * Auxtrace support for s390 CPU-Measurement Sampling Facility
+ *
+ * Author(s):  Thomas Richter <tmricht@linux.ibm.com>
+ *
+ * Auxiliary traces are collected during 'perf record' using rbd000 event.
+ * Several PERF_RECORD_XXX are generated during recording:
+ *
+ * PERF_RECORD_AUX:
+ *     Records that new data landed in the AUX buffer part.
+ * PERF_RECORD_AUXTRACE:
+ *     Defines auxtrace data. Followed by the actual data. The contents of
+ *     the auxtrace data is dependent on the event and the CPU.
+ *     This record is generated by perf record command. For details
+ *     see Documentation/perf.data-file-format.txt.
+ * PERF_RECORD_AUXTRACE_INFO:
+ *     Defines a table of contains for PERF_RECORD_AUXTRACE records. This
+ *     record is generated during 'perf record' command. Each record contains up
+ *     to 256 entries describing offset and size of the AUXTRACE data in the
+ *     perf.data file.
+ * PERF_RECORD_AUXTRACE_ERROR:
+ *     Indicates an error during AUXTRACE collection such as buffer overflow.
+ * PERF_RECORD_FINISHED_ROUND:
+ *     Perf events are not necessarily in time stamp order, as they can be
+ *     collected in parallel on different CPUs. If the events should be
+ *     processed in time order they need to be sorted first.
+ *     Perf report guarantees that there is no reordering over a
+ *     PERF_RECORD_FINISHED_ROUND boundary event. All perf records with a
+ *     time stamp lower than this record are processed (and displayed) before
+ *     the succeeding perf record are processed.
+ *
+ * These records are evaluated during perf report command.
+ *
+ * 1. PERF_RECORD_AUXTRACE_INFO is used to set up the infrastructure for
+ * auxiliary trace data processing. See s390_cpumsf_process_auxtrace_info()
+ * below.
+ * Auxiliary trace data is collected per CPU. To merge the data into the report
+ * an auxtrace_queue is created for each CPU. It is assumed that the auxtrace
+ * data is in ascending order.
+ *
+ * Each queue has a double linked list of auxtrace_buffers. This list contains
+ * the offset and size of a CPU's auxtrace data. During auxtrace processing
+ * the data portion is mmap()'ed.
+ *
+ * To sort the queues in chronological order, all queue access is controlled
+ * by the auxtrace_heap. This is basicly a stack, each stack element has two
+ * entries, the queue number and a time stamp. However the stack is sorted by
+ * the time stamps. The highest time stamp is at the bottom the lowest
+ * (nearest) time stamp is at the top. That sort order is maintained at all
+ * times!
+ *
+ * After the auxtrace infrastructure has been setup, the auxtrace queues are
+ * filled with data (offset/size pairs) and the auxtrace_heap is populated.
+ *
+ * 2. PERF_RECORD_XXX processing triggers access to the auxtrace_queues.
+ * Each record is handled by s390_cpumsf_process_event(). The time stamp of
+ * the perf record is compared with the time stamp located on the auxtrace_heap
+ * top element. If that time stamp is lower than the time stamp from the
+ * record sample, the auxtrace queues will be processed. As auxtrace queues
+ * control many auxtrace_buffers and each buffer can be quite large, the
+ * auxtrace buffer might be processed only partially. In this case the
+ * position in the auxtrace_buffer of that queue is remembered and the time
+ * stamp of the last processed entry of the auxtrace_buffer replaces the
+ * current auxtrace_heap top.
+ *
+ * 3. Auxtrace_queues might run of out data and are feeded by the
+ * PERF_RECORD_AUXTRACE handling, see s390_cpumsf_process_auxtrace_event().
+ *
+ * Event Generation
+ * Each sampling-data entry in the auxilary trace data generates a perf sample.
+ * This sample is filled
+ * with data from the auxtrace such as PID/TID, instruction address, CPU state,
+ * etc. This sample is processed with perf_session__deliver_synth_event() to
+ * be included into the GUI.
+ *
+ * 4. PERF_RECORD_FINISHED_ROUND event is used to process all the remaining
+ * auxiliary traces entries until the time stamp of this record is reached
+ * auxtrace_heap top. This is triggered by ordered_event->deliver().
+ *
+ *
+ * Perf event processing.
+ * Event processing of PERF_RECORD_XXX entries relies on time stamp entries.
+ * This is the function call sequence:
+ *
+ * __cmd_report()
+ * |
+ * perf_session__process_events()
+ * |
+ * __perf_session__process_events()
+ * |
+ * perf_session__process_event()
+ * |  This functions splits the PERF_RECORD_XXX records.
+ * |  - Those generated by perf record command (type number equal or higher
+ * |    than PERF_RECORD_USER_TYPE_START) are handled by
+ * |    perf_session__process_user_event(see below)
+ * |  - Those generated by the kernel are handled by
+ * |    perf_evlist__parse_sample_timestamp()
+ * |
+ * perf_evlist__parse_sample_timestamp()
+ * |  Extract time stamp from sample data.
+ * |
+ * perf_session__queue_event()
+ * |  If timestamp is positive the sample is entered into an ordered_event
+ * |  list, sort order is the timestamp. The event processing is deferred until
+ * |  later (see perf_session__process_user_event()).
+ * |  Other timestamps (0 or -1) are handled immediately by
+ * |  perf_session__deliver_event(). These are events generated at start up
+ * |  of command perf record. They create PERF_RECORD_COMM and PERF_RECORD_MMAP*
+ * |  records. They are needed to create a list of running processes and its
+ * |  memory mappings and layout. They are needed at the beginning to enable
+ * |  command perf report to create process trees and memory mappings.
+ * |
+ * perf_session__deliver_event()
+ * |  Delivers a PERF_RECORD_XXX entry for handling.
+ * |
+ * auxtrace__process_event()
+ * |  The timestamp of the PERF_RECORD_XXX entry is taken to correlate with
+ * |  time stamps from the auxiliary trace buffers. This enables
+ * |  synchronization between auxiliary trace data and the events on the
+ * |  perf.data file.
+ * |
+ * machine__deliver_event()
+ * |  Handles the PERF_RECORD_XXX event. This depends on the record type.
+ *    It might update the process tree, update a process memory map or enter
+ *    a sample with IP and call back chain data into GUI data pool.
+ *
+ *
+ * Deferred processing determined by perf_session__process_user_event() is
+ * finally processed when a PERF_RECORD_FINISHED_ROUND is encountered. These
+ * are generated during command perf record.
+ * The timestamp of PERF_RECORD_FINISHED_ROUND event is taken to process all
+ * PERF_RECORD_XXX entries stored in the ordered_event list. This list was
+ * built up while reading the perf.data file.
+ * Each event is now processed by calling perf_session__deliver_event().
+ * This enables time synchronization between the data in the perf.data file and
+ * the data in the auxiliary trace buffers.
+ */
+
+#include <endian.h>
+#include <errno.h>
+#include <byteswap.h>
+#include <inttypes.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/log2.h>
+
+#include "cpumap.h"
+#include "color.h"
+#include "evsel.h"
+#include "evlist.h"
+#include "machine.h"
+#include "session.h"
+#include "util.h"
+#include "thread.h"
+#include "debug.h"
+#include "auxtrace.h"
+#include "s390-cpumsf.h"
+#include "s390-cpumsf-kernel.h"
+
+struct s390_cpumsf {
+       struct auxtrace         auxtrace;
+       struct auxtrace_queues  queues;
+       struct auxtrace_heap    heap;
+       struct perf_session     *session;
+       struct machine          *machine;
+       u32                     auxtrace_type;
+       u32                     pmu_type;
+       u16                     machine_type;
+       bool                    data_queued;
+};
+
+struct s390_cpumsf_queue {
+       struct s390_cpumsf      *sf;
+       unsigned int            queue_nr;
+       struct auxtrace_buffer  *buffer;
+       int                     cpu;
+};
+
+/* Display s390 CPU measurement facility basic-sampling data entry */
+static bool s390_cpumsf_basic_show(const char *color, size_t pos,
+                                  struct hws_basic_entry *basic)
+{
+       if (basic->def != 1) {
+               pr_err("Invalid AUX trace basic entry [%#08zx]\n", pos);
+               return false;
+       }
+       color_fprintf(stdout, color, "    [%#08zx] Basic   Def:%04x Inst:%#04x"
+                     " %c%c%c%c AS:%d ASN:%#04x IA:%#018llx\n"
+                     "\t\tCL:%d HPP:%#018llx GPP:%#018llx\n",
+                     pos, basic->def, basic->U,
+                     basic->T ? 'T' : ' ',
+                     basic->W ? 'W' : ' ',
+                     basic->P ? 'P' : ' ',
+                     basic->I ? 'I' : ' ',
+                     basic->AS, basic->prim_asn, basic->ia, basic->CL,
+                     basic->hpp, basic->gpp);
+       return true;
+}
+
+/* Display s390 CPU measurement facility diagnostic-sampling data entry */
+static bool s390_cpumsf_diag_show(const char *color, size_t pos,
+                                 struct hws_diag_entry *diag)
+{
+       if (diag->def < S390_CPUMSF_DIAG_DEF_FIRST) {
+               pr_err("Invalid AUX trace diagnostic entry [%#08zx]\n", pos);
+               return false;
+       }
+       color_fprintf(stdout, color, "    [%#08zx] Diag    Def:%04x %c\n",
+                     pos, diag->def, diag->I ? 'I' : ' ');
+       return true;
+}
+
+/* Return TOD timestamp contained in an trailer entry */
+static unsigned long long trailer_timestamp(struct hws_trailer_entry *te)
+{
+       /* te->t set: TOD in STCKE format, bytes 8-15
+        * to->t not set: TOD in STCK format, bytes 0-7
+        */
+       unsigned long long ts;
+
+       memcpy(&ts, &te->timestamp[te->t], sizeof(ts));
+       return ts;
+}
+
+/* Display s390 CPU measurement facility trailer entry */
+static bool s390_cpumsf_trailer_show(const char *color, size_t pos,
+                                    struct hws_trailer_entry *te)
+{
+       if (te->bsdes != sizeof(struct hws_basic_entry)) {
+               pr_err("Invalid AUX trace trailer entry [%#08zx]\n", pos);
+               return false;
+       }
+       color_fprintf(stdout, color, "    [%#08zx] Trailer %c%c%c bsdes:%d"
+                     " dsdes:%d Overflow:%lld Time:%#llx\n"
+                     "\t\tC:%d TOD:%#lx 1:%#llx 2:%#llx\n",
+                     pos,
+                     te->f ? 'F' : ' ',
+                     te->a ? 'A' : ' ',
+                     te->t ? 'T' : ' ',
+                     te->bsdes, te->dsdes, te->overflow,
+                     trailer_timestamp(te), te->clock_base, te->progusage2,
+                     te->progusage[0], te->progusage[1]);
+       return true;
+}
+
+/* Test a sample data block. It must be 4KB or a multiple thereof in size and
+ * 4KB page aligned. Each sample data page has a trailer entry at the
+ * end which contains the sample entry data sizes.
+ *
+ * Return true if the sample data block passes the checks and set the
+ * basic set entry size and diagnostic set entry size.
+ *
+ * Return false on failure.
+ *
+ * Note: Old hardware does not set the basic or diagnostic entry sizes
+ * in the trailer entry. Use the type number instead.
+ */
+static bool s390_cpumsf_validate(int machine_type,
+                                unsigned char *buf, size_t len,
+                                unsigned short *bsdes,
+                                unsigned short *dsdes)
+{
+       struct hws_basic_entry *basic = (struct hws_basic_entry *)buf;
+       struct hws_trailer_entry *te;
+
+       *dsdes = *bsdes = 0;
+       if (len & (S390_CPUMSF_PAGESZ - 1))     /* Illegal size */
+               return false;
+       if (basic->def != 1)            /* No basic set entry, must be first */
+               return false;
+       /* Check for trailer entry at end of SDB */
+       te = (struct hws_trailer_entry *)(buf + S390_CPUMSF_PAGESZ
+                                             - sizeof(*te));
+       *bsdes = te->bsdes;
+       *dsdes = te->dsdes;
+       if (!te->bsdes && !te->dsdes) {
+               /* Very old hardware, use CPUID */
+               switch (machine_type) {
+               case 2097:
+               case 2098:
+                       *dsdes = 64;
+                       *bsdes = 32;
+                       break;
+               case 2817:
+               case 2818:
+                       *dsdes = 74;
+                       *bsdes = 32;
+                       break;
+               case 2827:
+               case 2828:
+                       *dsdes = 85;
+                       *bsdes = 32;
+                       break;
+               default:
+                       /* Illegal trailer entry */
+                       return false;
+               }
+       }
+       return true;
+}
+
+/* Return true if there is room for another entry */
+static bool s390_cpumsf_reached_trailer(size_t entry_sz, size_t pos)
+{
+       size_t payload = S390_CPUMSF_PAGESZ - sizeof(struct hws_trailer_entry);
+
+       if (payload - (pos & (S390_CPUMSF_PAGESZ - 1)) < entry_sz)
+               return false;
+       return true;
+}
+
+/* Dump an auxiliary buffer. These buffers are multiple of
+ * 4KB SDB pages.
+ */
+static void s390_cpumsf_dump(struct s390_cpumsf *sf,
+                            unsigned char *buf, size_t len)
+{
+       const char *color = PERF_COLOR_BLUE;
+       struct hws_basic_entry *basic;
+       struct hws_diag_entry *diag;
+       unsigned short bsdes, dsdes;
+       size_t pos = 0;
+
+       color_fprintf(stdout, color,
+                     ". ... s390 AUX data: size %zu bytes\n",
+                     len);
+
+       if (!s390_cpumsf_validate(sf->machine_type, buf, len, &bsdes,
+                                 &dsdes)) {
+               pr_err("Invalid AUX trace data block size:%zu"
+                      " (type:%d bsdes:%hd dsdes:%hd)\n",
+                      len, sf->machine_type, bsdes, dsdes);
+               return;
+       }
+
+       /* s390 kernel always returns 4KB blocks fully occupied,
+        * no partially filled SDBs.
+        */
+       while (pos < len) {
+               /* Handle Basic entry */
+               basic = (struct hws_basic_entry *)(buf + pos);
+               if (s390_cpumsf_basic_show(color, pos, basic))
+                       pos += bsdes;
+               else
+                       return;
+
+               /* Handle Diagnostic entry */
+               diag = (struct hws_diag_entry *)(buf + pos);
+               if (s390_cpumsf_diag_show(color, pos, diag))
+                       pos += dsdes;
+               else
+                       return;
+
+               /* Check for trailer entry */
+               if (!s390_cpumsf_reached_trailer(bsdes + dsdes, pos)) {
+                       /* Show trailer entry */
+                       struct hws_trailer_entry te;
+
+                       pos = (pos + S390_CPUMSF_PAGESZ)
+                              & ~(S390_CPUMSF_PAGESZ - 1);
+                       pos -= sizeof(te);
+                       memcpy(&te, buf + pos, sizeof(te));
+                       /* Set descriptor sizes in case of old hardware
+                        * where these values are not set.
+                        */
+                       te.bsdes = bsdes;
+                       te.dsdes = dsdes;
+                       if (s390_cpumsf_trailer_show(color, pos, &te))
+                               pos += sizeof(te);
+                       else
+                               return;
+               }
+       }
+}
+
+static void s390_cpumsf_dump_event(struct s390_cpumsf *sf, unsigned char *buf,
+                                  size_t len)
+{
+       printf(".\n");
+       s390_cpumsf_dump(sf, buf, len);
+}
+
+#define        S390_LPP_PID_MASK       0xffffffff
+
+static bool s390_cpumsf_make_event(size_t pos,
+                                  struct hws_basic_entry *basic,
+                                  struct s390_cpumsf_queue *sfq)
+{
+       struct perf_sample sample = {
+                               .ip = basic->ia,
+                               .pid = basic->hpp & S390_LPP_PID_MASK,
+                               .tid = basic->hpp & S390_LPP_PID_MASK,
+                               .cpumode = PERF_RECORD_MISC_CPUMODE_UNKNOWN,
+                               .cpu = sfq->cpu,
+                               .period = 1
+                           };
+       union perf_event event;
+
+       memset(&event, 0, sizeof(event));
+       if (basic->CL == 1)     /* Native LPAR mode */
+               sample.cpumode = basic->P ? PERF_RECORD_MISC_USER
+                                         : PERF_RECORD_MISC_KERNEL;
+       else if (basic->CL == 2)        /* Guest kernel/user space */
+               sample.cpumode = basic->P ? PERF_RECORD_MISC_GUEST_USER
+                                         : PERF_RECORD_MISC_GUEST_KERNEL;
+       else if (basic->gpp || basic->prim_asn != 0xffff)
+               /* Use heuristics on old hardware */
+               sample.cpumode = basic->P ? PERF_RECORD_MISC_GUEST_USER
+                                         : PERF_RECORD_MISC_GUEST_KERNEL;
+       else
+               sample.cpumode = basic->P ? PERF_RECORD_MISC_USER
+                                         : PERF_RECORD_MISC_KERNEL;
+
+       event.sample.header.type = PERF_RECORD_SAMPLE;
+       event.sample.header.misc = sample.cpumode;
+       event.sample.header.size = sizeof(struct perf_event_header);
+
+       pr_debug4("%s pos:%#zx ip:%#" PRIx64 " P:%d CL:%d pid:%d.%d cpumode:%d cpu:%d\n",
+                __func__, pos, sample.ip, basic->P, basic->CL, sample.pid,
+                sample.tid, sample.cpumode, sample.cpu);
+       if (perf_session__deliver_synth_event(sfq->sf->session, &event,
+                                             &sample)) {
+               pr_err("s390 Auxiliary Trace: failed to deliver event\n");
+               return false;
+       }
+       return true;
+}
+
+static unsigned long long get_trailer_time(const unsigned char *buf)
+{
+       struct hws_trailer_entry *te;
+       unsigned long long aux_time;
+
+       te = (struct hws_trailer_entry *)(buf + S390_CPUMSF_PAGESZ
+                                             - sizeof(*te));
+
+       if (!te->clock_base)    /* TOD_CLOCK_BASE value missing */
+               return 0;
+
+       /* Correct calculation to convert time stamp in trailer entry to
+        * nano seconds (taken from arch/s390 function tod_to_ns()).
+        * TOD_CLOCK_BASE is stored in trailer entry member progusage2.
+        */
+       aux_time = trailer_timestamp(te) - te->progusage2;
+       aux_time = (aux_time >> 9) * 125 + (((aux_time & 0x1ff) * 125) >> 9);
+       return aux_time;
+}
+
+/* Process the data samples of a single queue. The first parameter is a
+ * pointer to the queue, the second parameter is the time stamp. This
+ * is the time stamp:
+ * - of the event that triggered this processing.
+ * - or the time stamp when the last proccesing of this queue stopped.
+ *   In this case it stopped at a 4KB page boundary and record the
+ *   position on where to continue processing on the next invocation
+ *   (see buffer->use_data and buffer->use_size).
+ *
+ * When this function returns the second parameter is updated to
+ * reflect the time stamp of the last processed auxiliary data entry
+ * (taken from the trailer entry of that page). The caller uses this
+ * returned time stamp to record the last processed entry in this
+ * queue.
+ *
+ * The function returns:
+ * 0:  Processing successful. The second parameter returns the
+ *     time stamp from the trailer entry until which position
+ *     processing took place. Subsequent calls resume from this
+ *     position.
+ * <0: An error occurred during processing. The second parameter
+ *     returns the maximum time stamp.
+ * >0: Done on this queue. The second parameter returns the
+ *     maximum time stamp.
+ */
+static int s390_cpumsf_samples(struct s390_cpumsf_queue *sfq, u64 *ts)
+{
+       struct s390_cpumsf *sf = sfq->sf;
+       unsigned char *buf = sfq->buffer->use_data;
+       size_t len = sfq->buffer->use_size;
+       struct hws_basic_entry *basic;
+       unsigned short bsdes, dsdes;
+       size_t pos = 0;
+       int err = 1;
+       u64 aux_ts;
+
+       if (!s390_cpumsf_validate(sf->machine_type, buf, len, &bsdes,
+                                 &dsdes)) {
+               *ts = ~0ULL;
+               return -1;
+       }
+
+       /* Get trailer entry time stamp and check if entries in
+        * this auxiliary page are ready for processing. If the
+        * time stamp of the first entry is too high, whole buffer
+        * can be skipped. In this case return time stamp.
+        */
+       aux_ts = get_trailer_time(buf);
+       if (!aux_ts) {
+               pr_err("[%#08" PRIx64 "] Invalid AUX trailer entry TOD clock base\n",
+                      sfq->buffer->data_offset);
+               aux_ts = ~0ULL;
+               goto out;
+       }
+       if (aux_ts > *ts) {
+               *ts = aux_ts;
+               return 0;
+       }
+
+       while (pos < len) {
+               /* Handle Basic entry */
+               basic = (struct hws_basic_entry *)(buf + pos);
+               if (s390_cpumsf_make_event(pos, basic, sfq))
+                       pos += bsdes;
+               else {
+                       err = -EBADF;
+                       goto out;
+               }
+
+               pos += dsdes;   /* Skip diagnositic entry */
+
+               /* Check for trailer entry */
+               if (!s390_cpumsf_reached_trailer(bsdes + dsdes, pos)) {
+                       pos = (pos + S390_CPUMSF_PAGESZ)
+                              & ~(S390_CPUMSF_PAGESZ - 1);
+                       /* Check existence of next page */
+                       if (pos >= len)
+                               break;
+                       aux_ts = get_trailer_time(buf + pos);
+                       if (!aux_ts) {
+                               aux_ts = ~0ULL;
+                               goto out;
+                       }
+                       if (aux_ts > *ts) {
+                               *ts = aux_ts;
+                               sfq->buffer->use_data += pos;
+                               sfq->buffer->use_size -= pos;
+                               return 0;
+                       }
+               }
+       }
+out:
+       *ts = aux_ts;
+       sfq->buffer->use_size = 0;
+       sfq->buffer->use_data = NULL;
+       return err;     /* Buffer completely scanned or error */
+}
+
+/* Run the s390 auxiliary trace decoder.
+ * Select the queue buffer to operate on, the caller already selected
+ * the proper queue, depending on second parameter 'ts'.
+ * This is the time stamp until which the auxiliary entries should
+ * be processed. This value is updated by called functions and
+ * returned to the caller.
+ *
+ * Resume processing in the current buffer. If there is no buffer
+ * get a new buffer from the queue and setup start position for
+ * processing.
+ * When a buffer is completely processed remove it from the queue
+ * before returning.
+ *
+ * This function returns
+ * 1: When the queue is empty. Second parameter will be set to
+ *    maximum time stamp.
+ * 0: Normal processing done.
+ * <0: Error during queue buffer setup. This causes the caller
+ *     to stop processing completely.
+ */
+static int s390_cpumsf_run_decoder(struct s390_cpumsf_queue *sfq,
+                                  u64 *ts)
+{
+
+       struct auxtrace_buffer *buffer;
+       struct auxtrace_queue *queue;
+       int err;
+
+       queue = &sfq->sf->queues.queue_array[sfq->queue_nr];
+
+       /* Get buffer and last position in buffer to resume
+        * decoding the auxiliary entries. One buffer might be large
+        * and decoding might stop in between. This depends on the time
+        * stamp of the trailer entry in each page of the auxiliary
+        * data and the time stamp of the event triggering the decoding.
+        */
+       if (sfq->buffer == NULL) {
+               sfq->buffer = buffer = auxtrace_buffer__next(queue,
+                                                            sfq->buffer);
+               if (!buffer) {
+                       *ts = ~0ULL;
+                       return 1;       /* Processing done on this queue */
+               }
+               /* Start with a new buffer on this queue */
+               if (buffer->data) {
+                       buffer->use_size = buffer->size;
+                       buffer->use_data = buffer->data;
+               }
+       } else
+               buffer = sfq->buffer;
+
+       if (!buffer->data) {
+               int fd = perf_data__fd(sfq->sf->session->data);
+
+               buffer->data = auxtrace_buffer__get_data(buffer, fd);
+               if (!buffer->data)
+                       return -ENOMEM;
+               buffer->use_size = buffer->size;
+               buffer->use_data = buffer->data;
+       }
+       pr_debug4("%s queue_nr:%d buffer:%" PRId64 " offset:%#" PRIx64 " size:%#zx rest:%#zx\n",
+                 __func__, sfq->queue_nr, buffer->buffer_nr, buffer->offset,
+                 buffer->size, buffer->use_size);
+       err = s390_cpumsf_samples(sfq, ts);
+
+       /* If non-zero, there is either an error (err < 0) or the buffer is
+        * completely done (err > 0). The error is unrecoverable, usually
+        * some descriptors could not be read successfully, so continue with
+        * the next buffer.
+        * In both cases the parameter 'ts' has been updated.
+        */
+       if (err) {
+               sfq->buffer = NULL;
+               list_del(&buffer->list);
+               auxtrace_buffer__free(buffer);
+               if (err > 0)            /* Buffer done, no error */
+                       err = 0;
+       }
+       return err;
+}
+
+static struct s390_cpumsf_queue *
+s390_cpumsf_alloc_queue(struct s390_cpumsf *sf, unsigned int queue_nr)
+{
+       struct s390_cpumsf_queue *sfq;
+
+       sfq = zalloc(sizeof(struct s390_cpumsf_queue));
+       if (sfq == NULL)
+               return NULL;
+
+       sfq->sf = sf;
+       sfq->queue_nr = queue_nr;
+       sfq->cpu = -1;
+       return sfq;
+}
+
+static int s390_cpumsf_setup_queue(struct s390_cpumsf *sf,
+                                  struct auxtrace_queue *queue,
+                                  unsigned int queue_nr, u64 ts)
+{
+       struct s390_cpumsf_queue *sfq = queue->priv;
+
+       if (list_empty(&queue->head))
+               return 0;
+
+       if (sfq == NULL) {
+               sfq = s390_cpumsf_alloc_queue(sf, queue_nr);
+               if (!sfq)
+                       return -ENOMEM;
+               queue->priv = sfq;
+
+               if (queue->cpu != -1)
+                       sfq->cpu = queue->cpu;
+       }
+       return auxtrace_heap__add(&sf->heap, queue_nr, ts);
+}
+
+static int s390_cpumsf_setup_queues(struct s390_cpumsf *sf, u64 ts)
+{
+       unsigned int i;
+       int ret = 0;
+
+       for (i = 0; i < sf->queues.nr_queues; i++) {
+               ret = s390_cpumsf_setup_queue(sf, &sf->queues.queue_array[i],
+                                             i, ts);
+               if (ret)
+                       break;
+       }
+       return ret;
+}
+
+static int s390_cpumsf_update_queues(struct s390_cpumsf *sf, u64 ts)
+{
+       if (!sf->queues.new_data)
+               return 0;
+
+       sf->queues.new_data = false;
+       return s390_cpumsf_setup_queues(sf, ts);
+}
+
+static int s390_cpumsf_process_queues(struct s390_cpumsf *sf, u64 timestamp)
+{
+       unsigned int queue_nr;
+       u64 ts;
+       int ret;
+
+       while (1) {
+               struct auxtrace_queue *queue;
+               struct s390_cpumsf_queue *sfq;
+
+               if (!sf->heap.heap_cnt)
+                       return 0;
+
+               if (sf->heap.heap_array[0].ordinal >= timestamp)
+                       return 0;
+
+               queue_nr = sf->heap.heap_array[0].queue_nr;
+               queue = &sf->queues.queue_array[queue_nr];
+               sfq = queue->priv;
+
+               auxtrace_heap__pop(&sf->heap);
+               if (sf->heap.heap_cnt) {
+                       ts = sf->heap.heap_array[0].ordinal + 1;
+                       if (ts > timestamp)
+                               ts = timestamp;
+               } else {
+                       ts = timestamp;
+               }
+
+               ret = s390_cpumsf_run_decoder(sfq, &ts);
+               if (ret < 0) {
+                       auxtrace_heap__add(&sf->heap, queue_nr, ts);
+                       return ret;
+               }
+               if (!ret) {
+                       ret = auxtrace_heap__add(&sf->heap, queue_nr, ts);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+       return 0;
+}
+
+static int s390_cpumsf_synth_error(struct s390_cpumsf *sf, int code, int cpu,
+                                  pid_t pid, pid_t tid, u64 ip)
+{
+       char msg[MAX_AUXTRACE_ERROR_MSG];
+       union perf_event event;
+       int err;
+
+       strncpy(msg, "Lost Auxiliary Trace Buffer", sizeof(msg) - 1);
+       auxtrace_synth_error(&event.auxtrace_error, PERF_AUXTRACE_ERROR_ITRACE,
+                            code, cpu, pid, tid, ip, msg);
+
+       err = perf_session__deliver_synth_event(sf->session, &event, NULL);
+       if (err)
+               pr_err("s390 Auxiliary Trace: failed to deliver error event,"
+                       "error %d\n", err);
+       return err;
+}
+
+static int s390_cpumsf_lost(struct s390_cpumsf *sf, struct perf_sample *sample)
+{
+       return s390_cpumsf_synth_error(sf, 1, sample->cpu,
+                                      sample->pid, sample->tid, 0);
+}
+
+static int
+s390_cpumsf_process_event(struct perf_session *session __maybe_unused,
+                         union perf_event *event,
+                         struct perf_sample *sample,
+                         struct perf_tool *tool)
+{
+       struct s390_cpumsf *sf = container_of(session->auxtrace,
+                                             struct s390_cpumsf,
+                                             auxtrace);
+       u64 timestamp = sample->time;
+       int err = 0;
+
+       if (dump_trace)
+               return 0;
+
+       if (!tool->ordered_events) {
+               pr_err("s390 Auxiliary Trace requires ordered events\n");
+               return -EINVAL;
+       }
+
+       if (event->header.type == PERF_RECORD_AUX &&
+           event->aux.flags & PERF_AUX_FLAG_TRUNCATED)
+               return s390_cpumsf_lost(sf, sample);
+
+       if (timestamp) {
+               err = s390_cpumsf_update_queues(sf, timestamp);
+               if (!err)
+                       err = s390_cpumsf_process_queues(sf, timestamp);
+       }
+       return err;
+}
+
+struct s390_cpumsf_synth {
+       struct perf_tool cpumsf_tool;
+       struct perf_session *session;
+};
+
+static int
+s390_cpumsf_process_auxtrace_event(struct perf_session *session,
+                                  union perf_event *event __maybe_unused,
+                                  struct perf_tool *tool __maybe_unused)
+{
+       struct s390_cpumsf *sf = container_of(session->auxtrace,
+                                             struct s390_cpumsf,
+                                             auxtrace);
+
+       int fd = perf_data__fd(session->data);
+       struct auxtrace_buffer *buffer;
+       off_t data_offset;
+       int err;
+
+       if (sf->data_queued)
+               return 0;
+
+       if (perf_data__is_pipe(session->data)) {
+               data_offset = 0;
+       } else {
+               data_offset = lseek(fd, 0, SEEK_CUR);
+               if (data_offset == -1)
+                       return -errno;
+       }
+
+       err = auxtrace_queues__add_event(&sf->queues, session, event,
+                                        data_offset, &buffer);
+       if (err)
+               return err;
+
+       /* Dump here after copying piped trace out of the pipe */
+       if (dump_trace) {
+               if (auxtrace_buffer__get_data(buffer, fd)) {
+                       s390_cpumsf_dump_event(sf, buffer->data,
+                                              buffer->size);
+                       auxtrace_buffer__put_data(buffer);
+               }
+       }
+       return 0;
+}
+
+static void s390_cpumsf_free_events(struct perf_session *session __maybe_unused)
+{
+}
+
+static int s390_cpumsf_flush(struct perf_session *session __maybe_unused,
+                            struct perf_tool *tool __maybe_unused)
+{
+       return 0;
+}
+
+static void s390_cpumsf_free_queues(struct perf_session *session)
+{
+       struct s390_cpumsf *sf = container_of(session->auxtrace,
+                                             struct s390_cpumsf,
+                                             auxtrace);
+       struct auxtrace_queues *queues = &sf->queues;
+       unsigned int i;
+
+       for (i = 0; i < queues->nr_queues; i++)
+               zfree(&queues->queue_array[i].priv);
+       auxtrace_queues__free(queues);
+}
+
+static void s390_cpumsf_free(struct perf_session *session)
+{
+       struct s390_cpumsf *sf = container_of(session->auxtrace,
+                                             struct s390_cpumsf,
+                                             auxtrace);
+
+       auxtrace_heap__free(&sf->heap);
+       s390_cpumsf_free_queues(session);
+       session->auxtrace = NULL;
+       free(sf);
+}
+
+static int s390_cpumsf_get_type(const char *cpuid)
+{
+       int ret, family = 0;
+
+       ret = sscanf(cpuid, "%*[^,],%u", &family);
+       return (ret == 1) ? family : 0;
+}
+
+/* Check itrace options set on perf report command.
+ * Return true, if none are set or all options specified can be
+ * handled on s390.
+ * Return false otherwise.
+ */
+static bool check_auxtrace_itrace(struct itrace_synth_opts *itops)
+{
+       if (!itops || !itops->set)
+               return true;
+       pr_err("No --itrace options supported\n");
+       return false;
+}
+
+int s390_cpumsf_process_auxtrace_info(union perf_event *event,
+                                     struct perf_session *session)
+{
+       struct auxtrace_info_event *auxtrace_info = &event->auxtrace_info;
+       struct s390_cpumsf *sf;
+       int err;
+
+       if (auxtrace_info->header.size < sizeof(struct auxtrace_info_event))
+               return -EINVAL;
+
+       sf = zalloc(sizeof(struct s390_cpumsf));
+       if (sf == NULL)
+               return -ENOMEM;
+
+       if (!check_auxtrace_itrace(session->itrace_synth_opts)) {
+               err = -EINVAL;
+               goto err_free;
+       }
+
+       err = auxtrace_queues__init(&sf->queues);
+       if (err)
+               goto err_free;
+
+       sf->session = session;
+       sf->machine = &session->machines.host; /* No kvm support */
+       sf->auxtrace_type = auxtrace_info->type;
+       sf->pmu_type = PERF_TYPE_RAW;
+       sf->machine_type = s390_cpumsf_get_type(session->evlist->env->cpuid);
+
+       sf->auxtrace.process_event = s390_cpumsf_process_event;
+       sf->auxtrace.process_auxtrace_event = s390_cpumsf_process_auxtrace_event;
+       sf->auxtrace.flush_events = s390_cpumsf_flush;
+       sf->auxtrace.free_events = s390_cpumsf_free_events;
+       sf->auxtrace.free = s390_cpumsf_free;
+       session->auxtrace = &sf->auxtrace;
+
+       if (dump_trace)
+               return 0;
+
+       err = auxtrace_queues__process_index(&sf->queues, session);
+       if (err)
+               goto err_free_queues;
+
+       if (sf->queues.populated)
+               sf->data_queued = true;
+
+       return 0;
+
+err_free_queues:
+       auxtrace_queues__free(&sf->queues);
+       session->auxtrace = NULL;
+err_free:
+       free(sf);
+       return err;
+}
diff --git a/tools/perf/util/s390-cpumsf.h b/tools/perf/util/s390-cpumsf.h
new file mode 100644 (file)
index 0000000..fb64d10
--- /dev/null
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright IBM Corp. 2018
+ * Auxtrace support for s390 CPU-Measurement Sampling Facility
+ *
+ * Author(s):  Thomas Richter <tmricht@linux.ibm.com>
+ */
+
+#ifndef INCLUDE__PERF_S390_CPUMSF_H
+#define INCLUDE__PERF_S390_CPUMSF_H
+
+union perf_event;
+struct perf_session;
+struct perf_pmu;
+
+struct auxtrace_record *
+s390_cpumsf_recording_init(int *err, struct perf_pmu *s390_cpumsf_pmu);
+
+int s390_cpumsf_process_auxtrace_info(union perf_event *event,
+                                     struct perf_session *session);
+#endif
index 7b79c413486b3a6ef8b0f6c32e330911c5ce7638..45484f0f7292d983b3a741b67b3893b62ff2eeca 100644 (file)
@@ -535,7 +535,7 @@ static int perl_stop_script(void)
        return 0;
 }
 
-static int perl_generate_script(struct pevent *pevent, const char *outfile)
+static int perl_generate_script(struct tep_handle *pevent, const char *outfile)
 {
        struct event_format *event = NULL;
        struct format_field *f;
index bc32e57d17be76bddbc561bcbafe3b06e5295461..dfc6093f118c9787ad0a1dd8e530103188f66676 100644 (file)
@@ -871,8 +871,8 @@ static void python_process_tracepoint(struct perf_sample *sample,
                        offset = field->offset;
                        len    = field->size;
                        if (field->flags & FIELD_IS_DYNAMIC) {
-                               val     = pevent_read_number(scripting_context->pevent,
-                                                            data + offset, len);
+                               val     = tep_read_number(scripting_context->pevent,
+                                                         data + offset, len);
                                offset  = val;
                                len     = offset >> 16;
                                offset &= 0xffff;
@@ -1588,7 +1588,7 @@ static int python_stop_script(void)
        return 0;
 }
 
-static int python_generate_script(struct pevent *pevent, const char *outfile)
+static int python_generate_script(struct tep_handle *pevent, const char *outfile)
 {
        struct event_format *event = NULL;
        struct format_field *f;
index 001be4f9d3b9fc1bf032c74f2447b88b6c6cea26..97efbcad076e02249e75b5aa60f6f6804953a9a1 100644 (file)
@@ -1,12 +1,20 @@
 #!/usr/bin/python
 
 from os import getenv
+from subprocess import Popen, PIPE
+from re import sub
+
+def clang_has_option(option):
+    return [o for o in Popen(['clang', option], stderr=PIPE).stderr.readlines() if "unknown argument" in o] == [ ]
 
 cc = getenv("CC")
 if cc == "clang":
     from _sysconfigdata import build_time_vars
-    from re import sub
     build_time_vars["CFLAGS"] = sub("-specs=[^ ]+", "", build_time_vars["CFLAGS"])
+    if not clang_has_option("-mcet"):
+        build_time_vars["CFLAGS"] = sub("-mcet", "", build_time_vars["CFLAGS"])
+    if not clang_has_option("-fcf-protection"):
+        build_time_vars["CFLAGS"] = sub("-fcf-protection", "", build_time_vars["CFLAGS"])
 
 from distutils.core import setup, Extension
 
index fed2952ab45a7bc7658ec5c568698f5c148abfef..b284276ec963548e3633ac7e21ecded8666b56e1 100644 (file)
@@ -601,7 +601,7 @@ static char *get_trace_output(struct hist_entry *he)
 {
        struct trace_seq seq;
        struct perf_evsel *evsel;
-       struct pevent_record rec = {
+       struct tep_record rec = {
                .data = he->raw_data,
                .size = he->raw_size,
        };
@@ -610,10 +610,10 @@ static char *get_trace_output(struct hist_entry *he)
 
        trace_seq_init(&seq);
        if (symbol_conf.raw_trace) {
-               pevent_print_fields(&seq, he->raw_data, he->raw_size,
-                                   evsel->tp_format);
+               tep_print_fields(&seq, he->raw_data, he->raw_size,
+                                evsel->tp_format);
        } else {
-               pevent_event_info(&seq, evsel->tp_format, &rec);
+               tep_event_info(&seq, evsel->tp_format, &rec);
        }
        /*
         * Trim the buffer, it starts at 4KB and we're not going to
@@ -2047,7 +2047,7 @@ static int __sort__hde_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
                struct trace_seq seq;
 raw_field:
                trace_seq_init(&seq);
-               pevent_print_field(&seq, he->raw_data, hde->field);
+               tep_print_field(&seq, he->raw_data, hde->field);
                str = seq.buffer;
        }
 
@@ -2074,7 +2074,7 @@ static int64_t __sort__hde_cmp(struct perf_hpp_fmt *fmt,
        if (field->flags & FIELD_IS_DYNAMIC) {
                unsigned long long dyn;
 
-               pevent_read_number_field(field, a->raw_data, &dyn);
+               tep_read_number_field(field, a->raw_data, &dyn);
                offset = dyn & 0xffff;
                size = (dyn >> 16) & 0xffff;
 
@@ -2311,7 +2311,7 @@ static int add_all_matching_fields(struct perf_evlist *evlist,
                if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
                        continue;
 
-               field = pevent_find_any_field(evsel->tp_format, field_name);
+               field = tep_find_any_field(evsel->tp_format, field_name);
                if (field == NULL)
                        continue;
 
@@ -2378,7 +2378,7 @@ static int add_dynamic_entry(struct perf_evlist *evlist, const char *tok,
        if (!strcmp(field_name, "*")) {
                ret = add_evsel_fields(evsel, raw_trace, level);
        } else {
-               field = pevent_find_any_field(evsel->tp_format, field_name);
+               field = tep_find_any_field(evsel->tp_format, field_name);
                if (field == NULL) {
                        pr_debug("Cannot find event field for %s.%s\n",
                                 event_name, field_name);
index 8bf302cafcecd6b285d68e2b2c56130019dea101..a97cf8e6be8656b1dadd531462310f48110233e9 100644 (file)
@@ -276,7 +276,7 @@ extern struct sort_entry sort_thread;
 extern struct list_head hist_entry__sort_list;
 
 struct perf_evlist;
-struct pevent;
+struct tep_handle;
 int setup_sorting(struct perf_evlist *evlist);
 int setup_output_field(void);
 void reset_output_field(void);
index e0a6e9a6a05355bc43e99585ec3a3f134e65b1e8..920b1d58a06899d6cecf6aea2aa30abedc95695d 100644 (file)
@@ -32,7 +32,7 @@
 static int get_common_field(struct scripting_context *context,
                            int *offset, int *size, const char *type)
 {
-       struct pevent *pevent = context->pevent;
+       struct tep_handle *pevent = context->pevent;
        struct event_format *event;
        struct format_field *field;
 
@@ -41,14 +41,14 @@ static int get_common_field(struct scripting_context *context,
                        return 0;
 
                event = pevent->events[0];
-               field = pevent_find_common_field(event, type);
+               field = tep_find_common_field(event, type);
                if (!field)
                        return 0;
                *offset = field->offset;
                *size = field->size;
        }
 
-       return pevent_read_number(pevent, context->event_data + *offset, *size);
+       return tep_read_number(pevent, context->event_data + *offset, *size);
 }
 
 int common_lock_depth(struct scripting_context *context)
@@ -99,24 +99,24 @@ raw_field_value(struct event_format *event, const char *name, void *data)
        struct format_field *field;
        unsigned long long val;
 
-       field = pevent_find_any_field(event, name);
+       field = tep_find_any_field(event, name);
        if (!field)
                return 0ULL;
 
-       pevent_read_number_field(field, data, &val);
+       tep_read_number_field(field, data, &val);
 
        return val;
 }
 
 unsigned long long read_size(struct event_format *event, void *ptr, int size)
 {
-       return pevent_read_number(event->pevent, ptr, size);
+       return tep_read_number(event->pevent, ptr, size);
 }
 
 void event_format__fprintf(struct event_format *event,
                           int cpu, void *data, int size, FILE *fp)
 {
-       struct pevent_record record;
+       struct tep_record record;
        struct trace_seq s;
 
        memset(&record, 0, sizeof(record));
@@ -125,7 +125,7 @@ void event_format__fprintf(struct event_format *event,
        record.data = data;
 
        trace_seq_init(&s);
-       pevent_event_info(&s, event, &record);
+       tep_event_info(&s, event, &record);
        trace_seq_do_fprintf(&s, fp);
        trace_seq_destroy(&s);
 }
@@ -136,7 +136,7 @@ void event_format__print(struct event_format *event,
        return event_format__fprintf(event, cpu, data, size, stdout);
 }
 
-void parse_ftrace_printk(struct pevent *pevent,
+void parse_ftrace_printk(struct tep_handle *pevent,
                         char *file, unsigned int size __maybe_unused)
 {
        unsigned long long addr;
@@ -157,11 +157,11 @@ void parse_ftrace_printk(struct pevent *pevent,
                /* fmt still has a space, skip it */
                printk = strdup(fmt+1);
                line = strtok_r(NULL, "\n", &next);
-               pevent_register_print_string(pevent, printk, addr);
+               tep_register_print_string(pevent, printk, addr);
        }
 }
 
-void parse_saved_cmdline(struct pevent *pevent,
+void parse_saved_cmdline(struct tep_handle *pevent,
                         char *file, unsigned int size __maybe_unused)
 {
        char *comm;
@@ -172,24 +172,24 @@ void parse_saved_cmdline(struct pevent *pevent,
        line = strtok_r(file, "\n", &next);
        while (line) {
                sscanf(line, "%d %ms", &pid, &comm);
-               pevent_register_comm(pevent, comm, pid);
+               tep_register_comm(pevent, comm, pid);
                free(comm);
                line = strtok_r(NULL, "\n", &next);
        }
 }
 
-int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size)
+int parse_ftrace_file(struct tep_handle *pevent, char *buf, unsigned long size)
 {
-       return pevent_parse_event(pevent, buf, size, "ftrace");
+       return tep_parse_event(pevent, buf, size, "ftrace");
 }
 
-int parse_event_file(struct pevent *pevent,
+int parse_event_file(struct tep_handle *pevent,
                     char *buf, unsigned long size, char *sys)
 {
-       return pevent_parse_event(pevent, buf, size, sys);
+       return tep_parse_event(pevent, buf, size, sys);
 }
 
-struct event_format *trace_find_next_event(struct pevent *pevent,
+struct event_format *trace_find_next_event(struct tep_handle *pevent,
                                           struct event_format *event)
 {
        static int idx;
index 40b425949aa31d7b4b334fa5923436f57dd2c842..3dfc1db6b25b62c192971d1ccc7dc4e83d03f662 100644 (file)
@@ -96,7 +96,7 @@ static void skip(int size)
        };
 }
 
-static unsigned int read4(struct pevent *pevent)
+static unsigned int read4(struct tep_handle *pevent)
 {
        unsigned int data;
 
@@ -105,7 +105,7 @@ static unsigned int read4(struct pevent *pevent)
        return __data2host4(pevent, data);
 }
 
-static unsigned long long read8(struct pevent *pevent)
+static unsigned long long read8(struct tep_handle *pevent)
 {
        unsigned long long data;
 
@@ -158,7 +158,7 @@ out:
        return str;
 }
 
-static int read_proc_kallsyms(struct pevent *pevent)
+static int read_proc_kallsyms(struct tep_handle *pevent)
 {
        unsigned int size;
 
@@ -181,7 +181,7 @@ static int read_proc_kallsyms(struct pevent *pevent)
        return 0;
 }
 
-static int read_ftrace_printk(struct pevent *pevent)
+static int read_ftrace_printk(struct tep_handle *pevent)
 {
        unsigned int size;
        char *buf;
@@ -208,7 +208,7 @@ static int read_ftrace_printk(struct pevent *pevent)
        return 0;
 }
 
-static int read_header_files(struct pevent *pevent)
+static int read_header_files(struct tep_handle *pevent)
 {
        unsigned long long size;
        char *header_page;
@@ -235,13 +235,13 @@ static int read_header_files(struct pevent *pevent)
                return -1;
        }
 
-       if (!pevent_parse_header_page(pevent, header_page, size,
-                                     pevent_get_long_size(pevent))) {
+       if (!tep_parse_header_page(pevent, header_page, size,
+                                  tep_get_long_size(pevent))) {
                /*
                 * The commit field in the page is of type long,
                 * use that instead, since it represents the kernel.
                 */
-               pevent_set_long_size(pevent, pevent->header_page_size_size);
+               tep_set_long_size(pevent, pevent->header_page_size_size);
        }
        free(header_page);
 
@@ -259,7 +259,7 @@ static int read_header_files(struct pevent *pevent)
        return ret;
 }
 
-static int read_ftrace_file(struct pevent *pevent, unsigned long long size)
+static int read_ftrace_file(struct tep_handle *pevent, unsigned long long size)
 {
        int ret;
        char *buf;
@@ -284,8 +284,8 @@ out:
        return ret;
 }
 
-static int read_event_file(struct pevent *pevent, char *sys,
-                           unsigned long long size)
+static int read_event_file(struct tep_handle *pevent, char *sys,
+                          unsigned long long size)
 {
        int ret;
        char *buf;
@@ -310,7 +310,7 @@ out:
        return ret;
 }
 
-static int read_ftrace_files(struct pevent *pevent)
+static int read_ftrace_files(struct tep_handle *pevent)
 {
        unsigned long long size;
        int count;
@@ -328,7 +328,7 @@ static int read_ftrace_files(struct pevent *pevent)
        return 0;
 }
 
-static int read_event_files(struct pevent *pevent)
+static int read_event_files(struct tep_handle *pevent)
 {
        unsigned long long size;
        char *sys;
@@ -356,7 +356,7 @@ static int read_event_files(struct pevent *pevent)
        return 0;
 }
 
-static int read_saved_cmdline(struct pevent *pevent)
+static int read_saved_cmdline(struct tep_handle *pevent)
 {
        unsigned long long size;
        char *buf;
@@ -399,7 +399,7 @@ ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe)
        int host_bigendian;
        int file_long_size;
        int file_page_size;
-       struct pevent *pevent = NULL;
+       struct tep_handle *pevent = NULL;
        int err;
 
        repipe = __repipe;
@@ -439,9 +439,9 @@ ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe)
 
        pevent = tevent->pevent;
 
-       pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT);
-       pevent_set_file_bigendian(pevent, file_bigendian);
-       pevent_set_host_bigendian(pevent, host_bigendian);
+       tep_set_flag(pevent, TEP_NSEC_OUTPUT);
+       tep_set_file_bigendian(pevent, file_bigendian);
+       tep_set_host_bigendian(pevent, host_bigendian);
 
        if (do_read(buf, 1) < 0)
                goto out;
@@ -451,8 +451,8 @@ ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe)
        if (!file_page_size)
                goto out;
 
-       pevent_set_long_size(pevent, file_long_size);
-       pevent_set_page_size(pevent, file_page_size);
+       tep_set_long_size(pevent, file_long_size);
+       tep_set_page_size(pevent, file_page_size);
 
        err = read_header_files(pevent);
        if (err)
@@ -479,9 +479,9 @@ ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe)
        repipe = false;
 
        if (show_funcs) {
-               pevent_print_funcs(pevent);
+               tep_print_funcs(pevent);
        } else if (show_printk) {
-               pevent_print_printk(pevent);
+               tep_print_printk(pevent);
        }
 
        pevent = NULL;
index b1e5c3a2b8e36cada0370ec30db338cb0fc45081..b749f812ac70fa2b9bf7d0447c5524fc7a8a142b 100644 (file)
@@ -66,7 +66,7 @@ static int python_start_script_unsupported(const char *script __maybe_unused,
        return -1;
 }
 
-static int python_generate_script_unsupported(struct pevent *pevent
+static int python_generate_script_unsupported(struct tep_handle *pevent
                                              __maybe_unused,
                                              const char *outfile
                                              __maybe_unused)
@@ -130,7 +130,7 @@ static int perl_start_script_unsupported(const char *script __maybe_unused,
        return -1;
 }
 
-static int perl_generate_script_unsupported(struct pevent *pevent
+static int perl_generate_script_unsupported(struct tep_handle *pevent
                                            __maybe_unused,
                                            const char *outfile __maybe_unused)
 {
index 1aa3686032688f95609274918aab97bd7850e14b..58bb72f266f3758c2f8da29a65b572afbe26be3f 100644 (file)
@@ -28,10 +28,10 @@ static bool tevent_initialized;
 
 int trace_event__init(struct trace_event *t)
 {
-       struct pevent *pevent = pevent_alloc();
+       struct tep_handle *pevent = tep_alloc();
 
        if (pevent) {
-               t->plugin_list = traceevent_load_plugins(pevent);
+               t->plugin_list = tep_load_plugins(pevent);
                t->pevent  = pevent;
        }
 
@@ -40,33 +40,33 @@ int trace_event__init(struct trace_event *t)
 
 static int trace_event__init2(void)
 {
-       int be = traceevent_host_bigendian();
-       struct pevent *pevent;
+       int be = tep_host_bigendian();
+       struct tep_handle *pevent;
 
        if (trace_event__init(&tevent))
                return -1;
 
        pevent = tevent.pevent;
-       pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT);
-       pevent_set_file_bigendian(pevent, be);
-       pevent_set_host_bigendian(pevent, be);
+       tep_set_flag(pevent, TEP_NSEC_OUTPUT);
+       tep_set_file_bigendian(pevent, be);
+       tep_set_host_bigendian(pevent, be);
        tevent_initialized = true;
        return 0;
 }
 
 int trace_event__register_resolver(struct machine *machine,
-                                  pevent_func_resolver_t *func)
+                                  tep_func_resolver_t *func)
 {
        if (!tevent_initialized && trace_event__init2())
                return -1;
 
-       return pevent_set_function_resolver(tevent.pevent, func, machine);
+       return tep_set_function_resolver(tevent.pevent, func, machine);
 }
 
 void trace_event__cleanup(struct trace_event *t)
 {
-       traceevent_unload_plugins(t->plugin_list, t->pevent);
-       pevent_free(t->pevent);
+       tep_unload_plugins(t->plugin_list, t->pevent);
+       tep_free(t->pevent);
 }
 
 /*
@@ -76,7 +76,7 @@ static struct event_format*
 tp_format(const char *sys, const char *name)
 {
        char *tp_dir = get_events_file(sys);
-       struct pevent *pevent = tevent.pevent;
+       struct tep_handle *pevent = tevent.pevent;
        struct event_format *event = NULL;
        char path[PATH_MAX];
        size_t size;
@@ -93,7 +93,7 @@ tp_format(const char *sys, const char *name)
        if (err)
                return ERR_PTR(err);
 
-       pevent_parse_format(pevent, &event, data, size, sys);
+       tep_parse_format(pevent, &event, data, size, sys);
 
        free(data);
        return event;
@@ -116,5 +116,5 @@ struct event_format *trace_event__tp_format_id(int id)
        if (!tevent_initialized && trace_event__init2())
                return ERR_PTR(-ENOMEM);
 
-       return pevent_find_event(tevent.pevent, id);
+       return tep_find_event(tevent.pevent, id);
 }
index dcbdb53dc702a664a8e70da5f7856e4e4243ec17..40204ec3a7a284d238b3b929bf6c5c5b15876ac5 100644 (file)
@@ -13,14 +13,14 @@ struct thread;
 struct plugin_list;
 
 struct trace_event {
-       struct pevent           *pevent;
+       struct tep_handle       *pevent;
        struct plugin_list      *plugin_list;
 };
 
 int trace_event__init(struct trace_event *t);
 void trace_event__cleanup(struct trace_event *t);
 int trace_event__register_resolver(struct machine *machine,
-                                  pevent_func_resolver_t *func);
+                                  tep_func_resolver_t *func);
 struct event_format*
 trace_event__tp_format(const char *sys, const char *name);
 
@@ -34,20 +34,20 @@ void event_format__fprintf(struct event_format *event,
 void event_format__print(struct event_format *event,
                         int cpu, void *data, int size);
 
-int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size);
-int parse_event_file(struct pevent *pevent,
+int parse_ftrace_file(struct tep_handle *pevent, char *buf, unsigned long size);
+int parse_event_file(struct tep_handle *pevent,
                     char *buf, unsigned long size, char *sys);
 
 unsigned long long
 raw_field_value(struct event_format *event, const char *name, void *data);
 
-void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size);
-void parse_ftrace_printk(struct pevent *pevent, char *file, unsigned int size);
-void parse_saved_cmdline(struct pevent *pevent, char *file, unsigned int size);
+void parse_proc_kallsyms(struct tep_handle *pevent, char *file, unsigned int size);
+void parse_ftrace_printk(struct tep_handle *pevent, char *file, unsigned int size);
+void parse_saved_cmdline(struct tep_handle *pevent, char *file, unsigned int size);
 
 ssize_t trace_report(int fd, struct trace_event *tevent, bool repipe);
 
-struct event_format *trace_find_next_event(struct pevent *pevent,
+struct event_format *trace_find_next_event(struct tep_handle *pevent,
                                           struct event_format *event);
 unsigned long long read_size(struct event_format *event, void *ptr, int size);
 unsigned long long eval_flag(const char *flag);
@@ -83,7 +83,7 @@ struct scripting_ops {
        void (*process_stat)(struct perf_stat_config *config,
                             struct perf_evsel *evsel, u64 tstamp);
        void (*process_stat_interval)(u64 tstamp);
-       int (*generate_script) (struct pevent *pevent, const char *outfile);
+       int (*generate_script) (struct tep_handle *pevent, const char *outfile);
 };
 
 extern unsigned int scripting_max_stack;
@@ -94,7 +94,7 @@ void setup_perl_scripting(void);
 void setup_python_scripting(void);
 
 struct scripting_context {
-       struct pevent *pevent;
+       struct tep_handle *pevent;
        void *event_data;
 };
 
index a725b958cf31bb67f04267d75b951035cb767a8c..902ce6384f5748bd69818c5f269fdd2c0f6db572 100644 (file)
@@ -5,6 +5,8 @@
 #include <sys/stat.h>
 #include <sys/mman.h>
 #include <zlib.h>
+#include <linux/compiler.h>
+#include <unistd.h>
 
 #include "util/compress.h"
 #include "util/util.h"
@@ -79,3 +81,19 @@ out_close:
 
        return ret == Z_STREAM_END ? 0 : -1;
 }
+
+bool gzip_is_compressed(const char *input)
+{
+       int fd = open(input, O_RDONLY);
+       const uint8_t magic[2] = { 0x1f, 0x8b };
+       char buf[2] = { 0 };
+       ssize_t rc;
+
+       if (fd < 0)
+               return -1;
+
+       rc = read(fd, buf, sizeof(buf));
+       close(fd);
+       return rc == sizeof(buf) ?
+              memcmp(buf, magic, sizeof(buf)) == 0 : false;
+}
index 78c09e51663ac0fc60b65bf49a7dd2768a6751d1..840c17cc450ae25f407795064653d7ee476fd01f 100644 (file)
@@ -323,12 +323,12 @@ msgstr "  Hardwarebedingte Grenzen der Taktfrequenz: "
 #: utils/cpufreq-info.c:256
 #, c-format
 msgid "  available frequency steps: "
-msgstr "  mögliche Taktfrequenzen: "
+msgstr "  mögliche Taktfrequenzen: "
 
 #: utils/cpufreq-info.c:269
 #, c-format
 msgid "  available cpufreq governors: "
-msgstr "  mögliche Regler: "
+msgstr "  mögliche Regler: "
 
 #: utils/cpufreq-info.c:280
 #, c-format
@@ -381,7 +381,7 @@ msgstr "Optionen:\n"
 msgid "  -e, --debug          Prints out debug information [default]\n"
 msgstr ""
 "  -e, --debug          Erzeugt detaillierte Informationen, hilfreich\n"
-"                       zum Aufspüren von Fehlern\n"
+"                       zum Aufspüren von Fehlern\n"
 
 #: utils/cpufreq-info.c:475
 #, c-format
@@ -424,7 +424,7 @@ msgstr "  -p, --policy         Findet die momentane Taktik heraus *\n"
 #: utils/cpufreq-info.c:482
 #, c-format
 msgid "  -g, --governors      Determines available cpufreq governors *\n"
-msgstr "  -g, --governors      Erzeugt eine Liste mit verfügbaren Reglern *\n"
+msgstr "  -g, --governors      Erzeugt eine Liste mit verfügbaren Reglern *\n"
 
 #: utils/cpufreq-info.c:483
 #, c-format
@@ -450,7 +450,7 @@ msgstr ""
 #, c-format
 msgid "  -s, --stats          Shows cpufreq statistics if available\n"
 msgstr ""
-"  -s, --stats          Zeigt, sofern möglich, Statistiken über cpufreq an.\n"
+"  -s, --stats          Zeigt, sofern möglich, Statistiken über cpufreq an.\n"
 
 #: utils/cpufreq-info.c:487
 #, c-format
@@ -473,9 +473,9 @@ msgid ""
 "cpufreq\n"
 "                       interface in 2.4. and early 2.6. kernels\n"
 msgstr ""
-"  -o, --proc           Erzeugt Informationen in einem ähnlichem Format zu "
+"  -o, --proc           Erzeugt Informationen in einem ähnlichem Format zu "
 "dem\n"
-"                       der /proc/cpufreq-Datei in 2.4. und frühen 2.6.\n"
+"                       der /proc/cpufreq-Datei in 2.4. und frühen 2.6.\n"
 "                       Kernel-Versionen\n"
 
 #: utils/cpufreq-info.c:491
@@ -491,7 +491,7 @@ msgstr ""
 #: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152
 #, c-format
 msgid "  -h, --help           Prints out this screen\n"
-msgstr "  -h, --help           Gibt diese Kurzübersicht aus\n"
+msgstr "  -h, --help           Gibt diese Kurzübersicht aus\n"
 
 #: utils/cpufreq-info.c:495
 #, c-format
@@ -501,7 +501,7 @@ msgid ""
 msgstr ""
 "Sofern kein anderer Parameter als '-c, --cpu' angegeben wird, liefert "
 "dieses\n"
-"Programm Informationen, die z.B. zum Berichten von Fehlern nützlich sind.\n"
+"Programm Informationen, die z.B. zum Berichten von Fehlern nützlich sind.\n"
 
 #: utils/cpufreq-info.c:497
 #, c-format
@@ -557,7 +557,7 @@ msgid ""
 "select\n"
 msgstr ""
 "  -d FREQ, --min FREQ      neue minimale Taktfrequenz, die der Regler\n"
-"                           auswählen darf\n"
+"                           auswählen darf\n"
 
 #: utils/cpufreq-set.c:28
 #, c-format
@@ -566,7 +566,7 @@ msgid ""
 "select\n"
 msgstr ""
 "  -u FREQ, --max FREQ      neue maximale Taktfrequenz, die der Regler\n"
-"                           auswählen darf\n"
+"                           auswählen darf\n"
 
 #: utils/cpufreq-set.c:29
 #, c-format
@@ -579,20 +579,20 @@ msgid ""
 "  -f FREQ, --freq FREQ     specific frequency to be set. Requires userspace\n"
 "                           governor to be available and loaded\n"
 msgstr ""
-"  -f FREQ, --freq FREQ     setze exakte Taktfrequenz. Benötigt den Regler\n"
+"  -f FREQ, --freq FREQ     setze exakte Taktfrequenz. Benötigt den Regler\n"
 "                           'userspace'.\n"
 
 #: utils/cpufreq-set.c:32
 #, c-format
 msgid "  -r, --related            Switches all hardware-related CPUs\n"
 msgstr ""
-"  -r, --related            Setze Werte für alle CPUs, deren Taktfrequenz\n"
+"  -r, --related            Setze Werte für alle CPUs, deren Taktfrequenz\n"
 "                           hardwarebedingt identisch ist.\n"
 
 #: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27
 #, c-format
 msgid "  -h, --help               Prints out this screen\n"
-msgstr "  -h, --help               Gibt diese Kurzübersicht aus\n"
+msgstr "  -h, --help               Gibt diese Kurzübersicht aus\n"
 
 #: utils/cpufreq-set.c:35
 #, fuzzy, c-format
@@ -618,8 +618,8 @@ msgstr ""
 "   angenommen\n"
 "2. Der Parameter -f bzw. --freq kann mit keinem anderen als dem Parameter\n"
 "   -c bzw. --cpu kombiniert werden\n"
-"3. FREQuenzen können in Hz, kHz (Standard), MHz, GHz oder THz eingegeben\n"
-"   werden, indem der Wert und unmittelbar anschließend (ohne Leerzeichen!)\n"
+"3. FREQuenzen können in Hz, kHz (Standard), MHz, GHz oder THz eingegeben\n"
+"   werden, indem der Wert und unmittelbar anschließend (ohne Leerzeichen!)\n"
 "   die Einheit angegeben werden. (Bsp: 1GHz )\n"
 "   (FREQuenz in kHz =^ MHz * 1000 =^ GHz * 1000000).\n"
 
@@ -638,7 +638,7 @@ msgid ""
 msgstr ""
 "Beim Einstellen ist ein Fehler aufgetreten. Typische Fehlerquellen sind:\n"
 "- nicht ausreichende Rechte (Administrator)\n"
-"- der Regler ist nicht verfügbar bzw. nicht geladen\n"
+"- der Regler ist nicht verfügbar bzw. nicht geladen\n"
 "- die angegebene Taktik ist inkorrekt\n"
 "- eine spezifische Frequenz wurde angegeben, aber der Regler 'userspace'\n"
 "  kann entweder hardwarebedingt nicht genutzt werden oder ist nicht geladen\n"
@@ -821,7 +821,7 @@ msgstr ""
 #: utils/cpuidle-info.c:48
 #, fuzzy, c-format
 msgid "Available idle states:"
-msgstr "  mögliche Taktfrequenzen: "
+msgstr "  mögliche Taktfrequenzen: "
 
 #: utils/cpuidle-info.c:71
 #, c-format
@@ -924,7 +924,7 @@ msgstr "Aufruf: cpufreq-info [Optionen]\n"
 msgid "  -s, --silent         Only show general C-state information\n"
 msgstr ""
 "  -e, --debug          Erzeugt detaillierte Informationen, hilfreich\n"
-"                       zum Aufspüren von Fehlern\n"
+"                       zum Aufspüren von Fehlern\n"
 
 #: utils/cpuidle-info.c:150
 #, fuzzy, c-format
@@ -933,9 +933,9 @@ msgid ""
 "acpi/processor/*/power\n"
 "                       interface in older kernels\n"
 msgstr ""
-"  -o, --proc           Erzeugt Informationen in einem ähnlichem Format zu "
+"  -o, --proc           Erzeugt Informationen in einem ähnlichem Format zu "
 "dem\n"
-"                       der /proc/cpufreq-Datei in 2.4. und frühen 2.6.\n"
+"                       der /proc/cpufreq-Datei in 2.4. und frühen 2.6.\n"
 "                       Kernel-Versionen\n"
 
 #: utils/cpuidle-info.c:209
@@ -949,7 +949,7 @@ msgstr ""
 #~ "  -c CPU, --cpu CPU    CPU number which information shall be determined "
 #~ "about\n"
 #~ msgstr ""
-#~ "  -c CPU, --cpu CPU    Nummer der CPU, über die Informationen "
+#~ "  -c CPU, --cpu CPU    Nummer der CPU, über die Informationen "
 #~ "herausgefunden werden sollen\n"
 
 #~ msgid ""
index 245ad20a9bf92c4da45f31c42318485eba0f08d4..b46ca2548f865324efae0cc2b2721cf668cd047a 100644 (file)
@@ -212,7 +212,7 @@ msgstr ""
 #: utils/cpupower.c:91
 #, c-format
 msgid "Report errors and bugs to %s, please.\n"
-msgstr "Veuillez rapportez les erreurs et les bogues à %s, s'il vous plait.\n"
+msgstr "Veuillez rapportez les erreurs et les bogues à %s, s'il vous plait.\n"
 
 #: utils/cpupower.c:114
 #, c-format
@@ -227,14 +227,14 @@ msgstr ""
 #: utils/cpufreq-info.c:31
 #, c-format
 msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n"
-msgstr "Détermination du nombre de CPUs (%s : %s) impossible.  Assume 1\n"
+msgstr "Détermination du nombre de CPUs (%s : %s) impossible.  Assume 1\n"
 
 #: utils/cpufreq-info.c:63
 #, c-format
 msgid ""
 "          minimum CPU frequency  -  maximum CPU frequency  -  governor\n"
 msgstr ""
-"         Fréquence CPU minimale - Fréquence CPU maximale  - régulateur\n"
+"         Fréquence CPU minimale - Fréquence CPU maximale  - régulateur\n"
 
 #: utils/cpufreq-info.c:151
 #, c-format
@@ -302,12 +302,12 @@ msgstr "  pilote : %s\n"
 #: utils/cpufreq-info.c:219
 #, fuzzy, c-format
 msgid "  CPUs which run at the same hardware frequency: "
-msgstr "  CPUs qui doivent changer de fréquences en même temps : "
+msgstr "  CPUs qui doivent changer de fréquences en même temps : "
 
 #: utils/cpufreq-info.c:230
 #, fuzzy, c-format
 msgid "  CPUs which need to have their frequency coordinated by software: "
-msgstr "  CPUs qui doivent changer de fréquences en même temps : "
+msgstr "  CPUs qui doivent changer de fréquences en même temps : "
 
 #: utils/cpufreq-info.c:241
 #, c-format
@@ -317,22 +317,22 @@ msgstr ""
 #: utils/cpufreq-info.c:247
 #, c-format
 msgid "  hardware limits: "
-msgstr "  limitation matérielle : "
+msgstr "  limitation matérielle : "
 
 #: utils/cpufreq-info.c:256
 #, c-format
 msgid "  available frequency steps: "
-msgstr "  plage de fréquence : "
+msgstr "  plage de fréquence : "
 
 #: utils/cpufreq-info.c:269
 #, c-format
 msgid "  available cpufreq governors: "
-msgstr "  régulateurs disponibles : "
+msgstr "  régulateurs disponibles : "
 
 #: utils/cpufreq-info.c:280
 #, c-format
 msgid "  current policy: frequency should be within "
-msgstr "  tactique actuelle : la fréquence doit être comprise entre "
+msgstr "  tactique actuelle : la fréquence doit être comprise entre "
 
 #: utils/cpufreq-info.c:282
 #, c-format
@@ -345,18 +345,18 @@ msgid ""
 "The governor \"%s\" may decide which speed to use\n"
 "                  within this range.\n"
 msgstr ""
-"Le régulateur \"%s\" est libre de choisir la vitesse\n"
-"                  dans cette plage de fréquences.\n"
+"Le régulateur \"%s\" est libre de choisir la vitesse\n"
+"                  dans cette plage de fréquences.\n"
 
 #: utils/cpufreq-info.c:293
 #, c-format
 msgid "  current CPU frequency is "
-msgstr "  la fréquence actuelle de ce CPU est "
+msgstr "  la fréquence actuelle de ce CPU est "
 
 #: utils/cpufreq-info.c:296
 #, c-format
 msgid " (asserted by call to hardware)"
-msgstr " (vérifié par un appel direct du matériel)"
+msgstr " (vérifié par un appel direct du matériel)"
 
 #: utils/cpufreq-info.c:304
 #, c-format
@@ -377,7 +377,7 @@ msgstr "Options :\n"
 #: utils/cpufreq-info.c:474
 #, fuzzy, c-format
 msgid "  -e, --debug          Prints out debug information [default]\n"
-msgstr "  -e, --debug          Afficher les informations de déboguage\n"
+msgstr "  -e, --debug          Afficher les informations de déboguage\n"
 
 #: utils/cpufreq-info.c:475
 #, c-format
@@ -385,8 +385,8 @@ msgid ""
 "  -f, --freq           Get frequency the CPU currently runs at, according\n"
 "                       to the cpufreq core *\n"
 msgstr ""
-"  -f, --freq           Obtenir la fréquence actuelle du CPU selon le point\n"
-"                       de vue du coeur du système de cpufreq *\n"
+"  -f, --freq           Obtenir la fréquence actuelle du CPU selon le point\n"
+"                       de vue du coeur du système de cpufreq *\n"
 
 #: utils/cpufreq-info.c:477
 #, c-format
@@ -394,8 +394,8 @@ msgid ""
 "  -w, --hwfreq         Get frequency the CPU currently runs at, by reading\n"
 "                       it from hardware (only available to root) *\n"
 msgstr ""
-"  -w, --hwfreq         Obtenir la fréquence actuelle du CPU directement par\n"
-"                       le matériel (doit être root) *\n"
+"  -w, --hwfreq         Obtenir la fréquence actuelle du CPU directement par\n"
+"                       le matériel (doit être root) *\n"
 
 #: utils/cpufreq-info.c:479
 #, c-format
@@ -403,13 +403,13 @@ msgid ""
 "  -l, --hwlimits       Determine the minimum and maximum CPU frequency "
 "allowed *\n"
 msgstr ""
-"  -l, --hwlimits       Affiche les fréquences minimales et maximales du CPU "
+"  -l, --hwlimits       Affiche les fréquences minimales et maximales du CPU "
 "*\n"
 
 #: utils/cpufreq-info.c:480
 #, c-format
 msgid "  -d, --driver         Determines the used cpufreq kernel driver *\n"
-msgstr "  -d, --driver         Affiche le pilote cpufreq utilisé *\n"
+msgstr "  -d, --driver         Affiche le pilote cpufreq utilisé *\n"
 
 #: utils/cpufreq-info.c:481
 #, c-format
@@ -420,7 +420,7 @@ msgstr "  -p, --policy         Affiche la tactique actuelle de cpufreq *\n"
 #, c-format
 msgid "  -g, --governors      Determines available cpufreq governors *\n"
 msgstr ""
-"  -g, --governors      Affiche les régulateurs disponibles de cpufreq *\n"
+"  -g, --governors      Affiche les régulateurs disponibles de cpufreq *\n"
 
 #: utils/cpufreq-info.c:483
 #, fuzzy, c-format
@@ -429,7 +429,7 @@ msgid ""
 "frequency *\n"
 msgstr ""
 "  -a, --affected-cpus   Affiche quels sont les CPUs qui doivent changer de\n"
-"                        fréquences en même temps *\n"
+"                        fréquences en même temps *\n"
 
 #: utils/cpufreq-info.c:484
 #, fuzzy, c-format
@@ -438,7 +438,7 @@ msgid ""
 "                       coordinated by software *\n"
 msgstr ""
 "  -a, --affected-cpus   Affiche quels sont les CPUs qui doivent changer de\n"
-"                        fréquences en même temps *\n"
+"                        fréquences en même temps *\n"
 
 #: utils/cpufreq-info.c:486
 #, c-format
@@ -453,7 +453,7 @@ msgid ""
 "  -y, --latency        Determines the maximum latency on CPU frequency "
 "changes *\n"
 msgstr ""
-"  -l, --hwlimits       Affiche les fréquences minimales et maximales du CPU "
+"  -l, --hwlimits       Affiche les fréquences minimales et maximales du CPU "
 "*\n"
 
 #: utils/cpufreq-info.c:488
@@ -469,7 +469,7 @@ msgid ""
 "                       interface in 2.4. and early 2.6. kernels\n"
 msgstr ""
 "  -o, --proc           Affiche les informations en utilisant l'interface\n"
-"                       fournie par /proc/cpufreq, présente dans les "
+"                       fournie par /proc/cpufreq, présente dans les "
 "versions\n"
 "                       2.4 et les anciennes versions 2.6 du noyau\n"
 
@@ -485,7 +485,7 @@ msgstr ""
 #: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152
 #, c-format
 msgid "  -h, --help           Prints out this screen\n"
-msgstr "  -h, --help           affiche l'aide-mémoire\n"
+msgstr "  -h, --help           affiche l'aide-mémoire\n"
 
 #: utils/cpufreq-info.c:495
 #, c-format
@@ -493,8 +493,8 @@ msgid ""
 "If no argument or only the -c, --cpu parameter is given, debug output about\n"
 "cpufreq is printed which is useful e.g. for reporting bugs.\n"
 msgstr ""
-"Par défaut, les informations de déboguage seront affichées si aucun\n"
-"argument, ou bien si seulement l'argument -c (--cpu) est donné, afin de\n"
+"Par défaut, les informations de déboguage seront affichées si aucun\n"
+"argument, ou bien si seulement l'argument -c (--cpu) est donné, afin de\n"
 "faciliter les rapports de bogues par exemple\n"
 
 #: utils/cpufreq-info.c:497
@@ -517,8 +517,8 @@ msgid ""
 "You can't specify more than one --cpu parameter and/or\n"
 "more than one output-specific argument\n"
 msgstr ""
-"On ne peut indiquer plus d'un paramètre --cpu, tout comme l'on ne peut\n"
-"spécifier plus d'un argument de formatage\n"
+"On ne peut indiquer plus d'un paramètre --cpu, tout comme l'on ne peut\n"
+"spécifier plus d'un argument de formatage\n"
 
 #: utils/cpufreq-info.c:600 utils/cpufreq-set.c:82 utils/cpupower-set.c:42
 #: utils/cpupower-info.c:42 utils/cpuidle-info.c:213
@@ -529,7 +529,7 @@ msgstr "option invalide\n"
 #: utils/cpufreq-info.c:617
 #, c-format
 msgid "couldn't analyze CPU %d as it doesn't seem to be present\n"
-msgstr "analyse du CPU %d impossible puisqu'il ne semble pas être présent\n"
+msgstr "analyse du CPU %d impossible puisqu'il ne semble pas être présent\n"
 
 #: utils/cpufreq-info.c:620 utils/cpupower-info.c:142
 #, c-format
@@ -547,8 +547,8 @@ msgid ""
 "  -d FREQ, --min FREQ      new minimum CPU frequency the governor may "
 "select\n"
 msgstr ""
-"  -d FREQ, --min FREQ       nouvelle fréquence minimale du CPU à utiliser\n"
-"                            par le régulateur\n"
+"  -d FREQ, --min FREQ       nouvelle fréquence minimale du CPU à utiliser\n"
+"                            par le régulateur\n"
 
 #: utils/cpufreq-set.c:28
 #, c-format
@@ -556,13 +556,13 @@ msgid ""
 "  -u FREQ, --max FREQ      new maximum CPU frequency the governor may "
 "select\n"
 msgstr ""
-"  -u FREQ, --max FREQ       nouvelle fréquence maximale du CPU à utiliser\n"
-"                            par le régulateur\n"
+"  -u FREQ, --max FREQ       nouvelle fréquence maximale du CPU à utiliser\n"
+"                            par le régulateur\n"
 
 #: utils/cpufreq-set.c:29
 #, c-format
 msgid "  -g GOV, --governor GOV   new cpufreq governor\n"
-msgstr "  -g GOV, --governor GOV   active le régulateur GOV\n"
+msgstr "  -g GOV, --governor GOV   active le régulateur GOV\n"
 
 #: utils/cpufreq-set.c:30
 #, c-format
@@ -570,9 +570,9 @@ msgid ""
 "  -f FREQ, --freq FREQ     specific frequency to be set. Requires userspace\n"
 "                           governor to be available and loaded\n"
 msgstr ""
-"  -f FREQ, --freq FREQ     fixe la fréquence du processeur à FREQ. Il faut\n"
-"                           que le régulateur « userspace » soit disponible \n"
-"                           et activé.\n"
+"  -f FREQ, --freq FREQ     fixe la fréquence du processeur à FREQ. Il faut\n"
+"                           que le régulateur Â« userspace Â» soit disponible \n"
+"                           et activé.\n"
 
 #: utils/cpufreq-set.c:32
 #, c-format
@@ -582,7 +582,7 @@ msgstr ""
 #: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27
 #, fuzzy, c-format
 msgid "  -h, --help               Prints out this screen\n"
-msgstr "  -h, --help           affiche l'aide-mémoire\n"
+msgstr "  -h, --help           affiche l'aide-mémoire\n"
 
 #: utils/cpufreq-set.c:35
 #, fuzzy, c-format
@@ -602,11 +602,11 @@ msgid ""
 "   (FREQuency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
 msgstr ""
 "Remarque :\n"
-"1. Le CPU numéro 0 sera utilisé par défaut si -c (ou --cpu) est omis ;\n"
-"2. l'argument -f FREQ (ou --freq FREQ) ne peut être utilisé qu'avec --cpu ;\n"
-"3. on pourra préciser l'unité des fréquences en postfixant sans aucune "
+"1. Le CPU numéro 0 sera utilisé par défaut si -c (ou --cpu) est omis ;\n"
+"2. l'argument -f FREQ (ou --freq FREQ) ne peut être utilisé qu'avec --cpu ;\n"
+"3. on pourra préciser l'unité des fréquences en postfixant sans aucune "
 "espace\n"
-"   les valeurs par hz, kHz (par défaut), MHz, GHz ou THz\n"
+"   les valeurs par hz, kHz (par défaut), MHz, GHz ou THz\n"
 "   (kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n"
 
 #: utils/cpufreq-set.c:57
@@ -622,21 +622,21 @@ msgid ""
 "frequency\n"
 "   or because the userspace governor isn't loaded?\n"
 msgstr ""
-"En ajustant les nouveaux paramètres, une erreur est apparue. Les sources\n"
+"En ajustant les nouveaux paramètres, une erreur est apparue. Les sources\n"
 "d'erreur typique sont :\n"
-"- droit d'administration insuffisant (êtes-vous root ?) ;\n"
-"- le régulateur choisi n'est pas disponible, ou bien n'est pas disponible "
+"- droit d'administration insuffisant (êtes-vous root ?) ;\n"
+"- le régulateur choisi n'est pas disponible, ou bien n'est pas disponible "
 "en\n"
 "  tant que module noyau ;\n"
 "- la tactique n'est pas disponible ;\n"
-"- vous voulez utiliser l'option -f/--freq, mais le régulateur « userspace »\n"
-"  n'est pas disponible, par exemple parce que le matériel ne le supporte\n"
-"  pas, ou bien n'est tout simplement pas chargé.\n"
+"- vous voulez utiliser l'option -f/--freq, mais le régulateur Â« userspace Â»\n"
+"  n'est pas disponible, par exemple parce que le matériel ne le supporte\n"
+"  pas, ou bien n'est tout simplement pas chargé.\n"
 
 #: utils/cpufreq-set.c:170
 #, c-format
 msgid "wrong, unknown or unhandled CPU?\n"
-msgstr "CPU inconnu ou non supporté ?\n"
+msgstr "CPU inconnu ou non supporté ?\n"
 
 #: utils/cpufreq-set.c:302
 #, c-format
@@ -653,7 +653,7 @@ msgid ""
 "At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n"
 "-g/--governor must be passed\n"
 msgstr ""
-"L'un de ces paramètres est obligatoire : -f/--freq, -d/--min, -u/--max et\n"
+"L'un de ces paramètres est obligatoire : -f/--freq, -d/--min, -u/--max et\n"
 "-g/--governor\n"
 
 #: utils/cpufreq-set.c:347
@@ -810,7 +810,7 @@ msgstr ""
 #: utils/cpuidle-info.c:48
 #, fuzzy, c-format
 msgid "Available idle states:"
-msgstr "  plage de fréquence : "
+msgstr "  plage de fréquence : "
 
 #: utils/cpuidle-info.c:71
 #, c-format
@@ -911,7 +911,7 @@ msgstr "Usage : cpufreq-info [options]\n"
 #: utils/cpuidle-info.c:149
 #, fuzzy, c-format
 msgid "  -s, --silent         Only show general C-state information\n"
-msgstr "  -e, --debug          Afficher les informations de déboguage\n"
+msgstr "  -e, --debug          Afficher les informations de déboguage\n"
 
 #: utils/cpuidle-info.c:150
 #, fuzzy, c-format
@@ -921,7 +921,7 @@ msgid ""
 "                       interface in older kernels\n"
 msgstr ""
 "  -o, --proc           Affiche les informations en utilisant l'interface\n"
-"                       fournie par /proc/cpufreq, présente dans les "
+"                       fournie par /proc/cpufreq, présente dans les "
 "versions\n"
 "                       2.4 et les anciennes versions 2.6 du noyau\n"
 
@@ -929,19 +929,19 @@ msgstr ""
 #, fuzzy, c-format
 msgid "You can't specify more than one output-specific argument\n"
 msgstr ""
-"On ne peut indiquer plus d'un paramètre --cpu, tout comme l'on ne peut\n"
-"spécifier plus d'un argument de formatage\n"
+"On ne peut indiquer plus d'un paramètre --cpu, tout comme l'on ne peut\n"
+"spécifier plus d'un argument de formatage\n"
 
 #~ msgid ""
 #~ "  -c CPU, --cpu CPU    CPU number which information shall be determined "
 #~ "about\n"
 #~ msgstr ""
-#~ "  -c CPU, --cpu CPU    Numéro du CPU pour lequel l'information sera "
-#~ "affichée\n"
+#~ "  -c CPU, --cpu CPU    Numéro du CPU pour lequel l'information sera "
+#~ "affichée\n"
 
 #~ msgid ""
 #~ "  -c CPU, --cpu CPU        number of CPU where cpufreq settings shall be "
 #~ "modified\n"
 #~ msgstr ""
-#~ "  -c CPU, --cpu CPU        numéro du CPU à prendre en compte pour les\n"
+#~ "  -c CPU, --cpu CPU        numéro du CPU à prendre en compte pour les\n"
 #~ "                           changements\n"
index b53596ad601bb4964231c58151308f61221868f5..2e7fd822796911c2875a1dad87dca67fe185d589 100644 (file)
@@ -31,17 +31,21 @@ long __pmem_direct_access(struct pmem_device *pmem, pgoff_t pgoff,
        if (get_nfit_res(pmem->phys_addr + offset)) {
                struct page *page;
 
-               *kaddr = pmem->virt_addr + offset;
+               if (kaddr)
+                       *kaddr = pmem->virt_addr + offset;
                page = vmalloc_to_page(pmem->virt_addr + offset);
-               *pfn = page_to_pfn_t(page);
+               if (pfn)
+                       *pfn = page_to_pfn_t(page);
                pr_debug_ratelimited("%s: pmem: %p pgoff: %#lx pfn: %#lx\n",
                                __func__, pmem, pgoff, page_to_pfn(page));
 
                return 1;
        }
 
-       *kaddr = pmem->virt_addr + offset;
-       *pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags);
+       if (kaddr)
+               *kaddr = pmem->virt_addr + offset;
+       if (pfn)
+               *pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags);
 
        /*
         * If badblocks are present, limit known good range to the
index e2926f72a821471214817f7ddb1c253a93b1ee02..cffc2c5a778db4e6a236e4491f29ff92aa3c3b75 100644 (file)
@@ -142,6 +142,28 @@ static u32 handle[] = {
 static unsigned long dimm_fail_cmd_flags[NUM_DCR];
 static int dimm_fail_cmd_code[NUM_DCR];
 
+static const struct nd_intel_smart smart_def = {
+       .flags = ND_INTEL_SMART_HEALTH_VALID
+               | ND_INTEL_SMART_SPARES_VALID
+               | ND_INTEL_SMART_ALARM_VALID
+               | ND_INTEL_SMART_USED_VALID
+               | ND_INTEL_SMART_SHUTDOWN_VALID
+               | ND_INTEL_SMART_MTEMP_VALID
+               | ND_INTEL_SMART_CTEMP_VALID,
+       .health = ND_INTEL_SMART_NON_CRITICAL_HEALTH,
+       .media_temperature = 23 * 16,
+       .ctrl_temperature = 25 * 16,
+       .pmic_temperature = 40 * 16,
+       .spares = 75,
+       .alarm_flags = ND_INTEL_SMART_SPARE_TRIP
+               | ND_INTEL_SMART_TEMP_TRIP,
+       .ait_status = 1,
+       .life_used = 5,
+       .shutdown_state = 0,
+       .vendor_size = 0,
+       .shutdown_count = 100,
+};
+
 struct nfit_test_fw {
        enum intel_fw_update_state state;
        u32 context;
@@ -752,15 +774,30 @@ static int nfit_test_cmd_smart_inject(
        if (buf_len != sizeof(*inj))
                return -EINVAL;
 
-       if (inj->mtemp_enable)
-               smart->media_temperature = inj->media_temperature;
-       if (inj->spare_enable)
-               smart->spares = inj->spares;
-       if (inj->fatal_enable)
-               smart->health = ND_INTEL_SMART_FATAL_HEALTH;
-       if (inj->unsafe_shutdown_enable) {
-               smart->shutdown_state = 1;
-               smart->shutdown_count++;
+       if (inj->flags & ND_INTEL_SMART_INJECT_MTEMP) {
+               if (inj->mtemp_enable)
+                       smart->media_temperature = inj->media_temperature;
+               else
+                       smart->media_temperature = smart_def.media_temperature;
+       }
+       if (inj->flags & ND_INTEL_SMART_INJECT_SPARE) {
+               if (inj->spare_enable)
+                       smart->spares = inj->spares;
+               else
+                       smart->spares = smart_def.spares;
+       }
+       if (inj->flags & ND_INTEL_SMART_INJECT_FATAL) {
+               if (inj->fatal_enable)
+                       smart->health = ND_INTEL_SMART_FATAL_HEALTH;
+               else
+                       smart->health = ND_INTEL_SMART_NON_CRITICAL_HEALTH;
+       }
+       if (inj->flags & ND_INTEL_SMART_INJECT_SHUTDOWN) {
+               if (inj->unsafe_shutdown_enable) {
+                       smart->shutdown_state = 1;
+                       smart->shutdown_count++;
+               } else
+                       smart->shutdown_state = 0;
        }
        inj->status = 0;
        smart_notify(bus_dev, dimm_dev, smart, thresh);
@@ -884,6 +921,16 @@ static int nd_intel_test_cmd_set_lss_status(struct nfit_test *t,
        return 0;
 }
 
+static int override_return_code(int dimm, unsigned int func, int rc)
+{
+       if ((1 << func) & dimm_fail_cmd_flags[dimm]) {
+               if (dimm_fail_cmd_code[dimm])
+                       return dimm_fail_cmd_code[dimm];
+               return -EIO;
+       }
+       return rc;
+}
+
 static int get_dimm(struct nfit_mem *nfit_mem, unsigned int func)
 {
        int i;
@@ -894,13 +941,6 @@ static int get_dimm(struct nfit_mem *nfit_mem, unsigned int func)
                        break;
        if (i >= ARRAY_SIZE(handle))
                return -ENXIO;
-
-       if ((1 << func) & dimm_fail_cmd_flags[i]) {
-               if (dimm_fail_cmd_code[i])
-                       return dimm_fail_cmd_code[i];
-               return -EIO;
-       }
-
        return i;
 }
 
@@ -939,48 +979,59 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
 
                        switch (func) {
                        case ND_INTEL_ENABLE_LSS_STATUS:
-                               return nd_intel_test_cmd_set_lss_status(t,
+                               rc = nd_intel_test_cmd_set_lss_status(t,
                                                buf, buf_len);
+                               break;
                        case ND_INTEL_FW_GET_INFO:
-                               return nd_intel_test_get_fw_info(t, buf,
+                               rc = nd_intel_test_get_fw_info(t, buf,
                                                buf_len, i - t->dcr_idx);
+                               break;
                        case ND_INTEL_FW_START_UPDATE:
-                               return nd_intel_test_start_update(t, buf,
+                               rc = nd_intel_test_start_update(t, buf,
                                                buf_len, i - t->dcr_idx);
+                               break;
                        case ND_INTEL_FW_SEND_DATA:
-                               return nd_intel_test_send_data(t, buf,
+                               rc = nd_intel_test_send_data(t, buf,
                                                buf_len, i - t->dcr_idx);
+                               break;
                        case ND_INTEL_FW_FINISH_UPDATE:
-                               return nd_intel_test_finish_fw(t, buf,
+                               rc = nd_intel_test_finish_fw(t, buf,
                                                buf_len, i - t->dcr_idx);
+                               break;
                        case ND_INTEL_FW_FINISH_QUERY:
-                               return nd_intel_test_finish_query(t, buf,
+                               rc = nd_intel_test_finish_query(t, buf,
                                                buf_len, i - t->dcr_idx);
+                               break;
                        case ND_INTEL_SMART:
-                               return nfit_test_cmd_smart(buf, buf_len,
+                               rc = nfit_test_cmd_smart(buf, buf_len,
                                                &t->smart[i - t->dcr_idx]);
+                               break;
                        case ND_INTEL_SMART_THRESHOLD:
-                               return nfit_test_cmd_smart_threshold(buf,
+                               rc = nfit_test_cmd_smart_threshold(buf,
                                                buf_len,
                                                &t->smart_threshold[i -
                                                        t->dcr_idx]);
+                               break;
                        case ND_INTEL_SMART_SET_THRESHOLD:
-                               return nfit_test_cmd_smart_set_threshold(buf,
+                               rc = nfit_test_cmd_smart_set_threshold(buf,
                                                buf_len,
                                                &t->smart_threshold[i -
                                                        t->dcr_idx],
                                                &t->smart[i - t->dcr_idx],
                                                &t->pdev.dev, t->dimm_dev[i]);
+                               break;
                        case ND_INTEL_SMART_INJECT:
-                               return nfit_test_cmd_smart_inject(buf,
+                               rc = nfit_test_cmd_smart_inject(buf,
                                                buf_len,
                                                &t->smart_threshold[i -
                                                        t->dcr_idx],
                                                &t->smart[i - t->dcr_idx],
                                                &t->pdev.dev, t->dimm_dev[i]);
+                               break;
                        default:
                                return -ENOTTY;
                        }
+                       return override_return_code(i, func, rc);
                }
 
                if (!test_bit(cmd, &cmd_mask)
@@ -1006,6 +1057,7 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
                default:
                        return -ENOTTY;
                }
+               return override_return_code(i, func, rc);
        } else {
                struct ars_state *ars_state = &t->ars_state;
                struct nd_cmd_pkg *call_pkg = buf;
@@ -1302,29 +1354,9 @@ static void smart_init(struct nfit_test *t)
                .ctrl_temperature = 30 * 16,
                .spares = 5,
        };
-       const struct nd_intel_smart smart_data = {
-               .flags = ND_INTEL_SMART_HEALTH_VALID
-                       | ND_INTEL_SMART_SPARES_VALID
-                       | ND_INTEL_SMART_ALARM_VALID
-                       | ND_INTEL_SMART_USED_VALID
-                       | ND_INTEL_SMART_SHUTDOWN_VALID
-                       | ND_INTEL_SMART_MTEMP_VALID,
-               .health = ND_INTEL_SMART_NON_CRITICAL_HEALTH,
-               .media_temperature = 23 * 16,
-               .ctrl_temperature = 25 * 16,
-               .pmic_temperature = 40 * 16,
-               .spares = 75,
-               .alarm_flags = ND_INTEL_SMART_SPARE_TRIP
-                       | ND_INTEL_SMART_TEMP_TRIP,
-               .ait_status = 1,
-               .life_used = 5,
-               .shutdown_state = 0,
-               .vendor_size = 0,
-               .shutdown_count = 100,
-       };
 
        for (i = 0; i < t->num_dcr; i++) {
-               memcpy(&t->smart[i], &smart_data, sizeof(smart_data));
+               memcpy(&t->smart[i], &smart_def, sizeof(smart_def));
                memcpy(&t->smart_threshold[i], &smart_t_data,
                                sizeof(smart_t_data));
        }
index db66f8a0d4bed71aa581cdbf82c9acf422daef05..37baecc3766f61064caedee4efadf151631d8de1 100644 (file)
@@ -1,7 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 
-CFLAGS += -I. -I../../include -g -O2 -Wall -D_LGPL_SOURCE -fsanitize=address
-LDFLAGS += -fsanitize=address
+CFLAGS += -I. -I../../include -g -Og -Wall -D_LGPL_SOURCE -fsanitize=address \
+         -fsanitize=undefined
+LDFLAGS += -fsanitize=address -fsanitize=undefined
 LDLIBS+= -lpthread -lurcu
 TARGETS = main idr-test multiorder
 CORE_OFILES := radix-tree.o idr.o linux.o test.o find_bit.o
@@ -21,6 +22,7 @@ targets: generated/map-shift.h $(TARGETS)
 
 main:  $(OFILES)
 
+idr-test.o: ../../../lib/test_ida.c
 idr-test: idr-test.o $(CORE_OFILES)
 
 multiorder: multiorder.o $(CORE_OFILES)
index ee820fcc29b0d3c201cbd63e56daa2392e89bcbf..321ba92c70d2acb56ef5e9573c0a4b23b304062f 100644 (file)
@@ -309,141 +309,61 @@ void idr_checks(void)
        idr_u32_test(0);
 }
 
+#define module_init(x)
+#define module_exit(x)
+#define MODULE_AUTHOR(x)
+#define MODULE_LICENSE(x)
+#define dump_stack()    assert(0)
+void ida_dump(struct ida *);
+
+#include "../../../lib/test_ida.c"
+
 /*
  * Check that we get the correct error when we run out of memory doing
- * allocations.  To ensure we run out of memory, just "forget" to preload.
+ * allocations.  In userspace, GFP_NOWAIT will always fail an allocation.
  * The first test is for not having a bitmap available, and the second test
  * is for not being able to allocate a level of the radix tree.
  */
 void ida_check_nomem(void)
-{
-       DEFINE_IDA(ida);
-       int id, err;
-
-       err = ida_get_new_above(&ida, 256, &id);
-       assert(err == -EAGAIN);
-       err = ida_get_new_above(&ida, 1UL << 30, &id);
-       assert(err == -EAGAIN);
-}
-
-/*
- * Check what happens when we fill a leaf and then delete it.  This may
- * discover mishandling of IDR_FREE.
- */
-void ida_check_leaf(void)
 {
        DEFINE_IDA(ida);
        int id;
-       unsigned long i;
 
-       for (i = 0; i < IDA_BITMAP_BITS; i++) {
-               assert(ida_pre_get(&ida, GFP_KERNEL));
-               assert(!ida_get_new(&ida, &id));
-               assert(id == i);
-       }
-
-       ida_destroy(&ida);
-       assert(ida_is_empty(&ida));
-
-       assert(ida_pre_get(&ida, GFP_KERNEL));
-       assert(!ida_get_new(&ida, &id));
-       assert(id == 0);
-       ida_destroy(&ida);
-       assert(ida_is_empty(&ida));
+       id = ida_alloc_min(&ida, 256, GFP_NOWAIT);
+       IDA_BUG_ON(&ida, id != -ENOMEM);
+       id = ida_alloc_min(&ida, 1UL << 30, GFP_NOWAIT);
+       IDA_BUG_ON(&ida, id != -ENOMEM);
+       IDA_BUG_ON(&ida, !ida_is_empty(&ida));
 }
 
 /*
  * Check handling of conversions between exceptional entries and full bitmaps.
  */
-void ida_check_conv(void)
+void ida_check_conv_user(void)
 {
        DEFINE_IDA(ida);
-       int id;
        unsigned long i;
 
-       for (i = 0; i < IDA_BITMAP_BITS * 2; i += IDA_BITMAP_BITS) {
-               assert(ida_pre_get(&ida, GFP_KERNEL));
-               assert(!ida_get_new_above(&ida, i + 1, &id));
-               assert(id == i + 1);
-               assert(!ida_get_new_above(&ida, i + BITS_PER_LONG, &id));
-               assert(id == i + BITS_PER_LONG);
-               ida_remove(&ida, i + 1);
-               ida_remove(&ida, i + BITS_PER_LONG);
-               assert(ida_is_empty(&ida));
-       }
-
-       assert(ida_pre_get(&ida, GFP_KERNEL));
-
-       for (i = 0; i < IDA_BITMAP_BITS * 2; i++) {
-               assert(ida_pre_get(&ida, GFP_KERNEL));
-               assert(!ida_get_new(&ida, &id));
-               assert(id == i);
-       }
-
-       for (i = IDA_BITMAP_BITS * 2; i > 0; i--) {
-               ida_remove(&ida, i - 1);
-       }
-       assert(ida_is_empty(&ida));
-
-       for (i = 0; i < IDA_BITMAP_BITS + BITS_PER_LONG - 4; i++) {
-               assert(ida_pre_get(&ida, GFP_KERNEL));
-               assert(!ida_get_new(&ida, &id));
-               assert(id == i);
-       }
-
-       for (i = IDA_BITMAP_BITS + BITS_PER_LONG - 4; i > 0; i--) {
-               ida_remove(&ida, i - 1);
-       }
-       assert(ida_is_empty(&ida));
-
        radix_tree_cpu_dead(1);
        for (i = 0; i < 1000000; i++) {
-               int err = ida_get_new(&ida, &id);
-               if (err == -EAGAIN) {
-                       assert((i % IDA_BITMAP_BITS) == (BITS_PER_LONG - 2));
-                       assert(ida_pre_get(&ida, GFP_KERNEL));
-                       err = ida_get_new(&ida, &id);
+               int id = ida_alloc(&ida, GFP_NOWAIT);
+               if (id == -ENOMEM) {
+                       IDA_BUG_ON(&ida, (i % IDA_BITMAP_BITS) !=
+                                       BITS_PER_LONG - 2);
+                       id = ida_alloc(&ida, GFP_KERNEL);
                } else {
-                       assert((i % IDA_BITMAP_BITS) != (BITS_PER_LONG - 2));
+                       IDA_BUG_ON(&ida, (i % IDA_BITMAP_BITS) ==
+                                       BITS_PER_LONG - 2);
                }
-               assert(!err);
-               assert(id == i);
+               IDA_BUG_ON(&ida, id != i);
        }
        ida_destroy(&ida);
 }
 
-/*
- * Check allocations up to and slightly above the maximum allowed (2^31-1) ID.
- * Allocating up to 2^31-1 should succeed, and then allocating the next one
- * should fail.
- */
-void ida_check_max(void)
-{
-       DEFINE_IDA(ida);
-       int id, err;
-       unsigned long i, j;
-
-       for (j = 1; j < 65537; j *= 2) {
-               unsigned long base = (1UL << 31) - j;
-               for (i = 0; i < j; i++) {
-                       assert(ida_pre_get(&ida, GFP_KERNEL));
-                       assert(!ida_get_new_above(&ida, base, &id));
-                       assert(id == base + i);
-               }
-               assert(ida_pre_get(&ida, GFP_KERNEL));
-               err = ida_get_new_above(&ida, base, &id);
-               assert(err == -ENOSPC);
-               ida_destroy(&ida);
-               assert(ida_is_empty(&ida));
-               rcu_barrier();
-       }
-}
-
 void ida_check_random(void)
 {
        DEFINE_IDA(ida);
        DECLARE_BITMAP(bitmap, 2048);
-       int id, err;
        unsigned int i;
        time_t s = time(NULL);
 
@@ -454,15 +374,11 @@ void ida_check_random(void)
                int bit = i & 2047;
                if (test_bit(bit, bitmap)) {
                        __clear_bit(bit, bitmap);
-                       ida_remove(&ida, bit);
+                       ida_free(&ida, bit);
                } else {
                        __set_bit(bit, bitmap);
-                       do {
-                               ida_pre_get(&ida, GFP_KERNEL);
-                               err = ida_get_new_above(&ida, bit, &id);
-                       } while (err == -EAGAIN);
-                       assert(!err);
-                       assert(id == bit);
+                       IDA_BUG_ON(&ida, ida_alloc_min(&ida, bit, GFP_KERNEL)
+                                       != bit);
                }
        }
        ida_destroy(&ida);
@@ -488,71 +404,12 @@ void ida_simple_get_remove_test(void)
        ida_destroy(&ida);
 }
 
-void ida_checks(void)
+void user_ida_checks(void)
 {
-       DEFINE_IDA(ida);
-       int id;
-       unsigned long i;
-
        radix_tree_cpu_dead(1);
-       ida_check_nomem();
-
-       for (i = 0; i < 10000; i++) {
-               assert(ida_pre_get(&ida, GFP_KERNEL));
-               assert(!ida_get_new(&ida, &id));
-               assert(id == i);
-       }
-
-       ida_remove(&ida, 20);
-       ida_remove(&ida, 21);
-       for (i = 0; i < 3; i++) {
-               assert(ida_pre_get(&ida, GFP_KERNEL));
-               assert(!ida_get_new(&ida, &id));
-               if (i == 2)
-                       assert(id == 10000);
-       }
-
-       for (i = 0; i < 5000; i++)
-               ida_remove(&ida, i);
-
-       assert(ida_pre_get(&ida, GFP_KERNEL));
-       assert(!ida_get_new_above(&ida, 5000, &id));
-       assert(id == 10001);
-
-       ida_destroy(&ida);
-
-       assert(ida_is_empty(&ida));
 
-       assert(ida_pre_get(&ida, GFP_KERNEL));
-       assert(!ida_get_new_above(&ida, 1, &id));
-       assert(id == 1);
-
-       ida_remove(&ida, id);
-       assert(ida_is_empty(&ida));
-       ida_destroy(&ida);
-       assert(ida_is_empty(&ida));
-
-       assert(ida_pre_get(&ida, GFP_KERNEL));
-       assert(!ida_get_new_above(&ida, 1, &id));
-       ida_destroy(&ida);
-       assert(ida_is_empty(&ida));
-
-       assert(ida_pre_get(&ida, GFP_KERNEL));
-       assert(!ida_get_new_above(&ida, 1, &id));
-       assert(id == 1);
-       assert(ida_pre_get(&ida, GFP_KERNEL));
-       assert(!ida_get_new_above(&ida, 1025, &id));
-       assert(id == 1025);
-       assert(ida_pre_get(&ida, GFP_KERNEL));
-       assert(!ida_get_new_above(&ida, 10000, &id));
-       assert(id == 10000);
-       ida_remove(&ida, 1025);
-       ida_destroy(&ida);
-       assert(ida_is_empty(&ida));
-
-       ida_check_leaf();
-       ida_check_max();
-       ida_check_conv();
+       ida_check_nomem();
+       ida_check_conv_user();
        ida_check_random();
        ida_simple_get_remove_test();
 
@@ -582,12 +439,19 @@ void ida_thread_tests(void)
                pthread_join(threads[i], NULL);
 }
 
+void ida_tests(void)
+{
+       user_ida_checks();
+       ida_checks();
+       ida_exit();
+       ida_thread_tests();
+}
+
 int __weak main(void)
 {
        radix_tree_init();
        idr_checks();
-       ida_checks();
-       ida_thread_tests();
+       ida_tests();
        radix_tree_cpu_dead(1);
        rcu_barrier();
        if (nr_allocated)
diff --git a/tools/testing/radix-tree/linux/xarray.h b/tools/testing/radix-tree/linux/xarray.h
new file mode 100644 (file)
index 0000000..df3812c
--- /dev/null
@@ -0,0 +1,2 @@
+#include "generated/map-shift.h"
+#include "../../../../include/linux/xarray.h"
index 257f3f8aacaa52dad996447e7e8f603a4637240c..b741686e53d63ad66375d9748f0e78d68bbced49 100644 (file)
@@ -27,20 +27,22 @@ void __gang_check(unsigned long middle, long down, long up, int chunk, int hop)
                item_check_present(&tree, middle + idx);
        item_check_absent(&tree, middle + up);
 
-       item_gang_check_present(&tree, middle - down,
-                       up + down, chunk, hop);
-       item_full_scan(&tree, middle - down, down + up, chunk);
+       if (chunk > 0) {
+               item_gang_check_present(&tree, middle - down, up + down,
+                               chunk, hop);
+               item_full_scan(&tree, middle - down, down + up, chunk);
+       }
        item_kill_tree(&tree);
 }
 
 void gang_check(void)
 {
-       __gang_check(1 << 30, 128, 128, 35, 2);
-       __gang_check(1 << 31, 128, 128, 32, 32);
-       __gang_check(1 << 31, 128, 128, 32, 100);
-       __gang_check(1 << 31, 128, 128, 17, 7);
-       __gang_check(0xffff0000, 0, 65536, 17, 7);
-       __gang_check(0xfffffffe, 1, 1, 17, 7);
+       __gang_check(1UL << 30, 128, 128, 35, 2);
+       __gang_check(1UL << 31, 128, 128, 32, 32);
+       __gang_check(1UL << 31, 128, 128, 32, 100);
+       __gang_check(1UL << 31, 128, 128, 17, 7);
+       __gang_check(0xffff0000UL, 0, 65536, 17, 7);
+       __gang_check(0xfffffffeUL, 1, 1, 17, 7);
 }
 
 void __big_gang_check(void)
@@ -322,7 +324,7 @@ static void single_thread_tests(bool long_run)
        printv(2, "after dynamic_height_check: %d allocated, preempt %d\n",
                nr_allocated, preempt_count);
        idr_checks();
-       ida_checks();
+       ida_tests();
        rcu_barrier();
        printv(2, "after idr_checks: %d allocated, preempt %d\n",
                nr_allocated, preempt_count);
@@ -369,7 +371,6 @@ int main(int argc, char **argv)
        iteration_test(0, 10 + 90 * long_run);
        iteration_test(7, 10 + 90 * long_run);
        single_thread_tests(long_run);
-       ida_thread_tests();
 
        /* Free any remaining preallocated nodes */
        radix_tree_cpu_dead(0);
index 31f1d9b6f506ef884c978b568aa9dc5d89fd8312..92d901eacf49c92f2855706f349d032220caa0f0 100644 (file)
@@ -39,8 +39,7 @@ void multiorder_checks(void);
 void iteration_test(unsigned order, unsigned duration);
 void benchmark(void);
 void idr_checks(void);
-void ida_checks(void);
-void ida_thread_tests(void);
+void ida_tests(void);
 
 struct item *
 item_tag_set(struct radix_tree_root *root, unsigned long index, int tag);
index a944e72621a9e409cb7cb43c6291ae4c6a4e8ca2..b5fa0a2dc96886c21d47c04dc866b6dc98b93208 100644 (file)
@@ -51,6 +51,7 @@ int main(int argc, char *argv[])
 
        heap_size = 0;
        flags = 0;
+       heap_type = ION_HEAP_TYPE_SYSTEM;
 
        while ((opt = getopt(argc, argv, "hi:s:")) != -1) {
                switch (opt) {
diff --git a/tools/testing/selftests/cgroup/.gitignore b/tools/testing/selftests/cgroup/.gitignore
new file mode 100644 (file)
index 0000000..95eb3a5
--- /dev/null
@@ -0,0 +1 @@
+test_memcontrol
index f7a31392eb2ff1489eaeca4f1e83a0ca7cf7190b..23fbaa4a9630b2176bd47fda3b902db51ab6c6d7 100644 (file)
@@ -4,7 +4,9 @@ CFLAGS += -Wall
 all:
 
 TEST_GEN_PROGS = test_memcontrol
+TEST_GEN_PROGS += test_core
 
 include ../lib.mk
 
 $(OUTPUT)/test_memcontrol: cgroup_util.c
+$(OUTPUT)/test_core: cgroup_util.c
index 1e9e3c4705611792f2423cad1682c494b9332bc5..1c5d2b2a583b3348b13f47b89c75d5ce504ac621 100644 (file)
@@ -229,6 +229,14 @@ retry:
        return ret;
 }
 
+int cg_enter_current(const char *cgroup)
+{
+       char pidbuf[64];
+
+       snprintf(pidbuf, sizeof(pidbuf), "%d", getpid());
+       return cg_write(cgroup, "cgroup.procs", pidbuf);
+}
+
 int cg_run(const char *cgroup,
           int (*fn)(const char *cgroup, void *arg),
           void *arg)
index fe82a297d4e0be259a8d6350ef5837c13f95897b..1ff6f9f1abdc07f96b4dc5b18cdb9f490ee85abb 100644 (file)
@@ -32,6 +32,7 @@ extern int cg_write(const char *cgroup, const char *control, char *buf);
 extern int cg_run(const char *cgroup,
                  int (*fn)(const char *cgroup, void *arg),
                  void *arg);
+extern int cg_enter_current(const char *cgroup);
 extern int cg_run_nowait(const char *cgroup,
                         int (*fn)(const char *cgroup, void *arg),
                         void *arg);
diff --git a/tools/testing/selftests/cgroup/test_core.c b/tools/testing/selftests/cgroup/test_core.c
new file mode 100644 (file)
index 0000000..be59f9c
--- /dev/null
@@ -0,0 +1,395 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/limits.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "../kselftest.h"
+#include "cgroup_util.h"
+
+/*
+ * A(0) - B(0) - C(1)
+ *        \ D(0)
+ *
+ * A, B and C's "populated" fields would be 1 while D's 0.
+ * test that after the one process in C is moved to root,
+ * A,B and C's "populated" fields would flip to "0" and file
+ * modified events will be generated on the
+ * "cgroup.events" files of both cgroups.
+ */
+static int test_cgcore_populated(const char *root)
+{
+       int ret = KSFT_FAIL;
+       char *cg_test_a = NULL, *cg_test_b = NULL;
+       char *cg_test_c = NULL, *cg_test_d = NULL;
+
+       cg_test_a = cg_name(root, "cg_test_a");
+       cg_test_b = cg_name(root, "cg_test_a/cg_test_b");
+       cg_test_c = cg_name(root, "cg_test_a/cg_test_b/cg_test_c");
+       cg_test_d = cg_name(root, "cg_test_a/cg_test_b/cg_test_d");
+
+       if (!cg_test_a || !cg_test_b || !cg_test_c || !cg_test_d)
+               goto cleanup;
+
+       if (cg_create(cg_test_a))
+               goto cleanup;
+
+       if (cg_create(cg_test_b))
+               goto cleanup;
+
+       if (cg_create(cg_test_c))
+               goto cleanup;
+
+       if (cg_create(cg_test_d))
+               goto cleanup;
+
+       if (cg_enter_current(cg_test_c))
+               goto cleanup;
+
+       if (cg_read_strcmp(cg_test_a, "cgroup.events", "populated 1\n"))
+               goto cleanup;
+
+       if (cg_read_strcmp(cg_test_b, "cgroup.events", "populated 1\n"))
+               goto cleanup;
+
+       if (cg_read_strcmp(cg_test_c, "cgroup.events", "populated 1\n"))
+               goto cleanup;
+
+       if (cg_read_strcmp(cg_test_d, "cgroup.events", "populated 0\n"))
+               goto cleanup;
+
+       if (cg_enter_current(root))
+               goto cleanup;
+
+       if (cg_read_strcmp(cg_test_a, "cgroup.events", "populated 0\n"))
+               goto cleanup;
+
+       if (cg_read_strcmp(cg_test_b, "cgroup.events", "populated 0\n"))
+               goto cleanup;
+
+       if (cg_read_strcmp(cg_test_c, "cgroup.events", "populated 0\n"))
+               goto cleanup;
+
+       if (cg_read_strcmp(cg_test_d, "cgroup.events", "populated 0\n"))
+               goto cleanup;
+
+       ret = KSFT_PASS;
+
+cleanup:
+       if (cg_test_d)
+               cg_destroy(cg_test_d);
+       if (cg_test_c)
+               cg_destroy(cg_test_c);
+       if (cg_test_b)
+               cg_destroy(cg_test_b);
+       if (cg_test_a)
+               cg_destroy(cg_test_a);
+       free(cg_test_d);
+       free(cg_test_c);
+       free(cg_test_b);
+       free(cg_test_a);
+       return ret;
+}
+
+/*
+ * A (domain threaded) - B (threaded) - C (domain)
+ *
+ * test that C can't be used until it is turned into a
+ * threaded cgroup.  "cgroup.type" file will report "domain (invalid)" in
+ * these cases. Operations which fail due to invalid topology use
+ * EOPNOTSUPP as the errno.
+ */
+static int test_cgcore_invalid_domain(const char *root)
+{
+       int ret = KSFT_FAIL;
+       char *grandparent = NULL, *parent = NULL, *child = NULL;
+
+       grandparent = cg_name(root, "cg_test_grandparent");
+       parent = cg_name(root, "cg_test_grandparent/cg_test_parent");
+       child = cg_name(root, "cg_test_grandparent/cg_test_parent/cg_test_child");
+       if (!parent || !child || !grandparent)
+               goto cleanup;
+
+       if (cg_create(grandparent))
+               goto cleanup;
+
+       if (cg_create(parent))
+               goto cleanup;
+
+       if (cg_create(child))
+               goto cleanup;
+
+       if (cg_write(parent, "cgroup.type", "threaded"))
+               goto cleanup;
+
+       if (cg_read_strcmp(child, "cgroup.type", "domain invalid\n"))
+               goto cleanup;
+
+       if (!cg_enter_current(child))
+               goto cleanup;
+
+       if (errno != EOPNOTSUPP)
+               goto cleanup;
+
+       ret = KSFT_PASS;
+
+cleanup:
+       cg_enter_current(root);
+       if (child)
+               cg_destroy(child);
+       if (parent)
+               cg_destroy(parent);
+       if (grandparent)
+               cg_destroy(grandparent);
+       free(child);
+       free(parent);
+       free(grandparent);
+       return ret;
+}
+
+/*
+ * Test that when a child becomes threaded
+ * the parent type becomes domain threaded.
+ */
+static int test_cgcore_parent_becomes_threaded(const char *root)
+{
+       int ret = KSFT_FAIL;
+       char *parent = NULL, *child = NULL;
+
+       parent = cg_name(root, "cg_test_parent");
+       child = cg_name(root, "cg_test_parent/cg_test_child");
+       if (!parent || !child)
+               goto cleanup;
+
+       if (cg_create(parent))
+               goto cleanup;
+
+       if (cg_create(child))
+               goto cleanup;
+
+       if (cg_write(child, "cgroup.type", "threaded"))
+               goto cleanup;
+
+       if (cg_read_strcmp(parent, "cgroup.type", "domain threaded\n"))
+               goto cleanup;
+
+       ret = KSFT_PASS;
+
+cleanup:
+       if (child)
+               cg_destroy(child);
+       if (parent)
+               cg_destroy(parent);
+       free(child);
+       free(parent);
+       return ret;
+
+}
+
+/*
+ * Test that there's no internal process constrain on threaded cgroups.
+ * You can add threads/processes on a parent with a controller enabled.
+ */
+static int test_cgcore_no_internal_process_constraint_on_threads(const char *root)
+{
+       int ret = KSFT_FAIL;
+       char *parent = NULL, *child = NULL;
+
+       if (cg_read_strstr(root, "cgroup.controllers", "cpu") ||
+           cg_read_strstr(root, "cgroup.subtree_control", "cpu")) {
+               ret = KSFT_SKIP;
+               goto cleanup;
+       }
+
+       parent = cg_name(root, "cg_test_parent");
+       child = cg_name(root, "cg_test_parent/cg_test_child");
+       if (!parent || !child)
+               goto cleanup;
+
+       if (cg_create(parent))
+               goto cleanup;
+
+       if (cg_create(child))
+               goto cleanup;
+
+       if (cg_write(parent, "cgroup.type", "threaded"))
+               goto cleanup;
+
+       if (cg_write(child, "cgroup.type", "threaded"))
+               goto cleanup;
+
+       if (cg_write(parent, "cgroup.subtree_control", "+cpu"))
+               goto cleanup;
+
+       if (cg_enter_current(parent))
+               goto cleanup;
+
+       ret = KSFT_PASS;
+
+cleanup:
+       cg_enter_current(root);
+       cg_enter_current(root);
+       if (child)
+               cg_destroy(child);
+       if (parent)
+               cg_destroy(parent);
+       free(child);
+       free(parent);
+       return ret;
+}
+
+/*
+ * Test that you can't enable a controller on a child if it's not enabled
+ * on the parent.
+ */
+static int test_cgcore_top_down_constraint_enable(const char *root)
+{
+       int ret = KSFT_FAIL;
+       char *parent = NULL, *child = NULL;
+
+       parent = cg_name(root, "cg_test_parent");
+       child = cg_name(root, "cg_test_parent/cg_test_child");
+       if (!parent || !child)
+               goto cleanup;
+
+       if (cg_create(parent))
+               goto cleanup;
+
+       if (cg_create(child))
+               goto cleanup;
+
+       if (!cg_write(child, "cgroup.subtree_control", "+memory"))
+               goto cleanup;
+
+       ret = KSFT_PASS;
+
+cleanup:
+       if (child)
+               cg_destroy(child);
+       if (parent)
+               cg_destroy(parent);
+       free(child);
+       free(parent);
+       return ret;
+}
+
+/*
+ * Test that you can't disable a controller on a parent
+ * if it's enabled in a child.
+ */
+static int test_cgcore_top_down_constraint_disable(const char *root)
+{
+       int ret = KSFT_FAIL;
+       char *parent = NULL, *child = NULL;
+
+       parent = cg_name(root, "cg_test_parent");
+       child = cg_name(root, "cg_test_parent/cg_test_child");
+       if (!parent || !child)
+               goto cleanup;
+
+       if (cg_create(parent))
+               goto cleanup;
+
+       if (cg_create(child))
+               goto cleanup;
+
+       if (cg_write(parent, "cgroup.subtree_control", "+memory"))
+               goto cleanup;
+
+       if (cg_write(child, "cgroup.subtree_control", "+memory"))
+               goto cleanup;
+
+       if (!cg_write(parent, "cgroup.subtree_control", "-memory"))
+               goto cleanup;
+
+       ret = KSFT_PASS;
+
+cleanup:
+       if (child)
+               cg_destroy(child);
+       if (parent)
+               cg_destroy(parent);
+       free(child);
+       free(parent);
+       return ret;
+}
+
+/*
+ * Test internal process constraint.
+ * You can't add a pid to a domain parent if a controller is enabled.
+ */
+static int test_cgcore_internal_process_constraint(const char *root)
+{
+       int ret = KSFT_FAIL;
+       char *parent = NULL, *child = NULL;
+
+       parent = cg_name(root, "cg_test_parent");
+       child = cg_name(root, "cg_test_parent/cg_test_child");
+       if (!parent || !child)
+               goto cleanup;
+
+       if (cg_create(parent))
+               goto cleanup;
+
+       if (cg_create(child))
+               goto cleanup;
+
+       if (cg_write(parent, "cgroup.subtree_control", "+memory"))
+               goto cleanup;
+
+       if (!cg_enter_current(parent))
+               goto cleanup;
+
+       ret = KSFT_PASS;
+
+cleanup:
+       if (child)
+               cg_destroy(child);
+       if (parent)
+               cg_destroy(parent);
+       free(child);
+       free(parent);
+       return ret;
+}
+
+#define T(x) { x, #x }
+struct corecg_test {
+       int (*fn)(const char *root);
+       const char *name;
+} tests[] = {
+       T(test_cgcore_internal_process_constraint),
+       T(test_cgcore_top_down_constraint_enable),
+       T(test_cgcore_top_down_constraint_disable),
+       T(test_cgcore_no_internal_process_constraint_on_threads),
+       T(test_cgcore_parent_becomes_threaded),
+       T(test_cgcore_invalid_domain),
+       T(test_cgcore_populated),
+};
+#undef T
+
+int main(int argc, char *argv[])
+{
+       char root[PATH_MAX];
+       int i, ret = EXIT_SUCCESS;
+
+       if (cg_find_unified_root(root, sizeof(root)))
+               ksft_exit_skip("cgroup v2 isn't mounted\n");
+       for (i = 0; i < ARRAY_SIZE(tests); i++) {
+               switch (tests[i].fn(root)) {
+               case KSFT_PASS:
+                       ksft_test_result_pass("%s\n", tests[i].name);
+                       break;
+               case KSFT_SKIP:
+                       ksft_test_result_skip("%s\n", tests[i].name);
+                       break;
+               default:
+                       ret = EXIT_FAILURE;
+                       ksft_test_result_fail("%s\n", tests[i].name);
+                       break;
+               }
+       }
+
+       return ret;
+}
index b01924c71c097c1aeb2c48c8497033266896e876..07db5ab09cc7a790359a3c4c96e5a4ef1a1b01d9 100644 (file)
@@ -4,3 +4,6 @@ CONFIG_FUNCTION_PROFILER=y
 CONFIG_TRACER_SNAPSHOT=y
 CONFIG_STACK_TRACER=y
 CONFIG_HIST_TRIGGERS=y
+CONFIG_PREEMPT_TRACER=y
+CONFIG_IRQSOFF_TRACER=y
+CONFIG_PREEMPTIRQ_DELAY_TEST=m
index a0002563e9eeecc8f6b97d0a95ed90309cbd9a8c..1ad70cdaf442a2200c3bdf3b242301cfa2953880 100644 (file)
@@ -9,28 +9,22 @@ echo > kprobe_events
 
 case `uname -m` in
 x86_64)
-  ARG2=%si
-  OFFS=8
+  ARG1=%di
 ;;
 i[3456]86)
-  ARG2=%cx
-  OFFS=4
+  ARG1=%ax
 ;;
 aarch64)
-  ARG2=%x1
-  OFFS=8
+  ARG1=%x0
 ;;
 arm*)
-  ARG2=%r1
-  OFFS=4
+  ARG1=%r0
 ;;
 ppc64*)
-  ARG2=%r4
-  OFFS=8
+  ARG1=%r3
 ;;
 ppc*)
-  ARG2=%r4
-  OFFS=4
+  ARG1=%r3
 ;;
 *)
   echo "Please implement other architecture here"
@@ -38,17 +32,17 @@ ppc*)
 esac
 
 : "Test get argument (1)"
-echo "p:testprobe create_trace_kprobe arg1=+0(+0(${ARG2})):string" > kprobe_events
+echo "p:testprobe tracefs_create_dir arg1=+0(${ARG1}):string" > kprobe_events
 echo 1 > events/kprobes/testprobe/enable
-! echo test >> kprobe_events
-tail -n 1 trace | grep -qe "testprobe.* arg1=\"test\""
+echo "p:test _do_fork" >> kprobe_events
+grep -qe "testprobe.* arg1=\"test\"" trace
 
 echo 0 > events/kprobes/testprobe/enable
 : "Test get argument (2)"
-echo "p:testprobe create_trace_kprobe arg1=+0(+0(${ARG2})):string arg2=+0(+${OFFS}(${ARG2})):string" > kprobe_events
+echo "p:testprobe tracefs_create_dir arg1=+0(${ARG1}):string arg2=+0(${ARG1}):string" > kprobe_events
 echo 1 > events/kprobes/testprobe/enable
-! echo test1 test2 >> kprobe_events
-tail -n 1 trace | grep -qe "testprobe.* arg1=\"test1\" arg2=\"test2\""
+echo "p:test _do_fork" >> kprobe_events
+grep -qe "testprobe.* arg1=\"test\" arg2=\"test\"" trace
 
 echo 0 > events/enable
 echo > kprobe_events
index 4fda01a08da463d540c2e5fefcf9ad2d21deb0e0..519d2763f5d286bfe76086b6b2ec686d7291cc17 100644 (file)
@@ -4,7 +4,7 @@
 
 [ -f kprobe_events ] || exit_unsupported # this is configurable
 
-TARGET_FUNC=create_trace_kprobe
+TARGET_FUNC=tracefs_create_dir
 
 dec_addr() { # hexaddr
   printf "%d" "0x"`echo $1 | tail -c 8`
diff --git a/tools/testing/selftests/ftrace/test.d/preemptirq/irqsoff_tracer.tc b/tools/testing/selftests/ftrace/test.d/preemptirq/irqsoff_tracer.tc
new file mode 100644 (file)
index 0000000..cbd1743
--- /dev/null
@@ -0,0 +1,73 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# description: test for the preemptirqsoff tracer
+
+MOD=preemptirq_delay_test
+
+fail() {
+    reset_tracer
+    rmmod $MOD || true
+    exit_fail
+}
+
+unsup() { #msg
+    reset_tracer
+    rmmod $MOD || true
+    echo $1
+    exit_unsupported
+}
+
+modprobe $MOD || unsup "$MOD module not available"
+rmmod $MOD
+
+grep -q "preemptoff" available_tracers || unsup "preemptoff tracer not enabled"
+grep -q "irqsoff" available_tracers || unsup "irqsoff tracer not enabled"
+
+reset_tracer
+
+# Simulate preemptoff section for half a second couple of times
+echo preemptoff > current_tracer
+sleep 1
+modprobe $MOD test_mode=preempt delay=500000 || fail
+rmmod $MOD || fail
+modprobe $MOD test_mode=preempt delay=500000 || fail
+rmmod $MOD || fail
+modprobe $MOD test_mode=preempt delay=500000 || fail
+rmmod $MOD || fail
+
+cat trace
+
+# Confirm which tracer
+grep -q "tracer: preemptoff" trace || fail
+
+# Check the end of the section
+egrep -q "5.....us : <stack trace>" trace || fail
+
+# Check for 500ms of latency
+egrep -q "latency: 5..... us" trace || fail
+
+reset_tracer
+
+# Simulate irqsoff section for half a second couple of times
+echo irqsoff > current_tracer
+sleep 1
+modprobe $MOD test_mode=irq delay=500000 || fail
+rmmod $MOD || fail
+modprobe $MOD test_mode=irq delay=500000 || fail
+rmmod $MOD || fail
+modprobe $MOD test_mode=irq delay=500000 || fail
+rmmod $MOD || fail
+
+cat trace
+
+# Confirm which tracer
+grep -q "tracer: irqsoff" trace || fail
+
+# Check the end of the section
+egrep -q "5.....us : <stack trace>" trace || fail
+
+# Check for 500ms of latency
+egrep -q "latency: 5..... us" trace || fail
+
+reset_tracer
+exit 0
index dd0e5163f01fb7aeb1381581a7e9a64cb781e314..03b0f551bedffc7eecb6fd4452e99de1a8a4b828 100644 (file)
@@ -11,13 +11,16 @@ TEST_GEN_PROGS_x86_64 += sync_regs_test
 TEST_GEN_PROGS_x86_64 += vmx_tsc_adjust_test
 TEST_GEN_PROGS_x86_64 += cr4_cpuid_sync_test
 TEST_GEN_PROGS_x86_64 += state_test
+TEST_GEN_PROGS_x86_64 += dirty_log_test
 
 TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(UNAME_M))
 LIBKVM += $(LIBKVM_$(UNAME_M))
 
 INSTALL_HDR_PATH = $(top_srcdir)/usr
 LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
-CFLAGS += -O2 -g -std=gnu99 -I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -I..
+LINUX_TOOL_INCLUDE = $(top_srcdir)tools/include
+CFLAGS += -O2 -g -std=gnu99 -I$(LINUX_TOOL_INCLUDE) -I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -I..
+LDFLAGS += -lpthread
 
 # After inclusion, $(OUTPUT) is defined and
 # $(TEST_GEN_PROGS) starts with $(OUTPUT)/
index 8346b33c2073b9b88e2f4d5aac7eab2709a019a0..11ec358bf96906113c203c36bab921d1e41ea972 100644 (file)
 #define X86_FEATURE_OSXSAVE    (1<<27)
 #define VCPU_ID                        1
 
-enum {
-       GUEST_UPDATE_CR4 = 0x1000,
-       GUEST_FAILED,
-       GUEST_DONE,
-};
-
-static void exit_to_hv(uint16_t port)
-{
-       __asm__ __volatile__("in %[port], %%al"
-                            :
-                            : [port]"d"(port)
-                            : "rax");
-}
-
 static inline bool cr4_cpuid_is_sync(void)
 {
        int func, subfunc;
@@ -64,17 +50,15 @@ static void guest_code(void)
        set_cr4(cr4);
 
        /* verify CR4.OSXSAVE == CPUID.OSXSAVE */
-       if (!cr4_cpuid_is_sync())
-               exit_to_hv(GUEST_FAILED);
+       GUEST_ASSERT(cr4_cpuid_is_sync());
 
        /* notify hypervisor to change CR4 */
-       exit_to_hv(GUEST_UPDATE_CR4);
+       GUEST_SYNC(0);
 
        /* check again */
-       if (!cr4_cpuid_is_sync())
-               exit_to_hv(GUEST_FAILED);
+       GUEST_ASSERT(cr4_cpuid_is_sync());
 
-       exit_to_hv(GUEST_DONE);
+       GUEST_DONE();
 }
 
 int main(int argc, char *argv[])
@@ -95,7 +79,7 @@ int main(int argc, char *argv[])
        setbuf(stdout, NULL);
 
        /* Create VM */
-       vm = vm_create_default(VCPU_ID, guest_code);
+       vm = vm_create_default(VCPU_ID, 0, guest_code);
        vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid());
        run = vcpu_state(vm, VCPU_ID);
 
@@ -104,16 +88,16 @@ int main(int argc, char *argv[])
 
                if (run->exit_reason == KVM_EXIT_IO) {
                        switch (run->io.port) {
-                       case GUEST_UPDATE_CR4:
+                       case GUEST_PORT_SYNC:
                                /* emulate hypervisor clearing CR4.OSXSAVE */
                                vcpu_sregs_get(vm, VCPU_ID, &sregs);
                                sregs.cr4 &= ~X86_CR4_OSXSAVE;
                                vcpu_sregs_set(vm, VCPU_ID, &sregs);
                                break;
-                       case GUEST_FAILED:
+                       case GUEST_PORT_ABORT:
                                TEST_ASSERT(false, "Guest CR4 bit (OSXSAVE) unsynchronized with CPUID bit.");
                                break;
-                       case GUEST_DONE:
+                       case GUEST_PORT_DONE:
                                goto done;
                        default:
                                TEST_ASSERT(false, "Unknown port 0x%x.",
diff --git a/tools/testing/selftests/kvm/dirty_log_test.c b/tools/testing/selftests/kvm/dirty_log_test.c
new file mode 100644 (file)
index 0000000..0c2cdc1
--- /dev/null
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KVM dirty page logging test
+ *
+ * Copyright (C) 2018, Red Hat, Inc.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <pthread.h>
+#include <linux/bitmap.h>
+#include <linux/bitops.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+
+#define  DEBUG                 printf
+
+#define  VCPU_ID                        1
+/* The memory slot index to track dirty pages */
+#define  TEST_MEM_SLOT_INDEX            1
+/*
+ * GPA offset of the testing memory slot. Must be bigger than the
+ * default vm mem slot, which is DEFAULT_GUEST_PHY_PAGES.
+ */
+#define  TEST_MEM_OFFSET                (1ULL << 30) /* 1G */
+/* Size of the testing memory slot */
+#define  TEST_MEM_PAGES                 (1ULL << 18) /* 1G for 4K pages */
+/* How many pages to dirty for each guest loop */
+#define  TEST_PAGES_PER_LOOP            1024
+/* How many host loops to run (one KVM_GET_DIRTY_LOG for each loop) */
+#define  TEST_HOST_LOOP_N               32
+/* Interval for each host loop (ms) */
+#define  TEST_HOST_LOOP_INTERVAL        10
+
+/*
+ * Guest variables.  We use these variables to share data between host
+ * and guest.  There are two copies of the variables, one in host memory
+ * (which is unused) and one in guest memory.  When the host wants to
+ * access these variables, it needs to call addr_gva2hva() to access the
+ * guest copy.
+ */
+uint64_t guest_random_array[TEST_PAGES_PER_LOOP];
+uint64_t guest_iteration;
+uint64_t guest_page_size;
+
+/*
+ * Writes to the first byte of a random page within the testing memory
+ * region continuously.
+ */
+void guest_code(void)
+{
+       int i = 0;
+       uint64_t volatile *array = guest_random_array;
+       uint64_t volatile *guest_addr;
+
+       while (true) {
+               for (i = 0; i < TEST_PAGES_PER_LOOP; i++) {
+                       /*
+                        * Write to the first 8 bytes of a random page
+                        * on the testing memory region.
+                        */
+                       guest_addr = (uint64_t *)
+                           (TEST_MEM_OFFSET +
+                            (array[i] % TEST_MEM_PAGES) * guest_page_size);
+                       *guest_addr = guest_iteration;
+               }
+               /* Tell the host that we need more random numbers */
+               GUEST_SYNC(1);
+       }
+}
+
+/*
+ * Host variables.  These variables should only be used by the host
+ * rather than the guest.
+ */
+bool host_quit;
+
+/* Points to the test VM memory region on which we track dirty logs */
+void *host_test_mem;
+
+/* For statistics only */
+uint64_t host_dirty_count;
+uint64_t host_clear_count;
+uint64_t host_track_next_count;
+
+/*
+ * We use this bitmap to track some pages that should have its dirty
+ * bit set in the _next_ iteration.  For example, if we detected the
+ * page value changed to current iteration but at the same time the
+ * page bit is cleared in the latest bitmap, then the system must
+ * report that write in the next get dirty log call.
+ */
+unsigned long *host_bmap_track;
+
+void generate_random_array(uint64_t *guest_array, uint64_t size)
+{
+       uint64_t i;
+
+       for (i = 0; i < size; i++) {
+               guest_array[i] = random();
+       }
+}
+
+void *vcpu_worker(void *data)
+{
+       int ret;
+       uint64_t loops, *guest_array, pages_count = 0;
+       struct kvm_vm *vm = data;
+       struct kvm_run *run;
+       struct guest_args args;
+
+       run = vcpu_state(vm, VCPU_ID);
+
+       /* Retrieve the guest random array pointer and cache it */
+       guest_array = addr_gva2hva(vm, (vm_vaddr_t)guest_random_array);
+
+       DEBUG("VCPU starts\n");
+
+       generate_random_array(guest_array, TEST_PAGES_PER_LOOP);
+
+       while (!READ_ONCE(host_quit)) {
+               /* Let the guest to dirty these random pages */
+               ret = _vcpu_run(vm, VCPU_ID);
+               guest_args_read(vm, VCPU_ID, &args);
+               if (run->exit_reason == KVM_EXIT_IO &&
+                   args.port == GUEST_PORT_SYNC) {
+                       pages_count += TEST_PAGES_PER_LOOP;
+                       generate_random_array(guest_array, TEST_PAGES_PER_LOOP);
+               } else {
+                       TEST_ASSERT(false,
+                                   "Invalid guest sync status: "
+                                   "exit_reason=%s\n",
+                                   exit_reason_str(run->exit_reason));
+               }
+       }
+
+       DEBUG("VCPU exits, dirtied %"PRIu64" pages\n", pages_count);
+
+       return NULL;
+}
+
+void vm_dirty_log_verify(unsigned long *bmap, uint64_t iteration)
+{
+       uint64_t page;
+       uint64_t volatile *value_ptr;
+
+       for (page = 0; page < TEST_MEM_PAGES; page++) {
+               value_ptr = host_test_mem + page * getpagesize();
+
+               /* If this is a special page that we were tracking... */
+               if (test_and_clear_bit(page, host_bmap_track)) {
+                       host_track_next_count++;
+                       TEST_ASSERT(test_bit(page, bmap),
+                                   "Page %"PRIu64" should have its dirty bit "
+                                   "set in this iteration but it is missing",
+                                   page);
+               }
+
+               if (test_bit(page, bmap)) {
+                       host_dirty_count++;
+                       /*
+                        * If the bit is set, the value written onto
+                        * the corresponding page should be either the
+                        * previous iteration number or the current one.
+                        */
+                       TEST_ASSERT(*value_ptr == iteration ||
+                                   *value_ptr == iteration - 1,
+                                   "Set page %"PRIu64" value %"PRIu64
+                                   " incorrect (iteration=%"PRIu64")",
+                                   page, *value_ptr, iteration);
+               } else {
+                       host_clear_count++;
+                       /*
+                        * If cleared, the value written can be any
+                        * value smaller or equals to the iteration
+                        * number.  Note that the value can be exactly
+                        * (iteration-1) if that write can happen
+                        * like this:
+                        *
+                        * (1) increase loop count to "iteration-1"
+                        * (2) write to page P happens (with value
+                        *     "iteration-1")
+                        * (3) get dirty log for "iteration-1"; we'll
+                        *     see that page P bit is set (dirtied),
+                        *     and not set the bit in host_bmap_track
+                        * (4) increase loop count to "iteration"
+                        *     (which is current iteration)
+                        * (5) get dirty log for current iteration,
+                        *     we'll see that page P is cleared, with
+                        *     value "iteration-1".
+                        */
+                       TEST_ASSERT(*value_ptr <= iteration,
+                                   "Clear page %"PRIu64" value %"PRIu64
+                                   " incorrect (iteration=%"PRIu64")",
+                                   page, *value_ptr, iteration);
+                       if (*value_ptr == iteration) {
+                               /*
+                                * This page is _just_ modified; it
+                                * should report its dirtyness in the
+                                * next run
+                                */
+                               set_bit(page, host_bmap_track);
+                       }
+               }
+       }
+}
+
+void help(char *name)
+{
+       puts("");
+       printf("usage: %s [-i iterations] [-I interval] [-h]\n", name);
+       puts("");
+       printf(" -i: specify iteration counts (default: %"PRIu64")\n",
+              TEST_HOST_LOOP_N);
+       printf(" -I: specify interval in ms (default: %"PRIu64" ms)\n",
+              TEST_HOST_LOOP_INTERVAL);
+       puts("");
+       exit(0);
+}
+
+int main(int argc, char *argv[])
+{
+       pthread_t vcpu_thread;
+       struct kvm_vm *vm;
+       uint64_t volatile *psize, *iteration;
+       unsigned long *bmap, iterations = TEST_HOST_LOOP_N,
+           interval = TEST_HOST_LOOP_INTERVAL;
+       int opt;
+
+       while ((opt = getopt(argc, argv, "hi:I:")) != -1) {
+               switch (opt) {
+               case 'i':
+                       iterations = strtol(optarg, NULL, 10);
+                       break;
+               case 'I':
+                       interval = strtol(optarg, NULL, 10);
+                       break;
+               case 'h':
+               default:
+                       help(argv[0]);
+                       break;
+               }
+       }
+
+       TEST_ASSERT(iterations > 2, "Iteration must be bigger than zero\n");
+       TEST_ASSERT(interval > 0, "Interval must be bigger than zero");
+
+       DEBUG("Test iterations: %"PRIu64", interval: %"PRIu64" (ms)\n",
+             iterations, interval);
+
+       srandom(time(0));
+
+       bmap = bitmap_alloc(TEST_MEM_PAGES);
+       host_bmap_track = bitmap_alloc(TEST_MEM_PAGES);
+
+       vm = vm_create_default(VCPU_ID, TEST_MEM_PAGES, guest_code);
+
+       /* Add an extra memory slot for testing dirty logging */
+       vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS,
+                                   TEST_MEM_OFFSET,
+                                   TEST_MEM_SLOT_INDEX,
+                                   TEST_MEM_PAGES,
+                                   KVM_MEM_LOG_DIRTY_PAGES);
+       /* Cache the HVA pointer of the region */
+       host_test_mem = addr_gpa2hva(vm, (vm_paddr_t)TEST_MEM_OFFSET);
+
+       /* Do 1:1 mapping for the dirty track memory slot */
+       virt_map(vm, TEST_MEM_OFFSET, TEST_MEM_OFFSET,
+                TEST_MEM_PAGES * getpagesize(), 0);
+
+       vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid());
+
+       /* Tell the guest about the page size on the system */
+       psize = addr_gva2hva(vm, (vm_vaddr_t)&guest_page_size);
+       *psize = getpagesize();
+
+       /* Start the iterations */
+       iteration = addr_gva2hva(vm, (vm_vaddr_t)&guest_iteration);
+       *iteration = 1;
+
+       /* Start dirtying pages */
+       pthread_create(&vcpu_thread, NULL, vcpu_worker, vm);
+
+       while (*iteration < iterations) {
+               /* Give the vcpu thread some time to dirty some pages */
+               usleep(interval * 1000);
+               kvm_vm_get_dirty_log(vm, TEST_MEM_SLOT_INDEX, bmap);
+               vm_dirty_log_verify(bmap, *iteration);
+               (*iteration)++;
+       }
+
+       /* Tell the vcpu thread to quit */
+       host_quit = true;
+       pthread_join(vcpu_thread, NULL);
+
+       DEBUG("Total bits checked: dirty (%"PRIu64"), clear (%"PRIu64"), "
+             "track_next (%"PRIu64")\n", host_dirty_count, host_clear_count,
+             host_track_next_count);
+
+       free(bmap);
+       free(host_bmap_track);
+       kvm_vm_free(vm);
+
+       return 0;
+}
index d32632f71ab8d3021e6a8a6db2270a286d3a4d67..bb5a25fb82c60cbe8f7a108c81bc1c78aa2a7a20 100644 (file)
@@ -55,6 +55,7 @@ struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm);
 void kvm_vm_free(struct kvm_vm *vmp);
 void kvm_vm_restart(struct kvm_vm *vmp, int perm);
 void kvm_vm_release(struct kvm_vm *vmp);
+void kvm_vm_get_dirty_log(struct kvm_vm *vm, int slot, void *log);
 
 int kvm_memcmp_hva_gva(void *hva,
        struct kvm_vm *vm, const vm_vaddr_t gva, size_t len);
@@ -80,6 +81,8 @@ void vm_mem_region_set_flags(struct kvm_vm *vm, uint32_t slot, uint32_t flags);
 void vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpuid, int pgd_memslot, int gdt_memslot);
 vm_vaddr_t vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
        uint32_t data_memslot, uint32_t pgd_memslot);
+void virt_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
+             size_t size, uint32_t pgd_memslot);
 void *addr_gpa2hva(struct kvm_vm *vm, vm_paddr_t gpa);
 void *addr_gva2hva(struct kvm_vm *vm, vm_vaddr_t gva);
 vm_paddr_t addr_hva2gpa(struct kvm_vm *vm, void *hva);
@@ -127,7 +130,8 @@ kvm_get_supported_cpuid_entry(uint32_t function)
        return kvm_get_supported_cpuid_index(function, 0);
 }
 
-struct kvm_vm *vm_create_default(uint32_t vcpuid, void *guest_code);
+struct kvm_vm *vm_create_default(uint32_t vcpuid, uint64_t extra_mem_size,
+                                void *guest_code);
 void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, void *guest_code);
 
 typedef void (*vmx_guest_code_t)(vm_vaddr_t vmxon_vaddr,
@@ -144,4 +148,43 @@ allocate_kvm_dirty_log(struct kvm_userspace_memory_region *region);
 
 int vm_create_device(struct kvm_vm *vm, struct kvm_create_device *cd);
 
+#define GUEST_PORT_SYNC         0x1000
+#define GUEST_PORT_ABORT        0x1001
+#define GUEST_PORT_DONE         0x1002
+
+static inline void __exit_to_l0(uint16_t port, uint64_t arg0, uint64_t arg1)
+{
+       __asm__ __volatile__("in %[port], %%al"
+                            :
+                            : [port]"d"(port), "D"(arg0), "S"(arg1)
+                            : "rax");
+}
+
+/*
+ * Allows to pass three arguments to the host: port is 16bit wide,
+ * arg0 & arg1 are 64bit wide
+ */
+#define GUEST_SYNC_ARGS(_port, _arg0, _arg1) \
+       __exit_to_l0(_port, (uint64_t) (_arg0), (uint64_t) (_arg1))
+
+#define GUEST_ASSERT(_condition) do {                          \
+               if (!(_condition))                              \
+                       GUEST_SYNC_ARGS(GUEST_PORT_ABORT,       \
+                                       "Failed guest assert: " \
+                                       #_condition, __LINE__); \
+       } while (0)
+
+#define GUEST_SYNC(stage)  GUEST_SYNC_ARGS(GUEST_PORT_SYNC, "hello", stage)
+
+#define GUEST_DONE()  GUEST_SYNC_ARGS(GUEST_PORT_DONE, 0, 0)
+
+struct guest_args {
+       uint64_t arg0;
+       uint64_t arg1;
+       uint16_t port;
+} __attribute__ ((packed));
+
+void guest_args_read(struct kvm_vm *vm, uint32_t vcpu_id,
+                    struct guest_args *args);
+
 #endif /* SELFTEST_KVM_UTIL_H */
index ac53730b30aa48c9f9ecf54e3e6362f8cdf0e1c4..73c3933436ecc1206b8f90f2e4991ac4ddcf7bea 100644 (file)
@@ -28,8 +28,6 @@ int test_seq_read(const char *path, char **bufp, size_t *sizep);
 void test_assert(bool exp, const char *exp_str,
                 const char *file, unsigned int line, const char *fmt, ...);
 
-#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
-
 #define TEST_ASSERT(e, fmt, ...) \
        test_assert((e), #e, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
 
index 643309d6de743d0962b55bc4ce6f3c4c82df5c75..e9ba389c48dbc95390d965a8ea7d7f03da9ece44 100644 (file)
@@ -14,6 +14,7 @@
 #include <sys/mman.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <linux/kernel.h>
 
 #define KVM_DEV_PATH "/dev/kvm"
 
@@ -168,6 +169,16 @@ void kvm_vm_restart(struct kvm_vm *vmp, int perm)
        }
 }
 
+void kvm_vm_get_dirty_log(struct kvm_vm *vm, int slot, void *log)
+{
+       struct kvm_dirty_log args = { .dirty_bitmap = log, .slot = slot };
+       int ret;
+
+       ret = ioctl(vm->fd, KVM_GET_DIRTY_LOG, &args);
+       TEST_ASSERT(ret == 0, "%s: KVM_GET_DIRTY_LOG failed: %s",
+                   strerror(-ret));
+}
+
 /* Userspace Memory Region Find
  *
  * Input Args:
@@ -923,6 +934,39 @@ vm_vaddr_t vm_vaddr_alloc(struct kvm_vm *vm, size_t sz, vm_vaddr_t vaddr_min,
        return vaddr_start;
 }
 
+/*
+ * Map a range of VM virtual address to the VM's physical address
+ *
+ * Input Args:
+ *   vm - Virtual Machine
+ *   vaddr - Virtuall address to map
+ *   paddr - VM Physical Address
+ *   size - The size of the range to map
+ *   pgd_memslot - Memory region slot for new virtual translation tables
+ *
+ * Output Args: None
+ *
+ * Return: None
+ *
+ * Within the VM given by vm, creates a virtual translation for the
+ * page range starting at vaddr to the page range starting at paddr.
+ */
+void virt_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
+             size_t size, uint32_t pgd_memslot)
+{
+       size_t page_size = vm->page_size;
+       size_t npages = size / page_size;
+
+       TEST_ASSERT(vaddr + size > vaddr, "Vaddr overflow");
+       TEST_ASSERT(paddr + size > paddr, "Paddr overflow");
+
+       while (npages--) {
+               virt_pg_map(vm, vaddr, paddr, pgd_memslot);
+               vaddr += page_size;
+               paddr += page_size;
+       }
+}
+
 /* Address VM Physical to Host Virtual
  *
  * Input Args:
@@ -1536,3 +1580,17 @@ void *addr_gva2hva(struct kvm_vm *vm, vm_vaddr_t gva)
 {
        return addr_gpa2hva(vm, addr_gva2gpa(vm, gva));
 }
+
+void guest_args_read(struct kvm_vm *vm, uint32_t vcpu_id,
+                    struct guest_args *args)
+{
+       struct kvm_run *run = vcpu_state(vm, vcpu_id);
+       struct kvm_regs regs;
+
+       memset(&regs, 0, sizeof(regs));
+       vcpu_regs_get(vm, vcpu_id, &regs);
+
+       args->port = run->io.port;
+       args->arg0 = regs.rdi;
+       args->arg1 = regs.rsi;
+}
index e38345252df5e8f0b9ebeddd29751f996c589a5e..a3122f1949a8e67df2d6cb206ecf353d30f6d015 100644 (file)
@@ -702,6 +702,9 @@ void vcpu_set_cpuid(struct kvm_vm *vm,
  *
  * Input Args:
  *   vcpuid - The id of the single VCPU to add to the VM.
+ *   extra_mem_pages - The size of extra memories to add (this will
+ *                     decide how much extra space we will need to
+ *                     setup the page tables using mem slot 0)
  *   guest_code - The vCPU's entry point
  *
  * Output Args: None
@@ -709,12 +712,23 @@ void vcpu_set_cpuid(struct kvm_vm *vm,
  * Return:
  *   Pointer to opaque structure that describes the created VM.
  */
-struct kvm_vm *vm_create_default(uint32_t vcpuid, void *guest_code)
+struct kvm_vm *vm_create_default(uint32_t vcpuid, uint64_t extra_mem_pages,
+                                void *guest_code)
 {
        struct kvm_vm *vm;
+       /*
+        * For x86 the maximum page table size for a memory region
+        * will be when only 4K pages are used.  In that case the
+        * total extra size for page tables (for extra N pages) will
+        * be: N/512+N/512^2+N/512^3+... which is definitely smaller
+        * than N/512*2.
+        */
+       uint64_t extra_pg_pages = extra_mem_pages / 512 * 2;
 
        /* Create VM */
-       vm = vm_create(VM_MODE_FLAT48PG, DEFAULT_GUEST_PHY_PAGES, O_RDWR);
+       vm = vm_create(VM_MODE_FLAT48PG,
+                      DEFAULT_GUEST_PHY_PAGES + extra_pg_pages,
+                      O_RDWR);
 
        /* Setup guest code */
        kvm_vm_elf_load(vm, program_invocation_name, 0, 0);
index 090fd3f1935276146225e2e67db2fcd01c57b6c0..881419d5746e7e8a2e0bd8bb318867d50d75d731 100644 (file)
@@ -36,7 +36,7 @@ int main(int argc, char *argv[])
        setbuf(stdout, NULL);
 
        /* Create VM */
-       vm = vm_create_default(VCPU_ID, NULL);
+       vm = vm_create_default(VCPU_ID, 0, NULL);
 
        vcpu_sregs_get(vm, VCPU_ID, &sregs);
        sregs.apic_base = 1 << 10;
index ecabf25b70777d5d8eaa5df915e3c3d750cad65e..900e3e9dfb9f6516e4a31310de08c51dbf192d51 100644 (file)
 #include "vmx.h"
 
 #define VCPU_ID                5
-#define PORT_SYNC      0x1000
-#define PORT_ABORT     0x1001
-#define PORT_DONE      0x1002
-
-static inline void __exit_to_l0(uint16_t port, uint64_t arg0, uint64_t arg1)
-{
-       __asm__ __volatile__("in %[port], %%al"
-                            :
-                            : [port]"d"(port), "D"(arg0), "S"(arg1)
-                            : "rax");
-}
-
-#define exit_to_l0(_port, _arg0, _arg1) \
-       __exit_to_l0(_port, (uint64_t) (_arg0), (uint64_t) (_arg1))
-
-#define GUEST_ASSERT(_condition) do { \
-       if (!(_condition)) \
-               exit_to_l0(PORT_ABORT, "Failed guest assert: " #_condition, __LINE__);\
-} while (0)
-
-#define GUEST_SYNC(stage) \
-       exit_to_l0(PORT_SYNC, "hello", stage);
 
 static bool have_nested_state;
 
@@ -137,7 +115,7 @@ void guest_code(struct vmx_pages *vmx_pages)
        if (vmx_pages)
                l1_guest_code(vmx_pages);
 
-       exit_to_l0(PORT_DONE, 0, 0);
+       GUEST_DONE();
 }
 
 int main(int argc, char *argv[])
@@ -154,7 +132,7 @@ int main(int argc, char *argv[])
        struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1);
 
        /* Create VM */
-       vm = vm_create_default(VCPU_ID, guest_code);
+       vm = vm_create_default(VCPU_ID, 0, guest_code);
        vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid());
        run = vcpu_state(vm, VCPU_ID);
 
@@ -178,13 +156,13 @@ int main(int argc, char *argv[])
                memset(&regs1, 0, sizeof(regs1));
                vcpu_regs_get(vm, VCPU_ID, &regs1);
                switch (run->io.port) {
-               case PORT_ABORT:
+               case GUEST_PORT_ABORT:
                        TEST_ASSERT(false, "%s at %s:%d", (const char *) regs1.rdi,
                                    __FILE__, regs1.rsi);
                        /* NOT REACHED */
-               case PORT_SYNC:
+               case GUEST_PORT_SYNC:
                        break;
-               case PORT_DONE:
+               case GUEST_PORT_DONE:
                        goto done;
                default:
                        TEST_ASSERT(false, "Unknown port 0x%x.", run->io.port);
index eae1ece3c31b8505e99877bf11d8fa8fb6907cdc..213343e5dff96f91306d1de162a35fd459896396 100644 (file)
 #include "x86.h"
 
 #define VCPU_ID 5
-#define PORT_HOST_SYNC 0x1000
-
-static void __exit_to_l0(uint16_t port, uint64_t arg0, uint64_t arg1)
-{
-               __asm__ __volatile__("in %[port], %%al"
-                                    :
-                                    : [port]"d"(port), "D"(arg0), "S"(arg1)
-                                    : "rax");
-}
-
-#define exit_to_l0(_port, _arg0, _arg1) \
-        __exit_to_l0(_port, (uint64_t) (_arg0), (uint64_t) (_arg1))
-
-#define GUEST_ASSERT(_condition) do { \
-       if (!(_condition)) \
-               exit_to_l0(PORT_ABORT, "Failed guest assert: " #_condition, 0);\
-} while (0)
 
 void guest_code(void)
 {
        for (;;) {
-               exit_to_l0(PORT_HOST_SYNC, "hello", 0);
+               GUEST_SYNC(0);
                asm volatile ("inc %r11");
        }
 }
@@ -111,7 +94,7 @@ int main(int argc, char *argv[])
        }
 
        /* Create VM */
-       vm = vm_create_default(VCPU_ID, guest_code);
+       vm = vm_create_default(VCPU_ID, 0, guest_code);
 
        run = vcpu_state(vm, VCPU_ID);
 
index fc414c28436860a3124f425cfbb57b4bd7240b03..49bcc68b0235040b43091e274f01853a876dc2ad 100644 (file)
@@ -62,27 +62,12 @@ struct kvm_single_msr {
 /* The virtual machine object. */
 static struct kvm_vm *vm;
 
-#define exit_to_l0(_port, _arg) do_exit_to_l0(_port, (unsigned long) (_arg))
-static void do_exit_to_l0(uint16_t port, unsigned long arg)
-{
-       __asm__ __volatile__("in %[port], %%al"
-               :
-               : [port]"d"(port), "D"(arg)
-               : "rax");
-}
-
-
-#define GUEST_ASSERT(_condition) do {                                       \
-       if (!(_condition))                                                   \
-               exit_to_l0(PORT_ABORT, "Failed guest assert: " #_condition); \
-} while (0)
-
 static void check_ia32_tsc_adjust(int64_t max)
 {
        int64_t adjust;
 
        adjust = rdmsr(MSR_IA32_TSC_ADJUST);
-       exit_to_l0(PORT_REPORT, adjust);
+       GUEST_SYNC(adjust);
        GUEST_ASSERT(adjust <= max);
 }
 
@@ -132,7 +117,7 @@ static void l1_guest_code(struct vmx_pages *vmx_pages)
 
        check_ia32_tsc_adjust(-2 * TSC_ADJUST_VALUE);
 
-       exit_to_l0(PORT_DONE, 0);
+       GUEST_DONE();
 }
 
 void report(int64_t val)
@@ -152,7 +137,7 @@ int main(int argc, char *argv[])
                exit(KSFT_SKIP);
        }
 
-       vm = vm_create_default(VCPU_ID, (void *) l1_guest_code);
+       vm = vm_create_default(VCPU_ID, 0, (void *) l1_guest_code);
        vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid());
 
        /* Allocate VMX pages and shared descriptors (vmx_pages). */
@@ -161,26 +146,26 @@ int main(int argc, char *argv[])
 
        for (;;) {
                volatile struct kvm_run *run = vcpu_state(vm, VCPU_ID);
-               struct kvm_regs regs;
+               struct guest_args args;
 
                vcpu_run(vm, VCPU_ID);
-               vcpu_regs_get(vm, VCPU_ID, &regs);
+               guest_args_read(vm, VCPU_ID, &args);
                TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
-                           "Got exit_reason other than KVM_EXIT_IO: %u (%s), rip=%lx\n",
+                           "Got exit_reason other than KVM_EXIT_IO: %u (%s)\n",
                            run->exit_reason,
-                           exit_reason_str(run->exit_reason), regs.rip);
+                           exit_reason_str(run->exit_reason));
 
-               switch (run->io.port) {
-               case PORT_ABORT:
-                       TEST_ASSERT(false, "%s", (const char *) regs.rdi);
+               switch (args.port) {
+               case GUEST_PORT_ABORT:
+                       TEST_ASSERT(false, "%s", (const char *) args.arg0);
                        /* NOT REACHED */
-               case PORT_REPORT:
-                       report(regs.rdi);
+               case GUEST_PORT_SYNC:
+                       report(args.arg1);
                        break;
-               case PORT_DONE:
+               case GUEST_PORT_DONE:
                        goto done;
                default:
-                       TEST_ASSERT(false, "Unknown port 0x%x.", run->io.port);
+                       TEST_ASSERT(false, "Unknown port 0x%x.", args.port);
                }
        }
 
index b5d881e48548b76bf27f31be17c1a6deceb8afdf..416bd53ce982874948c3e84a2d12d952bf1c1977 100644 (file)
@@ -1,2 +1 @@
 CONFIG_USER_NS=y
-CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
index f8cc38afffa2e6a35dd316a40e2493356c16063c..32a194e3e07a5a60d4c00dfdcfd25ad31ef38b6e 100755 (executable)
@@ -46,6 +46,9 @@
 # Kselftest framework requirement - SKIP code is 4.
 ksft_skip=4
 
+# Some systems don't have a ping6 binary anymore
+which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping)
+
 tests="
        pmtu_vti6_exception             vti6: PMTU exceptions
        pmtu_vti4_exception             vti4: PMTU exceptions
@@ -274,7 +277,7 @@ test_pmtu_vti6_exception() {
        mtu "${ns_b}" veth_b 4000
        mtu "${ns_a}" vti6_a 5000
        mtu "${ns_b}" vti6_b 5000
-       ${ns_a} ping6 -q -i 0.1 -w 2 -s 60000 ${vti6_b_addr} > /dev/null
+       ${ns_a} ${ping6} -q -i 0.1 -w 2 -s 60000 ${vti6_b_addr} > /dev/null
 
        # Check that exception was created
        if [ "$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti6_b_addr})" = "" ]; then
@@ -334,7 +337,7 @@ test_pmtu_vti4_link_add_mtu() {
        fail=0
 
        min=68
-       max=$((65528 - 20))
+       max=$((65535 - 20))
        # Check invalid values first
        for v in $((min - 1)) $((max + 1)); do
                ${ns_a} ip link add vti4_a mtu ${v} type vti local ${veth4_a_addr} remote ${veth4_b_addr} key 10 2>/dev/null
index 74e5912e9f2efc771c3d3983d80318c666f542d7..82121a81681f7720a16709d659c6e7c53e6a3fa3 100644 (file)
@@ -9,3 +9,5 @@
 /proc-uptime-001
 /proc-uptime-002
 /read
+/self
+/thread-self
index db310eedc26874f76b43ab3034424b07adf24318..1c12c34cf85d801b09c6adbfe1fb1067c55283e8 100644 (file)
@@ -1,4 +1,5 @@
 CFLAGS += -Wall -O2 -Wno-unused-function
+CFLAGS += -D_GNU_SOURCE
 
 TEST_GEN_PROGS :=
 TEST_GEN_PROGS += fd-001-lookup
@@ -12,5 +13,7 @@ TEST_GEN_PROGS += proc-self-wchan
 TEST_GEN_PROGS += proc-uptime-001
 TEST_GEN_PROGS += proc-uptime-002
 TEST_GEN_PROGS += read
+TEST_GEN_PROGS += self
+TEST_GEN_PROGS += thread-self
 
 include ../lib.mk
index 4e178166fd84607d03ef81c67475d24eea018000..b7d57ea402376774b48715a84993acfe36165fff 100644 (file)
@@ -6,6 +6,18 @@
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+static inline pid_t sys_getpid(void)
+{
+       return syscall(SYS_getpid);
+}
+
+static inline pid_t sys_gettid(void)
+{
+       return syscall(SYS_gettid);
+}
 
 static inline bool streq(const char *s1, const char *s2)
 {
diff --git a/tools/testing/selftests/proc/self.c b/tools/testing/selftests/proc/self.c
new file mode 100644 (file)
index 0000000..21c15a1
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2018 Alexey Dobriyan <adobriyan@gmail.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+// Test that /proc/self gives correct TGID.
+#undef NDEBUG
+#include <assert.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "proc.h"
+
+int main(void)
+{
+       char buf1[64], buf2[64];
+       pid_t pid;
+       ssize_t rv;
+
+       pid = sys_getpid();
+       snprintf(buf1, sizeof(buf1), "%u", pid);
+
+       rv = readlink("/proc/self", buf2, sizeof(buf2));
+       assert(rv == strlen(buf1));
+       buf2[rv] = '\0';
+       assert(streq(buf1, buf2));
+
+       return 0;
+}
diff --git a/tools/testing/selftests/proc/thread-self.c b/tools/testing/selftests/proc/thread-self.c
new file mode 100644 (file)
index 0000000..4b23b39
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2018 Alexey Dobriyan <adobriyan@gmail.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+// Test that /proc/thread-self gives correct TGID/PID.
+#undef NDEBUG
+#include <assert.h>
+#include <sched.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+
+#include "proc.h"
+
+int f(void *arg)
+{
+       char buf1[64], buf2[64];
+       pid_t pid, tid;
+       ssize_t rv;
+
+       pid = sys_getpid();
+       tid = sys_gettid();
+       snprintf(buf1, sizeof(buf1), "%u/task/%u", pid, tid);
+
+       rv = readlink("/proc/thread-self", buf2, sizeof(buf2));
+       assert(rv == strlen(buf1));
+       buf2[rv] = '\0';
+       assert(streq(buf1, buf2));
+
+       if (arg)
+               exit(0);
+       return 0;
+}
+
+int main(void)
+{
+       const int PAGE_SIZE = sysconf(_SC_PAGESIZE);
+       pid_t pid;
+       void *stack;
+
+       /* main thread */
+       f((void *)0);
+
+       stack = mmap(NULL, 2 * PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+       assert(stack != MAP_FAILED);
+       /* side thread */
+       pid = clone(f, stack + PAGE_SIZE, CLONE_THREAD|CLONE_SIGHAND|CLONE_VM, (void *)1);
+       assert(pid > 0);
+       pause();
+
+       return 0;
+}
index f03763d816172e9a825ca896f0f3733e2109d503..30f9b54bd66689094d2556c354373cfc186a1932 100644 (file)
             "$TC actions flush action police"
         ]
     },
+    {
+        "id": "6aaf",
+        "name": "Add police actions with conform-exceed control pass/pipe [with numeric values]",
+        "category": [
+            "actions",
+            "police"
+        ],
+        "setup": [
+            [
+                "$TC actions flush action police",
+                0,
+                1,
+                255
+            ]
+        ],
+        "cmdUnderTest": "$TC actions add action police rate 3mbit burst 250k conform-exceed 0/3 index 1",
+        "expExitCode": "0",
+        "verifyCmd": "$TC actions get action police index 1",
+        "matchPattern": "action order [0-9]*:  police 0x1 rate 3Mbit burst 250Kb mtu 2Kb action pass/pipe",
+        "matchCount": "1",
+        "teardown": [
+            "$TC actions flush action police"
+        ]
+    },
+    {
+        "id": "29b1",
+        "name": "Add police actions with conform-exceed control <invalid>/drop",
+        "category": [
+            "actions",
+            "police"
+        ],
+        "setup": [
+            [
+                "$TC actions flush action police",
+                0,
+                1,
+                255
+            ]
+        ],
+        "cmdUnderTest": "$TC actions add action police rate 3mbit burst 250k conform-exceed 10/drop index 1",
+        "expExitCode": "255",
+        "verifyCmd": "$TC actions ls action police",
+        "matchPattern": "action order [0-9]*:  police 0x1 rate 3Mbit burst 250Kb mtu 2Kb action ",
+        "matchCount": "0",
+        "teardown": [
+            "$TC actions flush action police"
+        ]
+    },
     {
         "id": "c26f",
         "name": "Add police action with invalid peakrate value",
index f5d7a7851e2177b315111f4e8ae3f0b0a716487d..9e03d61f52fdfa911793010cc49b26e11bf3383f 100644 (file)
@@ -1,6 +1,14 @@
 # SPDX-License-Identifier: GPL-2.0
 include ../lib.mk
 
+uname_M := $(shell uname -m 2>/dev/null || echo not)
+ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
+
+TEST_GEN_PROGS := $(OUTPUT)/vdso_test
+ifeq ($(ARCH),x86)
+TEST_GEN_PROGS += $(OUTPUT)/vdso_standalone_test_x86
+endif
+
 ifndef CROSS_COMPILE
 CFLAGS := -std=gnu99
 CFLAGS_vdso_standalone_test_x86 := -nostdlib -fno-asynchronous-unwind-tables -fno-stack-protector
@@ -8,14 +16,11 @@ ifeq ($(CONFIG_X86_32),y)
 LDLIBS += -lgcc_s
 endif
 
-TEST_PROGS := $(OUTPUT)/vdso_test $(OUTPUT)/vdso_standalone_test_x86
-
-all: $(TEST_PROGS)
+all: $(TEST_GEN_PROGS)
 $(OUTPUT)/vdso_test: parse_vdso.c vdso_test.c
 $(OUTPUT)/vdso_standalone_test_x86: vdso_standalone_test_x86.c parse_vdso.c
        $(CC) $(CFLAGS) $(CFLAGS_vdso_standalone_test_x86) \
                vdso_standalone_test_x86.c parse_vdso.c \
                -o $@
 
-EXTRA_CLEAN := $(TEST_PROGS)
 endif
index 2df26bd0099ccb0033f0d48bbc4d9485bb42f5da..eda53f833d8e145c4a2ebec6884c319bc699de1c 100644 (file)
@@ -15,6 +15,8 @@
 #include <sys/auxv.h>
 #include <sys/time.h>
 
+#include "../kselftest.h"
+
 extern void *vdso_sym(const char *version, const char *name);
 extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
 extern void vdso_init_from_auxv(void *auxv);
@@ -37,7 +39,7 @@ int main(int argc, char **argv)
        unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
        if (!sysinfo_ehdr) {
                printf("AT_SYSINFO_EHDR is not present!\n");
-               return 0;
+               return KSFT_SKIP;
        }
 
        vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
@@ -48,7 +50,7 @@ int main(int argc, char **argv)
 
        if (!gtod) {
                printf("Could not find %s\n", name);
-               return 1;
+               return KSFT_SKIP;
        }
 
        struct timeval tv;
@@ -59,6 +61,7 @@ int main(int argc, char **argv)
                       (long long)tv.tv_sec, (long long)tv.tv_usec);
        } else {
                printf("%s failed\n", name);
+               return KSFT_FAIL;
        }
 
        return 0;
index 342c7bc9dc8c5d29441e27da5131d5312ea4bca8..af5ff83f6d7f85788de81f02eff7fa18d157bcf2 100644 (file)
@@ -1,6 +1,7 @@
 hugepage-mmap
 hugepage-shm
 map_hugetlb
+map_populate
 thuge-gen
 compaction_test
 mlock2-tests
index fdefa2295ddcd2255d794e620926fa3909dc770c..9881876d2aa0b065f0367a87ab184d41139360a3 100644 (file)
@@ -12,6 +12,7 @@ TEST_GEN_FILES += gup_benchmark
 TEST_GEN_FILES += hugepage-mmap
 TEST_GEN_FILES += hugepage-shm
 TEST_GEN_FILES += map_hugetlb
+TEST_GEN_FILES += map_populate
 TEST_GEN_FILES += mlock-random-test
 TEST_GEN_FILES += mlock2-tests
 TEST_GEN_FILES += on-fault-limit
diff --git a/tools/testing/selftests/vm/map_populate.c b/tools/testing/selftests/vm/map_populate.c
new file mode 100644 (file)
index 0000000..6b8aeaa
--- /dev/null
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Dmitry Safonov, Arista Networks
+ *
+ * MAP_POPULATE | MAP_PRIVATE should COW VMA pages.
+ */
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifndef MMAP_SZ
+#define MMAP_SZ                4096
+#endif
+
+#define BUG_ON(condition, description)                                 \
+       do {                                                            \
+               if (condition) {                                        \
+                       fprintf(stderr, "[FAIL]\t%s:%d\t%s:%s\n", __func__, \
+                               __LINE__, (description), strerror(errno)); \
+                       exit(1);                                        \
+               }                                                       \
+       } while (0)
+
+static int parent_f(int sock, unsigned long *smap, int child)
+{
+       int status, ret;
+
+       ret = read(sock, &status, sizeof(int));
+       BUG_ON(ret <= 0, "read(sock)");
+
+       *smap = 0x22222BAD;
+       ret = msync(smap, MMAP_SZ, MS_SYNC);
+       BUG_ON(ret, "msync()");
+
+       ret = write(sock, &status, sizeof(int));
+       BUG_ON(ret <= 0, "write(sock)");
+
+       waitpid(child, &status, 0);
+       BUG_ON(!WIFEXITED(status), "child in unexpected state");
+
+       return WEXITSTATUS(status);
+}
+
+static int child_f(int sock, unsigned long *smap, int fd)
+{
+       int ret, buf = 0;
+
+       smap = mmap(0, MMAP_SZ, PROT_READ | PROT_WRITE,
+                       MAP_PRIVATE | MAP_POPULATE, fd, 0);
+       BUG_ON(smap == MAP_FAILED, "mmap()");
+
+       BUG_ON(*smap != 0xdeadbabe, "MAP_PRIVATE | MAP_POPULATE changed file");
+
+       ret = write(sock, &buf, sizeof(int));
+       BUG_ON(ret <= 0, "write(sock)");
+
+       ret = read(sock, &buf, sizeof(int));
+       BUG_ON(ret <= 0, "read(sock)");
+
+       BUG_ON(*smap == 0x22222BAD, "MAP_POPULATE didn't COW private page");
+       BUG_ON(*smap != 0xdeadbabe, "mapping was corrupted");
+
+       return 0;
+}
+
+int main(int argc, char **argv)
+{
+       int sock[2], child, ret;
+       FILE *ftmp;
+       unsigned long *smap;
+
+       ftmp = tmpfile();
+       BUG_ON(ftmp == 0, "tmpfile()");
+
+       ret = ftruncate(fileno(ftmp), MMAP_SZ);
+       BUG_ON(ret, "ftruncate()");
+
+       smap = mmap(0, MMAP_SZ, PROT_READ | PROT_WRITE,
+                       MAP_SHARED, fileno(ftmp), 0);
+       BUG_ON(smap == MAP_FAILED, "mmap()");
+
+       *smap = 0xdeadbabe;
+       /* Probably unnecessary, but let it be. */
+       ret = msync(smap, MMAP_SZ, MS_SYNC);
+       BUG_ON(ret, "msync()");
+
+       ret = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sock);
+       BUG_ON(ret, "socketpair()");
+
+       child = fork();
+       BUG_ON(child == -1, "fork()");
+
+       if (child) {
+               ret = close(sock[0]);
+               BUG_ON(ret, "close()");
+
+               return parent_f(sock[1], smap, child);
+       }
+
+       ret = close(sock[1]);
+       BUG_ON(ret, "close()");
+
+       return child_f(sock[0], smap, fileno(ftmp));
+}
index 88cbe5575f0cf9e0d8f165ecbe27002a3c5ed8a1..584a91ae4a8f85e3c4dcf0baad7058abd8b3afea 100755 (executable)
@@ -167,6 +167,17 @@ else
        echo "[PASS]"
 fi
 
+echo "--------------------"
+echo "running map_populate"
+echo "--------------------"
+./map_populate
+if [ $? -ne 0 ]; then
+       echo "[FAIL]"
+       exitcode=1
+else
+       echo "[PASS]"
+fi
+
 echo "--------------------"
 echo "running mlock2-tests"
 echo "--------------------"
index 30cb0a0713fff9c63a158129cc5e59c115cb4e88..37908a83ddc27eac33d40f76ea869edf8bdd957d 100644 (file)
@@ -159,12 +159,6 @@ static const char * const page_flag_names[] = {
 };
 
 
-static const char * const debugfs_known_mountpoints[] = {
-       "/sys/kernel/debug",
-       "/debug",
-       0,
-};
-
 /*
  * data structures
  */
index f82c2eaa859d11fa755e8809dd9fce52af95fdec..334b16db0ebbe99b82855c80e641986c4f93edc8 100644 (file)
@@ -30,8 +30,8 @@ struct slabinfo {
        int alias;
        int refs;
        int aliases, align, cache_dma, cpu_slabs, destroy_by_rcu;
-       int hwcache_align, object_size, objs_per_slab;
-       int sanity_checks, slab_size, store_user, trace;
+       unsigned int hwcache_align, object_size, objs_per_slab;
+       unsigned int sanity_checks, slab_size, store_user, trace;
        int order, poison, reclaim_account, red_zone;
        unsigned long partial, objects, slabs, objects_partial, objects_total;
        unsigned long alloc_fastpath, alloc_slowpath;
index 237a028693ce9b497deabb95aa8f922485bee5fd..748f6a60bb1e00070dbc61a895ba19e4370b476f 100644 (file)
@@ -24,7 +24,7 @@ $(obj)/initramfs_data.o: $(obj)/$(datafile_y) FORCE
 # Generate the initramfs cpio archive
 
 hostprogs-y := gen_init_cpio
-initramfs   := $(CONFIG_SHELL) $(srctree)/scripts/gen_initramfs_list.sh
+initramfs   := $(CONFIG_SHELL) $(srctree)/$(src)/gen_initramfs_list.sh
 ramfs-input := $(if $(filter-out "",$(CONFIG_INITRAMFS_SOURCE)), \
                        $(shell echo $(CONFIG_INITRAMFS_SOURCE)),-d)
 ramfs-args  := \
diff --git a/usr/gen_initramfs_list.sh b/usr/gen_initramfs_list.sh
new file mode 100755 (executable)
index 0000000..0aad760
--- /dev/null
@@ -0,0 +1,328 @@
+#!/bin/sh
+# Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org>
+# Copyright (C) 2006 Sam Ravnborg <sam@ravnborg.org>
+#
+# Released under the terms of the GNU GPL
+#
+# Generate a cpio packed initramfs. It uses gen_init_cpio to generate
+# the cpio archive, and then compresses it.
+# The script may also be used to generate the inputfile used for gen_init_cpio
+# This script assumes that gen_init_cpio is located in usr/ directory
+
+# error out on errors
+set -e
+
+usage() {
+cat << EOF
+Usage:
+$0 [-o <file>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ...
+       -o <file>      Create compressed initramfs file named <file> using
+                      gen_init_cpio and compressor depending on the extension
+       -u <uid>       User ID to map to user ID 0 (root).
+                      <uid> is only meaningful if <cpio_source> is a
+                      directory.  "squash" forces all files to uid 0.
+       -g <gid>       Group ID to map to group ID 0 (root).
+                      <gid> is only meaningful if <cpio_source> is a
+                      directory.  "squash" forces all files to gid 0.
+       <cpio_source>  File list or directory for cpio archive.
+                      If <cpio_source> is a .cpio file it will be used
+                      as direct input to initramfs.
+       -d             Output the default cpio list.
+
+All options except -o and -l may be repeated and are interpreted
+sequentially and immediately.  -u and -g states are preserved across
+<cpio_source> options so an explicit "-u 0 -g 0" is required
+to reset the root/group mapping.
+EOF
+}
+
+# awk style field access
+# $1 - field number; rest is argument string
+field() {
+       shift $1 ; echo $1
+}
+
+list_default_initramfs() {
+       # echo usr/kinit/kinit
+       :
+}
+
+default_initramfs() {
+       cat <<-EOF >> ${output}
+               # This is a very simple, default initramfs
+
+               dir /dev 0755 0 0
+               nod /dev/console 0600 0 0 c 5 1
+               dir /root 0700 0 0
+               # file /kinit usr/kinit/kinit 0755 0 0
+               # slink /init kinit 0755 0 0
+       EOF
+}
+
+filetype() {
+       local argv1="$1"
+
+       # symlink test must come before file test
+       if [ -L "${argv1}" ]; then
+               echo "slink"
+       elif [ -f "${argv1}" ]; then
+               echo "file"
+       elif [ -d "${argv1}" ]; then
+               echo "dir"
+       elif [ -b "${argv1}" -o -c "${argv1}" ]; then
+               echo "nod"
+       elif [ -p "${argv1}" ]; then
+               echo "pipe"
+       elif [ -S "${argv1}" ]; then
+               echo "sock"
+       else
+               echo "invalid"
+       fi
+       return 0
+}
+
+list_print_mtime() {
+       :
+}
+
+print_mtime() {
+       local my_mtime="0"
+
+       if [ -e "$1" ]; then
+               my_mtime=$(find "$1" -printf "%T@\n" | sort -r | head -n 1)
+       fi
+
+       echo "# Last modified: ${my_mtime}" >> ${output}
+       echo "" >> ${output}
+}
+
+list_parse() {
+       if [ -L "$1" ]; then
+               return
+       fi
+       echo "$1" | sed 's/:/\\:/g; s/$/ \\/'
+}
+
+# for each file print a line in following format
+# <filetype> <name> <path to file> <octal mode> <uid> <gid>
+# for links, devices etc the format differs. See gen_init_cpio for details
+parse() {
+       local location="$1"
+       local name="/${location#${srcdir}}"
+       # change '//' into '/'
+       name=$(echo "$name" | sed -e 's://*:/:g')
+       local mode="$2"
+       local uid="$3"
+       local gid="$4"
+       local ftype=$(filetype "${location}")
+       # remap uid/gid to 0 if necessary
+       [ "$root_uid" = "squash" ] && uid=0 || [ "$uid" -eq "$root_uid" ] && uid=0
+       [ "$root_gid" = "squash" ] && gid=0 || [ "$gid" -eq "$root_gid" ] && gid=0
+       local str="${mode} ${uid} ${gid}"
+
+       [ "${ftype}" = "invalid" ] && return 0
+       [ "${location}" = "${srcdir}" ] && return 0
+
+       case "${ftype}" in
+               "file")
+                       str="${ftype} ${name} ${location} ${str}"
+                       ;;
+               "nod")
+                       local dev=`LC_ALL=C ls -l "${location}"`
+                       local maj=`field 5 ${dev}`
+                       local min=`field 6 ${dev}`
+                       maj=${maj%,}
+
+                       [ -b "${location}" ] && dev="b" || dev="c"
+
+                       str="${ftype} ${name} ${str} ${dev} ${maj} ${min}"
+                       ;;
+               "slink")
+                       local target=`readlink "${location}"`
+                       str="${ftype} ${name} ${target} ${str}"
+                       ;;
+               *)
+                       str="${ftype} ${name} ${str}"
+                       ;;
+       esac
+
+       echo "${str}" >> ${output}
+
+       return 0
+}
+
+unknown_option() {
+       printf "ERROR: unknown option \"$arg\"\n" >&2
+       printf "If the filename validly begins with '-', " >&2
+       printf "then it must be prefixed\n" >&2
+       printf "by './' so that it won't be interpreted as an option." >&2
+       printf "\n" >&2
+       usage >&2
+       exit 1
+}
+
+list_header() {
+       :
+}
+
+header() {
+       printf "\n#####################\n# $1\n" >> ${output}
+}
+
+# process one directory (incl sub-directories)
+dir_filelist() {
+       ${dep_list}header "$1"
+
+       srcdir=$(echo "$1" | sed -e 's://*:/:g')
+       dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | LANG=C sort)
+
+       # If $dirlist is only one line, then the directory is empty
+       if [  "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then
+               ${dep_list}print_mtime "$1"
+
+               echo "${dirlist}" | \
+               while read x; do
+                       ${dep_list}parse ${x}
+               done
+       fi
+}
+
+# if only one file is specified and it is .cpio file then use it direct as fs
+# if a directory is specified then add all files in given direcotry to fs
+# if a regular file is specified assume it is in gen_initramfs format
+input_file() {
+       source="$1"
+       if [ -f "$1" ]; then
+               ${dep_list}header "$1"
+               is_cpio="$(echo "$1" | sed 's/^.*\.cpio\(\..*\)\{0,1\}/cpio/')"
+               if [ $2 -eq 0 -a ${is_cpio} = "cpio" ]; then
+                       cpio_file=$1
+                       echo "$1" | grep -q '^.*\.cpio\..*' && is_cpio_compressed="compressed"
+                       [ ! -z ${dep_list} ] && echo "$1"
+                       return 0
+               fi
+               if [ -z ${dep_list} ]; then
+                       print_mtime "$1" >> ${output}
+                       cat "$1"         >> ${output}
+               else
+                       echo "$1 \\"
+                       cat "$1" | while read type dir file perm ; do
+                               if [ "$type" = "file" ]; then
+                                       echo "$file \\";
+                               fi
+                       done
+               fi
+       elif [ -d "$1" ]; then
+               dir_filelist "$1"
+       else
+               echo "  ${prog}: Cannot open '$1'" >&2
+               exit 1
+       fi
+}
+
+prog=$0
+root_uid=0
+root_gid=0
+dep_list=
+cpio_file=
+cpio_list=
+output="/dev/stdout"
+output_file=""
+is_cpio_compressed=
+compr="gzip -n -9 -f"
+
+arg="$1"
+case "$arg" in
+       "-l")   # files included in initramfs - used by kbuild
+               dep_list="list_"
+               echo "deps_initramfs := $0 \\"
+               shift
+               ;;
+       "-o")   # generate compressed cpio image named $1
+               shift
+               output_file="$1"
+               cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)"
+               output=${cpio_list}
+               echo "$output_file" | grep -q "\.gz$" \
+                && [ -x "`which gzip 2> /dev/null`" ] \
+                && compr="gzip -n -9 -f"
+               echo "$output_file" | grep -q "\.bz2$" \
+                && [ -x "`which bzip2 2> /dev/null`" ] \
+                && compr="bzip2 -9 -f"
+               echo "$output_file" | grep -q "\.lzma$" \
+                && [ -x "`which lzma 2> /dev/null`" ] \
+                && compr="lzma -9 -f"
+               echo "$output_file" | grep -q "\.xz$" \
+                && [ -x "`which xz 2> /dev/null`" ] \
+                && compr="xz --check=crc32 --lzma2=dict=1MiB"
+               echo "$output_file" | grep -q "\.lzo$" \
+                && [ -x "`which lzop 2> /dev/null`" ] \
+                && compr="lzop -9 -f"
+               echo "$output_file" | grep -q "\.lz4$" \
+                && [ -x "`which lz4 2> /dev/null`" ] \
+                && compr="lz4 -l -9 -f"
+               echo "$output_file" | grep -q "\.cpio$" && compr="cat"
+               shift
+               ;;
+esac
+while [ $# -gt 0 ]; do
+       arg="$1"
+       shift
+       case "$arg" in
+               "-u")   # map $1 to uid=0 (root)
+                       root_uid="$1"
+                       [ "$root_uid" = "-1" ] && root_uid=$(id -u || echo 0)
+                       shift
+                       ;;
+               "-g")   # map $1 to gid=0 (root)
+                       root_gid="$1"
+                       [ "$root_gid" = "-1" ] && root_gid=$(id -g || echo 0)
+                       shift
+                       ;;
+               "-d")   # display default initramfs list
+                       default_list="$arg"
+                       ${dep_list}default_initramfs
+                       ;;
+               "-h")
+                       usage
+                       exit 0
+                       ;;
+               *)
+                       case "$arg" in
+                               "-"*)
+                                       unknown_option
+                                       ;;
+                               *)      # input file/dir - process it
+                                       input_file "$arg" "$#"
+                                       ;;
+                       esac
+                       ;;
+       esac
+done
+
+# If output_file is set we will generate cpio archive and compress it
+# we are careful to delete tmp files
+if [ ! -z ${output_file} ]; then
+       if [ -z ${cpio_file} ]; then
+               timestamp=
+               if test -n "$KBUILD_BUILD_TIMESTAMP"; then
+                       timestamp="$(date -d"$KBUILD_BUILD_TIMESTAMP" +%s || :)"
+                       if test -n "$timestamp"; then
+                               timestamp="-t $timestamp"
+                       fi
+               fi
+               cpio_tfile="$(mktemp ${TMPDIR:-/tmp}/cpiofile.XXXXXX)"
+               usr/gen_init_cpio $timestamp ${cpio_list} > ${cpio_tfile}
+       else
+               cpio_tfile=${cpio_file}
+       fi
+       rm ${cpio_list}
+       if [ "${is_cpio_compressed}" = "compressed" ]; then
+               cat ${cpio_tfile} > ${output_file}
+       else
+               (cat ${cpio_tfile} | ${compr}  - > ${output_file}) \
+               || (rm -f ${output_file} ; false)
+       fi
+       [ -z ${cpio_file} ] && rm ${cpio_tfile}
+fi
+exit 0
index b28da799f6a6288c4e8c9b094ac10d3cb394cf04..d07648f05bbf8068adcb65fcf68991fbfb8480e9 100644 (file)
@@ -30,8 +30,8 @@ __irf_start:
 .incbin __stringify(INITRAMFS_IMAGE)
 __irf_end:
 .section .init.ramfs.info,"a"
-.globl VMLINUX_SYMBOL(__initramfs_size)
-VMLINUX_SYMBOL(__initramfs_size):
+.globl __initramfs_size
+__initramfs_size:
 #ifdef CONFIG_64BIT
        .quad __irf_end - __irf_start
 #else
index bd3d57f40f1be50205b0a295256af0910c704654..17cecc96f735e3785bb1f6a30e4e20ee613b4bcd 100644 (file)
@@ -295,9 +295,9 @@ static void phys_timer_emulate(struct kvm_vcpu *vcpu)
        struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
 
        /*
-        * If the timer can fire now we have just raised the IRQ line and we
-        * don't need to have a soft timer scheduled for the future.  If the
-        * timer cannot fire at all, then we also don't need a soft timer.
+        * If the timer can fire now, we don't need to have a soft timer
+        * scheduled for the future.  If the timer cannot fire at all,
+        * then we also don't need a soft timer.
         */
        if (kvm_timer_should_fire(ptimer) || !kvm_timer_irq_can_fire(ptimer)) {
                soft_timer_cancel(&timer->phys_timer, NULL);
@@ -332,10 +332,10 @@ static void kvm_timer_update_state(struct kvm_vcpu *vcpu)
        level = kvm_timer_should_fire(vtimer);
        kvm_timer_update_irq(vcpu, level, vtimer);
 
+       phys_timer_emulate(vcpu);
+
        if (kvm_timer_should_fire(ptimer) != ptimer->irq.level)
                kvm_timer_update_irq(vcpu, !ptimer->irq.level, ptimer);
-
-       phys_timer_emulate(vcpu);
 }
 
 static void vtimer_save_state(struct kvm_vcpu *vcpu)
@@ -487,6 +487,7 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
 {
        struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
        struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
+       struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
 
        if (unlikely(!timer->enabled))
                return;
@@ -502,6 +503,10 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
 
        /* Set the background timer for the physical timer emulation. */
        phys_timer_emulate(vcpu);
+
+       /* If the timer fired while we weren't running, inject it now */
+       if (kvm_timer_should_fire(ptimer) != ptimer->irq.level)
+               kvm_timer_update_irq(vcpu, !ptimer->irq.level, ptimer);
 }
 
 bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu)
index 108250e4d37640846c36c991420eafe3d4cbb18a..c92053bc3f96f875db4d2443ce79ab065fa2a00b 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/kvm.h>
 #include <linux/kvm_irqfd.h>
 #include <linux/irqbypass.h>
+#include <linux/sched/stat.h>
 #include <trace/events/kvm.h>
 #include <kvm/arm_pmu.h>
 #include <kvm/arm_psci.h>
@@ -380,6 +381,11 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
        kvm_timer_vcpu_load(vcpu);
        kvm_vcpu_load_sysregs(vcpu);
        kvm_arch_vcpu_load_fp(vcpu);
+
+       if (single_task_running())
+               vcpu_clear_wfe_traps(vcpu);
+       else
+               vcpu_set_wfe_traps(vcpu);
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
@@ -1044,6 +1050,32 @@ static int kvm_arm_vcpu_has_attr(struct kvm_vcpu *vcpu,
        return ret;
 }
 
+static int kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
+                                  struct kvm_vcpu_events *events)
+{
+       memset(events, 0, sizeof(*events));
+
+       return __kvm_arm_vcpu_get_events(vcpu, events);
+}
+
+static int kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
+                                  struct kvm_vcpu_events *events)
+{
+       int i;
+
+       /* check whether the reserved field is zero */
+       for (i = 0; i < ARRAY_SIZE(events->reserved); i++)
+               if (events->reserved[i])
+                       return -EINVAL;
+
+       /* check whether the pad field is zero */
+       for (i = 0; i < ARRAY_SIZE(events->exception.pad); i++)
+               if (events->exception.pad[i])
+                       return -EINVAL;
+
+       return __kvm_arm_vcpu_set_events(vcpu, events);
+}
+
 long kvm_arch_vcpu_ioctl(struct file *filp,
                         unsigned int ioctl, unsigned long arg)
 {
@@ -1124,6 +1156,25 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
                r = kvm_arm_vcpu_has_attr(vcpu, &attr);
                break;
        }
+       case KVM_GET_VCPU_EVENTS: {
+               struct kvm_vcpu_events events;
+
+               if (kvm_arm_vcpu_get_events(vcpu, &events))
+                       return -EINVAL;
+
+               if (copy_to_user(argp, &events, sizeof(events)))
+                       return -EFAULT;
+
+               return 0;
+       }
+       case KVM_SET_VCPU_EVENTS: {
+               struct kvm_vcpu_events events;
+
+               if (copy_from_user(&events, argp, sizeof(events)))
+                       return -EFAULT;
+
+               return kvm_arm_vcpu_set_events(vcpu, &events);
+       }
        default:
                r = -EINVAL;
        }
index 1d90d79706bd5b71d3914ecd808d2bd6c127286c..ed162a6c57c597d89a7f08600b84a4425feb0b13 100644 (file)
@@ -177,6 +177,35 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
        put_page(virt_to_page(pmd));
 }
 
+static inline void kvm_set_pte(pte_t *ptep, pte_t new_pte)
+{
+       WRITE_ONCE(*ptep, new_pte);
+       dsb(ishst);
+}
+
+static inline void kvm_set_pmd(pmd_t *pmdp, pmd_t new_pmd)
+{
+       WRITE_ONCE(*pmdp, new_pmd);
+       dsb(ishst);
+}
+
+static inline void kvm_pmd_populate(pmd_t *pmdp, pte_t *ptep)
+{
+       kvm_set_pmd(pmdp, kvm_mk_pmd(ptep));
+}
+
+static inline void kvm_pud_populate(pud_t *pudp, pmd_t *pmdp)
+{
+       WRITE_ONCE(*pudp, kvm_mk_pud(pmdp));
+       dsb(ishst);
+}
+
+static inline void kvm_pgd_populate(pgd_t *pgdp, pud_t *pudp)
+{
+       WRITE_ONCE(*pgdp, kvm_mk_pgd(pudp));
+       dsb(ishst);
+}
+
 /*
  * Unmapping vs dcache management:
  *
@@ -196,6 +225,10 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
  * This is why right after unmapping a page/section and invalidating
  * the corresponding TLBs, we call kvm_flush_dcache_p*() to make sure
  * the IO subsystem will never hit in the cache.
+ *
+ * This is all avoided on systems that have ARM64_HAS_STAGE2_FWB, as
+ * we then fully enforce cacheability of RAM, no matter what the guest
+ * does.
  */
 static void unmap_stage2_ptes(struct kvm *kvm, pmd_t *pmd,
                       phys_addr_t addr, phys_addr_t end)
@@ -576,7 +609,6 @@ static void create_hyp_pte_mappings(pmd_t *pmd, unsigned long start,
                pte = pte_offset_kernel(pmd, addr);
                kvm_set_pte(pte, pfn_pte(pfn, prot));
                get_page(virt_to_page(pte));
-               kvm_flush_dcache_to_poc(pte, sizeof(*pte));
                pfn++;
        } while (addr += PAGE_SIZE, addr != end);
 }
@@ -601,9 +633,8 @@ static int create_hyp_pmd_mappings(pud_t *pud, unsigned long start,
                                kvm_err("Cannot allocate Hyp pte\n");
                                return -ENOMEM;
                        }
-                       pmd_populate_kernel(NULL, pmd, pte);
+                       kvm_pmd_populate(pmd, pte);
                        get_page(virt_to_page(pmd));
-                       kvm_flush_dcache_to_poc(pmd, sizeof(*pmd));
                }
 
                next = pmd_addr_end(addr, end);
@@ -634,9 +665,8 @@ static int create_hyp_pud_mappings(pgd_t *pgd, unsigned long start,
                                kvm_err("Cannot allocate Hyp pmd\n");
                                return -ENOMEM;
                        }
-                       pud_populate(NULL, pud, pmd);
+                       kvm_pud_populate(pud, pmd);
                        get_page(virt_to_page(pud));
-                       kvm_flush_dcache_to_poc(pud, sizeof(*pud));
                }
 
                next = pud_addr_end(addr, end);
@@ -671,9 +701,8 @@ static int __create_hyp_mappings(pgd_t *pgdp, unsigned long ptrs_per_pgd,
                                err = -ENOMEM;
                                goto out;
                        }
-                       pgd_populate(NULL, pgd, pud);
+                       kvm_pgd_populate(pgd, pud);
                        get_page(virt_to_page(pgd));
-                       kvm_flush_dcache_to_poc(pgd, sizeof(*pgd));
                }
 
                next = pgd_addr_end(addr, end);
@@ -1015,19 +1044,35 @@ static int stage2_set_pmd_huge(struct kvm *kvm, struct kvm_mmu_memory_cache
        pmd = stage2_get_pmd(kvm, cache, addr);
        VM_BUG_ON(!pmd);
 
-       /*
-        * Mapping in huge pages should only happen through a fault.  If a
-        * page is merged into a transparent huge page, the individual
-        * subpages of that huge page should be unmapped through MMU
-        * notifiers before we get here.
-        *
-        * Merging of CompoundPages is not supported; they should become
-        * splitting first, unmapped, merged, and mapped back in on-demand.
-        */
-       VM_BUG_ON(pmd_present(*pmd) && pmd_pfn(*pmd) != pmd_pfn(*new_pmd));
-
        old_pmd = *pmd;
        if (pmd_present(old_pmd)) {
+               /*
+                * Multiple vcpus faulting on the same PMD entry, can
+                * lead to them sequentially updating the PMD with the
+                * same value. Following the break-before-make
+                * (pmd_clear() followed by tlb_flush()) process can
+                * hinder forward progress due to refaults generated
+                * on missing translations.
+                *
+                * Skip updating the page table if the entry is
+                * unchanged.
+                */
+               if (pmd_val(old_pmd) == pmd_val(*new_pmd))
+                       return 0;
+
+               /*
+                * Mapping in huge pages should only happen through a
+                * fault.  If a page is merged into a transparent huge
+                * page, the individual subpages of that huge page
+                * should be unmapped through MMU notifiers before we
+                * get here.
+                *
+                * Merging of CompoundPages is not supported; they
+                * should become splitting first, unmapped, merged,
+                * and mapped back in on-demand.
+                */
+               VM_BUG_ON(pmd_pfn(old_pmd) != pmd_pfn(*new_pmd));
+
                pmd_clear(pmd);
                kvm_tlb_flush_vmid_ipa(kvm, addr);
        } else {
@@ -1090,7 +1135,7 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
                if (!cache)
                        return 0; /* ignore calls from kvm_set_spte_hva */
                pte = mmu_memory_cache_alloc(cache);
-               pmd_populate_kernel(NULL, pmd, pte);
+               kvm_pmd_populate(pmd, pte);
                get_page(virt_to_page(pmd));
        }
 
@@ -1102,6 +1147,10 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
        /* Create 2nd stage page table mapping - Level 3 */
        old_pte = *pte;
        if (pte_present(old_pte)) {
+               /* Skip page table update if there is no change */
+               if (pte_val(old_pte) == pte_val(*new_pte))
+                       return 0;
+
                kvm_set_pte(pte, __pte(0));
                kvm_tlb_flush_vmid_ipa(kvm, addr);
        } else {
@@ -1768,18 +1817,6 @@ static int kvm_unmap_hva_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *dat
        return 0;
 }
 
-int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
-{
-       unsigned long end = hva + PAGE_SIZE;
-
-       if (!kvm->arch.pgd)
-               return 0;
-
-       trace_kvm_unmap_hva(hva);
-       handle_hva_to_gpa(kvm, hva, end, &kvm_unmap_hva_handler, NULL);
-       return 0;
-}
-
 int kvm_unmap_hva_range(struct kvm *kvm,
                        unsigned long start, unsigned long end)
 {
@@ -1811,13 +1848,20 @@ static int kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *data
 void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte)
 {
        unsigned long end = hva + PAGE_SIZE;
+       kvm_pfn_t pfn = pte_pfn(pte);
        pte_t stage2_pte;
 
        if (!kvm->arch.pgd)
                return;
 
        trace_kvm_set_spte_hva(hva);
-       stage2_pte = pfn_pte(pte_pfn(pte), PAGE_S2);
+
+       /*
+        * We've moved a page around, probably through CoW, so let's treat it
+        * just like a translation fault and clean the cache to the PoC.
+        */
+       clean_dcache_guest_page(pfn, PAGE_SIZE);
+       stage2_pte = pfn_pte(pfn, PAGE_S2);
        handle_hva_to_gpa(kvm, hva, end, &kvm_set_spte_handler, &stage2_pte);
 }
 
index e53b596f483b99f0a7f9d897938b30f47a079316..57b3edebbb4043e7cbeef0f834ccc2a1848caf78 100644 (file)
@@ -134,21 +134,6 @@ TRACE_EVENT(kvm_mmio_emulate,
                  __entry->vcpu_pc, __entry->instr, __entry->cpsr)
 );
 
-TRACE_EVENT(kvm_unmap_hva,
-       TP_PROTO(unsigned long hva),
-       TP_ARGS(hva),
-
-       TP_STRUCT__entry(
-               __field(        unsigned long,  hva             )
-       ),
-
-       TP_fast_assign(
-               __entry->hva            = hva;
-       ),
-
-       TP_printk("mmu notifier unmap hva: %#08lx", __entry->hva)
-);
-
 TRACE_EVENT(kvm_unmap_hva_range,
        TP_PROTO(unsigned long start, unsigned long end),
        TP_ARGS(start, end),
index c589d4c2b478b2df7ada6cee1837340c762a41b5..07aa900bac56a3aa5d85dadc462225905c2c4f0f 100644 (file)
 struct vgic_state_iter {
        int nr_cpus;
        int nr_spis;
+       int nr_lpis;
        int dist_id;
        int vcpu_id;
        int intid;
+       int lpi_idx;
+       u32 *lpi_array;
 };
 
 static void iter_next(struct vgic_state_iter *iter)
@@ -52,6 +55,12 @@ static void iter_next(struct vgic_state_iter *iter)
        if (iter->intid == VGIC_NR_PRIVATE_IRQS &&
            ++iter->vcpu_id < iter->nr_cpus)
                iter->intid = 0;
+
+       if (iter->intid >= (iter->nr_spis + VGIC_NR_PRIVATE_IRQS)) {
+               if (iter->lpi_idx < iter->nr_lpis)
+                       iter->intid = iter->lpi_array[iter->lpi_idx];
+               iter->lpi_idx++;
+       }
 }
 
 static void iter_init(struct kvm *kvm, struct vgic_state_iter *iter,
@@ -63,6 +72,11 @@ static void iter_init(struct kvm *kvm, struct vgic_state_iter *iter,
 
        iter->nr_cpus = nr_cpus;
        iter->nr_spis = kvm->arch.vgic.nr_spis;
+       if (kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
+               iter->nr_lpis = vgic_copy_lpi_list(kvm, NULL, &iter->lpi_array);
+               if (iter->nr_lpis < 0)
+                       iter->nr_lpis = 0;
+       }
 
        /* Fast forward to the right position if needed */
        while (pos--)
@@ -73,7 +87,8 @@ static bool end_of_vgic(struct vgic_state_iter *iter)
 {
        return iter->dist_id > 0 &&
                iter->vcpu_id == iter->nr_cpus &&
-               (iter->intid - VGIC_NR_PRIVATE_IRQS) == iter->nr_spis;
+               iter->intid >= (iter->nr_spis + VGIC_NR_PRIVATE_IRQS) &&
+               iter->lpi_idx > iter->nr_lpis;
 }
 
 static void *vgic_debug_start(struct seq_file *s, loff_t *pos)
@@ -130,6 +145,7 @@ static void vgic_debug_stop(struct seq_file *s, void *v)
 
        mutex_lock(&kvm->lock);
        iter = kvm->arch.vgic.iter;
+       kfree(iter->lpi_array);
        kfree(iter);
        kvm->arch.vgic.iter = NULL;
        mutex_unlock(&kvm->lock);
@@ -137,17 +153,20 @@ static void vgic_debug_stop(struct seq_file *s, void *v)
 
 static void print_dist_state(struct seq_file *s, struct vgic_dist *dist)
 {
+       bool v3 = dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3;
+
        seq_printf(s, "Distributor\n");
        seq_printf(s, "===========\n");
-       seq_printf(s, "vgic_model:\t%s\n",
-                  (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) ?
-                  "GICv3" : "GICv2");
+       seq_printf(s, "vgic_model:\t%s\n", v3 ? "GICv3" : "GICv2");
        seq_printf(s, "nr_spis:\t%d\n", dist->nr_spis);
+       if (v3)
+               seq_printf(s, "nr_lpis:\t%d\n", dist->lpi_list_count);
        seq_printf(s, "enabled:\t%d\n", dist->enabled);
        seq_printf(s, "\n");
 
        seq_printf(s, "P=pending_latch, L=line_level, A=active\n");
        seq_printf(s, "E=enabled, H=hw, C=config (level=1, edge=0)\n");
+       seq_printf(s, "G=group\n");
 }
 
 static void print_header(struct seq_file *s, struct vgic_irq *irq,
@@ -162,8 +181,8 @@ static void print_header(struct seq_file *s, struct vgic_irq *irq,
        }
 
        seq_printf(s, "\n");
-       seq_printf(s, "%s%2d TYP   ID TGT_ID PLAEHC     HWID   TARGET SRC PRI VCPU_ID\n", hdr, id);
-       seq_printf(s, "---------------------------------------------------------------\n");
+       seq_printf(s, "%s%2d TYP   ID TGT_ID PLAEHCG     HWID   TARGET SRC PRI VCPU_ID\n", hdr, id);
+       seq_printf(s, "----------------------------------------------------------------\n");
 }
 
 static void print_irq_state(struct seq_file *s, struct vgic_irq *irq,
@@ -174,15 +193,17 @@ static void print_irq_state(struct seq_file *s, struct vgic_irq *irq,
                type = "SGI";
        else if (irq->intid < VGIC_NR_PRIVATE_IRQS)
                type = "PPI";
-       else
+       else if (irq->intid < VGIC_MAX_SPI)
                type = "SPI";
+       else
+               type = "LPI";
 
        if (irq->intid ==0 || irq->intid == VGIC_NR_PRIVATE_IRQS)
                print_header(s, irq, vcpu);
 
        seq_printf(s, "       %s %4d "
                      "    %2d "
-                     "%d%d%d%d%d%d "
+                     "%d%d%d%d%d%d%d "
                      "%8d "
                      "%8x "
                      " %2x "
@@ -197,12 +218,12 @@ static void print_irq_state(struct seq_file *s, struct vgic_irq *irq,
                        irq->enabled,
                        irq->hw,
                        irq->config == VGIC_CONFIG_LEVEL,
+                       irq->group,
                        irq->hwintid,
                        irq->mpidr,
                        irq->source,
                        irq->priority,
                        (irq->vcpu) ? irq->vcpu->vcpu_id : -1);
-
 }
 
 static int vgic_debug_show(struct seq_file *s, void *v)
@@ -221,17 +242,20 @@ static int vgic_debug_show(struct seq_file *s, void *v)
        if (!kvm->arch.vgic.initialized)
                return 0;
 
-       if (iter->vcpu_id < iter->nr_cpus) {
+       if (iter->vcpu_id < iter->nr_cpus)
                vcpu = kvm_get_vcpu(kvm, iter->vcpu_id);
-               irq = &vcpu->arch.vgic_cpu.private_irqs[iter->intid];
-       } else {
-               irq = &kvm->arch.vgic.spis[iter->intid - VGIC_NR_PRIVATE_IRQS];
+
+       irq = vgic_get_irq(kvm, vcpu, iter->intid);
+       if (!irq) {
+               seq_printf(s, "       LPI %4d freed\n", iter->intid);
+               return 0;
        }
 
        spin_lock_irqsave(&irq->irq_lock, flags);
        print_irq_state(s, irq, vcpu);
        spin_unlock_irqrestore(&irq->irq_lock, flags);
 
+       vgic_put_irq(kvm, irq);
        return 0;
 }
 
index 2673efce65f34ac95511f555377981e78119f248..c0c0b88af1d58c0e1c3015424be66272f4873845 100644 (file)
@@ -175,10 +175,13 @@ static int kvm_vgic_dist_init(struct kvm *kvm, unsigned int nr_spis)
                irq->vcpu = NULL;
                irq->target_vcpu = vcpu0;
                kref_init(&irq->refcount);
-               if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2)
+               if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2) {
                        irq->targets = 0;
-               else
+                       irq->group = 0;
+               } else {
                        irq->mpidr = 0;
+                       irq->group = 1;
+               }
        }
        return 0;
 }
@@ -227,6 +230,18 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
                        /* PPIs */
                        irq->config = VGIC_CONFIG_LEVEL;
                }
+
+               /*
+                * GICv3 can only be created via the KVM_DEVICE_CREATE API and
+                * so we always know the emulation type at this point as it's
+                * either explicitly configured as GICv3, or explicitly
+                * configured as GICv2, or not configured yet which also
+                * implies GICv2.
+                */
+               if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
+                       irq->group = 1;
+               else
+                       irq->group = 0;
        }
 
        if (!irqchip_in_kernel(vcpu->kvm))
@@ -271,6 +286,10 @@ int vgic_init(struct kvm *kvm)
        if (vgic_initialized(kvm))
                return 0;
 
+       /* Are we also in the middle of creating a VCPU? */
+       if (kvm->created_vcpus != atomic_read(&kvm->online_vcpus))
+               return -EBUSY;
+
        /* freeze the number of spis */
        if (!dist->nr_spis)
                dist->nr_spis = VGIC_NR_IRQS_LEGACY - VGIC_NR_PRIVATE_IRQS;
@@ -294,6 +313,7 @@ int vgic_init(struct kvm *kvm)
 
        vgic_debug_init(kvm);
 
+       dist->implementation_rev = 2;
        dist->initialized = true;
 
 out:
index 4ed79c939fb447188d0a2bc7c740e85e1d82135c..12502251727eb9aaf35bd1caa63e32a193082042 100644 (file)
@@ -71,6 +71,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid,
        kref_init(&irq->refcount);
        irq->intid = intid;
        irq->target_vcpu = vcpu;
+       irq->group = 1;
 
        spin_lock_irqsave(&dist->lpi_list_lock, flags);
 
@@ -168,8 +169,14 @@ struct vgic_its_abi {
        int (*commit)(struct vgic_its *its);
 };
 
+#define ABI_0_ESZ      8
+#define ESZ_MAX                ABI_0_ESZ
+
 static const struct vgic_its_abi its_table_abi_versions[] = {
-       [0] = {.cte_esz = 8, .dte_esz = 8, .ite_esz = 8,
+       [0] = {
+        .cte_esz = ABI_0_ESZ,
+        .dte_esz = ABI_0_ESZ,
+        .ite_esz = ABI_0_ESZ,
         .save_tables = vgic_its_save_tables_v0,
         .restore_tables = vgic_its_restore_tables_v0,
         .commit = vgic_its_commit_v0,
@@ -183,7 +190,7 @@ inline const struct vgic_its_abi *vgic_its_get_abi(struct vgic_its *its)
        return &its_table_abi_versions[its->abi_rev];
 }
 
-int vgic_its_set_abi(struct vgic_its *its, int rev)
+static int vgic_its_set_abi(struct vgic_its *its, u32 rev)
 {
        const struct vgic_its_abi *abi;
 
@@ -312,9 +319,9 @@ static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
  * enumerate those LPIs without holding any lock.
  * Returns their number and puts the kmalloc'ed array into intid_ptr.
  */
-static int vgic_copy_lpi_list(struct kvm_vcpu *vcpu, u32 **intid_ptr)
+int vgic_copy_lpi_list(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 **intid_ptr)
 {
-       struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
+       struct vgic_dist *dist = &kvm->arch.vgic;
        struct vgic_irq *irq;
        unsigned long flags;
        u32 *intids;
@@ -337,7 +344,7 @@ static int vgic_copy_lpi_list(struct kvm_vcpu *vcpu, u32 **intid_ptr)
                if (i == irq_count)
                        break;
                /* We don't need to "get" the IRQ, as we hold the list lock. */
-               if (irq->target_vcpu != vcpu)
+               if (vcpu && irq->target_vcpu != vcpu)
                        continue;
                intids[i++] = irq->intid;
        }
@@ -429,7 +436,7 @@ static int its_sync_lpi_pending_table(struct kvm_vcpu *vcpu)
        unsigned long flags;
        u8 pendmask;
 
-       nr_irqs = vgic_copy_lpi_list(vcpu, &intids);
+       nr_irqs = vgic_copy_lpi_list(vcpu->kvm, vcpu, &intids);
        if (nr_irqs < 0)
                return nr_irqs;
 
@@ -1154,7 +1161,7 @@ static int vgic_its_cmd_handle_invall(struct kvm *kvm, struct vgic_its *its,
 
        vcpu = kvm_get_vcpu(kvm, collection->target_addr);
 
-       irq_count = vgic_copy_lpi_list(vcpu, &intids);
+       irq_count = vgic_copy_lpi_list(kvm, vcpu, &intids);
        if (irq_count < 0)
                return irq_count;
 
@@ -1202,7 +1209,7 @@ static int vgic_its_cmd_handle_movall(struct kvm *kvm, struct vgic_its *its,
        vcpu1 = kvm_get_vcpu(kvm, target1_addr);
        vcpu2 = kvm_get_vcpu(kvm, target2_addr);
 
-       irq_count = vgic_copy_lpi_list(vcpu1, &intids);
+       irq_count = vgic_copy_lpi_list(kvm, vcpu1, &intids);
        if (irq_count < 0)
                return irq_count;
 
@@ -1881,14 +1888,14 @@ typedef int (*entry_fn_t)(struct vgic_its *its, u32 id, void *entry,
  * Return: < 0 on error, 0 if last element was identified, 1 otherwise
  * (the last element may not be found on second level tables)
  */
-static int scan_its_table(struct vgic_its *its, gpa_t base, int size, int esz,
+static int scan_its_table(struct vgic_its *its, gpa_t base, int size, u32 esz,
                          int start_id, entry_fn_t fn, void *opaque)
 {
        struct kvm *kvm = its->dev->kvm;
        unsigned long len = size;
        int id = start_id;
        gpa_t gpa = base;
-       char entry[esz];
+       char entry[ESZ_MAX];
        int ret;
 
        memset(entry, 0, esz);
index ffc587bf4742676d14930d21f07005275576a79e..738b65d2d0e76587d24fa0a44f7107c05400cc49 100644 (file)
 #include "vgic.h"
 #include "vgic-mmio.h"
 
+/*
+ * The Revision field in the IIDR have the following meanings:
+ *
+ * Revision 1: Report GICv2 interrupts as group 0 instead of group 1
+ * Revision 2: Interrupt groups are guest-configurable and signaled using
+ *            their configured groups.
+ */
+
 static unsigned long vgic_mmio_read_v2_misc(struct kvm_vcpu *vcpu,
                                            gpa_t addr, unsigned int len)
 {
+       struct vgic_dist *vgic = &vcpu->kvm->arch.vgic;
        u32 value;
 
        switch (addr & 0x0c) {
        case GIC_DIST_CTRL:
-               value = vcpu->kvm->arch.vgic.enabled ? GICD_ENABLE : 0;
+               value = vgic->enabled ? GICD_ENABLE : 0;
                break;
        case GIC_DIST_CTR:
-               value = vcpu->kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS;
+               value = vgic->nr_spis + VGIC_NR_PRIVATE_IRQS;
                value = (value >> 5) - 1;
                value |= (atomic_read(&vcpu->kvm->online_vcpus) - 1) << 5;
                break;
        case GIC_DIST_IIDR:
-               value = (PRODUCT_ID_KVM << 24) | (IMPLEMENTER_ARM << 0);
+               value = (PRODUCT_ID_KVM << GICD_IIDR_PRODUCT_ID_SHIFT) |
+                       (vgic->implementation_rev << GICD_IIDR_REVISION_SHIFT) |
+                       (IMPLEMENTER_ARM << GICD_IIDR_IMPLEMENTER_SHIFT);
                break;
        default:
                return 0;
@@ -66,6 +77,42 @@ static void vgic_mmio_write_v2_misc(struct kvm_vcpu *vcpu,
        }
 }
 
+static int vgic_mmio_uaccess_write_v2_misc(struct kvm_vcpu *vcpu,
+                                          gpa_t addr, unsigned int len,
+                                          unsigned long val)
+{
+       switch (addr & 0x0c) {
+       case GIC_DIST_IIDR:
+               if (val != vgic_mmio_read_v2_misc(vcpu, addr, len))
+                       return -EINVAL;
+
+               /*
+                * If we observe a write to GICD_IIDR we know that userspace
+                * has been updated and has had a chance to cope with older
+                * kernels (VGICv2 IIDR.Revision == 0) incorrectly reporting
+                * interrupts as group 1, and therefore we now allow groups to
+                * be user writable.  Doing this by default would break
+                * migration from old kernels to new kernels with legacy
+                * userspace.
+                */
+               vcpu->kvm->arch.vgic.v2_groups_user_writable = true;
+               return 0;
+       }
+
+       vgic_mmio_write_v2_misc(vcpu, addr, len, val);
+       return 0;
+}
+
+static int vgic_mmio_uaccess_write_v2_group(struct kvm_vcpu *vcpu,
+                                           gpa_t addr, unsigned int len,
+                                           unsigned long val)
+{
+       if (vcpu->kvm->arch.vgic.v2_groups_user_writable)
+               vgic_mmio_write_group(vcpu, addr, len, val);
+
+       return 0;
+}
+
 static void vgic_mmio_write_sgir(struct kvm_vcpu *source_vcpu,
                                 gpa_t addr, unsigned int len,
                                 unsigned long val)
@@ -352,17 +399,22 @@ static void vgic_mmio_write_apr(struct kvm_vcpu *vcpu,
 
                if (n > vgic_v3_max_apr_idx(vcpu))
                        return;
+
+               n = array_index_nospec(n, 4);
+
                /* GICv3 only uses ICH_AP1Rn for memory mapped (GICv2) guests */
                vgicv3->vgic_ap1r[n] = val;
        }
 }
 
 static const struct vgic_register_region vgic_v2_dist_registers[] = {
-       REGISTER_DESC_WITH_LENGTH(GIC_DIST_CTRL,
-               vgic_mmio_read_v2_misc, vgic_mmio_write_v2_misc, 12,
-               VGIC_ACCESS_32bit),
+       REGISTER_DESC_WITH_LENGTH_UACCESS(GIC_DIST_CTRL,
+               vgic_mmio_read_v2_misc, vgic_mmio_write_v2_misc,
+               NULL, vgic_mmio_uaccess_write_v2_misc,
+               12, VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_IGROUP,
-               vgic_mmio_read_rao, vgic_mmio_write_wi, NULL, NULL, 1,
+               vgic_mmio_read_group, vgic_mmio_write_group,
+               NULL, vgic_mmio_uaccess_write_v2_group, 1,
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ(GIC_DIST_ENABLE_SET,
                vgic_mmio_read_enable, vgic_mmio_write_senable, NULL, NULL, 1,
index 287784095b5b30a28c380d53f90bfcee977aa434..a2a175b08b172877c0e58c39e4c45db432b970ac 100644 (file)
@@ -59,19 +59,27 @@ bool vgic_supports_direct_msis(struct kvm *kvm)
        return kvm_vgic_global_state.has_gicv4 && vgic_has_its(kvm);
 }
 
+/*
+ * The Revision field in the IIDR have the following meanings:
+ *
+ * Revision 2: Interrupt groups are guest-configurable and signaled using
+ *            their configured groups.
+ */
+
 static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
                                            gpa_t addr, unsigned int len)
 {
+       struct vgic_dist *vgic = &vcpu->kvm->arch.vgic;
        u32 value = 0;
 
        switch (addr & 0x0c) {
        case GICD_CTLR:
-               if (vcpu->kvm->arch.vgic.enabled)
+               if (vgic->enabled)
                        value |= GICD_CTLR_ENABLE_SS_G1;
                value |= GICD_CTLR_ARE_NS | GICD_CTLR_DS;
                break;
        case GICD_TYPER:
-               value = vcpu->kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS;
+               value = vgic->nr_spis + VGIC_NR_PRIVATE_IRQS;
                value = (value >> 5) - 1;
                if (vgic_has_its(vcpu->kvm)) {
                        value |= (INTERRUPT_ID_BITS_ITS - 1) << 19;
@@ -81,7 +89,9 @@ static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
                }
                break;
        case GICD_IIDR:
-               value = (PRODUCT_ID_KVM << 24) | (IMPLEMENTER_ARM << 0);
+               value = (PRODUCT_ID_KVM << GICD_IIDR_PRODUCT_ID_SHIFT) |
+                       (vgic->implementation_rev << GICD_IIDR_REVISION_SHIFT) |
+                       (IMPLEMENTER_ARM << GICD_IIDR_IMPLEMENTER_SHIFT);
                break;
        default:
                return 0;
@@ -110,6 +120,20 @@ static void vgic_mmio_write_v3_misc(struct kvm_vcpu *vcpu,
        }
 }
 
+static int vgic_mmio_uaccess_write_v3_misc(struct kvm_vcpu *vcpu,
+                                          gpa_t addr, unsigned int len,
+                                          unsigned long val)
+{
+       switch (addr & 0x0c) {
+       case GICD_IIDR:
+               if (val != vgic_mmio_read_v3_misc(vcpu, addr, len))
+                       return -EINVAL;
+       }
+
+       vgic_mmio_write_v3_misc(vcpu, addr, len, val);
+       return 0;
+}
+
 static unsigned long vgic_mmio_read_irouter(struct kvm_vcpu *vcpu,
                                            gpa_t addr, unsigned int len)
 {
@@ -246,9 +270,9 @@ static unsigned long vgic_v3_uaccess_read_pending(struct kvm_vcpu *vcpu,
        return value;
 }
 
-static void vgic_v3_uaccess_write_pending(struct kvm_vcpu *vcpu,
-                                         gpa_t addr, unsigned int len,
-                                         unsigned long val)
+static int vgic_v3_uaccess_write_pending(struct kvm_vcpu *vcpu,
+                                        gpa_t addr, unsigned int len,
+                                        unsigned long val)
 {
        u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
        int i;
@@ -273,6 +297,8 @@ static void vgic_v3_uaccess_write_pending(struct kvm_vcpu *vcpu,
 
                vgic_put_irq(vcpu->kvm, irq);
        }
+
+       return 0;
 }
 
 /* We want to avoid outer shareable. */
@@ -444,14 +470,15 @@ static void vgic_mmio_write_pendbase(struct kvm_vcpu *vcpu,
        }
 
 static const struct vgic_register_region vgic_v3_dist_registers[] = {
-       REGISTER_DESC_WITH_LENGTH(GICD_CTLR,
-               vgic_mmio_read_v3_misc, vgic_mmio_write_v3_misc, 16,
-               VGIC_ACCESS_32bit),
+       REGISTER_DESC_WITH_LENGTH_UACCESS(GICD_CTLR,
+               vgic_mmio_read_v3_misc, vgic_mmio_write_v3_misc,
+               NULL, vgic_mmio_uaccess_write_v3_misc,
+               16, VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_LENGTH(GICD_STATUSR,
                vgic_mmio_read_rao, vgic_mmio_write_wi, 4,
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_IGROUPR,
-               vgic_mmio_read_rao, vgic_mmio_write_wi, NULL, NULL, 1,
+               vgic_mmio_read_group, vgic_mmio_write_group, NULL, NULL, 1,
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ISENABLER,
                vgic_mmio_read_enable, vgic_mmio_write_senable, NULL, NULL, 1,
@@ -465,7 +492,7 @@ static const struct vgic_register_region vgic_v3_dist_registers[] = {
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ICPENDR,
                vgic_mmio_read_pending, vgic_mmio_write_cpending,
-               vgic_mmio_read_raz, vgic_mmio_write_wi, 1,
+               vgic_mmio_read_raz, vgic_mmio_uaccess_write_wi, 1,
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_BITS_PER_IRQ_SHARED(GICD_ISACTIVER,
                vgic_mmio_read_active, vgic_mmio_write_sactive,
@@ -524,7 +551,7 @@ static const struct vgic_register_region vgic_v3_rdbase_registers[] = {
 
 static const struct vgic_register_region vgic_v3_sgibase_registers[] = {
        REGISTER_DESC_WITH_LENGTH(GICR_IGROUPR0,
-               vgic_mmio_read_rao, vgic_mmio_write_wi, 4,
+               vgic_mmio_read_group, vgic_mmio_write_group, 4,
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_LENGTH(GICR_ISENABLER0,
                vgic_mmio_read_enable, vgic_mmio_write_senable, 4,
@@ -538,7 +565,7 @@ static const struct vgic_register_region vgic_v3_sgibase_registers[] = {
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_LENGTH_UACCESS(GICR_ICPENDR0,
                vgic_mmio_read_pending, vgic_mmio_write_cpending,
-               vgic_mmio_read_raz, vgic_mmio_write_wi, 4,
+               vgic_mmio_read_raz, vgic_mmio_uaccess_write_wi, 4,
                VGIC_ACCESS_32bit),
        REGISTER_DESC_WITH_LENGTH_UACCESS(GICR_ISACTIVER0,
                vgic_mmio_read_active, vgic_mmio_write_sactive,
@@ -873,7 +900,8 @@ static int match_mpidr(u64 sgi_aff, u16 sgi_cpu_mask, struct kvm_vcpu *vcpu)
 /**
  * vgic_v3_dispatch_sgi - handle SGI requests from VCPUs
  * @vcpu: The VCPU requesting a SGI
- * @reg: The value written into the ICC_SGI1R_EL1 register by that VCPU
+ * @reg: The value written into ICC_{ASGI1,SGI0,SGI1}R by that VCPU
+ * @allow_group1: Does the sysreg access allow generation of G1 SGIs
  *
  * With GICv3 (and ARE=1) CPUs trigger SGIs by writing to a system register.
  * This will trap in sys_regs.c and call this function.
@@ -883,7 +911,7 @@ static int match_mpidr(u64 sgi_aff, u16 sgi_cpu_mask, struct kvm_vcpu *vcpu)
  * check for matching ones. If this bit is set, we signal all, but not the
  * calling VCPU.
  */
-void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg)
+void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg, bool allow_group1)
 {
        struct kvm *kvm = vcpu->kvm;
        struct kvm_vcpu *c_vcpu;
@@ -932,9 +960,19 @@ void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg)
                irq = vgic_get_irq(vcpu->kvm, c_vcpu, sgi);
 
                spin_lock_irqsave(&irq->irq_lock, flags);
-               irq->pending_latch = true;
 
-               vgic_queue_irq_unlock(vcpu->kvm, irq, flags);
+               /*
+                * An access targetting Group0 SGIs can only generate
+                * those, while an access targetting Group1 SGIs can
+                * generate interrupts of either group.
+                */
+               if (!irq->group || allow_group1) {
+                       irq->pending_latch = true;
+                       vgic_queue_irq_unlock(vcpu->kvm, irq, flags);
+               } else {
+                       spin_unlock_irqrestore(&irq->irq_lock, flags);
+               }
+
                vgic_put_irq(vcpu->kvm, irq);
        }
 }
index ff9655cfeb2f8678558163790de2aeb6ec5841df..f56ff1cf52ec25fc73aa15e4b1f909ef755c95d4 100644 (file)
@@ -40,6 +40,51 @@ void vgic_mmio_write_wi(struct kvm_vcpu *vcpu, gpa_t addr,
        /* Ignore */
 }
 
+int vgic_mmio_uaccess_write_wi(struct kvm_vcpu *vcpu, gpa_t addr,
+                              unsigned int len, unsigned long val)
+{
+       /* Ignore */
+       return 0;
+}
+
+unsigned long vgic_mmio_read_group(struct kvm_vcpu *vcpu,
+                                  gpa_t addr, unsigned int len)
+{
+       u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
+       u32 value = 0;
+       int i;
+
+       /* Loop over all IRQs affected by this read */
+       for (i = 0; i < len * 8; i++) {
+               struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
+
+               if (irq->group)
+                       value |= BIT(i);
+
+               vgic_put_irq(vcpu->kvm, irq);
+       }
+
+       return value;
+}
+
+void vgic_mmio_write_group(struct kvm_vcpu *vcpu, gpa_t addr,
+                          unsigned int len, unsigned long val)
+{
+       u32 intid = VGIC_ADDR_TO_INTID(addr, 1);
+       int i;
+       unsigned long flags;
+
+       for (i = 0; i < len * 8; i++) {
+               struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
+
+               spin_lock_irqsave(&irq->irq_lock, flags);
+               irq->group = !!(val & BIT(i));
+               vgic_queue_irq_unlock(vcpu->kvm, irq, flags);
+
+               vgic_put_irq(vcpu->kvm, irq);
+       }
+}
+
 /*
  * Read accesses to both GICD_ICENABLER and GICD_ISENABLER return the value
  * of the enabled bit, so there is only one function for both here.
@@ -363,11 +408,12 @@ void vgic_mmio_write_cactive(struct kvm_vcpu *vcpu,
        mutex_unlock(&vcpu->kvm->lock);
 }
 
-void vgic_mmio_uaccess_write_cactive(struct kvm_vcpu *vcpu,
+int vgic_mmio_uaccess_write_cactive(struct kvm_vcpu *vcpu,
                                     gpa_t addr, unsigned int len,
                                     unsigned long val)
 {
        __vgic_mmio_write_cactive(vcpu, addr, len, val);
+       return 0;
 }
 
 static void __vgic_mmio_write_sactive(struct kvm_vcpu *vcpu,
@@ -399,11 +445,12 @@ void vgic_mmio_write_sactive(struct kvm_vcpu *vcpu,
        mutex_unlock(&vcpu->kvm->lock);
 }
 
-void vgic_mmio_uaccess_write_sactive(struct kvm_vcpu *vcpu,
+int vgic_mmio_uaccess_write_sactive(struct kvm_vcpu *vcpu,
                                     gpa_t addr, unsigned int len,
                                     unsigned long val)
 {
        __vgic_mmio_write_sactive(vcpu, addr, len, val);
+       return 0;
 }
 
 unsigned long vgic_mmio_read_priority(struct kvm_vcpu *vcpu,
@@ -735,10 +782,9 @@ static int vgic_uaccess_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
 
        r_vcpu = iodev->redist_vcpu ? iodev->redist_vcpu : vcpu;
        if (region->uaccess_write)
-               region->uaccess_write(r_vcpu, addr, sizeof(u32), *val);
-       else
-               region->write(r_vcpu, addr, sizeof(u32), *val);
+               return region->uaccess_write(r_vcpu, addr, sizeof(u32), *val);
 
+       region->write(r_vcpu, addr, sizeof(u32), *val);
        return 0;
 }
 
index 5693f6df45ecd57e5d7b28aecc1579f87cdcd91e..a07f90acdaecb4af617326912a7a2edab1c83425 100644 (file)
@@ -37,8 +37,8 @@ struct vgic_register_region {
        unsigned long (*uaccess_read)(struct kvm_vcpu *vcpu, gpa_t addr,
                                      unsigned int len);
        union {
-               void (*uaccess_write)(struct kvm_vcpu *vcpu, gpa_t addr,
-                                     unsigned int len, unsigned long val);
+               int (*uaccess_write)(struct kvm_vcpu *vcpu, gpa_t addr,
+                                    unsigned int len, unsigned long val);
                int (*uaccess_its_write)(struct kvm *kvm, struct vgic_its *its,
                                         gpa_t addr, unsigned int len,
                                         unsigned long val);
@@ -134,6 +134,15 @@ unsigned long vgic_mmio_read_rao(struct kvm_vcpu *vcpu,
 void vgic_mmio_write_wi(struct kvm_vcpu *vcpu, gpa_t addr,
                        unsigned int len, unsigned long val);
 
+int vgic_mmio_uaccess_write_wi(struct kvm_vcpu *vcpu, gpa_t addr,
+                              unsigned int len, unsigned long val);
+
+unsigned long vgic_mmio_read_group(struct kvm_vcpu *vcpu, gpa_t addr,
+                                  unsigned int len);
+
+void vgic_mmio_write_group(struct kvm_vcpu *vcpu, gpa_t addr,
+                          unsigned int len, unsigned long val);
+
 unsigned long vgic_mmio_read_enable(struct kvm_vcpu *vcpu,
                                    gpa_t addr, unsigned int len);
 
@@ -167,13 +176,13 @@ void vgic_mmio_write_sactive(struct kvm_vcpu *vcpu,
                             gpa_t addr, unsigned int len,
                             unsigned long val);
 
-void vgic_mmio_uaccess_write_cactive(struct kvm_vcpu *vcpu,
-                                    gpa_t addr, unsigned int len,
-                                    unsigned long val);
+int vgic_mmio_uaccess_write_cactive(struct kvm_vcpu *vcpu,
+                                   gpa_t addr, unsigned int len,
+                                   unsigned long val);
 
-void vgic_mmio_uaccess_write_sactive(struct kvm_vcpu *vcpu,
-                                    gpa_t addr, unsigned int len,
-                                    unsigned long val);
+int vgic_mmio_uaccess_write_sactive(struct kvm_vcpu *vcpu,
+                                   gpa_t addr, unsigned int len,
+                                   unsigned long val);
 
 unsigned long vgic_mmio_read_priority(struct kvm_vcpu *vcpu,
                                      gpa_t addr, unsigned int len);
index a5f2e44f1c33d42ad2693d63b8142665864e64a6..69b892abd7dc6faec17e820fe6f4c0f95800ecb3 100644 (file)
@@ -62,7 +62,8 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
        struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
        struct vgic_v2_cpu_if *cpuif = &vgic_cpu->vgic_v2;
        int lr;
-       unsigned long flags;
+
+       DEBUG_SPINLOCK_BUG_ON(!irqs_disabled());
 
        cpuif->vgic_hcr &= ~GICH_HCR_UIE;
 
@@ -83,7 +84,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
 
                irq = vgic_get_irq(vcpu->kvm, vcpu, intid);
 
-               spin_lock_irqsave(&irq->irq_lock, flags);
+               spin_lock(&irq->irq_lock);
 
                /* Always preserve the active bit */
                irq->active = !!(val & GICH_LR_ACTIVE_BIT);
@@ -126,7 +127,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
                                vgic_irq_set_phys_active(irq, false);
                }
 
-               spin_unlock_irqrestore(&irq->irq_lock, flags);
+               spin_unlock(&irq->irq_lock);
                vgic_put_irq(vcpu->kvm, irq);
        }
 
@@ -159,6 +160,9 @@ void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
                }
        }
 
+       if (irq->group)
+               val |= GICH_LR_GROUP1;
+
        if (irq->hw) {
                val |= GICH_LR_HW;
                val |= irq->hwintid << GICH_LR_PHYSID_CPUID_SHIFT;
index cdce653e3c47fb31b9eb0ccf73c3bebd830d8496..9c0dd234ebe8112f601e81083de436d5547b5c55 100644 (file)
@@ -46,7 +46,8 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
        struct vgic_v3_cpu_if *cpuif = &vgic_cpu->vgic_v3;
        u32 model = vcpu->kvm->arch.vgic.vgic_model;
        int lr;
-       unsigned long flags;
+
+       DEBUG_SPINLOCK_BUG_ON(!irqs_disabled());
 
        cpuif->vgic_hcr &= ~ICH_HCR_UIE;
 
@@ -75,7 +76,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
                if (!irq)       /* An LPI could have been unmapped. */
                        continue;
 
-               spin_lock_irqsave(&irq->irq_lock, flags);
+               spin_lock(&irq->irq_lock);
 
                /* Always preserve the active bit */
                irq->active = !!(val & ICH_LR_ACTIVE_BIT);
@@ -118,7 +119,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
                                vgic_irq_set_phys_active(irq, false);
                }
 
-               spin_unlock_irqrestore(&irq->irq_lock, flags);
+               spin_unlock(&irq->irq_lock);
                vgic_put_irq(vcpu->kvm, irq);
        }
 
@@ -197,11 +198,7 @@ void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
        if (vgic_irq_is_mapped_level(irq) && (val & ICH_LR_PENDING_BIT))
                irq->line_level = false;
 
-       /*
-        * We currently only support Group1 interrupts, which is a
-        * known defect. This needs to be addressed at some point.
-        */
-       if (model == KVM_DEV_TYPE_ARM_VGIC_V3)
+       if (irq->group)
                val |= ICH_LR_GROUP;
 
        val |= (u64)irq->priority << ICH_LR_PRIORITY_SHIFT;
index 33c8325c8f35662c03c37319605d28e2f2f9d7a4..7cfdfbc910e0c48e38b9f6eaaefacbbe71d043fc 100644 (file)
 #define CREATE_TRACE_POINTS
 #include "trace.h"
 
-#ifdef CONFIG_DEBUG_SPINLOCK
-#define DEBUG_SPINLOCK_BUG_ON(p) BUG_ON(p)
-#else
-#define DEBUG_SPINLOCK_BUG_ON(p)
-#endif
-
 struct vgic_global kvm_vgic_global_state __ro_after_init = {
        .gicv3_cpuif = STATIC_KEY_FALSE_INIT,
 };
@@ -599,10 +593,11 @@ static void vgic_prune_ap_list(struct kvm_vcpu *vcpu)
 {
        struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
        struct vgic_irq *irq, *tmp;
-       unsigned long flags;
+
+       DEBUG_SPINLOCK_BUG_ON(!irqs_disabled());
 
 retry:
-       spin_lock_irqsave(&vgic_cpu->ap_list_lock, flags);
+       spin_lock(&vgic_cpu->ap_list_lock);
 
        list_for_each_entry_safe(irq, tmp, &vgic_cpu->ap_list_head, ap_list) {
                struct kvm_vcpu *target_vcpu, *vcpuA, *vcpuB;
@@ -643,7 +638,7 @@ retry:
                /* This interrupt looks like it has to be migrated. */
 
                spin_unlock(&irq->irq_lock);
-               spin_unlock_irqrestore(&vgic_cpu->ap_list_lock, flags);
+               spin_unlock(&vgic_cpu->ap_list_lock);
 
                /*
                 * Ensure locking order by always locking the smallest
@@ -657,7 +652,7 @@ retry:
                        vcpuB = vcpu;
                }
 
-               spin_lock_irqsave(&vcpuA->arch.vgic_cpu.ap_list_lock, flags);
+               spin_lock(&vcpuA->arch.vgic_cpu.ap_list_lock);
                spin_lock_nested(&vcpuB->arch.vgic_cpu.ap_list_lock,
                                 SINGLE_DEPTH_NESTING);
                spin_lock(&irq->irq_lock);
@@ -682,7 +677,7 @@ retry:
 
                spin_unlock(&irq->irq_lock);
                spin_unlock(&vcpuB->arch.vgic_cpu.ap_list_lock);
-               spin_unlock_irqrestore(&vcpuA->arch.vgic_cpu.ap_list_lock, flags);
+               spin_unlock(&vcpuA->arch.vgic_cpu.ap_list_lock);
 
                if (target_vcpu_needs_kick) {
                        kvm_make_request(KVM_REQ_IRQ_PENDING, target_vcpu);
@@ -692,7 +687,7 @@ retry:
                goto retry;
        }
 
-       spin_unlock_irqrestore(&vgic_cpu->ap_list_lock, flags);
+       spin_unlock(&vgic_cpu->ap_list_lock);
 }
 
 static inline void vgic_fold_lr_state(struct kvm_vcpu *vcpu)
index ead00b2072b260321c31330e20a8031b5ba362d8..a90024718ca44b941e8b4d7aa0f6bf20233c4596 100644 (file)
 #define KVM_VGIC_V3_RDIST_COUNT_MASK   GENMASK_ULL(63, 52)
 #define KVM_VGIC_V3_RDIST_COUNT_SHIFT  52
 
+#ifdef CONFIG_DEBUG_SPINLOCK
+#define DEBUG_SPINLOCK_BUG_ON(p) BUG_ON(p)
+#else
+#define DEBUG_SPINLOCK_BUG_ON(p)
+#endif
+
 /* Requires the irq_lock to be held by the caller. */
 static inline bool irq_is_pending(struct vgic_irq *irq)
 {
@@ -305,6 +311,7 @@ static inline bool vgic_dist_overlap(struct kvm *kvm, gpa_t base, size_t size)
                (base < d->vgic_dist_base + KVM_VGIC_V3_DIST_SIZE);
 }
 
+int vgic_copy_lpi_list(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 **intid_ptr);
 int vgic_its_resolve_lpi(struct kvm *kvm, struct vgic_its *its,
                         u32 devid, u32 eventid, struct vgic_irq **irq);
 struct vgic_its *vgic_msi_to_its(struct kvm *kvm, struct kvm_msi *msi);
index 9263ead9fd32506250d5559feaf008d10a5e5846..f986e31fa68cceaf8b16385e9869dc5e2bf55e4a 100644 (file)
@@ -140,9 +140,10 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm);
 static unsigned long long kvm_createvm_count;
 static unsigned long long kvm_active_vms;
 
-__weak void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
-               unsigned long start, unsigned long end)
+__weak int kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
+               unsigned long start, unsigned long end, bool blockable)
 {
+       return 0;
 }
 
 bool kvm_is_reserved_pfn(kvm_pfn_t pfn)
@@ -360,13 +361,15 @@ static void kvm_mmu_notifier_change_pte(struct mmu_notifier *mn,
        srcu_read_unlock(&kvm->srcu, idx);
 }
 
-static void kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
+static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
                                                    struct mm_struct *mm,
                                                    unsigned long start,
-                                                   unsigned long end)
+                                                   unsigned long end,
+                                                   bool blockable)
 {
        struct kvm *kvm = mmu_notifier_to_kvm(mn);
        int need_tlb_flush = 0, idx;
+       int ret;
 
        idx = srcu_read_lock(&kvm->srcu);
        spin_lock(&kvm->mmu_lock);
@@ -384,9 +387,11 @@ static void kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
 
        spin_unlock(&kvm->mmu_lock);
 
-       kvm_arch_mmu_notifier_invalidate_range(kvm, start, end);
+       ret = kvm_arch_mmu_notifier_invalidate_range(kvm, start, end, blockable);
 
        srcu_read_unlock(&kvm->srcu, idx);
+
+       return ret;
 }
 
 static void kvm_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
@@ -2568,7 +2573,7 @@ static long kvm_vcpu_ioctl(struct file *filp,
                if (arg)
                        goto out;
                oldpid = rcu_access_pointer(vcpu->pid);
-               if (unlikely(oldpid != current->pids[PIDTYPE_PID].pid)) {
+               if (unlikely(oldpid != task_pid(current))) {
                        /* The thread running this VCPU changed. */
                        struct pid *newpid;